From: "Kubacki, Michael A" <michael.a.kubacki@intel.com>
To: "Wei, David Y" <david.y.wei@intel.com>,
"devel@edk2.groups.io" <devel@edk2.groups.io>
Cc: "Wu, Hao A" <hao.a.wu@intel.com>,
"Gao, Liming" <liming.gao@intel.com>,
"Sinha, Ankit" <ankit.sinha@intel.com>,
"Agyeman, Prince" <prince.agyeman@intel.com>,
"Desimone, Nathaniel L" <nathaniel.l.desimone@intel.com>,
"Kinney, Michael D" <michael.d.kinney@intel.com>
Subject: Re: [edk2-platforms PATCH v4 3/7] SimicsOpenBoardPkg: Add SimicsOpenBoardPkg and its modules
Date: Wed, 4 Sep 2019 06:40:22 +0000 [thread overview]
Message-ID: <49AB4ACB9627B8468F29D589A27B745588AA0250@ORSMSX121.amr.corp.intel.com> (raw)
In-Reply-To: <e9ed36dae4c261640f5928b0af885ba7ffc9ce87.1567199162.git.david.y.wei@intel.com>
It would be helpful to expand the QSP acronym (Quick Start Package) in the commit message before being committed.
Reviewed-by: Michael Kubacki <michael.a.kubacki@intel.com>
> -----Original Message-----
> From: Wei, David Y
> Sent: Friday, August 30, 2019 2:19 PM
> To: devel@edk2.groups.io
> Cc: Wu, Hao A <hao.a.wu@intel.com>; Gao, Liming <liming.gao@intel.com>;
> Sinha, Ankit <ankit.sinha@intel.com>; Agyeman, Prince
> <prince.agyeman@intel.com>; Kubacki, Michael A
> <michael.a.kubacki@intel.com>; Desimone, Nathaniel L
> <nathaniel.l.desimone@intel.com>; Kinney, Michael D
> <michael.d.kinney@intel.com>
> Subject: [edk2-platforms PATCH v4 3/7] SimicsOpenBoardPkg: Add
> SimicsOpenBoardPkg and its modules
>
> Add modules Include, Library, SimicsDxe, SimicsPei, Policy, SmbiosPlatformDxe
> and SecCore for Simics QSP platform support
>
> Cc: Hao Wu <hao.a.wu@intel.com>
> Cc: Liming Gao <liming.gao@intel.com>
> Cc: Ankit Sinha <ankit.sinha@intel.com>
> Cc: Agyeman Prince <prince.agyeman@intel.com>
> Cc: Kubacki Michael A <michael.a.kubacki@intel.com>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
>
> Signed-off-by: David Wei <david.y.wei@intel.com>
> ---
> .../SimicsOpenBoardPkg/Library/DxeLogoLib/Logo.c | 647 ++++++++
> .../Library/LoadLinuxLib/Linux.c | 662 +++++++++
> .../Library/LoadLinuxLib/LinuxGdt.c | 175 +++
> .../Library/NvVarsFileLib/FsAccess.c | 507 +++++++
> .../Library/NvVarsFileLib/NvVarsFileLib.c | 77 +
> .../Library/PciHostBridgeLib/PciHostBridgeLib.c | 419 ++++++
> .../SimicsOpenBoardPkg/Library/PeiReportFvLib/Fv.c | 100 ++
> .../Library/PeiReportFvLib/PeiReportFvLib.c | 119 ++
> .../Library/PlatformBootManagerLib/BdsPlatform.c | 1553
> ++++++++++++++++++++
> .../Library/PlatformBootManagerLib/PlatformData.c | 35 +
> .../SerializeVariablesLib/SerializeVariablesLib.c | 869 +++++++++++
> .../SiliconPolicyInitLib/SiliconPolicyInitLib.c | 108 ++
> .../SiliconPolicyUpdateLib.c | 70 +
> .../Intel/SimicsOpenBoardPkg/SecCore/SecMain.c | 956 ++++++++++++
> .../Intel/SimicsOpenBoardPkg/SimicsDxe/Platform.c | 865 +++++++++++
> .../SimicsOpenBoardPkg/SimicsDxe/PlatformConfig.c | 124 ++
> Platform/Intel/SimicsOpenBoardPkg/SimicsPei/Cmos.c | 57 +
> .../SimicsOpenBoardPkg/SimicsPei/FeatureControl.c | 115 ++
> .../Intel/SimicsOpenBoardPkg/SimicsPei/MemDetect.c | 568 +++++++
> .../Intel/SimicsOpenBoardPkg/SimicsPei/Platform.c | 630 ++++++++
> .../SmbiosPlatformDxe/SmbiosPlatformDxe.c | 148 ++
> .../Include/Guid/SimicsBoardConfig.h | 18 +
> .../Include/IndustryStandard/I440FxPiix4.h | 50 +
> .../Include/IndustryStandard/LinuxBzImage.h | 159 ++
> .../Include/Library/LoadLinuxLib.h | 205 +++
> .../Include/Library/SerializeVariablesLib.h | 224 +++
> .../SimicsOpenBoardPkg/Include/SimicsPlatforms.h | 55 +
> .../Library/DxeLogoLib/DxeLogoLib.inf | 55 +
> .../Library/DxeLogoLib/OemBadging.h | 83 ++
> .../Library/LoadLinuxLib/DxeLoadLinuxLib.inf | 42 +
> .../Library/LoadLinuxLib/Ia32/JumpToKernel.nasm | 41 +
> .../Library/LoadLinuxLib/LoadLinuxLib.h | 52 +
> .../Library/LoadLinuxLib/X64/JumpToKernel.nasm | 85 ++
> .../Library/NvVarsFileLib/NvVarsFileLib.h | 55 +
> .../Library/NvVarsFileLib/NvVarsFileLib.inf | 53 +
> .../Library/PciHostBridgeLib/PciHostBridge.h | 68 +
> .../Library/PciHostBridgeLib/PciHostBridgeLib.inf | 51 +
> .../Library/PeiReportFvLib/PeiReportFvLib.inf | 56 +
> .../Library/PlatformBootManagerLib/BdsPlatform.h | 172 +++
> .../PlatformBootManagerLib.inf | 72 +
> .../SerializeVariablesLib/SerializeVariablesLib.h | 33 +
> .../SerializeVariablesLib.inf | 36 +
> .../SiliconPolicyInitLib/SiliconPolicyInitLib.inf | 38 +
> .../SiliconPolicyUpdateLib.inf | 35 +
> .../SimicsOpenBoardPkg/SecCore/Ia32/SecEntry.nasm | 45 +
> .../Intel/SimicsOpenBoardPkg/SecCore/SecMain.inf | 73 +
> .../SimicsOpenBoardPkg/SecCore/X64/SecEntry.nasm | 45 +
> .../Intel/SimicsOpenBoardPkg/SimicsDxe/Platform.h | 38 +
> .../SimicsOpenBoardPkg/SimicsDxe/Platform.uni | 31 +
> .../SimicsOpenBoardPkg/SimicsDxe/PlatformConfig.h | 52 +
> .../SimicsOpenBoardPkg/SimicsDxe/PlatformForms.vfr | 67 +
> .../SimicsOpenBoardPkg/SimicsDxe/SimicsDxe.inf | 65 +
> Platform/Intel/SimicsOpenBoardPkg/SimicsPei/Cmos.h | 50 +
> .../Intel/SimicsOpenBoardPkg/SimicsPei/Platform.h | 88 ++
> .../SimicsOpenBoardPkg/SimicsPei/SimicsPei.inf | 104 ++
> .../SmbiosPlatformDxe/SmbiosPlatformDxe.h | 38 +
> .../SmbiosPlatformDxe/SmbiosPlatformDxe.inf | 51 +
> 57 files changed, 11289 insertions(+)
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Library/DxeLogoLib/Logo.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/Linux.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/LinuxGdt.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/FsAccess.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/NvVarsFileLib.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Library/PciHostBridgeLib/PciHostBridgeLib.
> c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Library/PeiReportFvLib/Fv.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Library/PeiReportFvLib/PeiReportFvLib.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Library/PlatformBootManagerLib/BdsPlatf
> orm.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Library/PlatformBootManagerLib/Platform
> Data.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVaria
> blesLib.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyInitLib/SiliconPo
> licyInitLib.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyUpdateLib/Silic
> onPolicyUpdateLib.c
> create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SecCore/SecMain.c
> create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/Platform.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/PlatformConfig.c
> create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SimicsPei/Cmos.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/SimicsPei/FeatureControl.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/SimicsPei/MemDetect.c
> create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SimicsPei/Platform.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Include/Guid/SimicsBoardConfig.h
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Include/IndustryStandard/I440FxPiix4.h
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Include/IndustryStandard/LinuxBzImage.h
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Include/Library/LoadLinuxLib.h
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Include/Library/SerializeVariablesLib.h
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Include/SimicsPlatforms.h
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Library/DxeLogoLib/DxeLogoLib.inf
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Library/DxeLogoLib/OemBadging.h
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/DxeLoadLinuxLib.inf
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/Ia32/JumpToKernel.n
> asm
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/LoadLinuxLib.h
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/X64/JumpToKernel.n
> asm
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/NvVarsFileLib.h
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/NvVarsFileLib.inf
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Library/PciHostBridgeLib/PciHostBridge.h
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Library/PciHostBridgeLib/PciHostBridgeLib.
> inf
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Library/PeiReportFvLib/PeiReportFvLib.inf
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Library/PlatformBootManagerLib/BdsPlatf
> orm.h
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Library/PlatformBootManagerLib/Platform
> BootManagerLib.inf
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVaria
> blesLib.h
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVaria
> blesLib.inf
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyInitLib/SiliconPo
> licyInitLib.inf
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyUpdateLib/Silic
> onPolicyUpdateLib.inf
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/SecCore/Ia32/SecEntry.nasm
> create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SecCore/SecMain.inf
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/SecCore/X64/SecEntry.nasm
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/Platform.h
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/Platform.uni
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/PlatformConfig.h
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/PlatformForms.vfr
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/SimicsDxe.inf
> create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SimicsPei/Cmos.h
> create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SimicsPei/Platform.h
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/SimicsPei/SimicsPei.inf
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.h
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.in
> f
>
> diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/DxeLogoLib/Logo.c
> b/Platform/Intel/SimicsOpenBoardPkg/Library/DxeLogoLib/Logo.c
> new file mode 100644
> index 0000000000..48a718a90d
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/Library/DxeLogoLib/Logo.c
> @@ -0,0 +1,647 @@
> +/** @file
> + BDS Lib functions which contain all the code to connect console device
> +
> + Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <PiDxe.h>
> +#include <Protocol/SimpleTextOut.h>
> +#include <OemBadging.h>
> +#include <Protocol/GraphicsOutput.h>
> +#include <Protocol/UgaDraw.h>
> +#include <Library/BaseLib.h>
> +#include <Library/UefiLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/DxeServicesLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/DebugLib.h>
> +
> +#include <IndustryStandard/Bmp.h>
> +#include <Protocol/BootLogo.h>
> +
> +/**
> + Convert a *.BMP graphics image to a GOP blt buffer. If a NULL Blt buffer
> + is passed in a GopBlt buffer will be allocated by this routine. If a GopBlt
> + buffer is passed in it will be used if it is big enough.
> +
> + @param BmpImage Pointer to BMP file
> + @param BmpImageSize Number of bytes in BmpImage
> + @param GopBlt Buffer containing GOP version of BmpImage.
> + @param GopBltSize Size of GopBlt in bytes.
> + @param PixelHeight Height of GopBlt/BmpImage in pixels
> + @param PixelWidth Width of GopBlt/BmpImage in pixels
> +
> + @retval EFI_SUCCESS GopBlt and GopBltSize are returned.
> + @retval EFI_UNSUPPORTED BmpImage is not a valid *.BMP image
> + @retval EFI_BUFFER_TOO_SMALL The passed in GopBlt buffer is not big
> enough.
> + GopBltSize will contain the required size.
> + @retval EFI_OUT_OF_RESOURCES No enough buffer to allocate.
> +
> +**/
> +EFI_STATUS
> +ConvertBmpToGopBlt (
> + IN VOID *BmpImage,
> + IN UINTN BmpImageSize,
> + IN OUT VOID **GopBlt,
> + IN OUT UINTN *GopBltSize,
> + OUT UINTN *PixelHeight,
> + OUT UINTN *PixelWidth
> + )
> +{
> + UINT8 *Image;
> + UINT8 *ImageHeader;
> + BMP_IMAGE_HEADER *BmpHeader;
> + BMP_COLOR_MAP *BmpColorMap;
> + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer;
> + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt;
> + UINT64 BltBufferSize;
> + UINTN Index;
> + UINTN Height;
> + UINTN Width;
> + UINTN ImageIndex;
> + UINT32 DataSizePerLine;
> + BOOLEAN IsAllocated;
> + UINT32 ColorMapNum;
> +
> + if (sizeof (BMP_IMAGE_HEADER) > BmpImageSize) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + BmpHeader = (BMP_IMAGE_HEADER *) BmpImage;
> +
> + if (BmpHeader->CharB != 'B' || BmpHeader->CharM != 'M') {
> + return EFI_UNSUPPORTED;
> + }
> +
> + //
> + // Doesn't support compress.
> + //
> + if (BmpHeader->CompressionType != 0) {
> + return EFI_UNSUPPORTED;
> + }
> +
> + //
> + // Only support BITMAPINFOHEADER format.
> + // BITMAPFILEHEADER + BITMAPINFOHEADER = BMP_IMAGE_HEADER
> + //
> + if (BmpHeader->HeaderSize != sizeof (BMP_IMAGE_HEADER) -
> OFFSET_OF(BMP_IMAGE_HEADER, HeaderSize)) {
> + return EFI_UNSUPPORTED;
> + }
> +
> + //
> + // The data size in each line must be 4 byte alignment.
> + //
> + DataSizePerLine = ((BmpHeader->PixelWidth * BmpHeader->BitPerPixel + 31)
> >> 3) & (~0x3);
> + BltBufferSize = MultU64x32 (DataSizePerLine, BmpHeader->PixelHeight);
> + if (BltBufferSize > (UINT32) ~0) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + if ((BmpHeader->Size != BmpImageSize) ||
> + (BmpHeader->Size < BmpHeader->ImageOffset) ||
> + (BmpHeader->Size - BmpHeader->ImageOffset != BmpHeader->PixelHeight
> * DataSizePerLine)) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + //
> + // Calculate Color Map offset in the image.
> + //
> + Image = BmpImage;
> + BmpColorMap = (BMP_COLOR_MAP *) (Image + sizeof
> (BMP_IMAGE_HEADER));
> + if (BmpHeader->ImageOffset < sizeof (BMP_IMAGE_HEADER)) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + if (BmpHeader->ImageOffset > sizeof (BMP_IMAGE_HEADER)) {
> + switch (BmpHeader->BitPerPixel) {
> + case 1:
> + ColorMapNum = 2;
> + break;
> + case 4:
> + ColorMapNum = 16;
> + break;
> + case 8:
> + ColorMapNum = 256;
> + break;
> + default:
> + ColorMapNum = 0;
> + break;
> + }
> + //
> + // BMP file may has padding data between the bmp header section and the
> bmp data section.
> + //
> + if (BmpHeader->ImageOffset - sizeof (BMP_IMAGE_HEADER) < sizeof
> (BMP_COLOR_MAP) * ColorMapNum) {
> + return EFI_INVALID_PARAMETER;
> + }
> + }
> +
> + //
> + // Calculate graphics image data address in the image
> + //
> + Image = ((UINT8 *) BmpImage) + BmpHeader->ImageOffset;
> + ImageHeader = Image;
> +
> + //
> + // Calculate the BltBuffer needed size.
> + //
> + BltBufferSize = MultU64x32 ((UINT64) BmpHeader->PixelWidth, BmpHeader-
> >PixelHeight);
> + //
> + // Ensure the BltBufferSize * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
> doesn't overflow
> + //
> + if (BltBufferSize > DivU64x32 ((UINTN) ~0, sizeof
> (EFI_GRAPHICS_OUTPUT_BLT_PIXEL))) {
> + return EFI_UNSUPPORTED;
> + }
> + BltBufferSize = MultU64x32 (BltBufferSize, sizeof
> (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
> +
> + IsAllocated = FALSE;
> + if (*GopBlt == NULL) {
> + //
> + // GopBlt is not allocated by caller.
> + //
> + *GopBltSize = (UINTN) BltBufferSize;
> + *GopBlt = AllocatePool (*GopBltSize);
> + IsAllocated = TRUE;
> + if (*GopBlt == NULL) {
> + return EFI_OUT_OF_RESOURCES;
> + }
> + } else {
> + //
> + // GopBlt has been allocated by caller.
> + //
> + if (*GopBltSize < (UINTN) BltBufferSize) {
> + *GopBltSize = (UINTN) BltBufferSize;
> + return EFI_BUFFER_TOO_SMALL;
> + }
> + }
> +
> + *PixelWidth = BmpHeader->PixelWidth;
> + *PixelHeight = BmpHeader->PixelHeight;
> +
> + //
> + // Convert image from BMP to Blt buffer format
> + //
> + BltBuffer = *GopBlt;
> + for (Height = 0; Height < BmpHeader->PixelHeight; Height++) {
> + Blt = &BltBuffer[(BmpHeader->PixelHeight - Height - 1) * BmpHeader-
> >PixelWidth];
> + for (Width = 0; Width < BmpHeader->PixelWidth; Width++, Image++, Blt++) {
> + switch (BmpHeader->BitPerPixel) {
> + case 1:
> + //
> + // Convert 1-bit (2 colors) BMP to 24-bit color
> + //
> + for (Index = 0; Index < 8 && Width < BmpHeader->PixelWidth; Index++) {
> + Blt->Red = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Red;
> + Blt->Green = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Green;
> + Blt->Blue = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Blue;
> + Blt++;
> + Width++;
> + }
> +
> + Blt--;
> + Width--;
> + break;
> +
> + case 4:
> + //
> + // Convert 4-bit (16 colors) BMP Palette to 24-bit color
> + //
> + Index = (*Image) >> 4;
> + Blt->Red = BmpColorMap[Index].Red;
> + Blt->Green = BmpColorMap[Index].Green;
> + Blt->Blue = BmpColorMap[Index].Blue;
> + if (Width < (BmpHeader->PixelWidth - 1)) {
> + Blt++;
> + Width++;
> + Index = (*Image) & 0x0f;
> + Blt->Red = BmpColorMap[Index].Red;
> + Blt->Green = BmpColorMap[Index].Green;
> + Blt->Blue = BmpColorMap[Index].Blue;
> + }
> + break;
> +
> + case 8:
> + //
> + // Convert 8-bit (256 colors) BMP Palette to 24-bit color
> + //
> + Blt->Red = BmpColorMap[*Image].Red;
> + Blt->Green = BmpColorMap[*Image].Green;
> + Blt->Blue = BmpColorMap[*Image].Blue;
> + break;
> +
> + case 24:
> + //
> + // It is 24-bit BMP.
> + //
> + Blt->Blue = *Image++;
> + Blt->Green = *Image++;
> + Blt->Red = *Image;
> + break;
> +
> + default:
> + //
> + // Other bit format BMP is not supported.
> + //
> + if (IsAllocated) {
> + FreePool (*GopBlt);
> + *GopBlt = NULL;
> + }
> + return EFI_UNSUPPORTED;
> + break;
> + };
> +
> + }
> +
> + ImageIndex = (UINTN) (Image - ImageHeader);
> + if ((ImageIndex % 4) != 0) {
> + //
> + // Bmp Image starts each row on a 32-bit boundary!
> + //
> + Image = Image + (4 - (ImageIndex % 4));
> + }
> + }
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + Use SystemTable Conout to stop video based Simple Text Out consoles from
> going
> + to the video device. Put up LogoFile on every video device that is a console.
> +
> + @param[in] LogoFile File name of logo to display on the center of the
> screen.
> +
> + @retval EFI_SUCCESS ConsoleControl has been flipped to graphics and logo
> displayed.
> + @retval EFI_UNSUPPORTED Logo not found
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +EnableBootLogo (
> + IN EFI_GUID *LogoFile
> + )
> +{
> + EFI_STATUS Status;
> + EFI_OEM_BADGING_PROTOCOL *Badging;
> + UINT32 SizeOfX;
> + UINT32 SizeOfY;
> + INTN DestX;
> + INTN DestY;
> + UINT8 *ImageData;
> + UINTN ImageSize;
> + UINTN BltSize;
> + UINT32 Instance;
> + EFI_BADGING_FORMAT Format;
> + EFI_BADGING_DISPLAY_ATTRIBUTE Attribute;
> + UINTN CoordinateX;
> + UINTN CoordinateY;
> + UINTN Height;
> + UINTN Width;
> + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt;
> + EFI_UGA_DRAW_PROTOCOL *UgaDraw;
> + UINT32 ColorDepth;
> + UINT32 RefreshRate;
> + EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
> + EFI_BOOT_LOGO_PROTOCOL *BootLogo;
> + UINTN NumberOfLogos;
> + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *LogoBlt;
> + UINTN LogoDestX;
> + UINTN LogoDestY;
> + UINTN LogoHeight;
> + UINTN LogoWidth;
> + UINTN NewDestX;
> + UINTN NewDestY;
> + UINTN NewHeight;
> + UINTN NewWidth;
> + UINT64 BufferSize;
> +
> + UgaDraw = NULL;
> + //
> + // Try to open GOP first
> + //
> + Status = gBS->HandleProtocol (gST->ConsoleOutHandle,
> &gEfiGraphicsOutputProtocolGuid, (VOID **) &GraphicsOutput);
> + if (EFI_ERROR (Status) && FeaturePcdGet (PcdUgaConsumeSupport)) {
> + GraphicsOutput = NULL;
> + //
> + // Open GOP failed, try to open UGA
> + //
> + Status = gBS->HandleProtocol (gST->ConsoleOutHandle,
> &gEfiUgaDrawProtocolGuid, (VOID **) &UgaDraw);
> + }
> + if (EFI_ERROR (Status)) {
> + return EFI_UNSUPPORTED;
> + }
> +
> + //
> + // Try to open Boot Logo Protocol.
> + //
> + BootLogo = NULL;
> + gBS->LocateProtocol (&gEfiBootLogoProtocolGuid, NULL, (VOID **)
> &BootLogo);
> +
> + //
> + // Erase Cursor from screen
> + //
> + gST->ConOut->EnableCursor (gST->ConOut, FALSE);
> +
> + Badging = NULL;
> + Status = gBS->LocateProtocol (&gEfiOemBadgingProtocolGuid, NULL, (VOID
> **) &Badging);
> +
> + if (GraphicsOutput != NULL) {
> + SizeOfX = GraphicsOutput->Mode->Info->HorizontalResolution;
> + SizeOfY = GraphicsOutput->Mode->Info->VerticalResolution;
> +
> + } else if (UgaDraw != NULL && FeaturePcdGet (PcdUgaConsumeSupport)) {
> + Status = UgaDraw->GetMode (UgaDraw, &SizeOfX, &SizeOfY, &ColorDepth,
> &RefreshRate);
> + if (EFI_ERROR (Status)) {
> + return EFI_UNSUPPORTED;
> + }
> + } else {
> + return EFI_UNSUPPORTED;
> + }
> +
> + Blt = NULL;
> + NumberOfLogos = 0;
> + LogoDestX = 0;
> + LogoDestY = 0;
> + LogoHeight = 0;
> + LogoWidth = 0;
> + NewDestX = 0;
> + NewDestY = 0;
> + NewHeight = 0;
> + NewWidth = 0;
> + Instance = 0;
> + while (1) {
> + ImageData = NULL;
> + ImageSize = 0;
> +
> + if (Badging != NULL) {
> + //
> + // Get image from OEMBadging protocol.
> + //
> + Status = Badging->GetImage (
> + Badging,
> + &Instance,
> + &Format,
> + &ImageData,
> + &ImageSize,
> + &Attribute,
> + &CoordinateX,
> + &CoordinateY
> + );
> + if (EFI_ERROR (Status)) {
> + goto Done;
> + }
> +
> + } else {
> + //
> + // Get the specified image from FV.
> + //
> + Status = GetSectionFromAnyFv (LogoFile, EFI_SECTION_RAW, 0, (VOID **)
> &ImageData, &ImageSize);
> + if (EFI_ERROR (Status)) {
> + return EFI_UNSUPPORTED;
> + }
> +
> + CoordinateX = 0;
> + CoordinateY = 0;
> + Attribute = EfiBadgingDisplayAttributeCenter;
> + }
> +
> + if (Blt != NULL) {
> + FreePool (Blt);
> + }
> +
> + //
> + // Try BMP decoder
> + //
> + Blt = NULL;
> + Status = ConvertBmpToGopBlt (
> + ImageData,
> + ImageSize,
> + (VOID **) &Blt,
> + &BltSize,
> + &Height,
> + &Width
> + );
> +
> + if (EFI_ERROR (Status)) {
> + FreePool (ImageData);
> +
> + if (Badging == NULL) {
> + return Status;
> + } else {
> + continue;
> + }
> + }
> +
> + //
> + // Calculate the display position according to Attribute.
> + //
> + switch (Attribute) {
> + case EfiBadgingDisplayAttributeLeftTop:
> + DestX = CoordinateX;
> + DestY = CoordinateY;
> + break;
> +
> + case EfiBadgingDisplayAttributeCenterTop:
> + DestX = (SizeOfX - Width) / 2;
> + DestY = CoordinateY;
> + break;
> +
> + case EfiBadgingDisplayAttributeRightTop:
> + DestX = (SizeOfX - Width - CoordinateX);
> + DestY = CoordinateY;;
> + break;
> +
> + case EfiBadgingDisplayAttributeCenterRight:
> + DestX = (SizeOfX - Width - CoordinateX);
> + DestY = (SizeOfY - Height) / 2;
> + break;
> +
> + case EfiBadgingDisplayAttributeRightBottom:
> + DestX = (SizeOfX - Width - CoordinateX);
> + DestY = (SizeOfY - Height - CoordinateY);
> + break;
> +
> + case EfiBadgingDisplayAttributeCenterBottom:
> + DestX = (SizeOfX - Width) / 2;
> + DestY = (SizeOfY - Height - CoordinateY);
> + break;
> +
> + case EfiBadgingDisplayAttributeLeftBottom:
> + DestX = CoordinateX;
> + DestY = (SizeOfY - Height - CoordinateY);
> + break;
> +
> + case EfiBadgingDisplayAttributeCenterLeft:
> + DestX = CoordinateX;
> + DestY = (SizeOfY - Height) / 2;
> + break;
> +
> + case EfiBadgingDisplayAttributeCenter:
> + DestX = (SizeOfX - Width) / 2;
> + DestY = (SizeOfY - Height) / 2;
> + break;
> +
> + default:
> + DestX = CoordinateX;
> + DestY = CoordinateY;
> + break;
> + }
> +
> + if ((DestX >= 0) && (DestY >= 0)) {
> + if (GraphicsOutput != NULL) {
> + Status = GraphicsOutput->Blt (
> + GraphicsOutput,
> + Blt,
> + EfiBltBufferToVideo,
> + 0,
> + 0,
> + (UINTN) DestX,
> + (UINTN) DestY,
> + Width,
> + Height,
> + Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
> + );
> + } else if (UgaDraw != NULL && FeaturePcdGet (PcdUgaConsumeSupport)) {
> + Status = UgaDraw->Blt (
> + UgaDraw,
> + (EFI_UGA_PIXEL *) Blt,
> + EfiUgaBltBufferToVideo,
> + 0,
> + 0,
> + (UINTN) DestX,
> + (UINTN) DestY,
> + Width,
> + Height,
> + Width * sizeof (EFI_UGA_PIXEL)
> + );
> + } else {
> + Status = EFI_UNSUPPORTED;
> + }
> +
> + //
> + // Report displayed Logo information.
> + //
> + if (!EFI_ERROR (Status)) {
> + NumberOfLogos++;
> +
> + if (LogoWidth == 0) {
> + //
> + // The first Logo.
> + //
> + LogoDestX = (UINTN) DestX;
> + LogoDestY = (UINTN) DestY;
> + LogoWidth = Width;
> + LogoHeight = Height;
> + } else {
> + //
> + // Merge new logo with old one.
> + //
> + NewDestX = MIN ((UINTN) DestX, LogoDestX);
> + NewDestY = MIN ((UINTN) DestY, LogoDestY);
> + NewWidth = MAX ((UINTN) DestX + Width, LogoDestX + LogoWidth) -
> NewDestX;
> + NewHeight = MAX ((UINTN) DestY + Height, LogoDestY + LogoHeight) -
> NewDestY;
> +
> + LogoDestX = NewDestX;
> + LogoDestY = NewDestY;
> + LogoWidth = NewWidth;
> + LogoHeight = NewHeight;
> + }
> + }
> + }
> +
> + FreePool (ImageData);
> +
> + if (Badging == NULL) {
> + break;
> + }
> + }
> +
> +Done:
> + if (BootLogo == NULL || NumberOfLogos == 0) {
> + //
> + // No logo displayed.
> + //
> + if (Blt != NULL) {
> + FreePool (Blt);
> + }
> +
> + return Status;
> + }
> +
> + //
> + // Advertise displayed Logo information.
> + //
> + if (NumberOfLogos == 1) {
> + //
> + // Only one logo displayed, use its Blt buffer directly for BootLogo protocol.
> + //
> + LogoBlt = Blt;
> + Status = EFI_SUCCESS;
> + } else {
> + //
> + // More than one Logo displayed, get merged BltBuffer using VideoToBuffer
> operation.
> + //
> + if (Blt != NULL) {
> + FreePool (Blt);
> + }
> +
> + //
> + // Ensure the LogoHeight * LogoWidth doesn't overflow
> + //
> + if (LogoHeight > DivU64x64Remainder ((UINTN) ~0, LogoWidth, NULL)) {
> + return EFI_UNSUPPORTED;
> + }
> + BufferSize = MultU64x64 (LogoWidth, LogoHeight);
> +
> + //
> + // Ensure the BufferSize * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
> doesn't overflow
> + //
> + if (BufferSize > DivU64x32 ((UINTN) ~0, sizeof
> (EFI_GRAPHICS_OUTPUT_BLT_PIXEL))) {
> + return EFI_UNSUPPORTED;
> + }
> +
> + LogoBlt = AllocateZeroPool ((UINTN)BufferSize * sizeof
> (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
> + if (LogoBlt == NULL) {
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + if (GraphicsOutput != NULL) {
> + Status = GraphicsOutput->Blt (
> + GraphicsOutput,
> + LogoBlt,
> + EfiBltVideoToBltBuffer,
> + LogoDestX,
> + LogoDestY,
> + 0,
> + 0,
> + LogoWidth,
> + LogoHeight,
> + LogoWidth * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
> + );
> + } else if (UgaDraw != NULL && FeaturePcdGet (PcdUgaConsumeSupport)) {
> + Status = UgaDraw->Blt (
> + UgaDraw,
> + (EFI_UGA_PIXEL *) LogoBlt,
> + EfiUgaVideoToBltBuffer,
> + LogoDestX,
> + LogoDestY,
> + 0,
> + 0,
> + LogoWidth,
> + LogoHeight,
> + LogoWidth * sizeof (EFI_UGA_PIXEL)
> + );
> + } else {
> + Status = EFI_UNSUPPORTED;
> + }
> + }
> +
> + if (!EFI_ERROR (Status)) {
> + BootLogo->SetBootLogo (BootLogo, LogoBlt, LogoDestX, LogoDestY,
> LogoWidth, LogoHeight);
> + }
> + FreePool (LogoBlt);
> +
> + return Status;
> +}
> diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/Linux.c
> b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/Linux.c
> new file mode 100644
> index 0000000000..631bb7ee69
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/Linux.c
> @@ -0,0 +1,662 @@
> +/** @file
> + Copyright (c) 2011 - 2019 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "LoadLinuxLib.h"
> +
> +
> +/**
> + A simple check of the kernel setup image
> +
> + An assumption is made that the size of the data is at least the
> + size of struct boot_params.
> +
> + @param[in] KernelSetup - The kernel setup image
> +
> + @retval EFI_SUCCESS - The kernel setup looks valid and supported
> + @retval EFI_INVALID_PARAMETER - KernelSetup was NULL
> + @retval EFI_UNSUPPORTED - The kernel setup is not valid or supported
> +
> +**/
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +BasicKernelSetupCheck (
> + IN VOID *KernelSetup
> + )
> +{
> + return LoadLinuxCheckKernelSetup(KernelSetup, sizeof (struct boot_params));
> +}
> +
> +
> +EFI_STATUS
> +EFIAPI
> +LoadLinuxCheckKernelSetup (
> + IN VOID *KernelSetup,
> + IN UINTN KernelSetupSize
> + )
> +{
> + struct boot_params *Bp;
> +
> + if (KernelSetup == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + if (KernelSetupSize < sizeof (*Bp)) {
> + return EFI_UNSUPPORTED;
> + }
> +
> + Bp = (struct boot_params*) KernelSetup;
> +
> + if ((Bp->hdr.signature != 0xAA55) || // Check boot sector signature
> + (Bp->hdr.header != SETUP_HDR) ||
> + (Bp->hdr.version < 0x205) || // We only support relocatable kernels
> + (!Bp->hdr.relocatable_kernel)
> + ) {
> + return EFI_UNSUPPORTED;
> + } else {
> + return EFI_SUCCESS;
> + }
> +}
> +
> +
> +UINTN
> +EFIAPI
> +LoadLinuxGetKernelSize (
> + IN VOID *KernelSetup,
> + IN UINTN KernelSize
> + )
> +{
> + struct boot_params *Bp;
> +
> + if (EFI_ERROR (BasicKernelSetupCheck (KernelSetup))) {
> + return 0;
> + }
> +
> + Bp = (struct boot_params*) KernelSetup;
> +
> + if (Bp->hdr.version > 0x20a) {
> + return Bp->hdr.init_size;
> + } else {
> + //
> + // Add extra size for kernel decompression
> + //
> + return 3 * KernelSize;
> + }
> +}
> +
> +
> +VOID*
> +EFIAPI
> +LoadLinuxAllocateKernelSetupPages (
> + IN UINTN Pages
> + )
> +{
> + EFI_STATUS Status;
> + EFI_PHYSICAL_ADDRESS Address;
> +
> + Address = BASE_1GB;
> + Status = gBS->AllocatePages (
> + AllocateMaxAddress,
> + EfiLoaderData,
> + Pages,
> + &Address
> + );
> + if (!EFI_ERROR (Status)) {
> + return (VOID*)(UINTN) Address;
> + } else {
> + return NULL;
> + }
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +LoadLinuxInitializeKernelSetup (
> + IN VOID *KernelSetup
> + )
> +{
> + EFI_STATUS Status;
> + UINTN SetupEnd;
> + struct boot_params *Bp;
> +
> + Status = BasicKernelSetupCheck (KernelSetup);
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + Bp = (struct boot_params*) KernelSetup;
> +
> + SetupEnd = 0x202 + (Bp->hdr.jump & 0xff);
> +
> + //
> + // Clear all but the setup_header
> + //
> + ZeroMem (KernelSetup, 0x1f1);
> + ZeroMem (((UINT8 *)KernelSetup) + SetupEnd, 4096 - SetupEnd);
> + DEBUG ((EFI_D_INFO, "Cleared kernel setup 0-0x1f1, 0x%Lx-0x1000\n",
> + (UINT64)SetupEnd));
> +
> + return EFI_SUCCESS;
> +}
> +
> +VOID*
> +EFIAPI
> +LoadLinuxAllocateKernelPages (
> + IN VOID *KernelSetup,
> + IN UINTN Pages
> + )
> +{
> + EFI_STATUS Status;
> + EFI_PHYSICAL_ADDRESS KernelAddress;
> + UINT32 Loop;
> + struct boot_params *Bp;
> +
> + if (EFI_ERROR (BasicKernelSetupCheck (KernelSetup))) {
> + return NULL;
> + }
> +
> + Bp = (struct boot_params*) KernelSetup;
> +
> + for (Loop = 1; Loop < 512; Loop++) {
> + KernelAddress = MultU64x32 (
> + 2 * Bp->hdr.kernel_alignment,
> + Loop
> + );
> + Status = gBS->AllocatePages (
> + AllocateAddress,
> + EfiLoaderData,
> + Pages,
> + &KernelAddress
> + );
> + if (!EFI_ERROR (Status)) {
> + return (VOID*)(UINTN) KernelAddress;
> + }
> + }
> +
> + return NULL;
> +}
> +
> +
> +VOID*
> +EFIAPI
> +LoadLinuxAllocateCommandLinePages (
> + IN UINTN Pages
> + )
> +{
> + EFI_STATUS Status;
> + EFI_PHYSICAL_ADDRESS Address;
> +
> + Address = 0xa0000;
> + Status = gBS->AllocatePages (
> + AllocateMaxAddress,
> + EfiLoaderData,
> + Pages,
> + &Address
> + );
> + if (!EFI_ERROR (Status)) {
> + return (VOID*)(UINTN) Address;
> + } else {
> + return NULL;
> + }
> +}
> +
> +
> +VOID*
> +EFIAPI
> +LoadLinuxAllocateInitrdPages (
> + IN VOID *KernelSetup,
> + IN UINTN Pages
> + )
> +{
> + EFI_STATUS Status;
> + EFI_PHYSICAL_ADDRESS Address;
> +
> + struct boot_params *Bp;
> +
> + if (EFI_ERROR (BasicKernelSetupCheck (KernelSetup))) {
> + return NULL;
> + }
> +
> + Bp = (struct boot_params*) KernelSetup;
> +
> + Address = (EFI_PHYSICAL_ADDRESS)(UINTN) Bp->hdr.ramdisk_max;
> + Status = gBS->AllocatePages (
> + AllocateMaxAddress,
> + EfiLoaderData,
> + Pages,
> + &Address
> + );
> + if (!EFI_ERROR (Status)) {
> + return (VOID*)(UINTN) Address;
> + } else {
> + return NULL;
> + }
> +}
> +
> +
> +STATIC
> +VOID
> +SetupLinuxMemmap (
> + IN OUT struct boot_params *Bp
> + )
> +{
> + EFI_STATUS Status;
> + UINT8 TmpMemoryMap[1];
> + UINTN MapKey;
> + UINTN DescriptorSize;
> + UINT32 DescriptorVersion;
> + UINTN MemoryMapSize;
> + EFI_MEMORY_DESCRIPTOR *MemoryMap;
> + EFI_MEMORY_DESCRIPTOR *MemoryMapPtr;
> + UINTN Index;
> + struct efi_info *Efi;
> + struct e820_entry *LastE820;
> + struct e820_entry *E820;
> + UINTN E820EntryCount;
> + EFI_PHYSICAL_ADDRESS LastEndAddr;
> +
> + //
> + // Get System MemoryMapSize
> + //
> + MemoryMapSize = sizeof (TmpMemoryMap);
> + Status = gBS->GetMemoryMap (
> + &MemoryMapSize,
> + (EFI_MEMORY_DESCRIPTOR *)TmpMemoryMap,
> + &MapKey,
> + &DescriptorSize,
> + &DescriptorVersion
> + );
> + ASSERT (Status == EFI_BUFFER_TOO_SMALL);
> + //
> + // Enlarge space here, because we will allocate pool now.
> + //
> + MemoryMapSize += EFI_PAGE_SIZE;
> + Status = gBS->AllocatePool (
> + EfiLoaderData,
> + MemoryMapSize,
> + (VOID **) &MemoryMap
> + );
> + ASSERT_EFI_ERROR (Status);
> +
> + //
> + // Get System MemoryMap
> + //
> + Status = gBS->GetMemoryMap (
> + &MemoryMapSize,
> + MemoryMap,
> + &MapKey,
> + &DescriptorSize,
> + &DescriptorVersion
> + );
> + ASSERT_EFI_ERROR (Status);
> +
> + LastE820 = NULL;
> + E820 = &Bp->e820_map[0];
> + E820EntryCount = 0;
> + LastEndAddr = 0;
> + MemoryMapPtr = MemoryMap;
> + for (Index = 0; Index < (MemoryMapSize / DescriptorSize); Index++) {
> + UINTN E820Type = 0;
> +
> + if (MemoryMap->NumberOfPages == 0) {
> + continue;
> + }
> +
> + switch(MemoryMap->Type) {
> + case EfiReservedMemoryType:
> + case EfiRuntimeServicesCode:
> + case EfiRuntimeServicesData:
> + case EfiMemoryMappedIO:
> + case EfiMemoryMappedIOPortSpace:
> + case EfiPalCode:
> + E820Type = E820_RESERVED;
> + break;
> +
> + case EfiUnusableMemory:
> + E820Type = E820_UNUSABLE;
> + break;
> +
> + case EfiACPIReclaimMemory:
> + E820Type = E820_ACPI;
> + break;
> +
> + case EfiLoaderCode:
> + case EfiLoaderData:
> + case EfiBootServicesCode:
> + case EfiBootServicesData:
> + case EfiConventionalMemory:
> + E820Type = E820_RAM;
> + break;
> +
> + case EfiACPIMemoryNVS:
> + E820Type = E820_NVS;
> + break;
> +
> + default:
> + DEBUG ((
> + EFI_D_ERROR,
> + "Invalid EFI memory descriptor type (0x%x)!\n",
> + MemoryMap->Type
> + ));
> + continue;
> + }
> +
> + if ((LastE820 != NULL) &&
> + (LastE820->type == (UINT32) E820Type) &&
> + (MemoryMap->PhysicalStart == LastEndAddr)) {
> + LastE820->size += EFI_PAGES_TO_SIZE ((UINTN) MemoryMap-
> >NumberOfPages);
> + LastEndAddr += EFI_PAGES_TO_SIZE ((UINTN) MemoryMap-
> >NumberOfPages);
> + } else {
> + if (E820EntryCount >= (sizeof (Bp->e820_map) / sizeof (Bp->e820_map[0])))
> {
> + break;
> + }
> + E820->type = (UINT32) E820Type;
> + E820->addr = MemoryMap->PhysicalStart;
> + E820->size = EFI_PAGES_TO_SIZE ((UINTN) MemoryMap->NumberOfPages);
> + LastE820 = E820;
> + LastEndAddr = E820->addr + E820->size;
> + E820++;
> + E820EntryCount++;
> + }
> +
> + //
> + // Get next item
> + //
> + MemoryMap = (EFI_MEMORY_DESCRIPTOR *)((UINTN)MemoryMap +
> DescriptorSize);
> + }
> + Bp->e820_entries = (UINT8) E820EntryCount;
> +
> + Efi = &Bp->efi_info;
> + Efi->efi_systab = (UINT32)(UINTN) gST;
> + Efi->efi_memdesc_size = (UINT32) DescriptorSize;
> + Efi->efi_memdesc_version = DescriptorVersion;
> + Efi->efi_memmap = (UINT32)(UINTN) MemoryMapPtr;
> + Efi->efi_memmap_size = (UINT32) MemoryMapSize;
> +#ifdef MDE_CPU_IA32
> + Efi->efi_loader_signature = SIGNATURE_32 ('E', 'L', '3', '2');
> +#else
> + Efi->efi_systab_hi = (UINT32) (((UINT64)(UINTN) gST) >> 32);
> + Efi->efi_memmap_hi = (UINT32) (((UINT64)(UINTN) MemoryMapPtr) >> 32);
> + Efi->efi_loader_signature = SIGNATURE_32 ('E', 'L', '6', '4');
> +#endif
> +
> + gBS->ExitBootServices (gImageHandle, MapKey);
> +}
> +
> +
> +EFI_STATUS
> +EFIAPI
> +LoadLinuxSetCommandLine (
> + IN OUT VOID *KernelSetup,
> + IN CHAR8 *CommandLine
> + )
> +{
> + EFI_STATUS Status;
> + struct boot_params *Bp;
> +
> + Status = BasicKernelSetupCheck (KernelSetup);
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + Bp = (struct boot_params*) KernelSetup;
> +
> + Bp->hdr.cmd_line_ptr = (UINT32)(UINTN) CommandLine;
> +
> + return EFI_SUCCESS;
> +}
> +
> +
> +EFI_STATUS
> +EFIAPI
> +LoadLinuxSetInitrd (
> + IN OUT VOID *KernelSetup,
> + IN VOID *Initrd,
> + IN UINTN InitrdSize
> + )
> +{
> + EFI_STATUS Status;
> + struct boot_params *Bp;
> +
> + Status = BasicKernelSetupCheck (KernelSetup);
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + Bp = (struct boot_params*) KernelSetup;
> +
> + Bp->hdr.ramdisk_start = (UINT32)(UINTN) Initrd;
> + Bp->hdr.ramdisk_len = (UINT32) InitrdSize;
> +
> + return EFI_SUCCESS;
> +}
> +
> +
> +STATIC VOID
> +FindBits (
> + unsigned long Mask,
> + UINT8 *Pos,
> + UINT8 *Size
> + )
> +{
> + UINT8 First, Len;
> +
> + First = 0;
> + Len = 0;
> +
> + if (Mask) {
> + while (!(Mask & 0x1)) {
> + Mask = Mask >> 1;
> + First++;
> + }
> +
> + while (Mask & 0x1) {
> + Mask = Mask >> 1;
> + Len++;
> + }
> + }
> + *Pos = First;
> + *Size = Len;
> +}
> +
> +
> +STATIC
> +EFI_STATUS
> +SetupGraphicsFromGop (
> + struct screen_info *Si,
> + EFI_GRAPHICS_OUTPUT_PROTOCOL *Gop
> + )
> +{
> + EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info;
> + EFI_STATUS Status;
> + UINTN Size;
> +
> + Status = Gop->QueryMode(Gop, Gop->Mode->Mode, &Size, &Info);
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + /* We found a GOP */
> +
> + /* EFI framebuffer */
> + Si->orig_video_isVGA = 0x70;
> +
> + Si->orig_x = 0;
> + Si->orig_y = 0;
> + Si->orig_video_page = 0;
> + Si->orig_video_mode = 0;
> + Si->orig_video_cols = 0;
> + Si->orig_video_lines = 0;
> + Si->orig_video_ega_bx = 0;
> + Si->orig_video_points = 0;
> +
> + Si->lfb_base = (UINT32) Gop->Mode->FrameBufferBase;
> + Si->lfb_size = (UINT32) Gop->Mode->FrameBufferSize;
> + Si->lfb_width = (UINT16) Info->HorizontalResolution;
> + Si->lfb_height = (UINT16) Info->VerticalResolution;
> + Si->pages = 1;
> + Si->vesapm_seg = 0;
> + Si->vesapm_off = 0;
> +
> + if (Info->PixelFormat == PixelRedGreenBlueReserved8BitPerColor) {
> + Si->lfb_depth = 32;
> + Si->red_size = 8;
> + Si->red_pos = 0;
> + Si->green_size = 8;
> + Si->green_pos = 8;
> + Si->blue_size = 8;
> + Si->blue_pos = 16;
> + Si->rsvd_size = 8;
> + Si->rsvd_pos = 24;
> + Si->lfb_linelength = (UINT16) (Info->PixelsPerScanLine * 4);
> +
> + } else if (Info->PixelFormat == PixelBlueGreenRedReserved8BitPerColor) {
> + Si->lfb_depth = 32;
> + Si->red_size = 8;
> + Si->red_pos = 16;
> + Si->green_size = 8;
> + Si->green_pos = 8;
> + Si->blue_size = 8;
> + Si->blue_pos = 0;
> + Si->rsvd_size = 8;
> + Si->rsvd_pos = 24;
> + Si->lfb_linelength = (UINT16) (Info->PixelsPerScanLine * 4);
> + } else if (Info->PixelFormat == PixelBitMask) {
> + FindBits(Info->PixelInformation.RedMask,
> + &Si->red_pos, &Si->red_size);
> + FindBits(Info->PixelInformation.GreenMask,
> + &Si->green_pos, &Si->green_size);
> + FindBits(Info->PixelInformation.BlueMask,
> + &Si->blue_pos, &Si->blue_size);
> + FindBits(Info->PixelInformation.ReservedMask,
> + &Si->rsvd_pos, &Si->rsvd_size);
> + Si->lfb_depth = Si->red_size + Si->green_size +
> + Si->blue_size + Si->rsvd_size;
> + Si->lfb_linelength = (UINT16) ((Info->PixelsPerScanLine * Si->lfb_depth) / 8);
> + } else {
> + Si->lfb_depth = 4;
> + Si->red_size = 0;
> + Si->red_pos = 0;
> + Si->green_size = 0;
> + Si->green_pos = 0;
> + Si->blue_size = 0;
> + Si->blue_pos = 0;
> + Si->rsvd_size = 0;
> + Si->rsvd_pos = 0;
> + Si->lfb_linelength = Si->lfb_width / 2;
> + }
> +
> + return Status;
> +}
> +
> +
> +STATIC
> +EFI_STATUS
> +SetupGraphics (
> + IN OUT struct boot_params *Bp
> + )
> +{
> + EFI_STATUS Status;
> + EFI_HANDLE *HandleBuffer;
> + UINTN HandleCount;
> + UINTN Index;
> + EFI_GRAPHICS_OUTPUT_PROTOCOL *Gop;
> +
> + ZeroMem ((VOID*)&Bp->screen_info, sizeof(Bp->screen_info));
> +
> + Status = gBS->LocateHandleBuffer (
> + ByProtocol,
> + &gEfiGraphicsOutputProtocolGuid,
> + NULL,
> + &HandleCount,
> + &HandleBuffer
> + );
> + if (!EFI_ERROR (Status)) {
> + for (Index = 0; Index < HandleCount; Index++) {
> + Status = gBS->HandleProtocol (
> + HandleBuffer[Index],
> + &gEfiGraphicsOutputProtocolGuid,
> + (VOID*) &Gop
> + );
> + if (EFI_ERROR (Status)) {
> + continue;
> + }
> +
> + Status = SetupGraphicsFromGop (&Bp->screen_info, Gop);
> + if (!EFI_ERROR (Status)) {
> + FreePool (HandleBuffer);
> + return EFI_SUCCESS;
> + }
> + }
> +
> + FreePool (HandleBuffer);
> + }
> +
> + return EFI_NOT_FOUND;
> +}
> +
> +
> +STATIC
> +EFI_STATUS
> +SetupLinuxBootParams (
> + IN OUT struct boot_params *Bp
> + )
> +{
> + SetupGraphics (Bp);
> +
> + SetupLinuxMemmap (Bp);
> +
> + return EFI_SUCCESS;
> +}
> +
> +
> +EFI_STATUS
> +EFIAPI
> +LoadLinux (
> + IN VOID *Kernel,
> + IN OUT VOID *KernelSetup
> + )
> +{
> + EFI_STATUS Status;
> + struct boot_params *Bp;
> +
> + Status = BasicKernelSetupCheck (KernelSetup);
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + Bp = (struct boot_params *) KernelSetup;
> +
> + if (Bp->hdr.version < 0x205 || !Bp->hdr.relocatable_kernel) {
> + //
> + // We only support relocatable kernels
> + //
> + return EFI_UNSUPPORTED;
> + }
> +
> + InitLinuxDescriptorTables ();
> +
> + Bp->hdr.code32_start = (UINT32)(UINTN) Kernel;
> + if (Bp->hdr.version >= 0x20c && Bp->hdr.handover_offset &&
> + (Bp->hdr.xloadflags & (sizeof (UINTN) == 4 ? BIT2 : BIT3))) {
> + DEBUG ((EFI_D_INFO, "Jumping to kernel EFI handover point at ofs %x\n",
> Bp->hdr.handover_offset));
> +
> + DisableInterrupts ();
> + JumpToUefiKernel ((VOID*) gImageHandle, (VOID*) gST, KernelSetup,
> Kernel);
> + }
> +
> + //
> + // Old kernels without EFI handover protocol
> + //
> + SetupLinuxBootParams (KernelSetup);
> +
> + DEBUG ((EFI_D_INFO, "Jumping to kernel\n"));
> + DisableInterrupts ();
> + SetLinuxDescriptorTables ();
> + JumpToKernel (Kernel, (VOID*) KernelSetup);
> +
> + return EFI_SUCCESS;
> +}
> +
> diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/LinuxGdt.c
> b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/LinuxGdt.c
> new file mode 100644
> index 0000000000..fda185e3d7
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/LinuxGdt.c
> @@ -0,0 +1,175 @@
> +/** @file
> + Initialize GDT for Linux.
> +
> + Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "LoadLinuxLib.h"
> +
> +
> +//
> +// Local structure definitions
> +//
> +
> +#pragma pack (1)
> +
> +//
> +// Global Descriptor Entry structures
> +//
> +
> +typedef struct _GDT_ENTRY {
> + UINT16 Limit15_0;
> + UINT16 Base15_0;
> + UINT8 Base23_16;
> + UINT8 Type;
> + UINT8 Limit19_16_and_flags;
> + UINT8 Base31_24;
> +} GDT_ENTRY;
> +
> +typedef
> +struct _GDT_ENTRIES {
> + GDT_ENTRY Null;
> + GDT_ENTRY Null2;
> + GDT_ENTRY Linear;
> + GDT_ENTRY LinearCode;
> + GDT_ENTRY TaskSegment;
> + GDT_ENTRY Spare4;
> + GDT_ENTRY Spare5;
> +} GDT_ENTRIES;
> +
> +#pragma pack ()
> +
> +STATIC GDT_ENTRIES *mGdt = NULL;
> +
> +//
> +// Global descriptor table (GDT) Template
> +//
> +STATIC GDT_ENTRIES GdtTemplate = {
> + //
> + // Null
> + //
> + {
> + 0x0, // limit 15:0
> + 0x0, // base 15:0
> + 0x0, // base 23:16
> + 0x0, // type
> + 0x0, // limit 19:16, flags
> + 0x0, // base 31:24
> + },
> + //
> + // Null2
> + //
> + {
> + 0x0, // limit 15:0
> + 0x0, // base 15:0
> + 0x0, // base 23:16
> + 0x0, // type
> + 0x0, // limit 19:16, flags
> + 0x0, // base 31:24
> + },
> + //
> + // Linear
> + //
> + {
> + 0x0FFFF, // limit 0xFFFFF
> + 0x0, // base 0
> + 0x0,
> + 0x09A, // present, ring 0, data, expand-up, writable
> + 0x0CF, // page-granular, 32-bit
> + 0x0,
> + },
> + //
> + // LinearCode
> + //
> + {
> + 0x0FFFF, // limit 0xFFFFF
> + 0x0, // base 0
> + 0x0,
> + 0x092, // present, ring 0, data, expand-up, writable
> + 0x0CF, // page-granular, 32-bit
> + 0x0,
> + },
> + //
> + // TaskSegment
> + //
> + {
> + 0x0, // limit 0
> + 0x0, // base 0
> + 0x0,
> + 0x089, // ?
> + 0x080, // ?
> + 0x0,
> + },
> + //
> + // Spare4
> + //
> + {
> + 0x0, // limit 0
> + 0x0, // base 0
> + 0x0,
> + 0x0, // present, ring 0, data, expand-up, writable
> + 0x0, // page-granular, 32-bit
> + 0x0,
> + },
> + //
> + // Spare5
> + //
> + {
> + 0x0, // limit 0
> + 0x0, // base 0
> + 0x0,
> + 0x0, // present, ring 0, data, expand-up, writable
> + 0x0, // page-granular, 32-bit
> + 0x0,
> + },
> +};
> +
> +/**
> + Initialize Global Descriptor Table.
> +
> +**/
> +VOID
> +InitLinuxDescriptorTables (
> + VOID
> + )
> +{
> + //
> + // Allocate Runtime Data for the GDT
> + //
> + mGdt = AllocateRuntimePool (sizeof (GdtTemplate) + 8);
> + ASSERT (mGdt != NULL);
> + mGdt = ALIGN_POINTER (mGdt, 8);
> +
> + //
> + // Initialize all GDT entries
> + //
> + CopyMem (mGdt, &GdtTemplate, sizeof (GdtTemplate));
> +
> +}
> +
> +/**
> + Initialize Global Descriptor Table.
> +
> +**/
> +VOID
> +SetLinuxDescriptorTables (
> + VOID
> + )
> +{
> + IA32_DESCRIPTOR GdtPtr;
> + IA32_DESCRIPTOR IdtPtr;
> +
> + //
> + // Write GDT register
> + //
> + GdtPtr.Base = (UINT32)(UINTN)(VOID*) mGdt;
> + GdtPtr.Limit = (UINT16) (sizeof (GdtTemplate) - 1);
> + AsmWriteGdtr (&GdtPtr);
> +
> + IdtPtr.Base = (UINT32) 0;
> + IdtPtr.Limit = (UINT16) 0;
> + AsmWriteIdtr (&IdtPtr);
> +}
> +
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/FsAccess.c
> b/Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/FsAccess.c
> new file mode 100644
> index 0000000000..3d98291410
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/FsAccess.c
> @@ -0,0 +1,507 @@
> +/** @file
> + File System Access for NvVarsFileLib
> +
> + Copyright (c) 2004 - 2019 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "NvVarsFileLib.h"
> +
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +
> +
> +/**
> + Open the NvVars file for reading or writing
> +
> + @param[in] FsHandle - Handle for a gEfiSimpleFileSystemProtocolGuid
> instance
> + @param[in] ReadingFile - TRUE: open the file for reading. FALSE: writing
> + @param[out] NvVarsFile - If EFI_SUCCESS is returned, then this is updated
> + with the opened NvVars file.
> +
> + @return EFI_SUCCESS if the file was opened
> +
> +**/
> +EFI_STATUS
> +GetNvVarsFile (
> + IN EFI_HANDLE FsHandle,
> + IN BOOLEAN ReadingFile,
> + OUT EFI_FILE_HANDLE *NvVarsFile
> + )
> +{
> + EFI_STATUS Status;
> + EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Fs;
> + EFI_FILE_HANDLE Root;
> +
> + //
> + // Get the FileSystem protocol on that handle
> + //
> + Status = gBS->HandleProtocol (
> + FsHandle,
> + &gEfiSimpleFileSystemProtocolGuid,
> + (VOID **)&Fs
> + );
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + //
> + // Get the volume (the root directory)
> + //
> + Status = Fs->OpenVolume (Fs, &Root);
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + //
> + // Attempt to open the NvVars file in the root directory
> + //
> + Status = Root->Open (
> + Root,
> + NvVarsFile,
> + L"NvVars",
> + ReadingFile ?
> + EFI_FILE_MODE_READ :
> + (
> + EFI_FILE_MODE_CREATE |
> + EFI_FILE_MODE_READ |
> + EFI_FILE_MODE_WRITE
> + ),
> + 0
> + );
> +
> + return Status;
> +}
> +
> +
> +/**
> + Open the NvVars file for reading or writing
> +
> + @param[in] File - The file to inspect
> + @param[out] Exists - Returns whether the file exists
> + @param[out] Size - Returns the size of the file
> + (0 if the file does not exist)
> +
> +**/
> +VOID
> +NvVarsFileReadCheckup (
> + IN EFI_FILE_HANDLE File,
> + OUT BOOLEAN *Exists,
> + OUT UINTN *Size
> + )
> +{
> + EFI_FILE_INFO *FileInfo;
> +
> + *Exists = FALSE;
> + *Size = 0;
> +
> + FileInfo = FileHandleGetInfo (File);
> + if (FileInfo == NULL) {
> + return;
> + }
> +
> + if ((FileInfo->Attribute & EFI_FILE_DIRECTORY) != 0) {
> + FreePool (FileInfo);
> + return;
> + }
> +
> + *Exists = TRUE;
> + *Size = (UINTN) FileInfo->FileSize;
> +
> + FreePool (FileInfo);
> +}
> +
> +
> +/**
> + Open the NvVars file for reading or writing
> +
> + @param[in] File - The file to inspect
> + @param[out] Exists - Returns whether the file exists
> + @param[out] Size - Returns the size of the file
> + (0 if the file does not exist)
> +
> +**/
> +EFI_STATUS
> +FileHandleEmpty (
> + IN EFI_FILE_HANDLE File
> + )
> +{
> + EFI_STATUS Status;
> + EFI_FILE_INFO *FileInfo;
> +
> + //
> + // Retrieve the FileInfo structure
> + //
> + FileInfo = FileHandleGetInfo (File);
> + if (FileInfo == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + //
> + // If the path is a directory, then return an error
> + //
> + if ((FileInfo->Attribute & EFI_FILE_DIRECTORY) != 0) {
> + FreePool (FileInfo);
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + //
> + // If the file size is already 0, then it is empty, so
> + // we can return success.
> + //
> + if (FileInfo->FileSize == 0) {
> + FreePool (FileInfo);
> + return EFI_SUCCESS;
> + }
> +
> + //
> + // Set the file size to 0.
> + //
> + FileInfo->FileSize = 0;
> + Status = FileHandleSetInfo (File, FileInfo);
> +
> + FreePool (FileInfo);
> +
> + return Status;
> +}
> +
> +
> +/**
> + Reads a file to a newly allocated buffer
> +
> + @param[in] File - The file to read
> + @param[in] ReadSize - The size of data to read from the file
> +
> + @return Pointer to buffer allocated to hold the file
> + contents. NULL if an error occurred.
> +
> +**/
> +VOID*
> +FileHandleReadToNewBuffer (
> + IN EFI_FILE_HANDLE FileHandle,
> + IN UINTN ReadSize
> + )
> +{
> + EFI_STATUS Status;
> + UINTN ActualReadSize;
> + VOID *FileContents;
> +
> + ActualReadSize = ReadSize;
> + FileContents = AllocatePool (ReadSize);
> + if (FileContents != NULL) {
> + Status = FileHandleRead (
> + FileHandle,
> + &ReadSize,
> + FileContents
> + );
> + if (EFI_ERROR (Status) || (ActualReadSize != ReadSize)) {
> + FreePool (FileContents);
> + return NULL;
> + }
> + }
> +
> + return FileContents;
> +}
> +
> +
> +/**
> + Reads the contents of the NvVars file on the file system
> +
> + @param[in] FsHandle - Handle for a gEfiSimpleFileSystemProtocolGuid
> instance
> +
> + @return EFI_STATUS based on the success or failure of the file read
> +
> +**/
> +EFI_STATUS
> +ReadNvVarsFile (
> + IN EFI_HANDLE FsHandle
> + )
> +{
> + EFI_STATUS Status;
> + EFI_FILE_HANDLE File;
> + UINTN FileSize;
> + BOOLEAN FileExists;
> + VOID *FileContents;
> + EFI_HANDLE SerializedVariables;
> +
> + Status = GetNvVarsFile (FsHandle, TRUE, &File);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((EFI_D_INFO, "FsAccess.c: Could not open NV Variables file on this
> file system\n"));
> + return Status;
> + }
> +
> + NvVarsFileReadCheckup (File, &FileExists, &FileSize);
> + if (FileSize == 0) {
> + FileHandleClose (File);
> + return EFI_UNSUPPORTED;
> + }
> +
> + FileContents = FileHandleReadToNewBuffer (File, FileSize);
> + if (FileContents == NULL) {
> + FileHandleClose (File);
> + return EFI_UNSUPPORTED;
> + }
> +
> + DEBUG ((
> + EFI_D_INFO,
> + "FsAccess.c: Read %Lu bytes from NV Variables file\n",
> + (UINT64)FileSize
> + ));
> +
> + Status = SerializeVariablesNewInstanceFromBuffer (
> + &SerializedVariables,
> + FileContents,
> + FileSize
> + );
> + if (!RETURN_ERROR (Status)) {
> + Status = SerializeVariablesSetSerializedVariables (SerializedVariables);
> + }
> +
> + FreePool (FileContents);
> + FileHandleClose (File);
> +
> + return Status;
> +}
> +
> +
> +/**
> + Writes a variable to indicate that the NV variables
> + have been loaded from the file system.
> +
> +**/
> +STATIC
> +VOID
> +SetNvVarsVariable (
> + VOID
> + )
> +{
> + BOOLEAN VarData;
> + UINTN Size;
> +
> + //
> + // Write a variable to indicate we've already loaded the
> + // variable data. If it is found, we skip the loading on
> + // subsequent attempts.
> + //
> + Size = sizeof (VarData);
> + VarData = TRUE;
> + gRT->SetVariable (
> + L"NvVars",
> + &gEfiSimpleFileSystemProtocolGuid,
> + EFI_VARIABLE_NON_VOLATILE |
> + EFI_VARIABLE_BOOTSERVICE_ACCESS |
> + EFI_VARIABLE_RUNTIME_ACCESS,
> + Size,
> + (VOID*) &VarData
> + );
> +}
> +
> +
> +/**
> + Loads the non-volatile variables from the NvVars file on the
> + given file system.
> +
> + @param[in] FsHandle - Handle for a gEfiSimpleFileSystemProtocolGuid
> instance
> +
> + @return EFI_STATUS based on the success or failure of load operation
> +
> +**/
> +EFI_STATUS
> +LoadNvVarsFromFs (
> + EFI_HANDLE FsHandle
> + )
> +{
> + EFI_STATUS Status;
> + BOOLEAN VarData;
> + UINTN Size;
> +
> + DEBUG ((EFI_D_INFO, "FsAccess.c: LoadNvVarsFromFs\n"));
> +
> + //
> + // We write a variable to indicate we've already loaded the
> + // variable data. If it is found, we skip the loading.
> + //
> + // This is relevant if the non-volatile variable have been
> + // able to survive a reboot operation. In that case, we don't
> + // want to re-load the file as it would overwrite newer changes
> + // made to the variables.
> + //
> + Size = sizeof (VarData);
> + VarData = TRUE;
> + Status = gRT->GetVariable (
> + L"NvVars",
> + &gEfiSimpleFileSystemProtocolGuid,
> + NULL,
> + &Size,
> + (VOID*) &VarData
> + );
> + if (Status == EFI_SUCCESS) {
> + DEBUG ((EFI_D_INFO, "NV Variables were already loaded\n"));
> + return EFI_ALREADY_STARTED;
> + }
> +
> + //
> + // Attempt to restore the variables from the NvVars file.
> + //
> + Status = ReadNvVarsFile (FsHandle);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((EFI_D_INFO, "Error while restoring NV variable data\n"));
> + return Status;
> + }
> +
> + //
> + // Write a variable to indicate we've already loaded the
> + // variable data. If it is found, we skip the loading on
> + // subsequent attempts.
> + //
> + SetNvVarsVariable();
> +
> + DEBUG ((
> + EFI_D_INFO,
> + "FsAccess.c: Read NV Variables file (size=%Lu)\n",
> + (UINT64)Size
> + ));
> +
> + return Status;
> +}
> +
> +
> +STATIC
> +RETURN_STATUS
> +EFIAPI
> +IterateVariablesCallbackAddAllNvVariables (
> + IN VOID *Context,
> + IN CHAR16 *VariableName,
> + IN EFI_GUID *VendorGuid,
> + IN UINT32 Attributes,
> + IN UINTN DataSize,
> + IN VOID *Data
> + )
> +{
> + EFI_HANDLE Instance;
> +
> + Instance = (EFI_HANDLE) Context;
> +
> + //
> + // Only save non-volatile variables
> + //
> + if ((Attributes & EFI_VARIABLE_NON_VOLATILE) == 0) {
> + return RETURN_SUCCESS;
> + }
> +
> + return SerializeVariablesAddVariable (
> + Instance,
> + VariableName,
> + VendorGuid,
> + Attributes,
> + DataSize,
> + Data
> + );
> +}
> +
> +
> +/**
> + Saves the non-volatile variables into the NvVars file on the
> + given file system.
> +
> + @param[in] FsHandle - Handle for a gEfiSimpleFileSystemProtocolGuid
> instance
> +
> + @return EFI_STATUS based on the success or failure of load operation
> +
> +**/
> +EFI_STATUS
> +SaveNvVarsToFs (
> + EFI_HANDLE FsHandle
> + )
> +{
> + EFI_STATUS Status;
> + EFI_FILE_HANDLE File;
> + UINTN WriteSize;
> + UINTN VariableDataSize;
> + VOID *VariableData;
> + EFI_HANDLE SerializedVariables;
> +
> + SerializedVariables = NULL;
> +
> + Status = SerializeVariablesNewInstance (&SerializedVariables);
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + Status = SerializeVariablesIterateSystemVariables (
> + IterateVariablesCallbackAddAllNvVariables,
> + (VOID*) SerializedVariables
> + );
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + VariableData = NULL;
> + VariableDataSize = 0;
> + Status = SerializeVariablesToBuffer (
> + SerializedVariables,
> + NULL,
> + &VariableDataSize
> + );
> + if (Status == RETURN_BUFFER_TOO_SMALL) {
> + VariableData = AllocatePool (VariableDataSize);
> + if (VariableData == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + } else {
> + Status = SerializeVariablesToBuffer (
> + SerializedVariables,
> + VariableData,
> + &VariableDataSize
> + );
> + }
> + }
> +
> + SerializeVariablesFreeInstance (SerializedVariables);
> +
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + //
> + // Open the NvVars file for writing.
> + //
> + Status = GetNvVarsFile (FsHandle, FALSE, &File);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((EFI_D_INFO, "FsAccess.c: Unable to open file to saved NV
> Variables\n"));
> + return Status;
> + }
> +
> + //
> + // Empty the starting file contents.
> + //
> + Status = FileHandleEmpty (File);
> + if (EFI_ERROR (Status)) {
> + FileHandleClose (File);
> + return Status;
> + }
> +
> + WriteSize = VariableDataSize;
> + Status = FileHandleWrite (File, &WriteSize, VariableData);
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + FileHandleClose (File);
> +
> + if (!EFI_ERROR (Status)) {
> + //
> + // Write a variable to indicate we've already loaded the
> + // variable data. If it is found, we skip the loading on
> + // subsequent attempts.
> + //
> + SetNvVarsVariable();
> +
> + DEBUG ((EFI_D_INFO, "Saved NV Variables to NvVars file\n"));
> + }
> +
> + return Status;
> +}
> +
> +
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/NvVarsFileLib.c
> b/Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/NvVarsFileLib.c
> new file mode 100644
> index 0000000000..2e9618455d
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/NvVarsFileLib.c
> @@ -0,0 +1,77 @@
> +/** @file
> + Save Non-Volatile Variables to a file system.
> +
> + Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "NvVarsFileLib.h"
> +#include <Library/DebugLib.h>
> +#include <Library/NvVarsFileLib.h>
> +
> +EFI_HANDLE mNvVarsFileLibFsHandle = NULL;
> +
> +
> +/**
> + Attempts to connect the NvVarsFileLib to the specified file system.
> +
> + @param[in] FsHandle - Handle for a gEfiSimpleFileSystemProtocolGuid
> instance
> +
> + @return The EFI_STATUS while attempting to connect the NvVarsFileLib
> + to the file system instance.
> + @retval EFI_SUCCESS - The given file system was connected successfully
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +ConnectNvVarsToFileSystem (
> + IN EFI_HANDLE FsHandle
> + )
> +{
> + EFI_STATUS Status;
> +
> + //
> + // We might fail to load the variable, since the file system initially
> + // will not have the NvVars file.
> + //
> + LoadNvVarsFromFs (FsHandle);
> +
> + //
> + // We must be able to save the variables successfully to the file system
> + // to have connected successfully.
> + //
> + Status = SaveNvVarsToFs (FsHandle);
> + if (!EFI_ERROR (Status)) {
> + mNvVarsFileLibFsHandle = FsHandle;
> + }
> +
> + return Status;
> +}
> +
> +
> +/**
> + Update non-volatile variables stored on the file system.
> +
> + @return The EFI_STATUS while attempting to update the variable on
> + the connected file system.
> + @retval EFI_SUCCESS - The non-volatile variables were saved to the disk
> + @retval EFI_NOT_STARTED - A file system has not been connected
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +UpdateNvVarsOnFileSystem (
> + )
> +{
> + if (mNvVarsFileLibFsHandle == NULL) {
> + //
> + // A file system had not been connected to the library.
> + //
> + return EFI_NOT_STARTED;
> + } else {
> + return SaveNvVarsToFs (mNvVarsFileLibFsHandle);
> + }
> +}
> +
> +
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Library/PciHostBridgeLib/PciHostBridgeL
> ib.c
> b/Platform/Intel/SimicsOpenBoardPkg/Library/PciHostBridgeLib/PciHostBridgeL
> ib.c
> new file mode 100644
> index 0000000000..3b71c8ae97
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Library/PciHostBridgeLib/PciHostBridgeL
> ib.c
> @@ -0,0 +1,419 @@
> +/** @file
> + SIMICS QSP's instance of the PCI Host Bridge Library.
> +
> + Copyright (C) 2016, Red Hat, Inc.
> + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <PiDxe.h>
> +
> +#include <IndustryStandard/Pci.h>
> +#include <Register/X58Ich10.h>
> +
> +#include <Protocol/PciHostBridgeResourceAllocation.h>
> +#include <Protocol/PciRootBridgeIo.h>
> +
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/DevicePathLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/PciHostBridgeLib.h>
> +#include <Library/PciLib.h>
> +#include "PciHostBridge.h"
> +
> +
> +#pragma pack(1)
> +typedef struct {
> + ACPI_HID_DEVICE_PATH AcpiDevicePath;
> + EFI_DEVICE_PATH_PROTOCOL EndDevicePath;
> +} OVMF_PCI_ROOT_BRIDGE_DEVICE_PATH;
> +#pragma pack ()
> +
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED
> +CHAR16 *mPciHostBridgeLibAcpiAddressSpaceTypeStr[] = {
> + L"Mem", L"I/O", L"Bus"
> +};
> +
> +
> +STATIC
> +CONST
> +OVMF_PCI_ROOT_BRIDGE_DEVICE_PATH mRootBridgeDevicePathTemplate =
> {
> + {
> + {
> + ACPI_DEVICE_PATH,
> + ACPI_DP,
> + {
> + (UINT8) (sizeof(ACPI_HID_DEVICE_PATH)),
> + (UINT8) ((sizeof(ACPI_HID_DEVICE_PATH)) >> 8)
> + }
> + },
> + EISA_PNP_ID(0x0A03), // HID
> + 0 // UID
> + },
> +
> + {
> + END_DEVICE_PATH_TYPE,
> + END_ENTIRE_DEVICE_PATH_SUBTYPE,
> + {
> + END_DEVICE_PATH_LENGTH,
> + 0
> + }
> + }
> +};
> +
> +STATIC PCI_ROOT_BRIDGE_APERTURE mNonExistAperture = { MAX_UINT64, 0
> };
> +
> +/**
> + Initialize a PCI_ROOT_BRIDGE structure.
> +
> + @param[in] Supports Supported attributes.
> +
> + @param[in] Attributes Initial attributes.
> +
> + @param[in] AllocAttributes Allocation attributes.
> +
> + @param[in] RootBusNumber The bus number to store in RootBus.
> +
> + @param[in] MaxSubBusNumber The inclusive maximum bus number that can
> be
> + assigned to any subordinate bus found behind any
> + PCI bridge hanging off this root bus.
> +
> + The caller is repsonsible for ensuring that
> + RootBusNumber <= MaxSubBusNumber. If
> + RootBusNumber equals MaxSubBusNumber, then the
> + root bus has no room for subordinate buses.
> +
> + @param[in] Io IO aperture.
> +
> + @param[in] Mem MMIO aperture.
> +
> + @param[in] MemAbove4G MMIO aperture above 4G.
> +
> + @param[in] PMem Prefetchable MMIO aperture.
> +
> + @param[in] PMemAbove4G Prefetchable MMIO aperture above 4G.
> +
> + @param[out] RootBus The PCI_ROOT_BRIDGE structure (allocated by
> the
> + caller) that should be filled in by this
> + function.
> +
> + @retval EFI_SUCCESS Initialization successful. A device path
> + consisting of an ACPI device path node, with
> + UID = RootBusNumber, has been allocated and
> + linked into RootBus.
> +
> + @retval EFI_OUT_OF_RESOURCES Memory allocation failed.
> +**/
> +EFI_STATUS
> +InitRootBridge (
> + IN UINT64 Supports,
> + IN UINT64 Attributes,
> + IN UINT64 AllocAttributes,
> + IN UINT8 RootBusNumber,
> + IN UINT8 MaxSubBusNumber,
> + IN PCI_ROOT_BRIDGE_APERTURE *Io,
> + IN PCI_ROOT_BRIDGE_APERTURE *Mem,
> + IN PCI_ROOT_BRIDGE_APERTURE *MemAbove4G,
> + IN PCI_ROOT_BRIDGE_APERTURE *PMem,
> + IN PCI_ROOT_BRIDGE_APERTURE *PMemAbove4G,
> + OUT PCI_ROOT_BRIDGE *RootBus
> + )
> +{
> + OVMF_PCI_ROOT_BRIDGE_DEVICE_PATH *DevicePath;
> +
> + //
> + // Be safe if other fields are added to PCI_ROOT_BRIDGE later.
> + //
> + ZeroMem (RootBus, sizeof *RootBus);
> +
> + RootBus->Segment = 0;
> +
> + RootBus->Supports = Supports;
> + RootBus->Attributes = Attributes;
> +
> + RootBus->DmaAbove4G = FALSE;
> +
> + RootBus->AllocationAttributes = AllocAttributes;
> + RootBus->Bus.Base = RootBusNumber;
> + RootBus->Bus.Limit = MaxSubBusNumber;
> + CopyMem (&RootBus->Io, Io, sizeof (*Io));
> + CopyMem (&RootBus->Mem, Mem, sizeof (*Mem));
> + CopyMem (&RootBus->MemAbove4G, MemAbove4G, sizeof
> (*MemAbove4G));
> + CopyMem (&RootBus->PMem, PMem, sizeof (*PMem));
> + CopyMem (&RootBus->PMemAbove4G, PMemAbove4G, sizeof
> (*PMemAbove4G));
> +
> + RootBus->NoExtendedConfigSpace = (PcdGet16
> (PcdSimicsX58HostBridgePciDevId) !=
> + INTEL_ICH10_DEVICE_ID);
> +
> + DevicePath = AllocateCopyPool (sizeof mRootBridgeDevicePathTemplate,
> + &mRootBridgeDevicePathTemplate);
> + if (DevicePath == NULL) {
> + DEBUG ((EFI_D_ERROR, "%a: %r\n", __FUNCTION__,
> EFI_OUT_OF_RESOURCES));
> + return EFI_OUT_OF_RESOURCES;
> + }
> + DevicePath->AcpiDevicePath.UID = RootBusNumber;
> + RootBus->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)DevicePath;
> +
> + DEBUG ((EFI_D_INFO,
> + "%a: populated root bus %d, with room for %d subordinate bus(es)\n",
> + __FUNCTION__, RootBusNumber, MaxSubBusNumber - RootBusNumber));
> + return EFI_SUCCESS;
> +}
> +
> +
> +/**
> + Uninitialize a PCI_ROOT_BRIDGE structure set up with InitRootBridge().
> +
> + param[in] RootBus The PCI_ROOT_BRIDGE structure, allocated by the caller
> and
> + initialized with InitRootBridge(), that should be
> + uninitialized. This function doesn't free RootBus.
> +**/
> +STATIC
> +VOID
> +UninitRootBridge (
> + IN PCI_ROOT_BRIDGE *RootBus
> + )
> +{
> + FreePool (RootBus->DevicePath);
> +}
> +
> +
> +/**
> + Return all the root bridge instances in an array.
> +
> + @param Count Return the count of root bridge instances.
> +
> + @return All the root bridge instances in an array.
> + The array should be passed into PciHostBridgeFreeRootBridges()
> + when it's not used.
> +**/
> +PCI_ROOT_BRIDGE *
> +EFIAPI
> +PciHostBridgeGetRootBridges (
> + UINTN *Count
> + )
> +{
> + EFI_STATUS Status;
> + UINT64 ExtraRootBridges;
> + PCI_ROOT_BRIDGE *Bridges;
> + UINTN Initialized;
> + UINTN LastRootBridgeNumber;
> + UINTN RootBridgeNumber;
> + UINT64 Attributes;
> + UINT64 AllocationAttributes;
> + PCI_ROOT_BRIDGE_APERTURE Io;
> + PCI_ROOT_BRIDGE_APERTURE Mem;
> + PCI_ROOT_BRIDGE_APERTURE MemAbove4G;
> +
> + ZeroMem (&Io, sizeof (Io));
> + ZeroMem (&Mem, sizeof (Mem));
> + ZeroMem (&MemAbove4G, sizeof (MemAbove4G));
> +
> + Attributes = EFI_PCI_ATTRIBUTE_IDE_PRIMARY_IO |
> + EFI_PCI_ATTRIBUTE_IDE_SECONDARY_IO |
> + EFI_PCI_ATTRIBUTE_ISA_IO_16 |
> + EFI_PCI_ATTRIBUTE_ISA_MOTHERBOARD_IO |
> + EFI_PCI_ATTRIBUTE_VGA_MEMORY |
> + EFI_PCI_ATTRIBUTE_VGA_IO_16 |
> + EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO_16;
> +
> + AllocationAttributes = EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM;
> + if (PcdGet64 (PcdPciMmio64Size) > 0) {
> + AllocationAttributes |= EFI_PCI_HOST_BRIDGE_MEM64_DECODE;
> + MemAbove4G.Base = PcdGet64 (PcdPciMmio64Base);
> + MemAbove4G.Limit = PcdGet64 (PcdPciMmio64Base) +
> + PcdGet64 (PcdPciMmio64Size) - 1;
> + } else {
> + CopyMem (&MemAbove4G, &mNonExistAperture, sizeof
> (mNonExistAperture));
> + }
> +
> + Io.Base = PcdGet64 (PcdPciIoBase);
> + Io.Limit = PcdGet64 (PcdPciIoBase) + (PcdGet64 (PcdPciIoSize) - 1);
> + Mem.Base = PcdGet64 (PcdPciMmio32Base);
> + Mem.Limit = PcdGet64 (PcdPciMmio32Base) + (PcdGet64 (PcdPciMmio32Size)
> - 1);
> +
> + *Count = 0;
> + ExtraRootBridges = 0;
> +
> + //
> + // Allocate the "main" root bridge, and any extra root bridges.
> + //
> + Bridges = AllocatePool ((1 + (UINTN)ExtraRootBridges) * sizeof *Bridges);
> + if (Bridges == NULL) {
> + DEBUG ((EFI_D_ERROR, "%a: %r\n", __FUNCTION__,
> EFI_OUT_OF_RESOURCES));
> + return NULL;
> + }
> + Initialized = 0;
> +
> + //
> + // The "main" root bus is always there.
> + //
> + LastRootBridgeNumber = 0;
> +
> + //
> + // Scan all other root buses. If function 0 of any device on a bus returns a
> + // VendorId register value different from all-bits-one, then that bus is
> + // alive.
> + //
> + for (RootBridgeNumber = 1;
> + RootBridgeNumber <= PCI_MAX_BUS && Initialized < ExtraRootBridges;
> + ++RootBridgeNumber) {
> + UINTN Device;
> +
> + for (Device = 0; Device <= PCI_MAX_DEVICE; ++Device) {
> + if (PciRead16 (PCI_LIB_ADDRESS (RootBridgeNumber, Device, 0,
> + PCI_VENDOR_ID_OFFSET)) != MAX_UINT16) {
> + break;
> + }
> + }
> + if (Device <= PCI_MAX_DEVICE) {
> + //
> + // Found the next root bus. We can now install the *previous* one,
> + // because now we know how big a bus number range *that* one has, for
> any
> + // subordinate buses that might exist behind PCI bridges hanging off it.
> + //
> + Status = InitRootBridge (
> + Attributes,
> + Attributes,
> + AllocationAttributes,
> + (UINT8) LastRootBridgeNumber,
> + (UINT8) (RootBridgeNumber - 1),
> + &Io,
> + &Mem,
> + &MemAbove4G,
> + &mNonExistAperture,
> + &mNonExistAperture,
> + &Bridges[Initialized]
> + );
> + if (EFI_ERROR (Status)) {
> + goto FreeBridges;
> + }
> + ++Initialized;
> + LastRootBridgeNumber = RootBridgeNumber;
> + }
> + }
> +
> + //
> + // Install the last root bus (which might be the only, ie. main, root bus, if
> + // we've found no extra root buses).
> + //
> + Status = InitRootBridge (
> + Attributes,
> + Attributes,
> + AllocationAttributes,
> + (UINT8) LastRootBridgeNumber,
> + PCI_MAX_BUS,
> + &Io,
> + &Mem,
> + &MemAbove4G,
> + &mNonExistAperture,
> + &mNonExistAperture,
> + &Bridges[Initialized]
> + );
> + if (EFI_ERROR (Status)) {
> + goto FreeBridges;
> + }
> + ++Initialized;
> +
> + *Count = Initialized;
> + return Bridges;
> +
> +FreeBridges:
> + while (Initialized > 0) {
> + --Initialized;
> + UninitRootBridge (&Bridges[Initialized]);
> + }
> +
> + FreePool (Bridges);
> + return NULL;
> +}
> +
> +
> +/**
> + Free the root bridge instances array returned from
> + PciHostBridgeGetRootBridges().
> +
> + @param The root bridge instances array.
> + @param The count of the array.
> +**/
> +VOID
> +EFIAPI
> +PciHostBridgeFreeRootBridges (
> + PCI_ROOT_BRIDGE *Bridges,
> + UINTN Count
> + )
> +{
> + if (Bridges == NULL && Count == 0) {
> + return;
> + }
> + ASSERT (Bridges != NULL && Count > 0);
> +
> + do {
> + --Count;
> + UninitRootBridge (&Bridges[Count]);
> + } while (Count > 0);
> +
> + FreePool (Bridges);
> +}
> +
> +
> +/**
> + Inform the platform that the resource conflict happens.
> +
> + @param HostBridgeHandle Handle of the Host Bridge.
> + @param Configuration Pointer to PCI I/O and PCI memory resource
> + descriptors. The Configuration contains the resources
> + for all the root bridges. The resource for each root
> + bridge is terminated with END descriptor and an
> + additional END is appended indicating the end of the
> + entire resources. The resource descriptor field
> + values follow the description in
> + EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
> + .SubmitResources().
> +**/
> +VOID
> +EFIAPI
> +PciHostBridgeResourceConflict (
> + EFI_HANDLE HostBridgeHandle,
> + VOID *Configuration
> + )
> +{
> + EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptor;
> + UINTN RootBridgeIndex;
> + DEBUG ((EFI_D_ERROR, "PciHostBridge: Resource conflict happens!\n"));
> +
> + RootBridgeIndex = 0;
> + Descriptor = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Configuration;
> + while (Descriptor->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR) {
> + DEBUG ((EFI_D_ERROR, "RootBridge[%d]:\n", RootBridgeIndex++));
> + for (; Descriptor->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR;
> Descriptor++) {
> + ASSERT (Descriptor->ResType <
> + (sizeof (mPciHostBridgeLibAcpiAddressSpaceTypeStr) /
> + sizeof (mPciHostBridgeLibAcpiAddressSpaceTypeStr[0])
> + )
> + );
> + DEBUG ((EFI_D_ERROR, " %s: Length/Alignment = 0x%lx / 0x%lx\n",
> + mPciHostBridgeLibAcpiAddressSpaceTypeStr[Descriptor->ResType],
> + Descriptor->AddrLen, Descriptor->AddrRangeMax
> + ));
> + if (Descriptor->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM) {
> + DEBUG ((EFI_D_ERROR, " Granularity/SpecificFlag = %ld / %02x%s\n",
> + Descriptor->AddrSpaceGranularity, Descriptor->SpecificFlag,
> + ((Descriptor->SpecificFlag &
> +
> EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE
> + ) != 0) ? L" (Prefetchable)" : L""
> + ));
> + }
> + }
> + //
> + // Skip the END descriptor for root bridge
> + //
> + ASSERT (Descriptor->Desc == ACPI_END_TAG_DESCRIPTOR);
> + Descriptor = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)(
> + (EFI_ACPI_END_TAG_DESCRIPTOR *)Descriptor + 1
> + );
> + }
> +}
> diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/PeiReportFvLib/Fv.c
> b/Platform/Intel/SimicsOpenBoardPkg/Library/PeiReportFvLib/Fv.c
> new file mode 100644
> index 0000000000..4e3762465a
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/Library/PeiReportFvLib/Fv.c
> @@ -0,0 +1,100 @@
> +/** @file
> + Build FV related hobs for platform.
> +
> + Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "PiPei.h"
> +#include <Library/DebugLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/PeiServicesLib.h>
> +#include <Library/PcdLib.h>
> +
> +BOOLEAN mS3Supported = TRUE;
> +
> +/**
> + Publish PEI & DXE (Decompressed) Memory based FVs to let PEI
> + and DXE know about them.
> +
> + @retval EFI_SUCCESS Platform PEI FVs were initialized successfully.
> +
> +**/
> +EFI_STATUS
> +PeiFvInitialization (
> + VOID
> + )
> +{
> + BOOLEAN SecureS3Needed;
> +
> + DEBUG ((EFI_D_INFO, "Platform PEI Firmware Volume Initialization\n"));
> +
> + DEBUG (
> + (EFI_D_ERROR, "Firmware Volume HOB: 0x%x 0x%x\n",
> + PcdGet32 (PcdSimicsPeiMemFvBase),
> + PcdGet32 (PcdSimicsPeiMemFvSize)
> + )
> + );
> + //
> + // Create a memory allocation HOB for the PEI FV.
> + //
> + // Allocate as ACPI NVS is S3 is supported
> + //
> + BuildMemoryAllocationHob (
> + PcdGet32 (PcdSimicsPeiMemFvBase),
> + PcdGet32 (PcdSimicsPeiMemFvSize),
> + mS3Supported ? EfiACPIMemoryNVS : EfiBootServicesData
> + );
> +
> + //
> + // Let DXE know about the DXE FV
> + //
> + BuildFvHob (PcdGet32 (PcdSimicsDxeMemFvBase), PcdGet32
> (PcdSimicsDxeMemFvSize));
> +
> + SecureS3Needed = mS3Supported && FeaturePcdGet
> (PcdSmmSmramRequire);
> +
> + //
> + // Create a memory allocation HOB for the DXE FV.
> + //
> + // If "secure" S3 is needed, then SEC will decompress both PEI and DXE
> + // firmware volumes at S3 resume too, hence we need to keep away the OS
> from
> + // DXEFV as well. Otherwise we only need to keep away DXE itself from the
> + // DXEFV area.
> + //
> + BuildMemoryAllocationHob (
> + PcdGet32 (PcdSimicsDxeMemFvBase),
> + PcdGet32 (PcdSimicsDxeMemFvSize),
> + SecureS3Needed ? EfiACPIMemoryNVS : EfiBootServicesData
> + );
> +
> + //
> + // Additionally, said decompression will use temporary memory above the end
> + // of DXEFV, so let's keep away the OS from there too.
> + //
> + if (SecureS3Needed) {
> + UINT32 DxeMemFvEnd;
> +
> + DxeMemFvEnd = PcdGet32 (PcdSimicsDxeMemFvBase) +
> + PcdGet32 (PcdSimicsDxeMemFvSize);
> + BuildMemoryAllocationHob (
> + DxeMemFvEnd,
> + PcdGet32 (PcdSimicsDecompressionScratchEnd) - DxeMemFvEnd,
> + EfiACPIMemoryNVS
> + );
> + }
> +
> + //
> + // Let PEI know about the DXE FV so it can find the DXE Core
> + //
> + PeiServicesInstallFvInfoPpi (
> + NULL,
> + (VOID *)(UINTN) PcdGet32 (PcdSimicsDxeMemFvBase),
> + PcdGet32 (PcdSimicsDxeMemFvSize),
> + NULL,
> + NULL
> + );
> +
> + return EFI_SUCCESS;
> +}
> +
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Library/PeiReportFvLib/PeiReportFvLib.c
> b/Platform/Intel/SimicsOpenBoardPkg/Library/PeiReportFvLib/PeiReportFvLib.c
> new file mode 100644
> index 0000000000..bb5a060b8e
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Library/PeiReportFvLib/PeiReportFvLib.c
> @@ -0,0 +1,119 @@
> +/** @file
> + Source code file for Report Firmware Volume (FV) library
> +
> + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <Base.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/PeiServicesLib.h>
> +#include <Library/ReportFvLib.h>
> +#include <Guid/FirmwareFileSystem2.h>
> +#include <Ppi/FirmwareVolumeInfo.h>
> +#include <Library/IoLib.h>
> +#include <Register/X58Ich10.h>
> +
> +EFI_STATUS
> +PeiFvInitialization(
> + VOID
> +);
> +
> +VOID
> +ReportPreMemFv (
> + VOID
> + )
> +{
> + if (IoBitFieldRead16(ICH10_PMBASE_IO + 4, 10, 12) != 0x5) { // not S3 resume
> + PeiFvInitialization();
> + }
> +
> + DEBUG ((DEBUG_INFO, "Install FlashFvSecurity - 0x%x, 0x%x\n", PcdGet32
> (PcdFlashFvSecurityBase), PcdGet32 (PcdFlashFvSecuritySize)));
> + PeiServicesInstallFvInfo2Ppi (
> + &(((EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) PcdGet32
> (PcdFlashFvSecurityBase))->FileSystemGuid),
> + (VOID *) (UINTN) PcdGet32 (PcdFlashFvSecurityBase),
> + PcdGet32 (PcdFlashFvSecuritySize),
> + NULL,
> + NULL,
> + 0
> + );
> + DEBUG ((DEBUG_INFO, "Install FlashFvAdvanced - 0x%x, 0x%x\n", PcdGet32
> (PcdFlashFvAdvancedBase), PcdGet32 (PcdFlashFvAdvancedSize)));
> + PeiServicesInstallFvInfo2Ppi (
> + &(((EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) PcdGet32
> (PcdFlashFvAdvancedBase))->FileSystemGuid),
> + (VOID *) (UINTN) PcdGet32 (PcdFlashFvAdvancedBase),
> + PcdGet32 (PcdFlashFvAdvancedSize),
> + NULL,
> + NULL,
> + 0
> + );
> +}
> +
> +VOID
> +ReportPostMemFv (
> + VOID
> + )
> +{
> + EFI_STATUS Status;
> + EFI_BOOT_MODE BootMode;
> +
> + Status = PeiServicesGetBootMode (&BootMode);
> + ASSERT_EFI_ERROR (Status);
> +
> + ///
> + /// Build HOB for DXE
> + ///
> + if (BootMode == BOOT_IN_RECOVERY_MODE) {
> + ///
> + /// Prepare the recovery service
> + ///
> + } else {
> + DEBUG ((DEBUG_INFO, "Install FlashFvPostMemory - 0x%x, 0x%x\n",
> PcdGet32 (PcdFlashFvPostMemoryBase), PcdGet32
> (PcdFlashFvPostMemorySize)));
> + PeiServicesInstallFvInfo2Ppi (
> + &(((EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) PcdGet32
> (PcdFlashFvPostMemoryBase))->FileSystemGuid),
> + (VOID *) (UINTN) PcdGet32 (PcdFlashFvPostMemoryBase),
> + PcdGet32 (PcdFlashFvPostMemorySize),
> + NULL,
> + NULL,
> + 0
> + );
> + DEBUG ((DEBUG_INFO, "Install FlashFvUefiBoot - 0x%x, 0x%x\n", PcdGet32
> (PcdFlashFvUefiBootBase), PcdGet32 (PcdFlashFvUefiBootSize)));
> + PeiServicesInstallFvInfo2Ppi (
> + &(((EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) PcdGet32
> (PcdFlashFvUefiBootBase))->FileSystemGuid),
> + (VOID *) (UINTN) PcdGet32 (PcdFlashFvUefiBootBase),
> + PcdGet32 (PcdFlashFvUefiBootSize),
> + NULL,
> + NULL,
> + 0
> + );
> + DEBUG ((DEBUG_INFO, "Install FlashFvOsBoot - 0x%x, 0x%x\n", PcdGet32
> (PcdFlashFvOsBootBase), PcdGet32 (PcdFlashFvOsBootSize)));
> + PeiServicesInstallFvInfo2Ppi (
> + &(((EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) PcdGet32
> (PcdFlashFvOsBootBase))->FileSystemGuid),
> + (VOID *) (UINTN) PcdGet32 (PcdFlashFvOsBootBase),
> + PcdGet32 (PcdFlashFvOsBootSize),
> + NULL,
> + NULL,
> + 0
> + );
> + }
> +
> + //
> + // Report resource HOB for flash FV
> + //
> + BuildResourceDescriptorHob (
> + EFI_RESOURCE_MEMORY_MAPPED_IO,
> + (EFI_RESOURCE_ATTRIBUTE_PRESENT |
> + EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
> + EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
> + (UINTN) PcdGet32 (PcdFlashAreaBaseAddress),
> + (UINTN) PcdGet32 (PcdFlashAreaSize)
> + );
> + BuildMemoryAllocationHob (
> + (UINTN) PcdGet32 (PcdFlashAreaBaseAddress),
> + (UINTN) PcdGet32 (PcdFlashAreaSize),
> + EfiMemoryMappedIO
> + );
> +}
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Library/PlatformBootManagerLib/BdsPla
> tform.c
> b/Platform/Intel/SimicsOpenBoardPkg/Library/PlatformBootManagerLib/BdsPla
> tform.c
> new file mode 100644
> index 0000000000..117c72b35f
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Library/PlatformBootManagerLib/BdsPla
> tform.c
> @@ -0,0 +1,1553 @@
> +/** @file
> + Platform BDS customizations.
> +
> + Copyright (c) 2004 - 2019 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "BdsPlatform.h"
> +#include <Guid/RootBridgesConnectedEventGroup.h>
> +#include <Protocol/FirmwareVolume2.h>
> +
> +#define LEGACY_8259_MASK_REGISTER_MASTER 0x21
> +#define LEGACY_8259_MASK_REGISTER_SLAVE 0xA1
> +#define LEGACY_8259_EDGE_LEVEL_TRIGGERED_REGISTER_MASTER 0x4D0
> +#define LEGACY_8259_EDGE_LEVEL_TRIGGERED_REGISTER_SLAVE 0x4D1
> +
> +//
> +// Global data
> +//
> +
> +VOID *mEfiDevPathNotifyReg;
> +EFI_EVENT mEfiDevPathEvent;
> +VOID *mEmuVariableEventReg;
> +EFI_EVENT mEmuVariableEvent;
> +BOOLEAN mDetectVgaOnly;
> +UINT16 mHostBridgeDevId;
> +
> +//
> +// Table of host IRQs matching PCI IRQs A-D
> +// (for configuring PCI Interrupt Line register)
> +//
> +CONST UINT8 PciHostIrqs[] = {
> + 0x0a, 0x0a, 0x0b, 0x0b
> +};
> +
> +//
> +// Type definitions
> +//
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *PROTOCOL_INSTANCE_CALLBACK)(
> + IN EFI_HANDLE Handle,
> + IN VOID *Instance,
> + IN VOID *Context
> + );
> +
> +/**
> + @param[in] Handle - Handle of PCI device instance
> + @param[in] PciIo - PCI IO protocol instance
> + @param[in] Pci - PCI Header register block
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *VISIT_PCI_INSTANCE_CALLBACK)(
> + IN EFI_HANDLE Handle,
> + IN EFI_PCI_IO_PROTOCOL *PciIo,
> + IN PCI_TYPE00 *Pci
> + );
> +
> +
> +//
> +// Function prototypes
> +//
> +
> +EFI_STATUS
> +VisitAllInstancesOfProtocol (
> + IN EFI_GUID *Id,
> + IN PROTOCOL_INSTANCE_CALLBACK CallBackFunction,
> + IN VOID *Context
> + );
> +
> +EFI_STATUS
> +VisitAllPciInstancesOfProtocol (
> + IN VISIT_PCI_INSTANCE_CALLBACK CallBackFunction
> + );
> +
> +VOID
> +InstallDevicePathCallback (
> + VOID
> + );
> +
> +VOID
> +PlatformRegisterFvBootOption (
> + EFI_GUID *FileGuid,
> + CHAR16 *Description,
> + UINT32 Attributes
> + )
> +{
> + EFI_STATUS Status;
> + INTN OptionIndex;
> + EFI_BOOT_MANAGER_LOAD_OPTION NewOption;
> + EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions;
> + UINTN BootOptionCount;
> + MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FileNode;
> + EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
> + EFI_DEVICE_PATH_PROTOCOL *DevicePath;
> +
> + Status = gBS->HandleProtocol (
> + gImageHandle,
> + &gEfiLoadedImageProtocolGuid,
> + (VOID **) &LoadedImage
> + );
> + ASSERT_EFI_ERROR (Status);
> +
> + EfiInitializeFwVolDevicepathNode (&FileNode, FileGuid);
> + DevicePath = DevicePathFromHandle (LoadedImage->DeviceHandle);
> + ASSERT (DevicePath != NULL);
> + DevicePath = AppendDevicePathNode (
> + DevicePath,
> + (EFI_DEVICE_PATH_PROTOCOL *) &FileNode
> + );
> + ASSERT (DevicePath != NULL);
> +
> + Status = EfiBootManagerInitializeLoadOption (
> + &NewOption,
> + LoadOptionNumberUnassigned,
> + LoadOptionTypeBoot,
> + Attributes,
> + Description,
> + DevicePath,
> + NULL,
> + 0
> + );
> + ASSERT_EFI_ERROR (Status);
> + FreePool (DevicePath);
> +
> + BootOptions = EfiBootManagerGetLoadOptions (
> + &BootOptionCount, LoadOptionTypeBoot
> + );
> +
> + OptionIndex = EfiBootManagerFindLoadOption (
> + &NewOption, BootOptions, BootOptionCount
> + );
> +
> + if (OptionIndex == -1) {
> + Status = EfiBootManagerAddLoadOptionVariable (&NewOption,
> MAX_UINTN);
> + ASSERT_EFI_ERROR (Status);
> + }
> + EfiBootManagerFreeLoadOption (&NewOption);
> + EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount);
> +}
> +
> +/**
> + Remove all MemoryMapped(...)/FvFile(...) and Fv(...)/FvFile(...) boot options
> + whose device paths do not resolve exactly to an FvFile in the system.
> +
> + This removes any boot options that point to binaries built into the firmware
> + and have become stale due to any of the following:
> + - DXEFV's base address or size changed (historical),
> + - DXEFV's FvNameGuid changed,
> + - the FILE_GUID of the pointed-to binary changed,
> + - the referenced binary is no longer built into the firmware.
> +
> + EfiBootManagerFindLoadOption() used in PlatformRegisterFvBootOption()
> only
> + avoids exact duplicates.
> +**/
> +VOID
> +RemoveStaleFvFileOptions (
> + VOID
> + )
> +{
> + EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions;
> + UINTN BootOptionCount;
> + UINTN Index;
> +
> + BootOptions = EfiBootManagerGetLoadOptions (&BootOptionCount,
> + LoadOptionTypeBoot);
> +
> + for (Index = 0; Index < BootOptionCount; ++Index) {
> + EFI_DEVICE_PATH_PROTOCOL *Node1, *Node2, *SearchNode;
> + EFI_STATUS Status;
> + EFI_HANDLE FvHandle;
> +
> + //
> + // If the device path starts with neither MemoryMapped(...) nor Fv(...),
> + // then keep the boot option.
> + //
> + Node1 = BootOptions[Index].FilePath;
> + if (!(DevicePathType (Node1) == HARDWARE_DEVICE_PATH &&
> + DevicePathSubType (Node1) == HW_MEMMAP_DP) &&
> + !(DevicePathType (Node1) == MEDIA_DEVICE_PATH &&
> + DevicePathSubType (Node1) == MEDIA_PIWG_FW_VOL_DP)) {
> + continue;
> + }
> +
> + //
> + // If the second device path node is not FvFile(...), then keep the boot
> + // option.
> + //
> + Node2 = NextDevicePathNode (Node1);
> + if (DevicePathType (Node2) != MEDIA_DEVICE_PATH ||
> + DevicePathSubType (Node2) != MEDIA_PIWG_FW_FILE_DP) {
> + continue;
> + }
> +
> + //
> + // Locate the Firmware Volume2 protocol instance that is denoted by the
> + // boot option. If this lookup fails (i.e., the boot option references a
> + // firmware volume that doesn't exist), then we'll proceed to delete the
> + // boot option.
> + //
> + SearchNode = Node1;
> + Status = gBS->LocateDevicePath (&gEfiFirmwareVolume2ProtocolGuid,
> + &SearchNode, &FvHandle);
> +
> + if (!EFI_ERROR (Status)) {
> + //
> + // The firmware volume was found; now let's see if it contains the FvFile
> + // identified by GUID.
> + //
> + EFI_FIRMWARE_VOLUME2_PROTOCOL *FvProtocol;
> + MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FvFileNode;
> + UINTN BufferSize;
> + EFI_FV_FILETYPE FoundType;
> + EFI_FV_FILE_ATTRIBUTES FileAttributes;
> + UINT32 AuthenticationStatus;
> +
> + Status = gBS->HandleProtocol (FvHandle,
> &gEfiFirmwareVolume2ProtocolGuid,
> + (VOID **)&FvProtocol);
> + ASSERT_EFI_ERROR (Status);
> +
> + FvFileNode = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *)Node2;
> + //
> + // Buffer==NULL means we request metadata only: BufferSize, FoundType,
> + // FileAttributes.
> + //
> + Status = FvProtocol->ReadFile (
> + FvProtocol,
> + &FvFileNode->FvFileName, // NameGuid
> + NULL, // Buffer
> + &BufferSize,
> + &FoundType,
> + &FileAttributes,
> + &AuthenticationStatus
> + );
> + if (!EFI_ERROR (Status)) {
> + //
> + // The FvFile was found. Keep the boot option.
> + //
> + continue;
> + }
> + }
> +
> + //
> + // Delete the boot option.
> + //
> + Status = EfiBootManagerDeleteLoadOptionVariable (
> + BootOptions[Index].OptionNumber, LoadOptionTypeBoot);
> + DEBUG_CODE (
> + CHAR16 *DevicePathString;
> +
> + DevicePathString = ConvertDevicePathToText(BootOptions[Index].FilePath,
> + FALSE, FALSE);
> + DEBUG ((
> + EFI_ERROR (Status) ? EFI_D_WARN : EFI_D_VERBOSE,
> + "%a: removing stale Boot#%04x %s: %r\n",
> + __FUNCTION__,
> + (UINT32)BootOptions[Index].OptionNumber,
> + DevicePathString == NULL ? L"<unavailable>" : DevicePathString,
> + Status
> + ));
> + if (DevicePathString != NULL) {
> + FreePool (DevicePathString);
> + }
> + );
> + }
> +
> + EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount);
> +}
> +
> +VOID
> +PlatformRegisterOptionsAndKeys (
> + VOID
> + )
> +{
> + EFI_STATUS Status;
> + EFI_INPUT_KEY Enter;
> + EFI_INPUT_KEY F2;
> + EFI_INPUT_KEY Esc;
> + EFI_BOOT_MANAGER_LOAD_OPTION BootOption;
> +
> + //
> + // Register ENTER as CONTINUE key
> + //
> + Enter.ScanCode = SCAN_NULL;
> + Enter.UnicodeChar = CHAR_CARRIAGE_RETURN;
> + Status = EfiBootManagerRegisterContinueKeyOption (0, &Enter, NULL);
> + ASSERT_EFI_ERROR (Status);
> +
> + //
> + // Map F2 to Boot Manager Menu
> + //
> + F2.ScanCode = SCAN_F2;
> + F2.UnicodeChar = CHAR_NULL;
> + Esc.ScanCode = SCAN_ESC;
> + Esc.UnicodeChar = CHAR_NULL;
> + Status = EfiBootManagerGetBootManagerMenu (&BootOption);
> + ASSERT_EFI_ERROR (Status);
> + Status = EfiBootManagerAddKeyOptionVariable (
> + NULL, (UINT16) BootOption.OptionNumber, 0, &F2, NULL
> + );
> + ASSERT (Status == EFI_SUCCESS || Status == EFI_ALREADY_STARTED);
> + Status = EfiBootManagerAddKeyOptionVariable (
> + NULL, (UINT16) BootOption.OptionNumber, 0, &Esc, NULL
> + );
> + ASSERT (Status == EFI_SUCCESS || Status == EFI_ALREADY_STARTED);
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +ConnectRootBridge (
> + IN EFI_HANDLE RootBridgeHandle,
> + IN VOID *Instance,
> + IN VOID *Context
> + );
> +
> +STATIC
> +VOID
> +SaveS3BootScript (
> + VOID
> + );
> +
> +//
> +// BDS Platform Functions
> +//
> +/**
> + Do the platform init, can be customized by OEM/IBV
> +
> + Possible things that can be done in PlatformBootManagerBeforeConsole:
> +
> + > Update console variable: 1. include hot-plug devices;
> + > 2. Clear ConIn and add SOL for AMT
> + > Register new Driver#### or Boot####
> + > Register new Key####: e.g.: F12
> + > Signal ReadyToLock event
> + > Authentication action: 1. connect Auth devices;
> + > 2. Identify auto logon user.
> +**/
> +VOID
> +EFIAPI
> +PlatformBootManagerBeforeConsole (
> + VOID
> + )
> +{
> +// EFI_HANDLE Handle;
> +// EFI_STATUS Status;
> +
> + DEBUG ((EFI_D_INFO, "PlatformBootManagerBeforeConsole\n"));
> + InstallDevicePathCallback ();
> +
> + VisitAllInstancesOfProtocol (&gEfiPciRootBridgeIoProtocolGuid,
> + ConnectRootBridge, NULL);
> + //
> + // Enable LPC
> + //
> + PciOr16(POWER_MGMT_REGISTER_ICH10(0x04),
> + BIT0 | BIT1 | BIT2);
> + //
> + // We can't signal End-of-Dxe earlier than this. Namely, End-of-Dxe triggers
> + // the preparation of S3 system information. That logic has a hard dependency
> + // on the presence of the FACS ACPI table. Since our ACPI tables are only
> + // installed after PCI enumeration completes, we must not trigger the S3 save
> + // earlier, hence we can't signal End-of-Dxe earlier.
> + //
> + EfiEventGroupSignal (&gEfiEndOfDxeEventGroupGuid);
> +
> + PlatformInitializeConsole (gPlatformConsole);
> +
> + PlatformRegisterOptionsAndKeys ();
> +}
> +
> +
> +EFI_STATUS
> +EFIAPI
> +ConnectRootBridge (
> + IN EFI_HANDLE RootBridgeHandle,
> + IN VOID *Instance,
> + IN VOID *Context
> + )
> +{
> + EFI_STATUS Status;
> +
> + //
> + // Make the PCI bus driver connect the root bridge, non-recursively. This
> + // will produce a number of child handles with PciIo on them.
> + //
> + Status = gBS->ConnectController (
> + RootBridgeHandle, // ControllerHandle
> + NULL, // DriverImageHandle
> + NULL, // RemainingDevicePath -- produce all
> + // children
> + FALSE // Recursive
> + );
> + return Status;
> +}
> +
> +
> +/**
> + Add IsaKeyboard to ConIn; add IsaSerial to ConOut, ConIn, ErrOut.
> +
> + @param[in] DeviceHandle Handle of the LPC Bridge device.
> +
> + @retval EFI_SUCCESS Console devices on the LPC bridge have been added to
> + ConOut, ConIn, and ErrOut.
> +
> + @return Error codes, due to EFI_DEVICE_PATH_PROTOCOL missing
> + from DeviceHandle.
> +**/
> +EFI_STATUS
> +PrepareLpcBridgeDevicePath (
> + IN EFI_HANDLE DeviceHandle
> + )
> +{
> + EFI_STATUS Status;
> + EFI_DEVICE_PATH_PROTOCOL *DevicePath;
> + EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;
> + CHAR16 *DevPathStr;
> +
> + DevicePath = NULL;
> + Status = gBS->HandleProtocol (
> + DeviceHandle,
> + &gEfiDevicePathProtocolGuid,
> + (VOID*)&DevicePath
> + );
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> + TempDevicePath = DevicePath;
> +
> + //
> + // Register Keyboard
> + //
> + DevicePath = AppendDevicePathNode (DevicePath,
> (EFI_DEVICE_PATH_PROTOCOL *)&gPnpPs2KeyboardDeviceNode);
> +
> + EfiBootManagerUpdateConsoleVariable (ConIn, DevicePath, NULL);
> +
> + //
> + // Register COM1
> + //
> + DevicePath = TempDevicePath;
> + gPnp16550ComPortDeviceNode.UID = 0;
> +
> + DevicePath = AppendDevicePathNode (DevicePath,
> (EFI_DEVICE_PATH_PROTOCOL *)&gPnp16550ComPortDeviceNode);
> + DevicePath = AppendDevicePathNode (DevicePath,
> (EFI_DEVICE_PATH_PROTOCOL *)&gUartDeviceNode);
> + DevicePath = AppendDevicePathNode (DevicePath,
> (EFI_DEVICE_PATH_PROTOCOL *)&gTerminalTypeDeviceNode);
> +
> + //
> + // Print Device Path
> + //
> + DevPathStr = ConvertDevicePathToText (DevicePath, FALSE, FALSE);
> + if (DevPathStr != NULL) {
> + DEBUG((
> + EFI_D_INFO,
> + "BdsPlatform.c+%d: COM%d DevPath: %s\n",
> + __LINE__,
> + gPnp16550ComPortDeviceNode.UID + 1,
> + DevPathStr
> + ));
> + FreePool(DevPathStr);
> + }
> +
> + EfiBootManagerUpdateConsoleVariable (ConOut, DevicePath, NULL);
> + EfiBootManagerUpdateConsoleVariable (ConIn, DevicePath, NULL);
> + EfiBootManagerUpdateConsoleVariable (ErrOut, DevicePath, NULL);
> +
> + //
> + // Register COM2
> + //
> + DevicePath = TempDevicePath;
> + gPnp16550ComPortDeviceNode.UID = 1;
> +
> + DevicePath = AppendDevicePathNode (DevicePath,
> (EFI_DEVICE_PATH_PROTOCOL *)&gPnp16550ComPortDeviceNode);
> + DevicePath = AppendDevicePathNode (DevicePath,
> (EFI_DEVICE_PATH_PROTOCOL *)&gUartDeviceNode);
> + DevicePath = AppendDevicePathNode (DevicePath,
> (EFI_DEVICE_PATH_PROTOCOL *)&gTerminalTypeDeviceNode);
> +
> + //
> + // Print Device Path
> + //
> + DevPathStr = ConvertDevicePathToText (DevicePath, FALSE, FALSE);
> + if (DevPathStr != NULL) {
> + DEBUG((
> + EFI_D_INFO,
> + "BdsPlatform.c+%d: COM%d DevPath: %s\n",
> + __LINE__,
> + gPnp16550ComPortDeviceNode.UID + 1,
> + DevPathStr
> + ));
> + FreePool(DevPathStr);
> + }
> +
> + EfiBootManagerUpdateConsoleVariable (ConOut, DevicePath, NULL);
> + EfiBootManagerUpdateConsoleVariable (ConIn, DevicePath, NULL);
> + EfiBootManagerUpdateConsoleVariable (ErrOut, DevicePath, NULL);
> +
> + return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +GetGopDevicePath (
> + IN EFI_DEVICE_PATH_PROTOCOL *PciDevicePath,
> + OUT EFI_DEVICE_PATH_PROTOCOL **GopDevicePath
> + )
> +{
> + UINTN Index;
> + EFI_STATUS Status;
> + EFI_HANDLE PciDeviceHandle;
> + EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;
> + EFI_DEVICE_PATH_PROTOCOL *TempPciDevicePath;
> + UINTN GopHandleCount;
> + EFI_HANDLE *GopHandleBuffer;
> +
> + if (PciDevicePath == NULL || GopDevicePath == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + //
> + // Initialize the GopDevicePath to be PciDevicePath
> + //
> + *GopDevicePath = PciDevicePath;
> + TempPciDevicePath = PciDevicePath;
> +
> + Status = gBS->LocateDevicePath (
> + &gEfiDevicePathProtocolGuid,
> + &TempPciDevicePath,
> + &PciDeviceHandle
> + );
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + //
> + // Try to connect this handle, so that GOP driver could start on this
> + // device and create child handles with GraphicsOutput Protocol installed
> + // on them, then we get device paths of these child handles and select
> + // them as possible console device.
> + //
> + gBS->ConnectController (PciDeviceHandle, NULL, NULL, FALSE);
> +
> + Status = gBS->LocateHandleBuffer (
> + ByProtocol,
> + &gEfiGraphicsOutputProtocolGuid,
> + NULL,
> + &GopHandleCount,
> + &GopHandleBuffer
> + );
> + if (!EFI_ERROR (Status)) {
> + //
> + // Add all the child handles as possible Console Device
> + //
> + for (Index = 0; Index < GopHandleCount; Index++) {
> + Status = gBS->HandleProtocol (GopHandleBuffer[Index],
> &gEfiDevicePathProtocolGuid, (VOID*)&TempDevicePath);
> + if (EFI_ERROR (Status)) {
> + continue;
> + }
> + if (CompareMem (
> + PciDevicePath,
> + TempDevicePath,
> + GetDevicePathSize (PciDevicePath) - END_DEVICE_PATH_LENGTH
> + ) == 0) {
> + //
> + // In current implementation, we only enable one of the child handles
> + // as console device, i.e. sotre one of the child handle's device
> + // path to variable "ConOut"
> + // In future, we could select all child handles to be console device
> + //
> +
> + *GopDevicePath = TempDevicePath;
> +
> + //
> + // Delete the PCI device's path that added by
> + // GetPlugInPciVgaDevicePath(). Add the integrity GOP device path.
> + //
> + EfiBootManagerUpdateConsoleVariable (ConOutDev, NULL,
> PciDevicePath);
> + EfiBootManagerUpdateConsoleVariable (ConOutDev, TempDevicePath,
> NULL);
> + }
> + }
> + gBS->FreePool (GopHandleBuffer);
> + }
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + Add PCI display to ConOut.
> +
> + @param[in] DeviceHandle Handle of the PCI display device.
> +
> + @retval EFI_SUCCESS The PCI display device has been added to ConOut.
> +
> + @return Error codes, due to EFI_DEVICE_PATH_PROTOCOL missing
> + from DeviceHandle.
> +**/
> +EFI_STATUS
> +PreparePciDisplayDevicePath (
> + IN EFI_HANDLE DeviceHandle
> + )
> +{
> + EFI_STATUS Status;
> + EFI_DEVICE_PATH_PROTOCOL *DevicePath;
> + EFI_DEVICE_PATH_PROTOCOL *GopDevicePath;
> +
> + DevicePath = NULL;
> + GopDevicePath = NULL;
> + Status = gBS->HandleProtocol (
> + DeviceHandle,
> + &gEfiDevicePathProtocolGuid,
> + (VOID*)&DevicePath
> + );
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + GetGopDevicePath (DevicePath, &GopDevicePath);
> + DevicePath = GopDevicePath;
> +
> + EfiBootManagerUpdateConsoleVariable (ConOut, DevicePath, NULL);
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + Add PCI Serial to ConOut, ConIn, ErrOut.
> +
> + @param[in] DeviceHandle Handle of the PCI serial device.
> +
> + @retval EFI_SUCCESS The PCI serial device has been added to ConOut, ConIn,
> + ErrOut.
> +
> + @return Error codes, due to EFI_DEVICE_PATH_PROTOCOL missing
> + from DeviceHandle.
> +**/
> +EFI_STATUS
> +PreparePciSerialDevicePath (
> + IN EFI_HANDLE DeviceHandle
> + )
> +{
> + EFI_STATUS Status;
> + EFI_DEVICE_PATH_PROTOCOL *DevicePath;
> +
> + DevicePath = NULL;
> + Status = gBS->HandleProtocol (
> + DeviceHandle,
> + &gEfiDevicePathProtocolGuid,
> + (VOID*)&DevicePath
> + );
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + DevicePath = AppendDevicePathNode (DevicePath,
> (EFI_DEVICE_PATH_PROTOCOL *)&gUartDeviceNode);
> + DevicePath = AppendDevicePathNode (DevicePath,
> (EFI_DEVICE_PATH_PROTOCOL *)&gTerminalTypeDeviceNode);
> +
> + EfiBootManagerUpdateConsoleVariable (ConOut, DevicePath, NULL);
> + EfiBootManagerUpdateConsoleVariable (ConIn, DevicePath, NULL);
> + EfiBootManagerUpdateConsoleVariable (ErrOut, DevicePath, NULL);
> +
> + return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +VisitAllInstancesOfProtocol (
> + IN EFI_GUID *Id,
> + IN PROTOCOL_INSTANCE_CALLBACK CallBackFunction,
> + IN VOID *Context
> + )
> +{
> + EFI_STATUS Status;
> + UINTN HandleCount;
> + EFI_HANDLE *HandleBuffer;
> + UINTN Index;
> + VOID *Instance;
> +
> + //
> + // Start to check all the PciIo to find all possible device
> + //
> + HandleCount = 0;
> + HandleBuffer = NULL;
> + Status = gBS->LocateHandleBuffer (
> + ByProtocol,
> + Id,
> + NULL,
> + &HandleCount,
> + &HandleBuffer
> + );
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + for (Index = 0; Index < HandleCount; Index++) {
> + Status = gBS->HandleProtocol (HandleBuffer[Index], Id, &Instance);
> + if (EFI_ERROR (Status)) {
> + continue;
> + }
> +
> + Status = (*CallBackFunction) (
> + HandleBuffer[Index],
> + Instance,
> + Context
> + );
> + }
> +
> + gBS->FreePool (HandleBuffer);
> +
> + return EFI_SUCCESS;
> +}
> +
> +
> +EFI_STATUS
> +EFIAPI
> +VisitingAPciInstance (
> + IN EFI_HANDLE Handle,
> + IN VOID *Instance,
> + IN VOID *Context
> + )
> +{
> + EFI_STATUS Status;
> + EFI_PCI_IO_PROTOCOL *PciIo;
> + PCI_TYPE00 Pci;
> +
> + PciIo = (EFI_PCI_IO_PROTOCOL*) Instance;
> +
> + //
> + // Check for all PCI device
> + //
> + Status = PciIo->Pci.Read (
> + PciIo,
> + EfiPciIoWidthUint32,
> + 0,
> + sizeof (Pci) / sizeof (UINT32),
> + &Pci
> + );
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + return (*(VISIT_PCI_INSTANCE_CALLBACK)(UINTN) Context) (
> + Handle,
> + PciIo,
> + &Pci
> + );
> +
> +}
> +
> +
> +
> +EFI_STATUS
> +VisitAllPciInstances (
> + IN VISIT_PCI_INSTANCE_CALLBACK CallBackFunction
> + )
> +{
> + return VisitAllInstancesOfProtocol (
> + &gEfiPciIoProtocolGuid,
> + VisitingAPciInstance,
> + (VOID*)(UINTN) CallBackFunction
> + );
> +}
> +
> +
> +/**
> + Do platform specific PCI Device check and add them to
> + ConOut, ConIn, ErrOut.
> +
> + @param[in] Handle - Handle of PCI device instance
> + @param[in] PciIo - PCI IO protocol instance
> + @param[in] Pci - PCI Header register block
> +
> + @retval EFI_SUCCESS - PCI Device check and Console variable update
> + successfully.
> + @retval EFI_STATUS - PCI Device check or Console variable update fail.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +DetectAndPreparePlatformPciDevicePath (
> + IN EFI_HANDLE Handle,
> + IN EFI_PCI_IO_PROTOCOL *PciIo,
> + IN PCI_TYPE00 *Pci
> + )
> +{
> + EFI_STATUS Status;
> +
> + Status = PciIo->Attributes (
> + PciIo,
> + EfiPciIoAttributeOperationEnable,
> + EFI_PCI_DEVICE_ENABLE,
> + NULL
> + );
> + ASSERT_EFI_ERROR (Status);
> +
> + if (!mDetectVgaOnly) {
> + //
> + // Here we decide whether it is LPC Bridge
> + //
> + if ((IS_PCI_LPC (Pci)) ||
> + ((IS_PCI_ISA_PDECODE (Pci)) &&
> + (Pci->Hdr.VendorId == 0x8086) &&
> + (Pci->Hdr.DeviceId == 0x7000)
> + )
> + ) {
> + //
> + // Add IsaKeyboard to ConIn,
> + // add IsaSerial to ConOut, ConIn, ErrOut
> + //
> + DEBUG ((EFI_D_INFO, "Found LPC Bridge device\n"));
> + PrepareLpcBridgeDevicePath (Handle);
> + return EFI_SUCCESS;
> + }
> + //
> + // Here we decide which Serial device to enable in PCI bus
> + //
> + if (IS_PCI_16550SERIAL (Pci)) {
> + //
> + // Add them to ConOut, ConIn, ErrOut.
> + //
> + DEBUG ((EFI_D_INFO, "Found PCI 16550 SERIAL device\n"));
> + PreparePciSerialDevicePath (Handle);
> + return EFI_SUCCESS;
> + }
> + }
> +
> + //
> + // Here we decide which display device to enable in PCI bus
> + //
> + if (IS_PCI_DISPLAY (Pci)) {
> + //
> + // Add them to ConOut.
> + //
> + DEBUG ((EFI_D_INFO, "Found PCI display device\n"));
> + PreparePciDisplayDevicePath (Handle);
> + return EFI_SUCCESS;
> + }
> +
> + return Status;
> +}
> +
> +
> +/**
> + Do platform specific PCI Device check and add them to ConOut, ConIn, ErrOut
> +
> + @param[in] DetectVgaOnly - Only detect VGA device if it's TRUE.
> +
> + @retval EFI_SUCCESS - PCI Device check and Console variable update
> successfully.
> + @retval EFI_STATUS - PCI Device check or Console variable update fail.
> +
> +**/
> +EFI_STATUS
> +DetectAndPreparePlatformPciDevicePaths (
> + BOOLEAN DetectVgaOnly
> + )
> +{
> + mDetectVgaOnly = DetectVgaOnly;
> + return VisitAllPciInstances (DetectAndPreparePlatformPciDevicePath);
> +}
> +
> +/**
> + Connect the predefined platform default console device.
> +
> + Always try to find and enable PCI display devices.
> +
> + @param[in] PlatformConsole Predefined platform default console device
> array.
> +**/
> +VOID
> +PlatformInitializeConsole (
> + IN PLATFORM_CONSOLE_CONNECT_ENTRY *PlatformConsole
> + )
> +{
> + UINTN Index;
> + EFI_DEVICE_PATH_PROTOCOL *VarConout;
> + EFI_DEVICE_PATH_PROTOCOL *VarConin;
> +
> + //
> + // Connect RootBridge
> + //
> + GetEfiGlobalVariable2 (EFI_CON_OUT_VARIABLE_NAME, (VOID **)
> &VarConout, NULL);
> + GetEfiGlobalVariable2 (EFI_CON_IN_VARIABLE_NAME, (VOID **) &VarConin,
> NULL);
> +
> + if (VarConout == NULL || VarConin == NULL) {
> + //
> + // Do platform specific PCI Device check and add them to ConOut, ConIn,
> ErrOut
> + //
> + DetectAndPreparePlatformPciDevicePaths (FALSE);
> + DetectAndPreparePlatformPciDevicePaths(TRUE);
> + //
> + // Have chance to connect the platform default console,
> + // the platform default console is the minimue device group
> + // the platform should support
> + //
> + for (Index = 0; PlatformConsole[Index].DevicePath != NULL; ++Index) {
> + //
> + // Update the console variable with the connect type
> + //
> + if ((PlatformConsole[Index].ConnectType & CONSOLE_IN) == CONSOLE_IN)
> {
> + EfiBootManagerUpdateConsoleVariable (ConIn,
> PlatformConsole[Index].DevicePath, NULL);
> + }
> + if ((PlatformConsole[Index].ConnectType & CONSOLE_OUT) ==
> CONSOLE_OUT) {
> + EfiBootManagerUpdateConsoleVariable (ConOut,
> PlatformConsole[Index].DevicePath, NULL);
> + }
> + if ((PlatformConsole[Index].ConnectType & STD_ERROR) == STD_ERROR) {
> + EfiBootManagerUpdateConsoleVariable (ErrOut,
> PlatformConsole[Index].DevicePath, NULL);
> + }
> + }
> + } else {
> + //
> + // Only detect VGA device and add them to ConOut
> + //
> + DetectAndPreparePlatformPciDevicePaths (TRUE);
> + }
> +}
> +
> +
> +/**
> + Configure PCI Interrupt Line register for applicable devices
> + Ported from SeaBIOS, src/fw/pciinit.c, *_pci_slot_get_irq()
> +
> + @param[in] Handle - Handle of PCI device instance
> + @param[in] PciIo - PCI IO protocol instance
> + @param[in] PciHdr - PCI Header register block
> +
> + @retval EFI_SUCCESS - PCI Interrupt Line register configured successfully.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SetPciIntLine (
> + IN EFI_HANDLE Handle,
> + IN EFI_PCI_IO_PROTOCOL *PciIo,
> + IN PCI_TYPE00 *PciHdr
> + )
> +{
> + EFI_DEVICE_PATH_PROTOCOL *DevPathNode;
> + EFI_DEVICE_PATH_PROTOCOL *DevPath;
> + UINTN RootSlot;
> + UINTN Idx;
> + UINT8 IrqLine;
> + EFI_STATUS Status;
> + UINT32 RootBusNumber;
> +
> + Status = EFI_SUCCESS;
> +
> + if (PciHdr->Device.InterruptPin != 0) {
> +
> + DevPathNode = DevicePathFromHandle (Handle);
> + ASSERT (DevPathNode != NULL);
> + DevPath = DevPathNode;
> +
> + RootBusNumber = 0;
> + if (DevicePathType (DevPathNode) == ACPI_DEVICE_PATH &&
> + DevicePathSubType (DevPathNode) == ACPI_DP &&
> + ((ACPI_HID_DEVICE_PATH *)DevPathNode)->HID ==
> EISA_PNP_ID(0x0A03)) {
> + RootBusNumber = ((ACPI_HID_DEVICE_PATH *)DevPathNode)->UID;
> + }
> +
> + //
> + // Compute index into PciHostIrqs[] table by walking
> + // the device path and adding up all device numbers
> + //
> + Status = EFI_NOT_FOUND;
> + RootSlot = 0;
> + Idx = PciHdr->Device.InterruptPin - 1;
> + while (!IsDevicePathEnd (DevPathNode)) {
> + if (DevicePathType (DevPathNode) == HARDWARE_DEVICE_PATH &&
> + DevicePathSubType (DevPathNode) == HW_PCI_DP) {
> +
> + Idx += ((PCI_DEVICE_PATH *)DevPathNode)->Device;
> +
> + //
> + // Unlike SeaBIOS, which starts climbing from the leaf device
> + // up toward the root, we traverse the device path starting at
> + // the root moving toward the leaf node.
> + // The slot number of the top-level parent bridge is needed
> + // with more than 24 slots on the root bus.
> + //
> + if (Status != EFI_SUCCESS) {
> + Status = EFI_SUCCESS;
> + RootSlot = ((PCI_DEVICE_PATH *)DevPathNode)->Device;
> + }
> + }
> +
> + DevPathNode = NextDevicePathNode (DevPathNode);
> + }
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> + if (RootBusNumber == 0 && RootSlot == 0) {
> + return Status; //bugbug: workaround; need SIMICS change B0/D0/F0
> PCI_IntPin reg(0x3D) = 0X0
> +// DEBUG((
> +// EFI_D_ERROR,
> +// "%a: PCI host bridge (00:00.0) should have no interrupts!\n",
> +// __FUNCTION__
> +// ));
> +// ASSERT (FALSE);
> + }
> +
> + //
> + // Final PciHostIrqs[] index calculation depends on the platform
> + // and should match SeaBIOS src/fw/pciinit.c *_pci_slot_get_irq()
> + //
> + switch (mHostBridgeDevId) {
> + case INTEL_82441_DEVICE_ID:
> + Idx -= 1;
> + break;
> + case INTEL_ICH10_DEVICE_ID:
> + //
> + // SeaBIOS contains the following comment:
> + // "Slots 0-24 rotate slot:pin mapping similar to piix above, but
> + // with a different starting index.
> + //
> + // Slots 25-31 all use LNKA mapping (or LNKE, but A:D = E:H)"
> + //
> + if (RootSlot > 24) {
> + //
> + // in this case, subtract back out RootSlot from Idx
> + // (SeaBIOS never adds it to begin with, but that would make our
> + // device path traversal loop above too awkward)
> + //
> + Idx -= RootSlot;
> + }
> + break;
> + default:
> + ASSERT (FALSE); // should never get here
> + }
> + Idx %= ARRAY_SIZE (PciHostIrqs);
> + IrqLine = PciHostIrqs[Idx];
> +
> + DEBUG_CODE_BEGIN ();
> + {
> + CHAR16 *DevPathString;
> + STATIC CHAR16 Fallback[] = L"<failed to convert>";
> + UINTN Segment, Bus, Device, Function;
> +
> + DevPathString = ConvertDevicePathToText (DevPath, FALSE, FALSE);
> + if (DevPathString == NULL) {
> + DevPathString = Fallback;
> + }
> + Status = PciIo->GetLocation (PciIo, &Segment, &Bus, &Device, &Function);
> + ASSERT_EFI_ERROR (Status);
> +
> + DEBUG ((EFI_D_VERBOSE, "%a: [%02x:%02x.%x] %s -> 0x%02x\n",
> __FUNCTION__,
> + (UINT32)Bus, (UINT32)Device, (UINT32)Function, DevPathString,
> + IrqLine));
> +
> + if (DevPathString != Fallback) {
> + FreePool (DevPathString);
> + }
> + }
> + DEBUG_CODE_END ();
> +
> + //
> + // Set PCI Interrupt Line register for this device to PciHostIrqs[Idx]
> + //
> + Status = PciIo->Pci.Write (
> + PciIo,
> + EfiPciIoWidthUint8,
> + PCI_INT_LINE_OFFSET,
> + 1,
> + &IrqLine
> + );
> + }
> +
> + return Status;
> +}
> +
> +/**
> +Write to mask and edge/level triggered registers of master and slave 8259
> PICs.
> +
> +@param[in] Mask low byte for master PIC mask register,
> +high byte for slave PIC mask register.
> +@param[in] EdgeLevel low byte for master PIC edge/level triggered register,
> +high byte for slave PIC edge/level triggered register.
> +
> +**/
> +VOID
> +Interrupt8259WriteMask(
> + IN UINT16 Mask,
> + IN UINT16 EdgeLevel
> +)
> +{
> + IoWrite8(LEGACY_8259_MASK_REGISTER_MASTER, (UINT8)Mask);
> + IoWrite8(LEGACY_8259_MASK_REGISTER_SLAVE, (UINT8)(Mask >> 8));
> + IoWrite8(LEGACY_8259_EDGE_LEVEL_TRIGGERED_REGISTER_MASTER,
> (UINT8)EdgeLevel);
> + IoWrite8(LEGACY_8259_EDGE_LEVEL_TRIGGERED_REGISTER_SLAVE,
> (UINT8)(EdgeLevel >> 8));
> +}
> +
> +VOID
> +PciAcpiInitialization (
> + )
> +{
> + UINTN Pmba;
> +
> + //
> + // Query Host Bridge DID to determine platform type
> + //
> + mHostBridgeDevId = PcdGet16 (PcdSimicsX58HostBridgePciDevId);
> + switch (mHostBridgeDevId) {
> + case INTEL_82441_DEVICE_ID:
> + Pmba = POWER_MGMT_REGISTER_PIIX4 (PIIX4_PMBA);
> + //
> + // 00:01.0 ISA Bridge (PIIX4) LNK routing targets
> + //
> + PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x60), 0x0b); // A
> + PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x61), 0x0b); // B
> + PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x62), 0x0a); // C
> + PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x63), 0x0a); // D
> + break;
> + case INTEL_ICH10_DEVICE_ID:
> + Pmba = POWER_MGMT_REGISTER_ICH10 (ICH10_PMBASE);
> + //
> + // 00:1f.0 LPC Bridge LNK routing targets
> + //
> + PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x60), 0x0a); // A
> + PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x61), 0x0a); // B
> + PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x62), 0x0b); // C
> + PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x63), 0x0b); // D
> + PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x68), 0x0a); // E
> + PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x69), 0x0a); // F
> + PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x6a), 0x0b); // G
> + PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x6b), 0x0b); // H
> + break;
> + default:
> + DEBUG ((EFI_D_ERROR, "%a: Unknown Host Bridge Device ID: 0x%04x\n",
> + __FUNCTION__, mHostBridgeDevId));
> + ASSERT (FALSE);
> + return;
> + }
> +
> + //
> + // Initialize PCI_INTERRUPT_LINE for applicable present PCI devices
> + //
> + VisitAllPciInstances (SetPciIntLine);
> +
> + //
> + // Set ACPI SCI_EN bit in PMCNTRL
> + //
> + IoOr16 ((PciRead32 (Pmba) & ~BIT0) + 4, BIT0);
> + //
> + // Set all 8259 interrupts to edge triggered and disabled
> + //
> + Interrupt8259WriteMask(0xFFFF, 0x0000);
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +ConnectRecursivelyIfPciMassStorage (
> + IN EFI_HANDLE Handle,
> + IN EFI_PCI_IO_PROTOCOL *Instance,
> + IN PCI_TYPE00 *PciHeader
> + )
> +{
> + EFI_STATUS Status;
> + EFI_DEVICE_PATH_PROTOCOL *DevicePath;
> + CHAR16 *DevPathStr;
> +
> + //
> + // Recognize PCI Mass Storage
> + //
> + if (IS_CLASS1 (PciHeader, PCI_CLASS_MASS_STORAGE)) {
> + DevicePath = NULL;
> + Status = gBS->HandleProtocol (
> + Handle,
> + &gEfiDevicePathProtocolGuid,
> + (VOID*)&DevicePath
> + );
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + //
> + // Print Device Path
> + //
> + DevPathStr = ConvertDevicePathToText (DevicePath, FALSE, FALSE);
> + if (DevPathStr != NULL) {
> + DEBUG((
> + EFI_D_INFO,
> + "Found Mass Storage device: %s\n",
> + DevPathStr
> + ));
> + FreePool(DevPathStr);
> + }
> +
> + Status = gBS->ConnectController (Handle, NULL, NULL, TRUE);
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + }
> +
> + return EFI_SUCCESS;
> +}
> +
> +
> +/**
> + This notification function is invoked when the
> + EMU Variable FVB has been changed.
> +
> + @param Event The event that occurred
> + @param Context For EFI compatibility. Not used.
> +
> +**/
> +VOID
> +EFIAPI
> +EmuVariablesUpdatedCallback (
> + IN EFI_EVENT Event,
> + IN VOID *Context
> + )
> +{
> + DEBUG ((EFI_D_INFO, "EmuVariablesUpdatedCallback\n"));
> + UpdateNvVarsOnFileSystem ();
> +}
> +
> +
> +EFI_STATUS
> +EFIAPI
> +VisitingFileSystemInstance (
> + IN EFI_HANDLE Handle,
> + IN VOID *Instance,
> + IN VOID *Context
> + )
> +{
> + EFI_STATUS Status;
> + STATIC BOOLEAN ConnectedToFileSystem = FALSE;
> +
> + if (ConnectedToFileSystem) {
> + return EFI_ALREADY_STARTED;
> + }
> +
> + Status = ConnectNvVarsToFileSystem (Handle);
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + ConnectedToFileSystem = TRUE;
> + mEmuVariableEvent =
> + EfiCreateProtocolNotifyEvent (
> + &gEfiDevicePathProtocolGuid,
> + TPL_CALLBACK,
> + EmuVariablesUpdatedCallback,
> + NULL,
> + &mEmuVariableEventReg
> + );
> + PcdSet64 (PcdEmuVariableEvent, (UINT64)(UINTN) mEmuVariableEvent);
> +
> + return EFI_SUCCESS;
> +}
> +
> +
> +VOID
> +PlatformBdsRestoreNvVarsFromHardDisk (
> + )
> +{
> + VisitAllPciInstances (ConnectRecursivelyIfPciMassStorage);
> + VisitAllInstancesOfProtocol (
> + &gEfiSimpleFileSystemProtocolGuid,
> + VisitingFileSystemInstance,
> + NULL
> + );
> +
> +}
> +
> +/**
> + Connect with predefined platform connect sequence.
> +
> + The OEM/IBV can customize with their own connect sequence.
> +**/
> +VOID
> +PlatformBdsConnectSequence (
> + VOID
> + )
> +{
> + UINTN Index;
> +
> + DEBUG ((EFI_D_INFO, "PlatformBdsConnectSequence\n"));
> +
> + Index = 0;
> +
> + //
> + // Here we can get the customized platform connect sequence
> + // Notes: we can connect with new variable which record the
> + // last time boots connect device path sequence
> + //
> + while (gPlatformConnectSequence[Index] != NULL) {
> + //
> + // Build the platform boot option
> + //
> + EfiBootManagerConnectDevicePath (gPlatformConnectSequence[Index],
> NULL);
> + Index++;
> + }
> +
> + //
> + // Just use the simple policy to connect all devices
> + //
> + DEBUG ((EFI_D_INFO, "EfiBootManagerConnectAll\n"));
> + EfiBootManagerConnectAll ();
> +
> + PciAcpiInitialization ();
> +}
> +
> +/**
> + Save the S3 boot script.
> +
> + Note that DxeSmmReadyToLock must be signaled after this function returns;
> + otherwise the script wouldn't be saved actually.
> +**/
> +STATIC
> +VOID
> +SaveS3BootScript (
> + VOID
> + )
> +{
> + EFI_STATUS Status;
> + EFI_S3_SAVE_STATE_PROTOCOL *BootScript;
> + STATIC CONST UINT8 Info[] = { 0xDE, 0xAD, 0xBE, 0xEF };
> +
> + Status = gBS->LocateProtocol (&gEfiS3SaveStateProtocolGuid, NULL,
> + (VOID **) &BootScript);
> + ASSERT_EFI_ERROR (Status);
> +
> + //
> + // Despite the opcode documentation in the PI spec, the protocol
> + // implementation embeds a deep copy of the info in the boot script, rather
> + // than storing just a pointer to runtime or NVS storage.
> + //
> + Status = BootScript->Write(BootScript,
> EFI_BOOT_SCRIPT_INFORMATION_OPCODE,
> + (UINT32) sizeof Info,
> + (EFI_PHYSICAL_ADDRESS)(UINTN) &Info);
> + ASSERT_EFI_ERROR (Status);
> +}
> +
> +
> +/**
> + Do the platform specific action after the console is ready
> +
> + Possible things that can be done in PlatformBootManagerAfterConsole:
> +
> + > Console post action:
> + > Dynamically switch output mode from 100x31 to 80x25 for certain
> senarino
> + > Signal console ready platform customized event
> + > Run diagnostics like memory testing
> + > Connect certain devices
> + > Dispatch aditional option roms
> + > Special boot: e.g.: USB boot, enter UI
> +**/
> +VOID
> +EFIAPI
> +PlatformBootManagerAfterConsole (
> + VOID
> + )
> +{
> + EFI_BOOT_MODE BootMode;
> + EFI_HANDLE Handle;
> + EFI_STATUS Status;
> +
> + DEBUG ((EFI_D_INFO, "PlatformBootManagerAfterConsole\n"));
> +
> + //
> + // Prevent further changes to LockBoxes or SMRAM.
> + //
> + Handle = NULL;
> + Status = gBS->InstallProtocolInterface(&Handle,
> + &gEfiDxeSmmReadyToLockProtocolGuid, EFI_NATIVE_INTERFACE,
> + NULL);
> + ASSERT_EFI_ERROR(Status);
> +
> + if (PcdGetBool (PcdOvmfFlashVariablesEnable)) {
> + DEBUG ((EFI_D_INFO, "PlatformBdsPolicyBehavior: not restoring NvVars "
> + "from disk since flash variables appear to be supported.\n"));
> + } else {
> + //
> + // Try to restore variables from the hard disk early so
> + // they can be used for the other BDS connect operations.
> + //
> + PlatformBdsRestoreNvVarsFromHardDisk ();
> + }
> +
> + //
> + // Get current Boot Mode
> + //
> + BootMode = GetBootModeHob ();
> + DEBUG ((EFI_D_ERROR, "Boot Mode:%x\n", BootMode));
> +
> + //
> + // Go the different platform policy with different boot mode
> + // Notes: this part code can be change with the table policy
> + //
> + ASSERT (BootMode == BOOT_WITH_FULL_CONFIGURATION);
> +
> + // Perform some platform specific connect sequence
> + //
> + PlatformBdsConnectSequence ();
> + //
> + // Logo show
> + //
> + EnableBootLogo(PcdGetPtr(PcdLogoFile));
> +
> + EfiBootManagerRefreshAllBootOption ();
> +
> + //
> + // Register UEFI Shell
> + //
> + PlatformRegisterFvBootOption (
> + PcdGetPtr (PcdShellFile), L"EFI Internal Shell", LOAD_OPTION_ACTIVE
> + );
> +
> + RemoveStaleFvFileOptions ();
> +}
> +
> +/**
> + This notification function is invoked when an instance of the
> + EFI_DEVICE_PATH_PROTOCOL is produced.
> +
> + @param Event The event that occurred
> + @param Context For EFI compatibility. Not used.
> +
> +**/
> +VOID
> +EFIAPI
> +NotifyDevPath (
> + IN EFI_EVENT Event,
> + IN VOID *Context
> + )
> +{
> + EFI_HANDLE Handle;
> + EFI_STATUS Status;
> + UINTN BufferSize;
> + EFI_DEVICE_PATH_PROTOCOL *DevPathNode;
> + ATAPI_DEVICE_PATH *Atapi;
> +
> + //
> + // Examine all new handles
> + //
> + for (;;) {
> + //
> + // Get the next handle
> + //
> + BufferSize = sizeof (Handle);
> + Status = gBS->LocateHandle (
> + ByRegisterNotify,
> + NULL,
> + mEfiDevPathNotifyReg,
> + &BufferSize,
> + &Handle
> + );
> +
> + //
> + // If not found, we're done
> + //
> + if (EFI_NOT_FOUND == Status) {
> + break;
> + }
> +
> + if (EFI_ERROR (Status)) {
> + continue;
> + }
> +
> + //
> + // Get the DevicePath protocol on that handle
> + //
> + Status = gBS->HandleProtocol (Handle, &gEfiDevicePathProtocolGuid, (VOID
> **)&DevPathNode);
> + ASSERT_EFI_ERROR (Status);
> +
> + while (!IsDevicePathEnd (DevPathNode)) {
> + //
> + // Find the handler to dump this device path node
> + //
> + if (
> + (DevicePathType(DevPathNode) == MESSAGING_DEVICE_PATH) &&
> + (DevicePathSubType(DevPathNode) == MSG_ATAPI_DP)
> + ) {
> + Atapi = (ATAPI_DEVICE_PATH*) DevPathNode;
> + PciOr16 (
> + PCI_LIB_ADDRESS (
> + 0,
> + 1,
> + 1,
> + (Atapi->PrimarySecondary == 1) ? 0x42: 0x40
> + ),
> + BIT15
> + );
> + }
> +
> + //
> + // Next device path node
> + //
> + DevPathNode = NextDevicePathNode (DevPathNode);
> + }
> + }
> +
> + return;
> +}
> +
> +
> +VOID
> +InstallDevicePathCallback (
> + VOID
> + )
> +{
> + DEBUG ((EFI_D_INFO, "Registered NotifyDevPath Event\n"));
> + mEfiDevPathEvent = EfiCreateProtocolNotifyEvent (
> + &gEfiDevicePathProtocolGuid,
> + TPL_CALLBACK,
> + NotifyDevPath,
> + NULL,
> + &mEfiDevPathNotifyReg
> + );
> +}
> +
> +/**
> + This function is called each second during the boot manager waits the
> + timeout.
> +
> + @param TimeoutRemain The remaining timeout.
> +**/
> +VOID
> +EFIAPI
> +PlatformBootManagerWaitCallback (
> + UINT16 TimeoutRemain
> + )
> +{
> + EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION Black;
> + EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION White;
> + UINT16 Timeout;
> +
> + Timeout = PcdGet16 (PcdPlatformBootTimeOut);
> +
> + Black.Raw = 0x00000000;
> + White.Raw = 0x00FFFFFF;
> +
> + BootLogoUpdateProgress (
> + White.Pixel,
> + Black.Pixel,
> + L"Start boot option",
> + White.Pixel,
> + (Timeout - TimeoutRemain) * 100 / Timeout,
> + 0
> + );
> +}
> +
> +/**
> + The function is called when no boot option could be launched,
> + including platform recovery options and options pointing to applications
> + built into firmware volumes.
> +
> + If this function returns, BDS attempts to enter an infinite loop.
> +**/
> +VOID
> +EFIAPI
> +PlatformBootManagerUnableToBoot (
> + VOID
> + )
> +{
> + // BUGBUG- will do it if need
> +}
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Library/PlatformBootManagerLib/Platfo
> rmData.c
> b/Platform/Intel/SimicsOpenBoardPkg/Library/PlatformBootManagerLib/Platfo
> rmData.c
> new file mode 100644
> index 0000000000..768843a8bf
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Library/PlatformBootManagerLib/Platfo
> rmData.c
> @@ -0,0 +1,35 @@
> +/** @file
> + Defined the platform specific device path which will be used by
> + platform Bbd to perform the platform policy connect.
> +
> + Copyright (c) 2004 - 2019 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "BdsPlatform.h"
> +
> +ACPI_HID_DEVICE_PATH gPnpPs2KeyboardDeviceNode =
> gPnpPs2Keyboard;
> +ACPI_HID_DEVICE_PATH gPnp16550ComPortDeviceNode =
> gPnp16550ComPort;
> +UART_DEVICE_PATH gUartDeviceNode = gUart;
> +VENDOR_DEVICE_PATH gTerminalTypeDeviceNode = gPcAnsiTerminal;
> +
> +//
> +// Platform specific keyboard device path
> +//
> +
> +//
> +// Predefined platform default console device path
> +//
> +PLATFORM_CONSOLE_CONNECT_ENTRY gPlatformConsole[] = {
> + {
> + NULL,
> + 0
> + }
> +};
> +
> +//
> +// Predefined platform connect sequence
> +//
> +EFI_DEVICE_PATH_PROTOCOL *gPlatformConnectSequence[] = { NULL };
> +
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVar
> iablesLib.c
> b/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVar
> iablesLib.c
> new file mode 100644
> index 0000000000..be619c838a
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVar
> iablesLib.c
> @@ -0,0 +1,869 @@
> +/** @file
> + Serialize Variables Library implementation
> +
> + Copyright (c) 2004 - 2019 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "SerializeVariablesLib.h"
> +
> +/**
> + Serialization format:
> +
> + The SerializeVariablesLib interface does not specify a format
> + for the serialization of the variable data. This library uses
> + a packed array of a non-uniformly sized data structure elements.
> +
> + Each variable is stored (packed) as:
> + UINT32 VendorNameSize; // Name size in bytes
> + CHAR16 VendorName[?]; // The variable unicode name including the
> + // null terminating character.
> + EFI_GUID VendorGuid; // The variable GUID
> + UINT32 DataSize; // The size of variable data in bytes
> + UINT8 Data[?]; // The variable data
> +
> +**/
> +
> +
> +/**
> + Unpacks the next variable from the buffer
> +
> + @param[in] Buffer - Buffer pointing to the next variable instance
> + On subsequent calls, the pointer should be incremented
> + by the returned SizeUsed value.
> + @param[in] MaxSize - Max allowable size for the variable data
> + On subsequent calls, this should be decremented
> + by the returned SizeUsed value.
> + @param[out] Name - Variable name string (address in Buffer)
> + @param[out] NameSize - Size of Name in bytes
> + @param[out] Guid - GUID of variable (address in Buffer)
> + @param[out] Attributes - Attributes of variable
> + @param[out] Data - Buffer containing Data for variable (address in Buffer)
> + @param[out] DataSize - Size of Data in bytes
> + @param[out] SizeUsed - Total size used for this variable instance in Buffer
> +
> + @return EFI_STATUS based on the success or failure of the operation
> +
> +**/
> +STATIC
> +EFI_STATUS
> +UnpackVariableFromBuffer (
> + IN VOID *Buffer,
> + IN UINTN MaxSize,
> + OUT CHAR16 **Name,
> + OUT UINT32 *NameSize,
> + OUT EFI_GUID **Guid,
> + OUT UINT32 *Attributes,
> + OUT UINT32 *DataSize,
> + OUT VOID **Data,
> + OUT UINTN *SizeUsed
> + )
> +{
> + UINT8 *BytePtr;
> + UINTN Offset;
> +
> + BytePtr = (UINT8*)Buffer;
> + Offset = 0;
> +
> + *NameSize = *(UINT32*) (BytePtr + Offset);
> + Offset = Offset + sizeof (UINT32);
> +
> + if (Offset > MaxSize) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + *Name = (CHAR16*) (BytePtr + Offset);
> + Offset = Offset + *(UINT32*)BytePtr;
> + if (Offset > MaxSize) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + *Guid = (EFI_GUID*) (BytePtr + Offset);
> + Offset = Offset + sizeof (EFI_GUID);
> + if (Offset > MaxSize) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + *Attributes = *(UINT32*) (BytePtr + Offset);
> + Offset = Offset + sizeof (UINT32);
> + if (Offset > MaxSize) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + *DataSize = *(UINT32*) (BytePtr + Offset);
> + Offset = Offset + sizeof (UINT32);
> + if (Offset > MaxSize) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + *Data = (VOID*) (BytePtr + Offset);
> + Offset = Offset + *DataSize;
> + if (Offset > MaxSize) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + *SizeUsed = Offset;
> +
> + return EFI_SUCCESS;
> +}
> +
> +
> +/**
> + Iterates through the variables in the buffer, and calls a callback
> + function for each variable found.
> +
> + @param[in] CallbackFunction - Function called for each variable instance
> + @param[in] Context - Passed to each call of CallbackFunction
> + @param[in] Buffer - Buffer containing serialized variables
> + @param[in] MaxSize - Size of Buffer in bytes
> +
> + @return EFI_STATUS based on the success or failure of the operation
> +
> +**/
> +STATIC
> +EFI_STATUS
> +IterateVariablesInBuffer (
> + IN VARIABLE_SERIALIZATION_ITERATION_CALLBACK CallbackFunction,
> + IN VOID *CallbackContext,
> + IN VOID *Buffer,
> + IN UINTN MaxSize
> + )
> +{
> + RETURN_STATUS Status;
> + UINTN TotalSizeUsed;
> + UINTN SizeUsed;
> +
> + CHAR16 *Name;
> + UINT32 NameSize;
> + CHAR16 *AlignedName;
> + UINT32 AlignedNameMaxSize;
> + EFI_GUID *Guid;
> + UINT32 Attributes;
> + UINT32 DataSize;
> + VOID *Data;
> +
> + SizeUsed = 0;
> + AlignedName = NULL;
> + AlignedNameMaxSize = 0;
> + Name = NULL;
> + Guid = NULL;
> + Attributes = 0;
> + DataSize = 0;
> + Data = NULL;
> +
> + for (
> + Status = EFI_SUCCESS, TotalSizeUsed = 0;
> + !EFI_ERROR (Status) && (TotalSizeUsed < MaxSize);
> + ) {
> + Status = UnpackVariableFromBuffer (
> + (VOID*) ((UINT8*) Buffer + TotalSizeUsed),
> + (MaxSize - TotalSizeUsed),
> + &Name,
> + &NameSize,
> + &Guid,
> + &Attributes,
> + &DataSize,
> + &Data,
> + &SizeUsed
> + );
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + //
> + // We copy the name to a separately allocated buffer,
> + // to be sure it is 16-bit aligned.
> + //
> + if (NameSize > AlignedNameMaxSize) {
> + if (AlignedName != NULL) {
> + FreePool (AlignedName);
> + }
> + AlignedName = AllocatePool (NameSize);
> + }
> + if (AlignedName == NULL) {
> + return EFI_OUT_OF_RESOURCES;
> + }
> + CopyMem (AlignedName, Name, NameSize);
> +
> + TotalSizeUsed = TotalSizeUsed + SizeUsed;
> +
> + //
> + // Run the callback function
> + //
> + Status = (*CallbackFunction) (
> + CallbackContext,
> + AlignedName,
> + Guid,
> + Attributes,
> + DataSize,
> + Data
> + );
> +
> + }
> +
> + if (AlignedName != NULL) {
> + FreePool (AlignedName);
> + }
> +
> + //
> + // Make sure the entire buffer was used, or else return an error
> + //
> + if (TotalSizeUsed != MaxSize) {
> + DEBUG ((
> + EFI_D_ERROR,
> + "Deserialize variables error: TotalSizeUsed(%Lu) != MaxSize(%Lu)\n",
> + (UINT64)TotalSizeUsed,
> + (UINT64)MaxSize
> + ));
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + return EFI_SUCCESS;
> +}
> +
> +
> +STATIC
> +RETURN_STATUS
> +EFIAPI
> +IterateVariablesCallbackNop (
> + IN VOID *Context,
> + IN CHAR16 *VariableName,
> + IN EFI_GUID *VendorGuid,
> + IN UINT32 Attributes,
> + IN UINTN DataSize,
> + IN VOID *Data
> + )
> +{
> + return RETURN_SUCCESS;
> +}
> +
> +
> +STATIC
> +RETURN_STATUS
> +EFIAPI
> +IterateVariablesCallbackSetInInstance (
> + IN VOID *Context,
> + IN CHAR16 *VariableName,
> + IN EFI_GUID *VendorGuid,
> + IN UINT32 Attributes,
> + IN UINTN DataSize,
> + IN VOID *Data
> + )
> +{
> + EFI_HANDLE Instance;
> +
> + Instance = (EFI_HANDLE) Context;
> +
> + return SerializeVariablesAddVariable (
> + Instance,
> + VariableName,
> + VendorGuid,
> + Attributes,
> + DataSize,
> + Data
> + );
> +}
> +
> +
> +STATIC
> +RETURN_STATUS
> +EFIAPI
> +IterateVariablesCallbackSetSystemVariable (
> + IN VOID *Context,
> + IN CHAR16 *VariableName,
> + IN EFI_GUID *VendorGuid,
> + IN UINT32 Attributes,
> + IN UINTN DataSize,
> + IN VOID *Data
> + )
> +{
> + EFI_STATUS Status;
> + STATIC CONST UINT32 AuthMask =
> + EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS |
> + EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;
> +
> + Status = gRT->SetVariable (
> + VariableName,
> + VendorGuid,
> + Attributes,
> + DataSize,
> + Data
> + );
> +
> + if (Status == EFI_SECURITY_VIOLATION && (Attributes & AuthMask) != 0) {
> + DEBUG ((DEBUG_WARN, "%a: setting authenticated variable \"%s\" "
> + "failed with EFI_SECURITY_VIOLATION, ignoring\n", __FUNCTION__,
> + VariableName));
> + Status = EFI_SUCCESS;
> + } else if (Status == EFI_WRITE_PROTECTED) {
> + DEBUG ((DEBUG_WARN, "%a: setting ReadOnly variable \"%s\" "
> + "failed with EFI_WRITE_PROTECTED, ignoring\n", __FUNCTION__,
> + VariableName));
> + Status = EFI_SUCCESS;
> + }
> + return Status;
> +}
> +
> +
> +STATIC
> +RETURN_STATUS
> +EnsureExtraBufferSpace (
> + IN SV_INSTANCE *Instance,
> + IN UINTN Size
> + )
> +{
> + VOID *NewBuffer;
> + UINTN NewSize;
> +
> + NewSize = Instance->DataSize + Size;
> + if (NewSize <= Instance->BufferSize) {
> + return RETURN_SUCCESS;
> + }
> +
> + //
> + // Double the required size to lessen the need to re-allocate in the future
> + //
> + NewSize = 2 * NewSize;
> +
> + NewBuffer = AllocatePool (NewSize);
> + if (NewBuffer == NULL) {
> + return RETURN_OUT_OF_RESOURCES;
> + }
> +
> + if (Instance->BufferPtr != NULL) {
> + CopyMem (NewBuffer, Instance->BufferPtr, Instance->DataSize);
> + FreePool (Instance->BufferPtr);
> + }
> +
> + Instance->BufferPtr = NewBuffer;
> + Instance->BufferSize = NewSize;
> +
> + return RETURN_SUCCESS;
> +}
> +
> +
> +STATIC
> +VOID
> +AppendToBuffer (
> + IN SV_INSTANCE *Instance,
> + IN VOID *Data,
> + IN UINTN Size
> + )
> +{
> + UINTN NewSize;
> +
> + ASSERT (Instance != NULL);
> + ASSERT (Data != NULL);
> +
> + NewSize = Instance->DataSize + Size;
> + ASSERT ((Instance->DataSize + Size) <= Instance->BufferSize);
> +
> + CopyMem (
> + (VOID*) (((UINT8*) (Instance->BufferPtr)) + Instance->DataSize),
> + Data,
> + Size
> + );
> +
> + Instance->DataSize = NewSize;
> +}
> +
> +
> +/**
> + Creates a new variable serialization instance
> +
> + @param[out] Handle - Handle for a variable serialization instance
> +
> + @retval RETURN_SUCCESS - The variable serialization instance was
> + successfully created.
> + @retval RETURN_OUT_OF_RESOURCES - There we not enough resources
> to
> + create the variable serialization instance.
> +
> +**/
> +RETURN_STATUS
> +EFIAPI
> +SerializeVariablesNewInstance (
> + OUT EFI_HANDLE *Handle
> + )
> +{
> + SV_INSTANCE *New;
> +
> + New = AllocateZeroPool (sizeof (*New));
> + if (New == NULL) {
> + return RETURN_OUT_OF_RESOURCES;
> + }
> +
> + New->Signature = SV_SIGNATURE;
> +
> + *Handle = (EFI_HANDLE) New;
> + return RETURN_SUCCESS;
> +}
> +
> +
> +/**
> + Free memory associated with a variable serialization instance
> +
> + @param[in] Handle - Handle for a variable serialization instance
> +
> + @retval RETURN_SUCCESS - The variable serialization instance was
> + successfully freed.
> + @retval RETURN_INVALID_PARAMETER - Handle was not a valid
> + variable serialization instance.
> +
> +**/
> +RETURN_STATUS
> +EFIAPI
> +SerializeVariablesFreeInstance (
> + IN EFI_HANDLE Handle
> + )
> +{
> + SV_INSTANCE *Instance;
> +
> + Instance = SV_FROM_HANDLE (Handle);
> +
> + if (Instance->Signature != SV_SIGNATURE) {
> + return RETURN_INVALID_PARAMETER;
> + }
> +
> + Instance->Signature = 0;
> +
> + if (Instance->BufferPtr != NULL) {
> + FreePool (Instance->BufferPtr);
> + }
> +
> + FreePool (Instance);
> +
> + return RETURN_SUCCESS;
> +}
> +
> +
> +/**
> + Creates a new variable serialization instance using the given
> + binary representation of the variables to fill the new instance
> +
> + @param[out] Handle - Handle for a variable serialization instance
> + @param[in] Buffer - A buffer with the serialized representation
> + of the variables. Must be the same format as produced
> + by SerializeVariablesToBuffer.
> + @param[in] Size - This is the size of the binary representation
> + of the variables.
> +
> + @retval RETURN_SUCCESS - The binary representation was successfully
> + imported into a new variable serialization instance
> + @retval RETURN_OUT_OF_RESOURCES - There we not enough resources
> to
> + create the new variable serialization instance
> +
> +**/
> +RETURN_STATUS
> +EFIAPI
> +SerializeVariablesNewInstanceFromBuffer (
> + OUT EFI_HANDLE *Handle,
> + IN VOID *Buffer,
> + IN UINTN Size
> + )
> +{
> + RETURN_STATUS Status;
> +
> + Status = SerializeVariablesNewInstance (Handle);
> + if (RETURN_ERROR (Status)) {
> + return Status;
> + }
> +
> + Status = IterateVariablesInBuffer (
> + IterateVariablesCallbackNop,
> + NULL,
> + Buffer,
> + Size
> + );
> + if (RETURN_ERROR (Status)) {
> + SerializeVariablesFreeInstance (*Handle);
> + return Status;
> + }
> +
> + Status = IterateVariablesInBuffer (
> + IterateVariablesCallbackSetInInstance,
> + (VOID*) *Handle,
> + Buffer,
> + Size
> + );
> + if (RETURN_ERROR (Status)) {
> + SerializeVariablesFreeInstance (*Handle);
> + return Status;
> + }
> +
> + return Status;
> +}
> +
> +
> +/**
> + Iterates all variables found with RuntimeServices GetNextVariableName
> +
> + @param[in] CallbackFunction - Function called for each variable instance
> + @param[in] Context - Passed to each call of CallbackFunction
> +
> + @retval RETURN_SUCCESS - All variables were iterated without the
> + CallbackFunction returning an error
> + @retval RETURN_OUT_OF_RESOURCES - There we not enough resources
> to
> + iterate through the variables
> + @return Any of RETURN_ERROR indicates an error reading the variable
> + or an error was returned from CallbackFunction
> +
> +**/
> +RETURN_STATUS
> +EFIAPI
> +SerializeVariablesIterateSystemVariables (
> + IN VARIABLE_SERIALIZATION_ITERATION_CALLBACK CallbackFunction,
> + IN VOID *Context
> + )
> +{
> + RETURN_STATUS Status;
> + UINTN VariableNameBufferSize;
> + UINTN VariableNameSize;
> + CHAR16 *VariableName;
> + EFI_GUID VendorGuid;
> + UINTN VariableDataBufferSize;
> + UINTN VariableDataSize;
> + VOID *VariableData;
> + UINT32 VariableAttributes;
> + VOID *NewBuffer;
> +
> + //
> + // Initialize the variable name and data buffer variables.
> + //
> + VariableNameBufferSize = sizeof (CHAR16);
> + VariableName = AllocateZeroPool (VariableNameBufferSize);
> +
> + VariableDataBufferSize = 0;
> + VariableData = NULL;
> +
> + for (;;) {
> + //
> + // Get the next variable name and guid
> + //
> + VariableNameSize = VariableNameBufferSize;
> + Status = gRT->GetNextVariableName (
> + &VariableNameSize,
> + VariableName,
> + &VendorGuid
> + );
> + if (Status == EFI_BUFFER_TOO_SMALL) {
> + //
> + // The currently allocated VariableName buffer is too small,
> + // so we allocate a larger buffer, and copy the old buffer
> + // to it.
> + //
> + NewBuffer = AllocatePool (VariableNameSize);
> + if (NewBuffer == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + break;
> + }
> + CopyMem (NewBuffer, VariableName, VariableNameBufferSize);
> + if (VariableName != NULL) {
> + FreePool (VariableName);
> + }
> + VariableName = NewBuffer;
> + VariableNameBufferSize = VariableNameSize;
> +
> + //
> + // Try to get the next variable name again with the larger buffer.
> + //
> + Status = gRT->GetNextVariableName (
> + &VariableNameSize,
> + VariableName,
> + &VendorGuid
> + );
> + }
> +
> + if (EFI_ERROR (Status)) {
> + if (Status == EFI_NOT_FOUND) {
> + Status = EFI_SUCCESS;
> + }
> + break;
> + }
> +
> + //
> + // Get the variable data and attributes
> + //
> + VariableDataSize = VariableDataBufferSize;
> + Status = gRT->GetVariable (
> + VariableName,
> + &VendorGuid,
> + &VariableAttributes,
> + &VariableDataSize,
> + VariableData
> + );
> + if (Status == EFI_BUFFER_TOO_SMALL) {
> + //
> + // The currently allocated VariableData buffer is too small,
> + // so we allocate a larger buffer.
> + //
> + if (VariableDataBufferSize != 0) {
> + FreePool (VariableData);
> + VariableData = NULL;
> + VariableDataBufferSize = 0;
> + }
> + VariableData = AllocatePool (VariableDataSize);
> + if (VariableData == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + break;
> + }
> + VariableDataBufferSize = VariableDataSize;
> +
> + //
> + // Try to read the variable again with the larger buffer.
> + //
> + Status = gRT->GetVariable (
> + VariableName,
> + &VendorGuid,
> + &VariableAttributes,
> + &VariableDataSize,
> + VariableData
> + );
> + }
> + if (EFI_ERROR (Status)) {
> + break;
> + }
> +
> + //
> + // Run the callback function
> + //
> + Status = (*CallbackFunction) (
> + Context,
> + VariableName,
> + &VendorGuid,
> + VariableAttributes,
> + VariableDataSize,
> + VariableData
> + );
> + if (EFI_ERROR (Status)) {
> + break;
> + }
> +
> + }
> +
> + if (VariableName != NULL) {
> + FreePool (VariableName);
> + }
> +
> + if (VariableData != NULL) {
> + FreePool (VariableData);
> + }
> +
> + return Status;
> +}
> +
> +
> +/**
> + Iterates all variables found in the variable serialization instance
> +
> + @param[in] Handle - Handle for a variable serialization instance
> + @param[in] CallbackFunction - Function called for each variable instance
> + @param[in] Context - Passed to each call of CallbackFunction
> +
> + @retval RETURN_SUCCESS - All variables were iterated without the
> + CallbackFunction returning an error
> + @retval RETURN_OUT_OF_RESOURCES - There we not enough resources
> to
> + iterate through the variables
> + @return Any of RETURN_ERROR indicates an error reading the variable
> + or an error was returned from CallbackFunction
> +
> +**/
> +RETURN_STATUS
> +EFIAPI
> +SerializeVariablesIterateInstanceVariables (
> + IN EFI_HANDLE Handle,
> + IN VARIABLE_SERIALIZATION_ITERATION_CALLBACK CallbackFunction,
> + IN VOID *Context
> + )
> +{
> + SV_INSTANCE *Instance;
> +
> + Instance = SV_FROM_HANDLE (Handle);
> +
> + if ((Instance->BufferPtr != NULL) && (Instance->DataSize != 0)) {
> + return IterateVariablesInBuffer (
> + CallbackFunction,
> + Context,
> + Instance->BufferPtr,
> + Instance->DataSize
> + );
> + } else {
> + return RETURN_SUCCESS;
> + }
> +}
> +
> +
> +/**
> + Sets all variables found in the variable serialization instance
> +
> + @param[in] Handle - Handle for a variable serialization instance
> +
> + @retval RETURN_SUCCESS - All variables were set successfully
> + @retval RETURN_OUT_OF_RESOURCES - There we not enough resources
> to
> + set all the variables
> + @return Any of RETURN_ERROR indicates an error reading the variables
> + or in attempting to set a variable
> +
> +**/
> +RETURN_STATUS
> +EFIAPI
> +SerializeVariablesSetSerializedVariables (
> + IN EFI_HANDLE Handle
> + )
> +{
> + return SerializeVariablesIterateInstanceVariables (
> + Handle,
> + IterateVariablesCallbackSetSystemVariable,
> + NULL
> + );
> +}
> +
> +
> +/**
> + Adds a variable to the variable serialization instance
> +
> + @param[in] Handle - Handle for a variable serialization instance
> + @param[in] VariableName - Refer to RuntimeServices GetVariable
> + @param[in] VendorGuid - Refer to RuntimeServices GetVariable
> + @param[in] Attributes - Refer to RuntimeServices GetVariable
> + @param[in] DataSize - Refer to RuntimeServices GetVariable
> + @param[in] Data - Refer to RuntimeServices GetVariable
> +
> + @retval RETURN_SUCCESS - All variables were set successfully
> + @retval RETURN_OUT_OF_RESOURCES - There we not enough resources
> to
> + add the variable
> + @retval RETURN_INVALID_PARAMETER - Handle was not a valid
> + variable serialization instance or
> + VariableName, VariableGuid or Data are NULL.
> +
> +**/
> +RETURN_STATUS
> +EFIAPI
> +SerializeVariablesAddVariable (
> + IN EFI_HANDLE Handle,
> + IN CHAR16 *VariableName,
> + IN EFI_GUID *VendorGuid,
> + IN UINT32 Attributes,
> + IN UINTN DataSize,
> + IN VOID *Data
> + )
> +{
> + RETURN_STATUS Status;
> + SV_INSTANCE *Instance;
> + UINT32 SerializedNameSize;
> + UINT32 SerializedDataSize;
> + UINTN SerializedSize;
> +
> + Instance = SV_FROM_HANDLE (Handle);
> +
> + if ((Instance->Signature != SV_SIGNATURE) ||
> + (VariableName == NULL) || (VendorGuid == NULL) || (Data == NULL)) {
> + }
> +
> + SerializedNameSize = (UINT32) StrSize (VariableName);
> +
> + SerializedSize =
> + sizeof (SerializedNameSize) +
> + SerializedNameSize +
> + sizeof (*VendorGuid) +
> + sizeof (Attributes) +
> + sizeof (SerializedDataSize) +
> + DataSize;
> +
> + Status = EnsureExtraBufferSpace (
> + Instance,
> + SerializedSize
> + );
> + if (RETURN_ERROR (Status)) {
> + return Status;
> + }
> +
> + //
> + // Add name size (UINT32)
> + //
> + AppendToBuffer (Instance, (VOID*) &SerializedNameSize, sizeof
> (SerializedNameSize));
> +
> + //
> + // Add variable unicode name string
> + //
> + AppendToBuffer (Instance, (VOID*) VariableName, SerializedNameSize);
> +
> + //
> + // Add variable GUID
> + //
> + AppendToBuffer (Instance, (VOID*) VendorGuid, sizeof (*VendorGuid));
> +
> + //
> + // Add variable attributes
> + //
> + AppendToBuffer (Instance, (VOID*) &Attributes, sizeof (Attributes));
> +
> + //
> + // Add variable data size (UINT32)
> + //
> + SerializedDataSize = (UINT32) DataSize;
> + AppendToBuffer (Instance, (VOID*) &SerializedDataSize, sizeof
> (SerializedDataSize));
> +
> + //
> + // Add variable data
> + //
> + AppendToBuffer (Instance, Data, DataSize);
> +
> + return RETURN_SUCCESS;
> +}
> +
> +
> +/**
> + Serializes the variables known to this instance into the
> + provided buffer.
> +
> + @param[in] Handle - Handle for a variable serialization instance
> + @param[out] Buffer - A buffer to store the binary representation
> + of the variables.
> + @param[in,out] Size - On input this is the size of the buffer.
> + On output this is the size of the binary representation
> + of the variables.
> +
> + @retval RETURN_SUCCESS - The binary representation was successfully
> + completed and returned in the buffer.
> + @retval RETURN_OUT_OF_RESOURCES - There we not enough resources
> to
> + save the variables to the buffer.
> + @retval RETURN_INVALID_PARAMETER - Handle was not a valid
> + variable serialization instance or
> + Size or Buffer were NULL.
> + @retval RETURN_BUFFER_TOO_SMALL - The Buffer size as indicated by
> + the Size parameter was too small for the serialized
> + variable data. Size is returned with the required size.
> +
> +**/
> +RETURN_STATUS
> +EFIAPI
> +SerializeVariablesToBuffer (
> + IN EFI_HANDLE Handle,
> + OUT VOID *Buffer,
> + IN OUT UINTN *Size
> + )
> +{
> + SV_INSTANCE *Instance;
> +
> + Instance = SV_FROM_HANDLE (Handle);
> +
> + if (Size == NULL) {
> + return RETURN_INVALID_PARAMETER;
> + }
> +
> + if (*Size < Instance->DataSize) {
> + *Size = Instance->DataSize;
> + return RETURN_BUFFER_TOO_SMALL;
> + }
> +
> + if (Buffer == NULL) {
> + return RETURN_INVALID_PARAMETER;
> + }
> +
> + *Size = Instance->DataSize;
> + CopyMem (Buffer, Instance->BufferPtr, Instance->DataSize);
> +
> + return RETURN_SUCCESS;
> +}
> +
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyInitLib/Silicon
> PolicyInitLib.c
> b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyInitLib/Silicon
> PolicyInitLib.c
> new file mode 100644
> index 0000000000..383501898d
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyInitLib/Silicon
> PolicyInitLib.c
> @@ -0,0 +1,108 @@
> +/** @file
> + Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Library/DebugLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/PeiServicesLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +
> +/**
> + Performs silicon pre-mem policy initialization.
> +
> + The meaning of Policy is defined by silicon code.
> + It could be the raw data, a handle, a PPI, etc.
> +
> + The returned data must be used as input data for SiliconPolicyDonePreMem(),
> + and SiliconPolicyUpdateLib.SiliconPolicyUpdatePreMem().
> +
> + 1) In FSP path, the input Policy should be FspmUpd.
> + Value of FspmUpd has been initialized by FSP binary default value.
> + Only a subset of FspmUpd needs to be updated for different silicon sku.
> + The return data is same FspmUpd.
> +
> + 2) In non-FSP path, the input policy could be NULL.
> + The return data is the initialized policy.
> +
> + @param[in, out] Policy Pointer to policy.
> +
> + @return the initialized policy.
> +**/
> +VOID *
> +EFIAPI
> +SiliconPolicyInitPreMem (
> + IN OUT VOID *Policy OPTIONAL
> + )
> +{
> + return Policy;
> +}
> +
> +/*
> + The silicon pre-mem policy is finalized.
> + Silicon code can do initialization based upon the policy data.
> +
> + The input Policy must be returned by SiliconPolicyInitPreMem().
> +
> + @param[in] Policy Pointer to policy.
> +
> + @retval RETURN_SUCCESS The policy is handled consumed by silicon code.
> +*/
> +RETURN_STATUS
> +EFIAPI
> +SiliconPolicyDonePreMem (
> + IN VOID *Policy
> + )
> +{
> + return RETURN_SUCCESS;
> +}
> +
> +/**
> + Performs silicon post-mem policy initialization.
> +
> + The meaning of Policy is defined by silicon code.
> + It could be the raw data, a handle, a PPI, etc.
> +
> + The returned data must be used as input data for
> SiliconPolicyDonePostMem(),
> + and SiliconPolicyUpdateLib.SiliconPolicyUpdatePostMem().
> +
> + 1) In FSP path, the input Policy should be FspsUpd.
> + Value of FspsUpd has been initialized by FSP binary default value.
> + Only a subset of FspsUpd needs to be updated for different silicon sku.
> + The return data is same FspsUpd.
> +
> + 2) In non-FSP path, the input policy could be NULL.
> + The return data is the initialized policy.
> +
> + @param[in, out] Policy Pointer to policy.
> +
> + @return the initialized policy.
> +**/
> +VOID *
> +EFIAPI
> +SiliconPolicyInitPostMem (
> + IN OUT VOID *Policy OPTIONAL
> + )
> +{
> + return Policy;
> +}
> +
> +/*
> + The silicon post-mem policy is finalized.
> + Silicon code can do initialization based upon the policy data.
> +
> + The input Policy must be returned by SiliconPolicyInitPostMem().
> +
> + @param[in] Policy Pointer to policy.
> +
> + @retval RETURN_SUCCESS The policy is handled consumed by silicon code.
> +*/
> +RETURN_STATUS
> +EFIAPI
> +SiliconPolicyDonePostMem (
> + IN VOID *Policy
> + )
> +{
> + return RETURN_SUCCESS;
> +}
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyUpdateLib/Sili
> conPolicyUpdateLib.c
> b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyUpdateLib/Sili
> conPolicyUpdateLib.c
> new file mode 100644
> index 0000000000..3b207a4e78
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyUpdateLib/Sili
> conPolicyUpdateLib.c
> @@ -0,0 +1,70 @@
> +/** @file
> + Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <PiPei.h>
> +
> +#include <Library/DebugLib.h>
> +#include <Library/IoLib.h>
> +#include <Ppi/ReadOnlyVariable2.h>
> +#include <Library/PeiServicesLib.h>
> +
> +/**
> + Performs silicon pre-mem policy update.
> +
> + The meaning of Policy is defined by silicon code.
> + It could be the raw data, a handle, a PPI, etc.
> +
> + The input Policy must be returned by SiliconPolicyDonePreMem().
> +
> + 1) In FSP path, the input Policy should be FspmUpd.
> + A platform may use this API to update the FSPM UPD policy initialized
> + by the silicon module or the default UPD data.
> + The output of FSPM UPD data from this API is the final UPD data.
> +
> + 2) In non-FSP path, the board may use additional way to get
> + the silicon policy data field based upon the input Policy.
> +
> + @param[in, out] Policy Pointer to policy.
> +
> + @return the updated policy.
> +**/
> +VOID *
> +EFIAPI
> +SiliconPolicyUpdatePreMem (
> + IN OUT VOID *Policy
> + )
> +{
> + return Policy;
> +}
> +
> +/**
> + Performs silicon post-mem policy update.
> +
> + The meaning of Policy is defined by silicon code.
> + It could be the raw data, a handle, a PPI, etc.
> +
> + The input Policy must be returned by SiliconPolicyDonePostMem().
> +
> + 1) In FSP path, the input Policy should be FspsUpd.
> + A platform may use this API to update the FSPS UPD policy initialized
> + by the silicon module or the default UPD data.
> + The output of FSPS UPD data from this API is the final UPD data.
> +
> + 2) In non-FSP path, the board may use additional way to get
> + the silicon policy data field based upon the input Policy.
> +
> + @param[in, out] Policy Pointer to policy.
> +
> + @return the updated policy.
> +**/
> +VOID *
> +EFIAPI
> +SiliconPolicyUpdatePostMem (
> + IN OUT VOID *Policy
> + )
> +{
> + return Policy;
> +}
> diff --git a/Platform/Intel/SimicsOpenBoardPkg/SecCore/SecMain.c
> b/Platform/Intel/SimicsOpenBoardPkg/SecCore/SecMain.c
> new file mode 100644
> index 0000000000..5cbb47687b
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/SecCore/SecMain.c
> @@ -0,0 +1,956 @@
> +/** @file
> + Main SEC phase code. Transitions to PEI.
> +
> + Copyright (c) 2008 - 2019, Intel Corporation. All rights reserved.<BR>
> + (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <PiPei.h>
> +
> +#include <Library/PeimEntryPoint.h>
> +#include <Library/BaseLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/PeiServicesLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/UefiCpuLib.h>
> +#include <Library/DebugAgentLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/PeCoffLib.h>
> +#include <Library/PeCoffGetEntryPointLib.h>
> +#include <Library/PeCoffExtraActionLib.h>
> +#include <Library/ExtractGuidedSectionLib.h>
> +#include <Library/LocalApicLib.h>
> +#include <Library/PciCf8Lib.h>
> +
> +#include <Ppi/TemporaryRamSupport.h>
> +#include <Register/X58Ich10.h>
> +
> +#define SEC_IDT_ENTRY_COUNT 34
> +
> +typedef struct _SEC_IDT_TABLE {
> + EFI_PEI_SERVICES *PeiService;
> + IA32_IDT_GATE_DESCRIPTOR IdtTable[SEC_IDT_ENTRY_COUNT];
> +} SEC_IDT_TABLE;
> +
> +VOID
> +EFIAPI
> +SecStartupPhase2 (
> + IN VOID *Context
> + );
> +
> +EFI_STATUS
> +EFIAPI
> +TemporaryRamMigration (
> + IN CONST EFI_PEI_SERVICES **PeiServices,
> + IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase,
> + IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase,
> + IN UINTN CopySize
> + );
> +
> +EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI mTemporaryRamSupportPpi = {
> + TemporaryRamMigration
> +};
> +
> +EFI_PEI_PPI_DESCRIPTOR mPrivateDispatchTable[] = {
> + {
> + (EFI_PEI_PPI_DESCRIPTOR_PPI |
> EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
> + &gEfiTemporaryRamSupportPpiGuid,
> + &mTemporaryRamSupportPpi
> + },
> +};
> +
> +//
> +// Template of an IDT entry pointing to 10:FFFFFFE4h.
> +//
> +IA32_IDT_GATE_DESCRIPTOR mIdtEntryTemplate = {
> + { // Bits
> + 0xffe4, // OffsetLow
> + 0x10, // Selector
> + 0x0, // Reserved_0
> + IA32_IDT_GATE_TYPE_INTERRUPT_32, // GateType
> + 0xffff // OffsetHigh
> + }
> +};
> +
> +/**
> + Locates the main boot firmware volume.
> +
> + @param[in,out] BootFv On input, the base of the BootFv
> + On output, the decompressed main firmware volume
> +
> + @retval EFI_SUCCESS The main firmware volume was located and
> decompressed
> + @retval EFI_NOT_FOUND The main firmware volume was not found
> +
> +**/
> +EFI_STATUS
> +FindMainFv (
> + IN OUT EFI_FIRMWARE_VOLUME_HEADER **BootFv
> + )
> +{
> + EFI_FIRMWARE_VOLUME_HEADER *Fv;
> + UINTN Distance;
> +
> + ASSERT (((UINTN) *BootFv & EFI_PAGE_MASK) == 0);
> +
> + Fv = *BootFv;
> + Distance = (UINTN) (*BootFv)->FvLength;
> + do {
> + Fv = (EFI_FIRMWARE_VOLUME_HEADER*) ((UINT8*) Fv - EFI_PAGE_SIZE);
> + Distance += EFI_PAGE_SIZE;
> + if (Distance > SIZE_32MB) {
> + return EFI_NOT_FOUND;
> + }
> +
> + if (Fv->Signature != EFI_FVH_SIGNATURE) {
> + continue;
> + }
> +
> + if ((UINTN) Fv->FvLength > Distance) {
> + continue;
> + }
> +
> + *BootFv = Fv;
> + return EFI_SUCCESS;
> +
> + } while (TRUE);
> +}
> +
> +/**
> + Locates a section within a series of sections
> + with the specified section type.
> +
> + The Instance parameter indicates which instance of the section
> + type to return. (0 is first instance, 1 is second...)
> +
> + @param[in] Sections The sections to search
> + @param[in] SizeOfSections Total size of all sections
> + @param[in] SectionType The section type to locate
> + @param[in] Instance The section instance number
> + @param[out] FoundSection The FFS section if found
> +
> + @retval EFI_SUCCESS The file and section was found
> + @retval EFI_NOT_FOUND The file and section was not found
> + @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted
> +
> +**/
> +EFI_STATUS
> +FindFfsSectionInstance (
> + IN VOID *Sections,
> + IN UINTN SizeOfSections,
> + IN EFI_SECTION_TYPE SectionType,
> + IN UINTN Instance,
> + OUT EFI_COMMON_SECTION_HEADER **FoundSection
> + )
> +{
> + EFI_PHYSICAL_ADDRESS CurrentAddress;
> + UINT32 Size;
> + EFI_PHYSICAL_ADDRESS EndOfSections;
> + EFI_COMMON_SECTION_HEADER *Section;
> + EFI_PHYSICAL_ADDRESS EndOfSection;
> +
> + //
> + // Loop through the FFS file sections within the PEI Core FFS file
> + //
> + EndOfSection = (EFI_PHYSICAL_ADDRESS)(UINTN) Sections;
> + EndOfSections = EndOfSection + SizeOfSections;
> + for (;;) {
> + if (EndOfSection == EndOfSections) {
> + break;
> + }
> + CurrentAddress = (EndOfSection + 3) & ~(3ULL);
> + if (CurrentAddress >= EndOfSections) {
> + return EFI_VOLUME_CORRUPTED;
> + }
> +
> + Section = (EFI_COMMON_SECTION_HEADER*)(UINTN) CurrentAddress;
> + DEBUG ((EFI_D_VERBOSE, "Section->Type: 0x%x\n", Section->Type));
> +
> + Size = SECTION_SIZE (Section);
> + if (Size < sizeof (*Section)) {
> + return EFI_VOLUME_CORRUPTED;
> + }
> +
> + EndOfSection = CurrentAddress + Size;
> + if (EndOfSection > EndOfSections) {
> + return EFI_VOLUME_CORRUPTED;
> + }
> +
> + //
> + // Look for the requested section type
> + //
> + if (Section->Type == SectionType) {
> + if (Instance == 0) {
> + *FoundSection = Section;
> + return EFI_SUCCESS;
> + } else {
> + Instance--;
> + }
> + }
> + DEBUG ((EFI_D_VERBOSE, "Section->Type (0x%x) != SectionType (0x%x)\n",
> Section->Type, SectionType));
> + }
> +
> + return EFI_NOT_FOUND;
> +}
> +
> +/**
> + Locates a section within a series of sections
> + with the specified section type.
> +
> + @param[in] Sections The sections to search
> + @param[in] SizeOfSections Total size of all sections
> + @param[in] SectionType The section type to locate
> + @param[out] FoundSection The FFS section if found
> +
> + @retval EFI_SUCCESS The file and section was found
> + @retval EFI_NOT_FOUND The file and section was not found
> + @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted
> +
> +**/
> +EFI_STATUS
> +FindFfsSectionInSections (
> + IN VOID *Sections,
> + IN UINTN SizeOfSections,
> + IN EFI_SECTION_TYPE SectionType,
> + OUT EFI_COMMON_SECTION_HEADER **FoundSection
> + )
> +{
> + return FindFfsSectionInstance (
> + Sections,
> + SizeOfSections,
> + SectionType,
> + 0,
> + FoundSection
> + );
> +}
> +
> +/**
> + Locates a FFS file with the specified file type and a section
> + within that file with the specified section type.
> +
> + @param[in] Fv The firmware volume to search
> + @param[in] FileType The file type to locate
> + @param[in] SectionType The section type to locate
> + @param[out] FoundSection The FFS section if found
> +
> + @retval EFI_SUCCESS The file and section was found
> + @retval EFI_NOT_FOUND The file and section was not found
> + @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted
> +
> +**/
> +EFI_STATUS
> +FindFfsFileAndSection (
> + IN EFI_FIRMWARE_VOLUME_HEADER *Fv,
> + IN EFI_FV_FILETYPE FileType,
> + IN EFI_SECTION_TYPE SectionType,
> + OUT EFI_COMMON_SECTION_HEADER **FoundSection
> + )
> +{
> + EFI_STATUS Status;
> + EFI_PHYSICAL_ADDRESS CurrentAddress;
> + EFI_PHYSICAL_ADDRESS EndOfFirmwareVolume;
> + EFI_FFS_FILE_HEADER *File;
> + UINT32 Size;
> + EFI_PHYSICAL_ADDRESS EndOfFile;
> +
> + if (Fv->Signature != EFI_FVH_SIGNATURE) {
> + DEBUG ((EFI_D_ERROR, "FV at %p does not have FV header signature\n",
> Fv));
> + return EFI_VOLUME_CORRUPTED;
> + }
> +
> + CurrentAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) Fv;
> + EndOfFirmwareVolume = CurrentAddress + Fv->FvLength;
> +
> + //
> + // Loop through the FFS files in the Boot Firmware Volume
> + //
> + for (EndOfFile = CurrentAddress + Fv->HeaderLength; ; ) {
> +
> + CurrentAddress = (EndOfFile + 7) & ~(7ULL);
> + if (CurrentAddress > EndOfFirmwareVolume) {
> + return EFI_VOLUME_CORRUPTED;
> + }
> +
> + File = (EFI_FFS_FILE_HEADER*)(UINTN) CurrentAddress;
> + Size = *(UINT32*) File->Size & 0xffffff;
> + if (Size < (sizeof (*File) + sizeof (EFI_COMMON_SECTION_HEADER))) {
> + return EFI_VOLUME_CORRUPTED;
> + }
> + DEBUG ((EFI_D_VERBOSE, "File->Type: 0x%x\n", File->Type));
> +
> + EndOfFile = CurrentAddress + Size;
> + if (EndOfFile > EndOfFirmwareVolume) {
> + return EFI_VOLUME_CORRUPTED;
> + }
> +
> + //
> + // Look for the request file type
> + //
> + if (File->Type != FileType) {
> + DEBUG ((EFI_D_VERBOSE, "File->Type (0x%x) != FileType (0x%x)\n", File-
> >Type, FileType));
> + continue;
> + }
> +
> + Status = FindFfsSectionInSections (
> + (VOID*) (File + 1),
> + (UINTN) EndOfFile - (UINTN) (File + 1),
> + SectionType,
> + FoundSection
> + );
> + if (!EFI_ERROR (Status) || (Status == EFI_VOLUME_CORRUPTED)) {
> + return Status;
> + }
> + }
> +}
> +
> +/**
> + Locates the compressed main firmware volume and decompresses it.
> +
> + @param[in,out] Fv On input, the firmware volume to search
> + On output, the decompressed BOOT/PEI FV
> +
> + @retval EFI_SUCCESS The file and section was found
> + @retval EFI_NOT_FOUND The file and section was not found
> + @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted
> +
> +**/
> +EFI_STATUS
> +DecompressMemFvs (
> + IN OUT EFI_FIRMWARE_VOLUME_HEADER **Fv
> + )
> +{
> + EFI_STATUS Status;
> + EFI_GUID_DEFINED_SECTION *Section;
> + UINT32 OutputBufferSize;
> + UINT32 ScratchBufferSize;
> + UINT16 SectionAttribute;
> + UINT32 AuthenticationStatus;
> + VOID *OutputBuffer;
> + VOID *ScratchBuffer;
> + EFI_COMMON_SECTION_HEADER *FvSection;
> + EFI_FIRMWARE_VOLUME_HEADER *PeiMemFv;
> + EFI_FIRMWARE_VOLUME_HEADER *DxeMemFv;
> + UINT32 FvHeaderSize;
> + UINT32 FvSectionSize;
> +
> + FvSection = (EFI_COMMON_SECTION_HEADER*) NULL;
> +
> + DEBUG ((EFI_D_VERBOSE, "Find and decompress FV image.\n"));
> + Status = FindFfsFileAndSection (
> + *Fv,
> + EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE,
> + EFI_SECTION_GUID_DEFINED,
> + (EFI_COMMON_SECTION_HEADER**) &Section
> + );
> + if (EFI_ERROR (Status)) {
> + DEBUG ((EFI_D_ERROR, "Unable to find GUID defined section\n"));
> + return Status;
> + }
> +
> + Status = ExtractGuidedSectionGetInfo (
> + Section,
> + &OutputBufferSize,
> + &ScratchBufferSize,
> + &SectionAttribute
> + );
> + if (EFI_ERROR (Status)) {
> + DEBUG ((EFI_D_ERROR, "Unable to GetInfo for GUIDed section\n"));
> + return Status;
> + }
> +
> + OutputBuffer = (VOID*) ((UINT8*)(UINTN) PcdGet32
> (PcdSimicsDxeMemFvBase) + SIZE_1MB);
> + ScratchBuffer = ALIGN_POINTER ((UINT8*) OutputBuffer + OutputBufferSize,
> SIZE_1MB);
> +
> + DEBUG ((EFI_D_VERBOSE, "PcdSimicsDxeMemFvBase: 0x%x\n", PcdGet32
> (PcdSimicsDxeMemFvBase)));
> + DEBUG ((EFI_D_VERBOSE, "OutputBuffer: 0x%x\n", OutputBuffer));
> + DEBUG ((EFI_D_VERBOSE, "OutputBufferSize: 0x%x\n", OutputBufferSize));
> + DEBUG ((EFI_D_VERBOSE, "ScratchBuffer: 0x%x\n", ScratchBuffer));
> + DEBUG ((EFI_D_VERBOSE, "ScratchBufferSize: 0x%x\n", ScratchBufferSize));
> + DEBUG ((EFI_D_VERBOSE, "PcdSimicsDecompressionScratchEnd: 0x%x\n",
> PcdGet32 (PcdSimicsDecompressionScratchEnd)));
> +
> + DEBUG ((EFI_D_VERBOSE, "%a: OutputBuffer@%p+0x%x
> ScratchBuffer@%p+0x%x "
> + "PcdSimicsDecompressionScratchEnd=0x%x\n", __FUNCTION__,
> OutputBuffer,
> + OutputBufferSize, ScratchBuffer, ScratchBufferSize,
> + PcdGet32 (PcdSimicsDecompressionScratchEnd)));
> + ASSERT ((UINTN)ScratchBuffer + ScratchBufferSize ==
> + PcdGet32 (PcdSimicsDecompressionScratchEnd));
> +
> + Status = ExtractGuidedSectionDecode (
> + Section,
> + &OutputBuffer,
> + ScratchBuffer,
> + &AuthenticationStatus
> + );
> + if (EFI_ERROR (Status)) {
> + DEBUG ((EFI_D_ERROR, "Error during GUID section decode\n"));
> + return Status;
> + }
> +
> + Status = FindFfsSectionInstance (
> + OutputBuffer,
> + OutputBufferSize,
> + EFI_SECTION_FIRMWARE_VOLUME_IMAGE,
> + 0,
> + &FvSection
> + );
> + if (EFI_ERROR (Status)) {
> + DEBUG ((EFI_D_ERROR, "Unable to find PEI FV section\n"));
> + return Status;
> + }
> +
> + ASSERT (SECTION_SIZE (FvSection) ==
> + (PcdGet32 (PcdSimicsPeiMemFvSize) + sizeof (*FvSection)));
> + ASSERT (FvSection->Type == EFI_SECTION_FIRMWARE_VOLUME_IMAGE);
> +
> + PeiMemFv = (EFI_FIRMWARE_VOLUME_HEADER*)(UINTN) PcdGet32
> (PcdSimicsPeiMemFvBase);
> + CopyMem (PeiMemFv, (VOID*) (FvSection + 1), PcdGet32
> (PcdSimicsPeiMemFvSize));
> +
> + if (PeiMemFv->Signature != EFI_FVH_SIGNATURE) {
> + DEBUG ((EFI_D_ERROR, "Extracted FV at %p does not have FV header
> signature\n", PeiMemFv));
> + CpuDeadLoop ();
> + return EFI_VOLUME_CORRUPTED;
> + }
> +
> + Status = FindFfsSectionInstance (
> + OutputBuffer,
> + OutputBufferSize,
> + EFI_SECTION_FIRMWARE_VOLUME_IMAGE,
> + 1,
> + &FvSection
> + );
> + if (EFI_ERROR (Status)) {
> + DEBUG ((EFI_D_ERROR, "Unable to find DXE FV section\n"));
> + return Status;
> + }
> +
> + ASSERT (FvSection->Type == EFI_SECTION_FIRMWARE_VOLUME_IMAGE);
> +
> + if (IS_SECTION2 (FvSection)) {
> + FvSectionSize = SECTION2_SIZE (FvSection);
> + FvHeaderSize = sizeof (EFI_COMMON_SECTION_HEADER2);
> + } else {
> + FvSectionSize = SECTION_SIZE (FvSection);
> + FvHeaderSize = sizeof (EFI_COMMON_SECTION_HEADER);
> + }
> +
> + ASSERT (FvSectionSize == (PcdGet32 (PcdSimicsDxeMemFvSize) +
> FvHeaderSize));
> +
> + DxeMemFv = (EFI_FIRMWARE_VOLUME_HEADER*)(UINTN) PcdGet32
> (PcdSimicsDxeMemFvBase);
> + CopyMem (DxeMemFv, (VOID*) ((UINTN)FvSection + FvHeaderSize), PcdGet32
> (PcdSimicsDxeMemFvSize));
> +
> + if (DxeMemFv->Signature != EFI_FVH_SIGNATURE) {
> + DEBUG ((EFI_D_ERROR, "Extracted FV at %p does not have FV header
> signature\n", DxeMemFv));
> + CpuDeadLoop ();
> + return EFI_VOLUME_CORRUPTED;
> + }
> +
> + *Fv = PeiMemFv;
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + Locates the PEI Core entry point address
> +
> + @param[in] Fv The firmware volume to search
> + @param[out] PeiCoreEntryPoint The entry point of the PEI Core image
> +
> + @retval EFI_SUCCESS The file and section was found
> + @retval EFI_NOT_FOUND The file and section was not found
> + @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted
> +
> +**/
> +EFI_STATUS
> +FindPeiCoreImageBaseInFv (
> + IN EFI_FIRMWARE_VOLUME_HEADER *Fv,
> + OUT EFI_PHYSICAL_ADDRESS *PeiCoreImageBase
> + )
> +{
> + EFI_STATUS Status;
> + EFI_COMMON_SECTION_HEADER *Section;
> +
> + DEBUG ((EFI_D_VERBOSE, "Find PEI Core image.\n"));
> + Status = FindFfsFileAndSection (
> + Fv,
> + EFI_FV_FILETYPE_PEI_CORE,
> + EFI_SECTION_PE32,
> + &Section
> + );
> + if (EFI_ERROR (Status)) {
> + Status = FindFfsFileAndSection (
> + Fv,
> + EFI_FV_FILETYPE_PEI_CORE,
> + EFI_SECTION_TE,
> + &Section
> + );
> + if (EFI_ERROR (Status)) {
> + DEBUG ((EFI_D_ERROR, "Unable to find PEI Core image\n"));
> + return Status;
> + }
> + }
> +
> + *PeiCoreImageBase = (EFI_PHYSICAL_ADDRESS)(UINTN)(Section + 1);
> + DEBUG ((EFI_D_VERBOSE, "PEI core image base 0x%016LX.\n",
> *PeiCoreImageBase));
> + return EFI_SUCCESS;
> +}
> +
> +
> +/**
> + Reads 8-bits of CMOS data.
> +
> + Reads the 8-bits of CMOS data at the location specified by Index.
> + The 8-bit read value is returned.
> +
> + @param Index The CMOS location to read.
> +
> + @return The value read.
> +
> +**/
> +STATIC
> +UINT8
> +CmosRead8 (
> + IN UINTN Index
> + )
> +{
> + IoWrite8 (0x70, (UINT8) Index);
> + return IoRead8 (0x71);
> +}
> +
> +
> +STATIC
> +BOOLEAN
> +IsS3Resume (
> + VOID
> + )
> +{
> + DEBUG((EFI_D_VERBOSE, "modeValue = %x\n",
> IoBitFieldRead16(ICH10_PMBASE_IO + 4, 10, 12)));
> + return (IoBitFieldRead16(ICH10_PMBASE_IO + 4, 10, 12) == 0x5);
> +}
> +
> +
> +STATIC
> +EFI_STATUS
> +GetS3ResumePeiFv (
> + IN OUT EFI_FIRMWARE_VOLUME_HEADER **PeiFv
> + )
> +{
> + *PeiFv = (EFI_FIRMWARE_VOLUME_HEADER*)(UINTN) PcdGet32
> (PcdSimicsPeiMemFvBase);
> + return EFI_SUCCESS;
> +}
> +
> +
> +/**
> + Locates the PEI Core entry point address
> +
> + @param[in,out] Fv The firmware volume to search
> + @param[out] PeiCoreEntryPoint The entry point of the PEI Core image
> +
> + @retval EFI_SUCCESS The file and section was found
> + @retval EFI_NOT_FOUND The file and section was not found
> + @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted
> +
> +**/
> +VOID
> +FindPeiCoreImageBase (
> + IN OUT EFI_FIRMWARE_VOLUME_HEADER **BootFv,
> + OUT EFI_PHYSICAL_ADDRESS *PeiCoreImageBase
> + )
> +{
> + BOOLEAN S3Resume;
> +
> + *PeiCoreImageBase = 0;
> +
> + S3Resume = IsS3Resume ();
> + if (S3Resume && !FeaturePcdGet (PcdSmmSmramRequire)) {
> + //
> + // A malicious runtime OS may have injected something into our previously
> + // decoded PEI FV, but we don't care about that unless SMM/SMRAM is
> required.
> + //
> + DEBUG ((EFI_D_VERBOSE, "SEC: S3 resume\n"));
> + GetS3ResumePeiFv (BootFv);
> + } else {
> + //
> + // We're either not resuming, or resuming "securely" -- we'll decompress
> + // both PEI FV and DXE FV from pristine flash.
> + //
> + DEBUG ((EFI_D_VERBOSE, "SEC: %a\n",
> + S3Resume ? "S3 resume (with PEI decompression)" : "Normal boot"));
> + FindMainFv (BootFv);
> +
> + DecompressMemFvs (BootFv);
> + }
> +
> + FindPeiCoreImageBaseInFv (*BootFv, PeiCoreImageBase);
> +}
> +
> +/**
> + Find core image base.
> +
> +**/
> +EFI_STATUS
> +FindImageBase (
> + IN EFI_FIRMWARE_VOLUME_HEADER *BootFirmwareVolumePtr,
> + OUT EFI_PHYSICAL_ADDRESS *SecCoreImageBase
> + )
> +{
> + EFI_PHYSICAL_ADDRESS CurrentAddress;
> + EFI_PHYSICAL_ADDRESS EndOfFirmwareVolume;
> + EFI_FFS_FILE_HEADER *File;
> + UINT32 Size;
> + EFI_PHYSICAL_ADDRESS EndOfFile;
> + EFI_COMMON_SECTION_HEADER *Section;
> + EFI_PHYSICAL_ADDRESS EndOfSection;
> +
> + *SecCoreImageBase = 0;
> +
> + CurrentAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) BootFirmwareVolumePtr;
> + EndOfFirmwareVolume = CurrentAddress + BootFirmwareVolumePtr-
> >FvLength;
> +
> + //
> + // Loop through the FFS files in the Boot Firmware Volume
> + //
> + for (EndOfFile = CurrentAddress + BootFirmwareVolumePtr->HeaderLength; ; )
> {
> +
> + CurrentAddress = (EndOfFile + 7) & 0xfffffffffffffff8ULL;
> + if (CurrentAddress > EndOfFirmwareVolume) {
> + return EFI_NOT_FOUND;
> + }
> +
> + File = (EFI_FFS_FILE_HEADER*)(UINTN) CurrentAddress;
> + Size = *(UINT32*) File->Size & 0xffffff;
> + if (Size < sizeof (*File)) {
> + return EFI_NOT_FOUND;
> + }
> +
> + EndOfFile = CurrentAddress + Size;
> + if (EndOfFile > EndOfFirmwareVolume) {
> + return EFI_NOT_FOUND;
> + }
> +
> + //
> + // Look for SEC Core
> + //
> + if (File->Type != EFI_FV_FILETYPE_SECURITY_CORE) {
> + continue;
> + }
> +
> + //
> + // Loop through the FFS file sections within the FFS file
> + //
> + EndOfSection = (EFI_PHYSICAL_ADDRESS)(UINTN) (File + 1);
> + for (;;) {
> + CurrentAddress = (EndOfSection + 3) & 0xfffffffffffffffcULL;
> + Section = (EFI_COMMON_SECTION_HEADER*)(UINTN) CurrentAddress;
> +
> + Size = *(UINT32*) Section->Size & 0xffffff;
> + if (Size < sizeof (*Section)) {
> + return EFI_NOT_FOUND;
> + }
> +
> + EndOfSection = CurrentAddress + Size;
> + if (EndOfSection > EndOfFile) {
> + return EFI_NOT_FOUND;
> + }
> +
> + //
> + // Look for executable sections
> + //
> + if (Section->Type == EFI_SECTION_PE32 || Section->Type ==
> EFI_SECTION_TE) {
> + if (File->Type == EFI_FV_FILETYPE_SECURITY_CORE) {
> + *SecCoreImageBase = (PHYSICAL_ADDRESS) (UINTN) (Section + 1);
> + }
> + break;
> + }
> + }
> +
> + //
> + // SEC Core image found
> + //
> + if (*SecCoreImageBase != 0) {
> + return EFI_SUCCESS;
> + }
> + }
> +}
> +
> +/*
> + Find and return Pei Core entry point.
> +
> + It also find SEC and PEI Core file debug information. It will report them if
> + remote debug is enabled.
> +
> +**/
> +VOID
> +FindAndReportEntryPoints (
> + IN EFI_FIRMWARE_VOLUME_HEADER **BootFirmwareVolumePtr,
> + OUT EFI_PEI_CORE_ENTRY_POINT *PeiCoreEntryPoint
> + )
> +{
> + EFI_STATUS Status;
> + EFI_PHYSICAL_ADDRESS SecCoreImageBase;
> + EFI_PHYSICAL_ADDRESS PeiCoreImageBase;
> + PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
> +
> + //
> + // Find SEC Core and PEI Core image base
> + //
> + Status = FindImageBase (*BootFirmwareVolumePtr, &SecCoreImageBase);
> + ASSERT_EFI_ERROR (Status);
> +
> + FindPeiCoreImageBase (BootFirmwareVolumePtr, &PeiCoreImageBase);
> +
> + ZeroMem ((VOID *) &ImageContext, sizeof
> (PE_COFF_LOADER_IMAGE_CONTEXT));
> + //
> + // Report SEC Core debug information when remote debug is enabled
> + //
> + ImageContext.ImageAddress = SecCoreImageBase;
> + ImageContext.PdbPointer = PeCoffLoaderGetPdbPointer ((VOID*) (UINTN)
> ImageContext.ImageAddress);
> + PeCoffLoaderRelocateImageExtraAction (&ImageContext);
> +
> + //
> + // Report PEI Core debug information when remote debug is enabled
> + //
> + ImageContext.ImageAddress =
> (EFI_PHYSICAL_ADDRESS)(UINTN)PeiCoreImageBase;
> + ImageContext.PdbPointer = PeCoffLoaderGetPdbPointer ((VOID*) (UINTN)
> ImageContext.ImageAddress);
> + PeCoffLoaderRelocateImageExtraAction (&ImageContext);
> +
> + //
> + // Find PEI Core entry point
> + //
> + Status = PeCoffLoaderGetEntryPoint ((VOID *) (UINTN) PeiCoreImageBase,
> (VOID**) PeiCoreEntryPoint);
> + if (EFI_ERROR (Status)) {
> + *PeiCoreEntryPoint = 0;
> + }
> +
> + return;
> +}
> +
> +VOID
> +EFIAPI
> +SecCoreStartupWithStack (
> + IN EFI_FIRMWARE_VOLUME_HEADER *BootFv,
> + IN VOID *TopOfCurrentStack
> + )
> +{
> + EFI_SEC_PEI_HAND_OFF SecCoreData;
> + SEC_IDT_TABLE IdtTableInStack;
> + IA32_DESCRIPTOR IdtDescriptor;
> + UINT32 Index;
> + volatile UINT8 *Table;
> +
> + //
> + // Initialize floating point operating environment
> + // to be compliant with UEFI spec.
> + //
> + InitializeFloatingPointUnits ();
> +
> + //
> + // Initialize the PCIe Configuration base register.
> + //
> + PciCf8Write32 (PCI_CF8_LIB_ADDRESS (0xFF, 0, 1, 0x50), 0xE0000001);
> +
> + //
> + // To ensure SMM can't be compromised on S3 resume, we must force re-init
> of
> + // the BaseExtractGuidedSectionLib. Since this is before library contructors
> + // are called, we must use a loop rather than SetMem.
> + //
> + Table = (UINT8*)(UINTN)FixedPcdGet64
> (PcdGuidedExtractHandlerTableAddress);
> + for (Index = 0;
> + Index < FixedPcdGet32 (PcdGuidedExtractHandlerTableSize);
> + ++Index) {
> + Table[Index] = 0;
> + }
> +
> + ProcessLibraryConstructorList (NULL, NULL);
> +
> + DEBUG ((EFI_D_INFO,
> + "SecCoreStartupWithStack(0x%x, 0x%x)\n",
> + (UINT32)(UINTN)BootFv,
> + (UINT32)(UINTN)TopOfCurrentStack
> + ));
> +
> + //
> + // Initialize IDT
> + //
> + IdtTableInStack.PeiService = NULL;
> + for (Index = 0; Index < SEC_IDT_ENTRY_COUNT; Index ++) {
> + CopyMem (&IdtTableInStack.IdtTable[Index], &mIdtEntryTemplate, sizeof
> (mIdtEntryTemplate));
> + }
> +
> + IdtDescriptor.Base = (UINTN)&IdtTableInStack.IdtTable;
> + IdtDescriptor.Limit = (UINT16)(sizeof (IdtTableInStack.IdtTable) - 1);
> +
> + AsmWriteIdtr (&IdtDescriptor);
> +
> +#if defined (MDE_CPU_X64)
> + //
> + // ASSERT that the Page Tables were set by the reset vector code to
> + // the address we expect.
> + //
> + ASSERT (AsmReadCr3 () == (UINTN) PcdGet32 (PcdSimicsSecPageTablesBase));
> +#endif
> +
> + //
> + // |-------------| <-- TopOfCurrentStack
> + // | Stack | 32k
> + // |-------------|
> + // | Heap | 32k
> + // |-------------| <-- SecCoreData.TemporaryRamBase
> + //
> +
> + ASSERT ((UINTN) (PcdGet32 (PcdSimicsSecPeiTempRamBase) +
> + PcdGet32 (PcdSimicsSecPeiTempRamSize)) ==
> + (UINTN) TopOfCurrentStack);
> +
> + //
> + // Initialize SEC hand-off state
> + //
> + SecCoreData.DataSize = sizeof(EFI_SEC_PEI_HAND_OFF);
> +
> + SecCoreData.TemporaryRamSize = (UINTN) PcdGet32
> (PcdSimicsSecPeiTempRamSize);
> + SecCoreData.TemporaryRamBase = (VOID*)((UINT8 *)TopOfCurrentStack -
> SecCoreData.TemporaryRamSize);
> +
> + SecCoreData.PeiTemporaryRamBase = SecCoreData.TemporaryRamBase;
> + SecCoreData.PeiTemporaryRamSize = SecCoreData.TemporaryRamSize >>
> 1;
> +
> + SecCoreData.StackBase = (UINT8 *)SecCoreData.TemporaryRamBase
> + SecCoreData.PeiTemporaryRamSize;
> + SecCoreData.StackSize = SecCoreData.TemporaryRamSize >> 1;
> +
> + SecCoreData.BootFirmwareVolumeBase = BootFv;
> + SecCoreData.BootFirmwareVolumeSize = (UINTN) BootFv->FvLength;
> +
> + //
> + // Make sure the 8259 is masked before initializing the Debug Agent and the
> debug timer is enabled
> + //
> + IoWrite8 (0x21, 0xff);
> + IoWrite8 (0xA1, 0xff);
> +
> + //
> + // Initialize Local APIC Timer hardware and disable Local APIC Timer
> + // interrupts before initializing the Debug Agent and the debug timer is
> + // enabled.
> + //
> + InitializeApicTimer (0, MAX_UINT32, TRUE, 5);
> + DisableApicTimerInterrupt ();
> +
> + //
> + // Initialize Debug Agent to support source level debug in SEC/PEI phases
> before memory ready.
> + //
> + InitializeDebugAgent (DEBUG_AGENT_INIT_PREMEM_SEC, &SecCoreData,
> SecStartupPhase2);
> +}
> +
> +/**
> + Caller provided function to be invoked at the end of InitializeDebugAgent().
> +
> + Entry point to the C language phase of SEC. After the SEC assembly
> + code has initialized some temporary memory and set up the stack,
> + the control is transferred to this function.
> +
> + @param[in] Context The first input parameter of InitializeDebugAgent().
> +
> +**/
> +VOID
> +EFIAPI
> +SecStartupPhase2(
> + IN VOID *Context
> + )
> +{
> + EFI_SEC_PEI_HAND_OFF *SecCoreData;
> + EFI_FIRMWARE_VOLUME_HEADER *BootFv;
> + EFI_PEI_CORE_ENTRY_POINT PeiCoreEntryPoint;
> +
> + SecCoreData = (EFI_SEC_PEI_HAND_OFF *) Context;
> +
> + //
> + // Find PEI Core entry point. It will report SEC and Pei Core debug information
> if remote debug
> + // is enabled.
> + //
> + BootFv = (EFI_FIRMWARE_VOLUME_HEADER *)SecCoreData-
> >BootFirmwareVolumeBase;
> + FindAndReportEntryPoints (&BootFv, &PeiCoreEntryPoint);
> + SecCoreData->BootFirmwareVolumeBase = BootFv;
> + SecCoreData->BootFirmwareVolumeSize = (UINTN) BootFv->FvLength;
> +
> + //
> + // Transfer the control to the PEI core
> + //
> + (*PeiCoreEntryPoint) (SecCoreData, (EFI_PEI_PPI_DESCRIPTOR
> *)&mPrivateDispatchTable);
> +
> + //
> + // If we get here then the PEI Core returned, which is not recoverable.
> + //
> + ASSERT (FALSE);
> + CpuDeadLoop ();
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +TemporaryRamMigration (
> + IN CONST EFI_PEI_SERVICES **PeiServices,
> + IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase,
> + IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase,
> + IN UINTN CopySize
> + )
> +{
> + IA32_DESCRIPTOR IdtDescriptor;
> + VOID *OldHeap;
> + VOID *NewHeap;
> + VOID *OldStack;
> + VOID *NewStack;
> + DEBUG_AGENT_CONTEXT_POSTMEM_SEC DebugAgentContext;
> + BOOLEAN OldStatus;
> + BASE_LIBRARY_JUMP_BUFFER JumpBuffer;
> +
> + DEBUG ((EFI_D_INFO,
> + "TemporaryRamMigration(0x%Lx, 0x%Lx, 0x%Lx)\n",
> + TemporaryMemoryBase,
> + PermanentMemoryBase,
> + (UINT64)CopySize
> + ));
> +
> + OldHeap = (VOID*)(UINTN)TemporaryMemoryBase;
> + NewHeap = (VOID*)((UINTN)PermanentMemoryBase + (CopySize >> 1));
> +
> + OldStack = (VOID*)((UINTN)TemporaryMemoryBase + (CopySize >> 1));
> + NewStack = (VOID*)(UINTN)PermanentMemoryBase;
> +
> + DebugAgentContext.HeapMigrateOffset = (UINTN)NewHeap -
> (UINTN)OldHeap;
> + DebugAgentContext.StackMigrateOffset = (UINTN)NewStack -
> (UINTN)OldStack;
> +
> + OldStatus = SaveAndSetDebugTimerInterrupt (FALSE);
> + InitializeDebugAgent (DEBUG_AGENT_INIT_POSTMEM_SEC, (VOID *)
> &DebugAgentContext, NULL);
> +
> + //
> + // Migrate Heap
> + //
> + CopyMem (NewHeap, OldHeap, CopySize >> 1);
> +
> + //
> + // Migrate Stack
> + //
> + CopyMem (NewStack, OldStack, CopySize >> 1);
> +
> + //
> + // Rebase IDT table in permanent memory
> + //
> + AsmReadIdtr (&IdtDescriptor);
> + IdtDescriptor.Base = IdtDescriptor.Base - (UINTN)OldStack +
> (UINTN)NewStack;
> +
> + AsmWriteIdtr (&IdtDescriptor);
> +
> + //
> + // Use SetJump()/LongJump() to switch to a new stack.
> + //
> + if (SetJump (&JumpBuffer) == 0) {
> +#if defined (MDE_CPU_IA32)
> + JumpBuffer.Esp = JumpBuffer.Esp + DebugAgentContext.StackMigrateOffset;
> +#endif
> +#if defined (MDE_CPU_X64)
> + JumpBuffer.Rsp = JumpBuffer.Rsp +
> DebugAgentContext.StackMigrateOffset;
> +#endif
> + LongJump (&JumpBuffer, (UINTN)-1);
> + }
> +
> + SaveAndSetDebugTimerInterrupt (OldStatus);
> +
> + return EFI_SUCCESS;
> +}
> diff --git a/Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/Platform.c
> b/Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/Platform.c
> new file mode 100644
> index 0000000000..b7fd4d1f6d
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/Platform.c
> @@ -0,0 +1,865 @@
> +/** @file
> + This driver effectuates QSP platform configuration settings and exposes
> + them via HII.
> +
> + Copyright (C) 2014, Red Hat, Inc.
> + Copyright (c) 2009 - 2019, Intel Corporation. All rights reserved.<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/DevicePathLib.h>
> +#include <Library/HiiLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/PrintLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiHiiServicesLib.h>
> +#include <Protocol/DevicePath.h>
> +#include <Protocol/GraphicsOutput.h>
> +#include <Protocol/HiiConfigAccess.h>
> +#include <Guid/MdeModuleHii.h>
> +#include <Guid/SimicsBoardConfig.h>
> +
> +#include "Platform.h"
> +#include "PlatformConfig.h"
> +#include <Library/DxeServicesTableLib.h>
> +//
> +// The HiiAddPackages() library function requires that any controller (or
> +// image) handle, to be associated with the HII packages under installation, be
> +// "decorated" with a device path. The tradition seems to be a vendor device
> +// path.
> +//
> +// We'd like to associate our HII packages with the driver's image handle. The
> +// first idea is to use the driver image's device path. Unfortunately, loaded
> +// images only come with an EFI_LOADED_IMAGE_DEVICE_PATH_PROTOCOL
> (not the
> +// usual EFI_DEVICE_PATH_PROTOCOL), ie. a different GUID. In addition, even
> the
> +// EFI_LOADED_IMAGE_DEVICE_PATH_PROTOCOL interface may be NULL, if
> the image
> +// has been loaded from an "unnamed" memory source buffer.
> +//
> +// Hence let's just stick with the tradition -- use a dedicated vendor device
> +// path, with the driver's FILE_GUID.
> +//
> +#pragma pack(1)
> +typedef struct {
> + VENDOR_DEVICE_PATH VendorDevicePath;
> + EFI_DEVICE_PATH_PROTOCOL End;
> +} PKG_DEVICE_PATH;
> +#pragma pack()
> +
> +STATIC PKG_DEVICE_PATH mPkgDevicePath = {
> + {
> + {
> + HARDWARE_DEVICE_PATH,
> + HW_VENDOR_DP,
> + {
> + (UINT8) (sizeof (VENDOR_DEVICE_PATH) ),
> + (UINT8) (sizeof (VENDOR_DEVICE_PATH) >> 8)
> + }
> + },
> + EFI_CALLER_ID_GUID
> + },
> + {
> + END_DEVICE_PATH_TYPE,
> + END_ENTIRE_DEVICE_PATH_SUBTYPE,
> + {
> + (UINT8) (END_DEVICE_PATH_LENGTH ),
> + (UINT8) (END_DEVICE_PATH_LENGTH >> 8)
> + }
> + }
> +};
> +
> +//
> +// The configuration interface between the HII engine (form display etc) and
> +// this driver.
> +//
> +STATIC EFI_HII_CONFIG_ACCESS_PROTOCOL mConfigAccess;
> +
> +//
> +// The handle representing our list of packages after installation.
> +//
> +STATIC EFI_HII_HANDLE mInstalledPackages;
> +
> +//
> +// The arrays below constitute our HII package list. They are auto-generated by
> +// the VFR compiler and linked into the driver image during the build.
> +//
> +// - The strings package receives its C identifier from the driver's BASE_NAME,
> +// plus "Strings".
> +//
> +// - The forms package receives its C identifier from the VFR file's basename,
> +// plus "Bin".
> +//
> +//
> +extern UINT8 SimicsDxeStrings[];
> +extern UINT8 PlatformFormsBin[];
> +
> +//
> +// We want to be notified about GOP installations until we find one GOP
> +// interface that lets us populate the form.
> +//
> +STATIC EFI_EVENT mGopEvent;
> +
> +//
> +// The registration record underneath this pointer allows us to iterate through
> +// the GOP instances one by one.
> +//
> +STATIC VOID *mGopTracker;
> +
> +//
> +// Cache the resolutions we get from the GOP.
> +//
> +typedef struct {
> + UINT32 X;
> + UINT32 Y;
> +} GOP_MODE;
> +
> +STATIC UINTN mNumGopModes;
> +STATIC GOP_MODE *mGopModes;
> +
> +
> +/**
> + Load the persistent platform configuration and translate it to binary form
> + state.
> +
> + If the platform configuration is missing, then the function fills in a
> + default state.
> +
> + @param[out] MainFormState Binary form/widget state after translation.
> +
> + @retval EFI_SUCCESS Form/widget state ready.
> + @return Error codes from underlying functions.
> +**/
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +PlatformConfigToFormState (
> + OUT MAIN_FORM_STATE *MainFormState
> + )
> +{
> + EFI_STATUS Status;
> + PLATFORM_CONFIG PlatformConfig;
> + UINT64 OptionalElements;
> + UINTN ModeNumber;
> +
> + ZeroMem (MainFormState, sizeof *MainFormState);
> +
> + Status = PlatformConfigLoad (&PlatformConfig, &OptionalElements);
> + switch (Status) {
> + case EFI_SUCCESS:
> + if (OptionalElements & PLATFORM_CONFIG_F_GRAPHICS_RESOLUTION) {
> + //
> + // Format the preferred resolution as text.
> + //
> + UnicodeSPrintAsciiFormat (
> + (CHAR16 *) MainFormState->CurrentPreferredResolution,
> + sizeof MainFormState->CurrentPreferredResolution,
> + "%Ldx%Ld",
> + (INT64) PlatformConfig.HorizontalResolution,
> + (INT64) PlatformConfig.VerticalResolution);
> +
> + //
> + // Try to locate it in the drop-down list too. This may not succeed, but
> + // that's fine.
> + //
> + for (ModeNumber = 0; ModeNumber < mNumGopModes; ++ModeNumber)
> {
> + if (mGopModes[ModeNumber].X == PlatformConfig.HorizontalResolution
> &&
> + mGopModes[ModeNumber].Y == PlatformConfig.VerticalResolution) {
> + MainFormState->NextPreferredResolution = (UINT32) ModeNumber;
> + break;
> + }
> + }
> +
> + break;
> + }
> + //
> + // fall through otherwise
> + //
> +
> + case EFI_NOT_FOUND:
> + UnicodeSPrintAsciiFormat (
> + (CHAR16 *) MainFormState->CurrentPreferredResolution,
> + sizeof MainFormState->CurrentPreferredResolution,
> + "Unset");
> + break;
> +
> + default:
> + return Status;
> + }
> +
> + return EFI_SUCCESS;
> +}
> +
> +
> +/**
> + This function is called by the HII machinery when it fetches the form state.
> +
> + See the precise documentation in the UEFI spec.
> +
> + @param[in] This The Config Access Protocol instance.
> +
> + @param[in] Request A <ConfigRequest> format UCS-2 string describing the
> + query.
> +
> + @param[out] Progress A pointer into Request on output, identifying the
> query
> + element where processing failed.
> +
> + @param[out] Results A <MultiConfigAltResp> format UCS-2 string that has
> + all values filled in for the names in the Request
> + string.
> +
> + @retval EFI_SUCCESS Extraction of form state in <MultiConfigAltResp>
> + encoding successful.
> + @return Status codes from underlying functions.
> +
> +**/
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +ExtractConfig (
> + IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
> + IN CONST EFI_STRING Request,
> + OUT EFI_STRING *Progress,
> + OUT EFI_STRING *Results
> +)
> +{
> + MAIN_FORM_STATE MainFormState;
> + EFI_STATUS Status;
> +
> + DEBUG ((EFI_D_VERBOSE, "%a: Request=\"%s\"\n", __FUNCTION__,
> Request));
> +
> + Status = PlatformConfigToFormState (&MainFormState);
> + if (EFI_ERROR (Status)) {
> + *Progress = Request;
> + return Status;
> + }
> +
> + //
> + // Answer the textual request keying off the binary form state.
> + //
> + Status = gHiiConfigRouting->BlockToConfig (gHiiConfigRouting, Request,
> + (VOID *) &MainFormState, sizeof MainFormState,
> + Results, Progress);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((EFI_D_ERROR, "%a: BlockToConfig(): %r, Progress=\"%s\"\n",
> + __FUNCTION__, Status, (Status == EFI_DEVICE_ERROR) ? NULL :
> *Progress));
> + } else {
> + DEBUG ((EFI_D_VERBOSE, "%a: Results=\"%s\"\n", __FUNCTION__,
> *Results));
> + }
> + return Status;
> +}
> +
> +
> +/**
> + Interpret the binary form state and save it as persistent platform
> + configuration.
> +
> + @param[in] MainFormState Binary form/widget state to verify and save.
> +
> + @retval EFI_SUCCESS Platform configuration saved.
> + @return Error codes from underlying functions.
> +**/
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +FormStateToPlatformConfig (
> + IN CONST MAIN_FORM_STATE *MainFormState
> + )
> +{
> + EFI_STATUS Status;
> + PLATFORM_CONFIG PlatformConfig;
> + CONST GOP_MODE *GopMode;
> +
> + //
> + // There's nothing to do with the textual CurrentPreferredResolution field.
> + // We verify and translate the selection in the drop-down list.
> + //
> + if (MainFormState->NextPreferredResolution >= mNumGopModes) {
> + return EFI_INVALID_PARAMETER;
> + }
> + GopMode = mGopModes + MainFormState->NextPreferredResolution;
> +
> + ZeroMem (&PlatformConfig, sizeof PlatformConfig);
> + PlatformConfig.HorizontalResolution = GopMode->X;
> + PlatformConfig.VerticalResolution = GopMode->Y;
> +
> + Status = PlatformConfigSave (&PlatformConfig);
> + return Status;
> +}
> +
> +
> +/**
> + This function is called by the HII machinery when it wants the driver to
> + interpret and persist the form state.
> +
> + See the precise documentation in the UEFI spec.
> +
> + @param[in] This The Config Access Protocol instance.
> +
> + @param[in] Configuration A <ConfigResp> format UCS-2 string describing
> the
> + form state.
> +
> + @param[out] Progress A pointer into Configuration on output,
> + identifying the element where processing failed.
> +
> + @retval EFI_SUCCESS Configuration verified, state permanent.
> +
> + @return Status codes from underlying functions.
> +**/
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +RouteConfig (
> + IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
> + IN CONST EFI_STRING Configuration,
> + OUT EFI_STRING *Progress
> +)
> +{
> + MAIN_FORM_STATE MainFormState;
> + UINTN BlockSize;
> + EFI_STATUS Status;
> +
> + DEBUG ((EFI_D_VERBOSE, "%a: Configuration=\"%s\"\n", __FUNCTION__,
> + Configuration));
> +
> + //
> + // the "read" step in RMW
> + //
> + Status = PlatformConfigToFormState (&MainFormState);
> + if (EFI_ERROR (Status)) {
> + *Progress = Configuration;
> + return Status;
> + }
> +
> + //
> + // the "modify" step in RMW
> + //
> + // (Update the binary form state. This update may be partial, which is why in
> + // general we must pre-load the form state from the platform config.)
> + //
> + BlockSize = sizeof MainFormState;
> + Status = gHiiConfigRouting->ConfigToBlock (gHiiConfigRouting,
> Configuration,
> + (VOID *) &MainFormState, &BlockSize, Progress);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((EFI_D_ERROR, "%a: ConfigToBlock(): %r, Progress=\"%s\"\n",
> + __FUNCTION__, Status,
> + (Status == EFI_BUFFER_TOO_SMALL) ? NULL : *Progress));
> + return Status;
> + }
> +
> + //
> + // the "write" step in RMW
> + //
> + Status = FormStateToPlatformConfig (&MainFormState);
> + if (EFI_ERROR (Status)) {
> + *Progress = Configuration;
> + }
> + return Status;
> +}
> +
> +
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +Callback (
> + IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
> + IN EFI_BROWSER_ACTION Action,
> + IN EFI_QUESTION_ID QuestionId,
> + IN UINT8 Type,
> + IN OUT EFI_IFR_TYPE_VALUE *Value,
> + OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
> + )
> +{
> + DEBUG ((EFI_D_VERBOSE, "%a: Action=0x%Lx QuestionId=%d Type=%d\n",
> + __FUNCTION__, (UINT64) Action, QuestionId, Type));
> +
> + if (Action != EFI_BROWSER_ACTION_CHANGED) {
> + return EFI_UNSUPPORTED;
> + }
> +
> + switch (QuestionId) {
> + case QUESTION_SAVE_EXIT:
> + *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT;
> + break;
> +
> + case QUESTION_DISCARD_EXIT:
> + *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT;
> + break;
> +
> + default:
> + break;
> + }
> +
> + return EFI_SUCCESS;
> +}
> +
> +
> +/**
> + Query and save all resolutions supported by the GOP.
> +
> + @param[in] Gop The Graphics Output Protocol instance to query.
> +
> + @param[out] NumGopModes The number of modes supported by the GOP.
> On output,
> + this parameter will be positive.
> +
> + @param[out] GopModes On output, a dynamically allocated array
> containing
> + the resolutions returned by the GOP. The caller is
> + responsible for freeing the array after use.
> +
> + @retval EFI_UNSUPPORTED No modes found.
> + @retval EFI_OUT_OF_RESOURCES Failed to allocate GopModes.
> + @return Error codes from Gop->QueryMode().
> +
> +**/
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +QueryGopModes (
> + IN EFI_GRAPHICS_OUTPUT_PROTOCOL *Gop,
> + OUT UINTN *NumGopModes,
> + OUT GOP_MODE **GopModes
> + )
> +{
> + EFI_STATUS Status;
> + UINT32 ModeNumber;
> +
> + if (Gop->Mode->MaxMode == 0) {
> + return EFI_UNSUPPORTED;
> + }
> + *NumGopModes = Gop->Mode->MaxMode;
> +
> + *GopModes = AllocatePool (Gop->Mode->MaxMode * sizeof **GopModes);
> + if (*GopModes == NULL) {
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + for (ModeNumber = 0; ModeNumber < Gop->Mode->MaxMode;
> ++ModeNumber) {
> + EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info;
> + UINTN SizeOfInfo;
> +
> + Status = Gop->QueryMode (Gop, ModeNumber, &SizeOfInfo, &Info);
> + if (EFI_ERROR (Status)) {
> + goto FreeGopModes;
> + }
> +
> + (*GopModes)[ModeNumber].X = Info->HorizontalResolution;
> + (*GopModes)[ModeNumber].Y = Info->VerticalResolution;
> + FreePool (Info);
> + }
> +
> + return EFI_SUCCESS;
> +
> +FreeGopModes:
> + FreePool (*GopModes);
> +
> + return Status;
> +}
> +
> +
> +/**
> + Create a set of "one-of-many" (ie. "drop down list") option IFR opcodes,
> + based on available GOP resolutions, to be placed under a "one-of-many" (ie.
> + "drop down list") opcode.
> +
> + @param[in] PackageList The package list with the formset and form for
> + which the drop down options are produced. Option
> + names are added as new strings to PackageList.
> +
> + @param[out] OpCodeBuffer On output, a dynamically allocated opcode
> buffer
> + with drop down list options corresponding to GOP
> + resolutions. The caller is responsible for freeing
> + OpCodeBuffer with HiiFreeOpCodeHandle() after use.
> +
> + @param[in] NumGopModes Number of entries in GopModes.
> +
> + @param[in] GopModes Array of resolutions retrieved from the GOP.
> +
> + @retval EFI_SUCESS Opcodes have been successfully produced.
> +
> + @return Status codes from underlying functions. PackageList may
> + have been extended with new strings. OpCodeBuffer is
> + unchanged.
> +**/
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +CreateResolutionOptions (
> + IN EFI_HII_HANDLE *PackageList,
> + OUT VOID **OpCodeBuffer,
> + IN UINTN NumGopModes,
> + IN GOP_MODE *GopModes
> + )
> +{
> + EFI_STATUS Status;
> + VOID *OutputBuffer;
> + UINTN ModeNumber;
> +
> + OutputBuffer = HiiAllocateOpCodeHandle ();
> + if (OutputBuffer == NULL) {
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + for (ModeNumber = 0; ModeNumber < NumGopModes; ++ModeNumber) {
> + CHAR16 Desc[MAXSIZE_RES_CUR];
> + EFI_STRING_ID NewString;
> + VOID *OpCode;
> +
> + UnicodeSPrintAsciiFormat (Desc, sizeof Desc, "%Ldx%Ld",
> + (INT64) GopModes[ModeNumber].X, (INT64) GopModes[ModeNumber].Y);
> + NewString = HiiSetString (PackageList, 0 /* new string */, Desc,
> + NULL /* for all languages */);
> + if (NewString == 0) {
> + Status = EFI_OUT_OF_RESOURCES;
> + goto FreeOutputBuffer;
> + }
> + OpCode = HiiCreateOneOfOptionOpCode (OutputBuffer, NewString,
> + 0 /* Flags */, EFI_IFR_NUMERIC_SIZE_4, ModeNumber);
> + if (OpCode == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + goto FreeOutputBuffer;
> + }
> + }
> +
> + *OpCodeBuffer = OutputBuffer;
> + return EFI_SUCCESS;
> +
> +FreeOutputBuffer:
> + HiiFreeOpCodeHandle (OutputBuffer);
> +
> + return Status;
> +}
> +
> +
> +/**
> + Populate the form identified by the (PackageList, FormSetGuid, FormId)
> + triplet.
> +
> + The drop down list of video resolutions is generated from (NumGopModes,
> + GopModes).
> +
> + @retval EFI_SUCESS Form successfully updated.
> + @return Status codes from underlying functions.
> +
> +**/
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +PopulateForm (
> + IN EFI_HII_HANDLE *PackageList,
> + IN EFI_GUID *FormSetGuid,
> + IN EFI_FORM_ID FormId,
> + IN UINTN NumGopModes,
> + IN GOP_MODE *GopModes
> + )
> +{
> + EFI_STATUS Status;
> + VOID *OpCodeBuffer;
> + VOID *OpCode;
> + EFI_IFR_GUID_LABEL *Anchor;
> + VOID *OpCodeBuffer2;
> +
> + OpCodeBuffer2 = NULL;
> +
> + //
> + // 1. Allocate an empty opcode buffer.
> + //
> + OpCodeBuffer = HiiAllocateOpCodeHandle ();
> + if (OpCodeBuffer == NULL) {
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + //
> + // 2. Create a label opcode (which is a Tiano extension) inside the buffer.
> + // The label's number must match the "anchor" label in the form.
> + //
> + OpCode = HiiCreateGuidOpCode (OpCodeBuffer, &gEfiIfrTianoGuid,
> + NULL /* optional copy origin */, sizeof *Anchor);
> + if (OpCode == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + goto FreeOpCodeBuffer;
> + }
> + Anchor = OpCode;
> + Anchor->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
> + Anchor->Number = LABEL_RES_NEXT;
> +
> + //
> + // 3. Create the opcodes inside the buffer that are to be inserted into the
> + // form.
> + //
> + // 3.1. Get a list of resolutions.
> + //
> + Status = CreateResolutionOptions (PackageList, &OpCodeBuffer2,
> + NumGopModes, GopModes);
> + if (EFI_ERROR (Status)) {
> + goto FreeOpCodeBuffer;
> + }
> +
> + //
> + // 3.2. Create a one-of-many question with the above options.
> + //
> + OpCode = HiiCreateOneOfOpCode (
> + OpCodeBuffer, // create opcode inside this
> + // opcode buffer,
> + QUESTION_RES_NEXT, // ID of question,
> + FORMSTATEID_MAIN_FORM, // identifies form state
> + // storage,
> + (UINT16) OFFSET_OF (MAIN_FORM_STATE, // value of question stored
> + NextPreferredResolution), // at this offset,
> + STRING_TOKEN (STR_RES_NEXT), // Prompt,
> + STRING_TOKEN (STR_RES_NEXT_HELP), // Help,
> + 0, // QuestionFlags,
> + EFI_IFR_NUMERIC_SIZE_4, // see sizeof
> + // NextPreferredResolution,
> + OpCodeBuffer2, // buffer with possible
> + // choices,
> + NULL // DEFAULT opcodes
> + );
> + if (OpCode == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + goto FreeOpCodeBuffer2;
> + }
> +
> + //
> + // 4. Update the form with the opcode buffer.
> + //
> + Status = HiiUpdateForm (PackageList, FormSetGuid, FormId,
> + OpCodeBuffer, // buffer with head anchor, and new contents to be
> + // inserted at it
> + NULL // buffer with tail anchor, for deleting old
> + // contents up to it
> + );
> +
> +FreeOpCodeBuffer2:
> + HiiFreeOpCodeHandle (OpCodeBuffer2);
> +
> +FreeOpCodeBuffer:
> + HiiFreeOpCodeHandle (OpCodeBuffer);
> +
> + return Status;
> +}
> +
> +
> +/**
> + Load and execute the platform configuration.
> +
> + @retval EFI_SUCCESS Configuration loaded and executed.
> + @return Status codes from PlatformConfigLoad().
> +**/
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +ExecutePlatformConfig (
> + VOID
> + )
> +{
> + EFI_STATUS Status;
> + PLATFORM_CONFIG PlatformConfig;
> + UINT64 OptionalElements;
> +
> + Status = PlatformConfigLoad (&PlatformConfig, &OptionalElements);
> + if (EFI_ERROR (Status)) {
> + DEBUG (((Status == EFI_NOT_FOUND) ? EFI_D_VERBOSE : EFI_D_ERROR,
> + "%a: failed to load platform config: %r\n", __FUNCTION__, Status));
> + return Status;
> + }
> +
> + if (OptionalElements & PLATFORM_CONFIG_F_GRAPHICS_RESOLUTION) {
> + //
> + // Pass the preferred resolution to GraphicsConsoleDxe via dynamic PCDs.
> + //
> + PcdSet32 (PcdVideoHorizontalResolution,
> + PlatformConfig.HorizontalResolution);
> + PcdSet32 (PcdVideoVerticalResolution,
> + PlatformConfig.VerticalResolution);
> + }
> +
> + return EFI_SUCCESS;
> +}
> +
> +
> +/**
> + Notification callback for GOP interface installation.
> +
> + @param[in] Event Event whose notification function is being invoked.
> +
> + @param[in] Context The pointer to the notification function's context, which
> + is implementation-dependent.
> +**/
> +STATIC
> +VOID
> +EFIAPI
> +GopInstalled (
> + IN EFI_EVENT Event,
> + IN VOID *Context
> + )
> +{
> + EFI_STATUS Status;
> + EFI_GRAPHICS_OUTPUT_PROTOCOL *Gop;
> +
> + ASSERT (Event == mGopEvent);
> +
> + //
> + // Check further GOPs.
> + //
> + for (;;) {
> + mNumGopModes = 0;
> + mGopModes = NULL;
> +
> + Status = gBS->LocateProtocol (&gEfiGraphicsOutputProtocolGuid,
> mGopTracker,
> + (VOID **) &Gop);
> + if (EFI_ERROR (Status)) {
> + return;
> + }
> +
> + Status = QueryGopModes (Gop, &mNumGopModes, &mGopModes);
> + if (EFI_ERROR (Status)) {
> + continue;
> + }
> +
> + Status = PopulateForm (mInstalledPackages, &gSimicsBoardConfigGuid,
> + FORMID_MAIN_FORM, mNumGopModes, mGopModes);
> + if (EFI_ERROR (Status)) {
> + FreePool (mGopModes);
> + continue;
> + }
> +
> + break;
> + }
> +
> + //
> + // Success -- so uninstall this callback. Closing the event removes all
> + // pending notifications and all protocol registrations.
> + //
> + Status = gBS->CloseEvent (mGopEvent);
> + ASSERT_EFI_ERROR (Status);
> + mGopEvent = NULL;
> + mGopTracker = NULL;
> +}
> +
> +
> +/**
> + Entry point for this driver.
> +
> + @param[in] ImageHandle Image handle of this driver.
> + @param[in] SystemTable Pointer to SystemTable.
> +
> + @retval EFI_SUCESS Driver has loaded successfully.
> + @retval EFI_OUT_OF_RESOURCES Failed to install HII packages.
> + @return Error codes from lower level functions.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +PlatformInit (
> + IN EFI_HANDLE ImageHandle,
> + IN EFI_SYSTEM_TABLE *SystemTable
> + )
> +{
> + EFI_STATUS Status;
> +
> + ExecutePlatformConfig ();
> +
> + mConfigAccess.ExtractConfig = &ExtractConfig;
> + mConfigAccess.RouteConfig = &RouteConfig;
> + mConfigAccess.Callback = &Callback;
> +
> + //
> + // Declare ourselves suitable for HII communication.
> + //
> + Status = gBS->InstallMultipleProtocolInterfaces (&ImageHandle,
> + &gEfiDevicePathProtocolGuid, &mPkgDevicePath,
> + &gEfiHiiConfigAccessProtocolGuid, &mConfigAccess,
> + NULL);
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + //
> + // Publish the HII package list to HII Database.
> + //
> + mInstalledPackages = HiiAddPackages (
> + &gEfiCallerIdGuid, // PackageListGuid
> + ImageHandle, // associated DeviceHandle
> + SimicsDxeStrings, // 1st package
> + PlatformFormsBin, // 2nd package
> + NULL // terminator
> + );
> + if (mInstalledPackages == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + goto UninstallProtocols;
> + }
> +
> + Status = gBS->CreateEvent (EVT_NOTIFY_SIGNAL, TPL_CALLBACK,
> &GopInstalled,
> + NULL /* Context */, &mGopEvent);
> + if (EFI_ERROR (Status)) {
> + goto RemovePackages;
> + }
> +
> + Status = gBS->RegisterProtocolNotify (&gEfiGraphicsOutputProtocolGuid,
> + mGopEvent, &mGopTracker);
> + if (EFI_ERROR (Status)) {
> + goto CloseGopEvent;
> + }
> +
> + //
> + // Check already installed GOPs.
> + //
> + Status = gBS->SignalEvent (mGopEvent);
> + ASSERT_EFI_ERROR (Status);
> +
> + return EFI_SUCCESS;
> +
> +CloseGopEvent:
> + gBS->CloseEvent (mGopEvent);
> +
> +RemovePackages:
> + HiiRemovePackages (mInstalledPackages);
> +
> +UninstallProtocols:
> + gBS->UninstallMultipleProtocolInterfaces (ImageHandle,
> + &gEfiDevicePathProtocolGuid, &mPkgDevicePath,
> + &gEfiHiiConfigAccessProtocolGuid, &mConfigAccess,
> + NULL);
> + return Status;
> +}
> +
> +/**
> + Unload the driver.
> +
> + @param[in] ImageHandle Handle that identifies the image to evict.
> +
> + @retval EFI_SUCCESS The image has been unloaded.
> +**/
> +EFI_STATUS
> +EFIAPI
> +PlatformUnload (
> + IN EFI_HANDLE ImageHandle
> + )
> +{
> + if (mGopEvent == NULL) {
> + //
> + // The GOP callback ran successfully and unregistered itself. Release the
> + // resources allocated there.
> + //
> + ASSERT (mGopModes != NULL);
> + FreePool (mGopModes);
> + } else {
> + //
> + // Otherwise we need to unregister the callback.
> + //
> + ASSERT (mGopModes == NULL);
> + gBS->CloseEvent (mGopEvent);
> + }
> +
> + //
> + // Release resources allocated by the entry point.
> + //
> + HiiRemovePackages (mInstalledPackages);
> + gBS->UninstallMultipleProtocolInterfaces (ImageHandle,
> + &gEfiDevicePathProtocolGuid, &mPkgDevicePath,
> + &gEfiHiiConfigAccessProtocolGuid, &mConfigAccess,
> + NULL);
> + return EFI_SUCCESS;
> +}
> diff --git a/Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/PlatformConfig.c
> b/Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/PlatformConfig.c
> new file mode 100644
> index 0000000000..09929e830a
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/PlatformConfig.c
> @@ -0,0 +1,124 @@
> +/** @file
> + Utility functions for serializing (persistently storing) and deserializing
> + SIMICS QSP's platform configuration.
> +
> + Copyright (C) 2014, Red Hat, Inc.
> + Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/UefiLib.h>
> +#include <Library/UefiRuntimeServicesTableLib.h>
> +#include <Guid/SimicsBoardConfig.h>
> +
> +#include "PlatformConfig.h"
> +
> +//
> +// Name of the UEFI variable that we use for persistent storage.
> +//
> +STATIC CHAR16 mVariableName[] = L"PlatformConfig";
> +
> +
> +/**
> + Serialize and persistently save platform configuration.
> +
> + @param[in] PlatformConfig The platform configuration to serialize and save.
> +
> + @return Status codes returned by gRT->SetVariable().
> +**/
> +EFI_STATUS
> +EFIAPI
> +PlatformConfigSave (
> + IN PLATFORM_CONFIG *PlatformConfig
> + )
> +{
> + EFI_STATUS Status;
> +
> + //
> + // We could implement any kind of translation here, as part of serialization.
> + // For example, we could expose the platform configuration in separate
> + // variables with human-readable contents, allowing other tools to access
> + // them more easily. For now, just save a binary dump.
> + //
> + Status = gRT->SetVariable (mVariableName, &gSimicsBoardConfigGuid,
> + EFI_VARIABLE_NON_VOLATILE |
> EFI_VARIABLE_BOOTSERVICE_ACCESS |
> + EFI_VARIABLE_RUNTIME_ACCESS,
> + sizeof *PlatformConfig, PlatformConfig);
> + return Status;
> +}
> +
> +
> +/**
> + Load and deserialize platform configuration.
> +
> + When the function fails, output parameters are indeterminate.
> +
> + @param[out] PlatformConfig The platform configuration to receive the
> + loaded data.
> +
> + @param[out] OptionalElements This bitmap describes the presence of
> optional
> + configuration elements that have been loaded.
> + PLATFORM_CONFIG_F_DOWNGRADE means that some
> + unknown elements, present in the wire format,
> + have been ignored.
> +
> + @retval EFI_SUCCESS Loading & deserialization successful.
> + @return Error codes returned by GetVariable2().
> +**/
> +EFI_STATUS
> +EFIAPI
> +PlatformConfigLoad (
> + OUT PLATFORM_CONFIG *PlatformConfig,
> + OUT UINT64 *OptionalElements
> + )
> +{
> + VOID *Data;
> + UINTN DataSize;
> + EFI_STATUS Status;
> +
> + //
> + // Any translation done in PlatformConfigSave() would have to be mirrored
> + // here. For now, just load the binary dump.
> + //
> + // Versioning of the binary wire format is implemented based on size
> + // (only incremental changes, ie. new fields), and on GUID.
> + // (Incompatible changes require a GUID change.)
> + //
> + Status = GetVariable2 (mVariableName, &gSimicsBoardConfigGuid, &Data,
> + &DataSize);
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + *OptionalElements = 0;
> + if (DataSize > sizeof *PlatformConfig) {
> + //
> + // Handle firmware downgrade -- keep only leading part.
> + //
> + CopyMem (PlatformConfig, Data, sizeof *PlatformConfig);
> + *OptionalElements |= PLATFORM_CONFIG_F_DOWNGRADE;
> + } else {
> + CopyMem (PlatformConfig, Data, DataSize);
> +
> + //
> + // Handle firmware upgrade -- zero out missing fields.
> + //
> + ZeroMem ((UINT8 *)PlatformConfig + DataSize,
> + sizeof *PlatformConfig - DataSize);
> + }
> +
> + //
> + // Based on DataSize, report the optional features that we recognize.
> + //
> + if (DataSize >= (OFFSET_OF (PLATFORM_CONFIG, VerticalResolution) +
> + sizeof PlatformConfig->VerticalResolution)) {
> + *OptionalElements |= PLATFORM_CONFIG_F_GRAPHICS_RESOLUTION;
> + }
> +
> + FreePool (Data);
> + return EFI_SUCCESS;
> +}
> diff --git a/Platform/Intel/SimicsOpenBoardPkg/SimicsPei/Cmos.c
> b/Platform/Intel/SimicsOpenBoardPkg/SimicsPei/Cmos.c
> new file mode 100644
> index 0000000000..b34ba9283b
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/SimicsPei/Cmos.c
> @@ -0,0 +1,57 @@
> +/** @file
> + PC/AT CMOS access routines
> +
> + Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "Cmos.h"
> +#include "Library/IoLib.h"
> +
> +/**
> + Reads 8-bits of CMOS data.
> +
> + Reads the 8-bits of CMOS data at the location specified by Index.
> + The 8-bit read value is returned.
> +
> + @param Index The CMOS location to read.
> +
> + @return The value read.
> +
> +**/
> +UINT8
> +EFIAPI
> +CmosRead8 (
> + IN UINTN Index
> + )
> +{
> + IoWrite8 (0x70, (UINT8) Index);
> + return IoRead8 (0x71);
> +}
> +
> +
> +/**
> + Writes 8-bits of CMOS data.
> +
> + Writes 8-bits of CMOS data to the location specified by Index
> + with the value specified by Value and returns Value.
> +
> + @param Index The CMOS location to write.
> + @param Value The value to write to CMOS.
> +
> + @return The value written to CMOS.
> +
> +**/
> +UINT8
> +EFIAPI
> +CmosWrite8 (
> + IN UINTN Index,
> + IN UINT8 Value
> + )
> +{
> + IoWrite8 (0x70, (UINT8) Index);
> + IoWrite8 (0x71, Value);
> + return Value;
> +}
> +
> diff --git a/Platform/Intel/SimicsOpenBoardPkg/SimicsPei/FeatureControl.c
> b/Platform/Intel/SimicsOpenBoardPkg/SimicsPei/FeatureControl.c
> new file mode 100644
> index 0000000000..9d2fc65a14
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/SimicsPei/FeatureControl.c
> @@ -0,0 +1,115 @@
> +/** @file
> + Install a callback when necessary for setting the Feature Control MSR on all
> + processors.
> +
> + Copyright (C) 2016, Red Hat, Inc.
> + Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Library/DebugLib.h>
> +#include <Library/PeiServicesLib.h>
> +#include <Ppi/MpServices.h>
> +#include <Register/Intel/Msr/Core2Msr.h>
> +
> +#include "Platform.h"
> +
> +//
> +// The value to be written to the Feature Control MSR, retrieved from fw_cfg.
> +//
> +STATIC UINT64 mFeatureControlValue = 0x00000005;
> +
> +/**
> + Write the Feature Control MSR on an Application Processor or the Boot
> + Processor.
> +
> + All APs execute this function in parallel. The BSP executes the function
> + separately.
> +
> + @param[in,out] WorkSpace Pointer to the input/output argument workspace
> + shared by all processors.
> +**/
> +STATIC
> +VOID
> +EFIAPI
> +WriteFeatureControl (
> + IN OUT VOID *WorkSpace
> + )
> +{
> + AsmWriteMsr64 (MSR_CORE2_FEATURE_CONTROL, mFeatureControlValue);
> +}
> +
> +/**
> + Notification function called when EFI_PEI_MP_SERVICES_PPI becomes
> available.
> +
> + @param[in] PeiServices Indirect reference to the PEI Services Table.
> + @param[in] NotifyDescriptor Address of the notification descriptor data
> + structure.
> + @param[in] Ppi Address of the PPI that was installed.
> +
> + @return Status of the notification. The status code returned from this
> + function is ignored.
> +**/
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +OnMpServicesAvailable (
> + IN EFI_PEI_SERVICES **PeiServices,
> + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
> + IN VOID *Ppi
> + )
> +{
> + EFI_PEI_MP_SERVICES_PPI *MpServices;
> + EFI_STATUS Status;
> +
> + DEBUG ((EFI_D_VERBOSE, "%a: %a\n", gEfiCallerBaseName,
> __FUNCTION__));
> + //
> + // Write the MSR on all the APs in parallel.
> + //
> + MpServices = Ppi;
> + Status = MpServices->StartupAllAPs (
> + (CONST EFI_PEI_SERVICES **)PeiServices,
> + MpServices,
> + WriteFeatureControl, // Procedure
> + FALSE, // SingleThread
> + 0, // TimeoutInMicroSeconds: inf.
> + NULL // ProcedureArgument
> + );
> + if (EFI_ERROR (Status) && Status != EFI_NOT_STARTED) {
> + DEBUG ((EFI_D_ERROR, "%a: StartupAllAps(): %r\n", __FUNCTION__,
> Status));
> + return Status;
> + }
> +
> + //
> + // Now write the MSR on the BSP too.
> + //
> + WriteFeatureControl (NULL);
> +
> + return EFI_SUCCESS;
> +}
> +
> +//
> +// Notification object for registering the callback, for when
> +// EFI_PEI_MP_SERVICES_PPI becomes available.
> +//
> +STATIC CONST EFI_PEI_NOTIFY_DESCRIPTOR mMpServicesNotify = {
> + EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | // Flags
> + EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
> + &gEfiPeiMpServicesPpiGuid, // Guid
> + OnMpServicesAvailable // Notify
> +};
> +
> +VOID
> +InstallFeatureControlCallback (
> + VOID
> + )
> +{
> + EFI_STATUS Status;
> +
> + Status = PeiServicesNotifyPpi (&mMpServicesNotify);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((EFI_D_ERROR, "%a: failed to set up MP Services callback: %r\n",
> + __FUNCTION__, Status));
> + }
> +}
> diff --git a/Platform/Intel/SimicsOpenBoardPkg/SimicsPei/MemDetect.c
> b/Platform/Intel/SimicsOpenBoardPkg/SimicsPei/MemDetect.c
> new file mode 100644
> index 0000000000..90e6d1d3cf
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/SimicsPei/MemDetect.c
> @@ -0,0 +1,568 @@
> +/** @file
> + Memory Detection for Virtual Machines.
> +
> + Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +//
> +// The package level header files this module uses
> +//
> +#include <PiPei.h>
> +
> +//
> +// The Library classes this module consumes
> +//
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/PeimEntryPoint.h>
> +#include <Library/ResourcePublicationLib.h>
> +#include <Library/MtrrLib.h>
> +#include <SimicsPlatforms.h>
> +#include <Guid/SmramMemoryReserve.h>
> +
> +#include "Platform.h"
> +#include "Cmos.h"
> +
> +UINT8 mPhysMemAddressWidth;
> +
> +STATIC UINT32 mS3AcpiReservedMemoryBase;
> +STATIC UINT32 mS3AcpiReservedMemorySize;
> +
> +STATIC UINT16 mX58TsegMbytes;
> +
> +VOID
> +X58TsegMbytesInitialization(
> + VOID
> +)
> +{
> +
> + if (mHostBridgeDevId != INTEL_ICH10_DEVICE_ID) {
> + DEBUG ((
> + DEBUG_ERROR,
> + "%a: no TSEG (SMRAM) on host bridge DID=0x%04x; "
> + "only DID=0x%04x (X58) is supported\n",
> + __FUNCTION__,
> + mHostBridgeDevId,
> + INTEL_ICH10_DEVICE_ID
> + ));
> + ASSERT (FALSE);
> + CpuDeadLoop ();
> + }
> +
> + //
> + // Check if QEMU offers an extended TSEG.
> + //
> + // This can be seen from writing MCH_EXT_TSEG_MB_QUERY to the
> MCH_EXT_TSEG_MB
> + // register, and reading back the register.
> + //
> + // On a QEMU machine type that does not offer an extended TSEG, the initial
> + // write overwrites whatever value a malicious guest OS may have placed in
> + // the (unimplemented) register, before entering S3 or rebooting.
> + // Subsequently, the read returns MCH_EXT_TSEG_MB_QUERY unchanged.
> + //
> + // On a QEMU machine type that offers an extended TSEG, the initial write
> + // triggers an update to the register. Subsequently, the value read back
> + // (which is guaranteed to differ from MCH_EXT_TSEG_MB_QUERY) tells us
> the
> + // number of megabytes.
> + //
> + mX58TsegMbytes = FixedPcdGet8(PcdX58TsegMbytes);
> + return;
> +}
> +
> +
> +UINT32
> +GetSystemMemorySizeBelow4gb (
> + VOID
> + )
> +{
> + UINT8 Cmos0x34;
> + UINT8 Cmos0x35;
> +
> + //
> + // CMOS 0x34/0x35 specifies the system memory above 16 MB.
> + // * CMOS(0x35) is the high byte
> + // * CMOS(0x34) is the low byte
> + // * The size is specified in 64kb chunks
> + // * Since this is memory above 16MB, the 16MB must be added
> + // into the calculation to get the total memory size.
> + //
> +
> + Cmos0x34 = (UINT8) CmosRead8 (0x34);
> + Cmos0x35 = (UINT8) CmosRead8 (0x35);
> +
> + return (UINT32) (((UINTN)((Cmos0x35 << 8) + Cmos0x34) << 16) + SIZE_16MB);
> +}
> +
> +
> +STATIC
> +UINT64
> +GetSystemMemorySizeAbove4gb (
> + )
> +{
> + UINT32 Size;
> + UINTN CmosIndex;
> +
> + //
> + // CMOS 0x5b-0x5d specifies the system memory above 4GB MB.
> + // * CMOS(0x5d) is the most significant size byte
> + // * CMOS(0x5c) is the middle size byte
> + // * CMOS(0x5b) is the least significant size byte
> + // * The size is specified in 64kb chunks
> + //
> +
> + Size = 0;
> + for (CmosIndex = 0x5d; CmosIndex >= 0x5b; CmosIndex--) {
> + Size = (UINT32) (Size << 8) + (UINT32) CmosRead8 (CmosIndex);
> + }
> +
> + return LShiftU64 (Size, 16);
> +}
> +
> +
> +/**
> + Return the highest address that DXE could possibly use, plus one.
> +**/
> +STATIC
> +UINT64
> +GetFirstNonAddress (
> + VOID
> + )
> +{
> + UINT64 FirstNonAddress;
> + UINT64 Pci64Base, Pci64Size;
> +
> + FirstNonAddress = BASE_4GB + GetSystemMemorySizeAbove4gb ();
> +
> + //
> + // If DXE is 32-bit, then we're done; PciBusDxe will degrade 64-bit MMIO
> + // resources to 32-bit anyway. See DegradeResource() in
> + // "PciResourceSupport.c".
> + //
> +#ifdef MDE_CPU_IA32
> + if (!FeaturePcdGet (PcdDxeIplSwitchToLongMode)) {
> + return FirstNonAddress;
> + }
> +#endif
> +
> + //
> + // Otherwise, in order to calculate the highest address plus one, we must
> + // consider the 64-bit PCI host aperture too. Fetch the default size.
> + //
> + Pci64Size = PcdGet64 (PcdPciMmio64Size);
> +
> + if (Pci64Size == 0) {
> + if (mBootMode != BOOT_ON_S3_RESUME) {
> + DEBUG ((EFI_D_INFO, "%a: disabling 64-bit PCI host aperture\n",
> + __FUNCTION__));
> + PcdSet64 (PcdPciMmio64Size, 0);
> + }
> +
> + //
> + // There's nothing more to do; the amount of memory above 4GB fully
> + // determines the highest address plus one. The memory hotplug area (see
> + // below) plays no role for the firmware in this case.
> + //
> + return FirstNonAddress;
> + }
> +
> + //
> + // SeaBIOS aligns both boundaries of the 64-bit PCI host aperture to 1GB, so
> + // that the host can map it with 1GB hugepages. Follow suit.
> + //
> + Pci64Base = ALIGN_VALUE (FirstNonAddress, (UINT64)SIZE_1GB);
> + Pci64Size = ALIGN_VALUE (Pci64Size, (UINT64)SIZE_1GB);
> +
> + //
> + // The 64-bit PCI host aperture should also be "naturally" aligned. The
> + // alignment is determined by rounding the size of the aperture down to the
> + // next smaller or equal power of two. That is, align the aperture by the
> + // largest BAR size that can fit into it.
> + //
> + Pci64Base = ALIGN_VALUE (Pci64Base, GetPowerOfTwo64 (Pci64Size));
> +
> + if (mBootMode != BOOT_ON_S3_RESUME) {
> + //
> + // The core PciHostBridgeDxe driver will automatically add this range to
> + // the GCD memory space map through our PciHostBridgeLib instance; here
> we
> + // only need to set the PCDs.
> + //
> + PcdSet64 (PcdPciMmio64Base, Pci64Base);
> + PcdSet64 (PcdPciMmio64Size, Pci64Size);
> + DEBUG ((EFI_D_INFO, "%a: Pci64Base=0x%Lx Pci64Size=0x%Lx\n",
> + __FUNCTION__, Pci64Base, Pci64Size));
> + }
> +
> + //
> + // The useful address space ends with the 64-bit PCI host aperture.
> + //
> + FirstNonAddress = Pci64Base + Pci64Size;
> + return FirstNonAddress;
> +}
> +
> +
> +/**
> + Initialize the mPhysMemAddressWidth variable, based on guest RAM size.
> +**/
> +VOID
> +AddressWidthInitialization (
> + VOID
> + )
> +{
> + UINT64 FirstNonAddress;
> +
> + //
> + // As guest-physical memory size grows, the permanent PEI RAM
> requirements
> + // are dominated by the identity-mapping page tables built by the DXE IPL.
> + // The DXL IPL keys off of the physical address bits advertized in the CPU
> + // HOB. To conserve memory, we calculate the minimum address width here.
> + //
> + FirstNonAddress = GetFirstNonAddress ();
> + mPhysMemAddressWidth = (UINT8)HighBitSet64 (FirstNonAddress);
> +
> + //
> + // If FirstNonAddress is not an integral power of two, then we need an
> + // additional bit.
> + //
> + if ((FirstNonAddress & (FirstNonAddress - 1)) != 0) {
> + ++mPhysMemAddressWidth;
> + }
> +
> + //
> + // The minimum address width is 36 (covers up to and excluding 64 GB, which
> + // is the maximum for Ia32 + PAE). The theoretical architecture maximum for
> + // X64 long mode is 52 bits, but the DXE IPL clamps that down to 48 bits. We
> + // can simply assert that here, since 48 bits are good enough for 256 TB.
> + //
> + if (mPhysMemAddressWidth <= 36) {
> + mPhysMemAddressWidth = 36;
> + }
> + ASSERT (mPhysMemAddressWidth <= 48);
> +}
> +
> +
> +/**
> + Calculate the cap for the permanent PEI memory.
> +**/
> +STATIC
> +UINT32
> +GetPeiMemoryCap (
> + VOID
> + )
> +{
> + BOOLEAN Page1GSupport;
> + UINT32 RegEax;
> + UINT32 RegEdx;
> + UINT32 Pml4Entries;
> + UINT32 PdpEntries;
> + UINTN TotalPages;
> +
> + //
> + // If DXE is 32-bit, then just return the traditional 64 MB cap.
> + //
> +#ifdef MDE_CPU_IA32
> + if (!FeaturePcdGet (PcdDxeIplSwitchToLongMode)) {
> + return SIZE_64MB;
> + }
> +#endif
> +
> + //
> + // Dependent on physical address width, PEI memory allocations can be
> + // dominated by the page tables built for 64-bit DXE. So we key the cap off
> + // of those. The code below is based on CreateIdentityMappingPageTables()
> in
> + // "MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c".
> + //
> + Page1GSupport = FALSE;
> + if (PcdGetBool (PcdUse1GPageTable)) {
> + AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);
> + if (RegEax >= 0x80000001) {
> + AsmCpuid (0x80000001, NULL, NULL, NULL, &RegEdx);
> + if ((RegEdx & BIT26) != 0) {
> + Page1GSupport = TRUE;
> + }
> + }
> + }
> +
> + if (mPhysMemAddressWidth <= 39) {
> + Pml4Entries = 1;
> + PdpEntries = 1 << (mPhysMemAddressWidth - 30);
> + ASSERT (PdpEntries <= 0x200);
> + } else {
> + Pml4Entries = 1 << (mPhysMemAddressWidth - 39);
> + ASSERT (Pml4Entries <= 0x200);
> + PdpEntries = 512;
> + }
> +
> + TotalPages = Page1GSupport ? Pml4Entries + 1 :
> + (PdpEntries + 1) * Pml4Entries + 1;
> + ASSERT (TotalPages <= 0x40201);
> +
> + //
> + // Add 64 MB for miscellaneous allocations. Note that for
> + // mPhysMemAddressWidth values close to 36, the cap will actually be
> + // dominated by this increment.
> + //
> + return (UINT32)(EFI_PAGES_TO_SIZE (TotalPages) + SIZE_64MB);
> +}
> +
> +
> +/**
> + Publish PEI core memory
> +
> + @return EFI_SUCCESS The PEIM initialized successfully.
> +
> +**/
> +EFI_STATUS
> +PublishPeiMemory (
> + VOID
> + )
> +{
> + EFI_STATUS Status;
> + EFI_PHYSICAL_ADDRESS MemoryBase;
> + UINT64 MemorySize;
> + UINT32 LowerMemorySize;
> + UINT32 PeiMemoryCap;
> +
> + LowerMemorySize = GetSystemMemorySizeBelow4gb ();
> + if (FeaturePcdGet (PcdSmmSmramRequire)) {
> + //
> + // TSEG is chipped from the end of low RAM
> + //
> + LowerMemorySize -= mX58TsegMbytes * SIZE_1MB;
> + }
> +
> + //
> + // If S3 is supported, then the S3 permanent PEI memory is placed next,
> + // downwards. Its size is primarily dictated by CpuMpPei. The formula below
> + // is an approximation.
> + //
> + if (mS3Supported) {
> + mS3AcpiReservedMemorySize = SIZE_512KB +
> + mMaxCpuCount *
> + PcdGet32 (PcdCpuApStackSize);
> + mS3AcpiReservedMemoryBase = LowerMemorySize -
> mS3AcpiReservedMemorySize;
> + LowerMemorySize = mS3AcpiReservedMemoryBase;
> + }
> +
> + if (mBootMode == BOOT_ON_S3_RESUME) {
> + MemoryBase = mS3AcpiReservedMemoryBase;
> + MemorySize = mS3AcpiReservedMemorySize;
> + } else {
> + PeiMemoryCap = GetPeiMemoryCap ();
> + DEBUG ((EFI_D_INFO, "%a: mPhysMemAddressWidth=%d
> PeiMemoryCap=%u KB\n",
> + __FUNCTION__, mPhysMemAddressWidth, PeiMemoryCap >> 10));
> +
> + //
> + // Determine the range of memory to use during PEI
> + //
> + // Technically we could lay the permanent PEI RAM over SEC's temporary
> + // decompression and scratch buffer even if "secure S3" is needed, since
> + // their lifetimes don't overlap. However, PeiFvInitialization() will cover
> + // RAM up to PcdOvmfDecompressionScratchEnd with an
> EfiACPIMemoryNVS memory
> + // allocation HOB, and other allocations served from the permanent PEI RAM
> + // shouldn't overlap with that HOB.
> + //
> + MemoryBase = mS3Supported && FeaturePcdGet (PcdSmmSmramRequire) ?
> + PcdGet32 (PcdSimicsDecompressionScratchEnd) :
> + PcdGet32 (PcdSimicsDxeMemFvBase) + PcdGet32
> (PcdSimicsDxeMemFvSize);
> + MemorySize = LowerMemorySize - MemoryBase;
> + }
> + DEBUG((EFI_D_INFO, "MemoryBase=0x%lx MemorySize=0x%lx\n",
> MemoryBase, MemorySize));
> + //
> + // Publish this memory to the PEI Core
> + //
> + Status = PublishSystemMemory(MemoryBase, MemorySize);
> + ASSERT_EFI_ERROR (Status);
> +
> + return Status;
> +}
> +
> +
> +/**
> + Peform Memory Detection for QEMU / KVM
> +
> +**/
> +STATIC
> +VOID
> +QemuInitializeRam (
> + VOID
> + )
> +{
> + UINT64 LowerMemorySize;
> + UINT64 UpperMemorySize;
> + UINTN BufferSize;
> + UINT8 SmramIndex;
> + UINT8 SmramRanges;
> + EFI_PEI_HOB_POINTERS Hob;
> + EFI_SMRAM_HOB_DESCRIPTOR_BLOCK *SmramHobDescriptorBlock;
> + UINT8 Index;
> +
> + DEBUG ((EFI_D_INFO, "%a called\n", __FUNCTION__));
> +
> + //
> + // Determine total memory size available
> + //
> + LowerMemorySize = GetSystemMemorySizeBelow4gb ();
> + UpperMemorySize = GetSystemMemorySizeAbove4gb ();
> +
> + if (mBootMode == BOOT_ON_S3_RESUME) {
> + //
> + // Create the following memory HOB as an exception on the S3 boot path.
> + //
> + // Normally we'd create memory HOBs only on the normal boot path.
> However,
> + // CpuMpPei specifically needs such a low-memory HOB on the S3 path as
> + // well, for "borrowing" a subset of it temporarily, for the AP startup
> + // vector.
> + //
> + // CpuMpPei saves the original contents of the borrowed area in permanent
> + // PEI RAM, in a backup buffer allocated with the normal PEI services.
> + // CpuMpPei restores the original contents ("returns" the borrowed area) at
> + // End-of-PEI. End-of-PEI in turn is emitted by S3Resume2Pei before
> + // transferring control to the OS's wakeup vector in the FACS.
> + //
> + // We expect any other PEIMs that "borrow" memory similarly to CpuMpPei
> to
> + // restore the original contents. Furthermore, we expect all such PEIMs
> + // (CpuMpPei included) to claim the borrowed areas by producing memory
> + // allocation HOBs, and to honor preexistent memory allocation HOBs when
> + // looking for an area to borrow.
> + //
> + AddMemoryRangeHob (0, BASE_512KB + BASE_128KB);
> + } else {
> + //
> + // Create memory HOBs
> + //
> + AddMemoryRangeHob (0, BASE_512KB + BASE_128KB);
> +
> + if (FeaturePcdGet (PcdSmmSmramRequire)) {
> + UINT32 TsegSize;
> +
> + TsegSize = mX58TsegMbytes * SIZE_1MB;
> + AddMemoryRangeHob (BASE_1MB, LowerMemorySize - TsegSize);
> + AddReservedMemoryBaseSizeHob (LowerMemorySize - TsegSize, TsegSize,
> + TRUE);
> +
> + BufferSize = sizeof(EFI_SMRAM_HOB_DESCRIPTOR_BLOCK);
> + SmramRanges = 1;
> +
> + Hob.Raw = BuildGuidHob(
> + &gEfiSmmPeiSmramMemoryReserveGuid,
> + BufferSize
> + );
> + ASSERT(Hob.Raw);
> +
> + SmramHobDescriptorBlock = (EFI_SMRAM_HOB_DESCRIPTOR_BLOCK
> *)(Hob.Raw);
> + SmramHobDescriptorBlock->NumberOfSmmReservedRegions =
> SmramRanges;
> +
> + SmramIndex = 0;
> + for (Index = 0; Index < SmramRanges; Index++) {
> + //
> + // This is an SMRAM range, create an SMRAM descriptor
> + //
> + SmramHobDescriptorBlock->Descriptor[SmramIndex].PhysicalStart =
> LowerMemorySize - TsegSize;
> + SmramHobDescriptorBlock->Descriptor[SmramIndex].CpuStart =
> LowerMemorySize - TsegSize;
> + SmramHobDescriptorBlock->Descriptor[SmramIndex].PhysicalSize =
> TsegSize;
> + SmramHobDescriptorBlock->Descriptor[SmramIndex].RegionState =
> EFI_SMRAM_CLOSED | EFI_CACHEABLE;
> + SmramIndex++;
> + }
> +
> + } else {
> + AddMemoryRangeHob (BASE_1MB, LowerMemorySize);
> + }
> +
> + //
> + // If QEMU presents an E820 map, then create memory HOBs for the >=4GB
> RAM
> + // entries. Otherwise, create a single memory HOB with the flat >=4GB
> + // memory size read from the CMOS.
> + //
> + if (UpperMemorySize != 0) {
> + AddMemoryBaseSizeHob (BASE_4GB, UpperMemorySize);
> + }
> + }
> +}
> +
> +/**
> + Publish system RAM and reserve memory regions
> +
> +**/
> +VOID
> +InitializeRamRegions (
> + VOID
> + )
> +{
> + QemuInitializeRam ();
> +
> + if (mS3Supported && mBootMode != BOOT_ON_S3_RESUME) {
> + //
> + // This is the memory range that will be used for PEI on S3 resume
> + //
> + BuildMemoryAllocationHob (
> + mS3AcpiReservedMemoryBase,
> + mS3AcpiReservedMemorySize,
> + EfiACPIMemoryNVS
> + );
> +
> + //
> + // Cover the initial RAM area used as stack and temporary PEI heap.
> + //
> + // This is reserved as ACPI NVS so it can be used on S3 resume.
> + //
> + BuildMemoryAllocationHob (
> + PcdGet32 (PcdSimicsSecPeiTempRamBase),
> + PcdGet32 (PcdSimicsSecPeiTempRamSize),
> + EfiACPIMemoryNVS
> + );
> +
> + //
> + // SEC stores its table of GUIDed section handlers here.
> + //
> + BuildMemoryAllocationHob (
> + PcdGet64 (PcdGuidedExtractHandlerTableAddress),
> + PcdGet32 (PcdGuidedExtractHandlerTableSize),
> + EfiACPIMemoryNVS
> + );
> +
> + }
> +
> + if (mBootMode != BOOT_ON_S3_RESUME) {
> + if (!FeaturePcdGet (PcdSmmSmramRequire)) {
> + //
> + // Reserve the lock box storage area
> + //
> + // Since this memory range will be used on S3 resume, it must be
> + // reserved as ACPI NVS.
> + //
> + // If S3 is unsupported, then various drivers might still write to the
> + // LockBox area. We ought to prevent DXE from serving allocation requests
> + // such that they would overlap the LockBox storage.
> + //
> + ZeroMem (
> + (VOID*)(UINTN) PcdGet32 (PcdSimicsLockBoxStorageBase),
> + (UINTN) PcdGet32 (PcdSimicsLockBoxStorageSize)
> + );
> + BuildMemoryAllocationHob (
> + (EFI_PHYSICAL_ADDRESS)(UINTN) PcdGet32
> (PcdSimicsLockBoxStorageBase),
> + (UINT64)(UINTN) PcdGet32 (PcdSimicsLockBoxStorageSize),
> + mS3Supported ? EfiACPIMemoryNVS : EfiBootServicesData
> + );
> + }
> +
> + if (FeaturePcdGet (PcdSmmSmramRequire)) {
> + UINT32 TsegSize;
> +
> + //
> + // Make sure the TSEG area that we reported as a reserved memory
> resource
> + // cannot be used for reserved memory allocations.
> + //
> + TsegSize = mX58TsegMbytes * SIZE_1MB;
> + BuildMemoryAllocationHob (
> + GetSystemMemorySizeBelow4gb() - TsegSize,
> + TsegSize,
> + EfiReservedMemoryType
> + );
> + }
> + }
> +}
> diff --git a/Platform/Intel/SimicsOpenBoardPkg/SimicsPei/Platform.c
> b/Platform/Intel/SimicsOpenBoardPkg/SimicsPei/Platform.c
> new file mode 100644
> index 0000000000..2fe34b02c4
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/SimicsPei/Platform.c
> @@ -0,0 +1,630 @@
> +/** @file
> + Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>
> + Copyright (c) 2011, Andrei Warkentin <andreiw@motorola.com>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +//
> +// The package level header files this module uses
> +//
> +#include <PiPei.h>
> +
> +//
> +// The Library classes this module consumes
> +//
> +#include <Library/DebugLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/PciLib.h>
> +#include <Library/PeimEntryPoint.h>
> +#include <Library/PeiServicesLib.h>
> +#include <Library/ResourcePublicationLib.h>
> +#include <Guid/MemoryTypeInformation.h>
> +#include <Ppi/MasterBootMode.h>
> +#include <IndustryStandard/Pci22.h>
> +#include <SimicsPlatforms.h>
> +
> +#include "Platform.h"
> +#include "Cmos.h"
> +
> +EFI_MEMORY_TYPE_INFORMATION mDefaultMemoryTypeInformation[] = {
> + { EfiACPIMemoryNVS, 0x004 },
> + { EfiACPIReclaimMemory, 0x008 },
> + { EfiReservedMemoryType, 0x004 },
> + { EfiRuntimeServicesData, 0x024 },
> + { EfiRuntimeServicesCode, 0x030 },
> + { EfiBootServicesCode, 0x180 },
> + { EfiBootServicesData, 0xF00 },
> + { EfiMaxMemoryType, 0x000 }
> +};
> +
> +
> +EFI_PEI_PPI_DESCRIPTOR mPpiBootMode[] = {
> + {
> + EFI_PEI_PPI_DESCRIPTOR_PPI |
> EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
> + &gEfiPeiMasterBootModePpiGuid,
> + NULL
> + }
> +};
> +
> +
> +UINT16 mHostBridgeDevId;
> +
> +EFI_BOOT_MODE mBootMode = BOOT_WITH_FULL_CONFIGURATION;
> +
> +BOOLEAN mS3Supported = FALSE;
> +
> +UINT32 mMaxCpuCount;
> +
> +VOID
> +AddIoMemoryBaseSizeHob (
> + EFI_PHYSICAL_ADDRESS MemoryBase,
> + UINT64 MemorySize
> + )
> +{
> + BuildResourceDescriptorHob (
> + EFI_RESOURCE_MEMORY_MAPPED_IO,
> + EFI_RESOURCE_ATTRIBUTE_PRESENT |
> + EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
> + EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
> + EFI_RESOURCE_ATTRIBUTE_TESTED,
> + MemoryBase,
> + MemorySize
> + );
> +}
> +
> +VOID
> +AddReservedMemoryBaseSizeHob (
> + EFI_PHYSICAL_ADDRESS MemoryBase,
> + UINT64 MemorySize,
> + BOOLEAN Cacheable
> + )
> +{
> + BuildResourceDescriptorHob (
> + EFI_RESOURCE_MEMORY_RESERVED,
> + EFI_RESOURCE_ATTRIBUTE_PRESENT |
> + EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
> + EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
> + (Cacheable ?
> + EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
> + EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
> + EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE :
> + 0
> + ) |
> + EFI_RESOURCE_ATTRIBUTE_TESTED,
> + MemoryBase,
> + MemorySize
> + );
> +}
> +
> +VOID
> +AddIoMemoryRangeHob (
> + EFI_PHYSICAL_ADDRESS MemoryBase,
> + EFI_PHYSICAL_ADDRESS MemoryLimit
> + )
> +{
> + AddIoMemoryBaseSizeHob (MemoryBase, (UINT64)(MemoryLimit -
> MemoryBase));
> +}
> +
> +
> +VOID
> +AddMemoryBaseSizeHob (
> + EFI_PHYSICAL_ADDRESS MemoryBase,
> + UINT64 MemorySize
> + )
> +{
> + BuildResourceDescriptorHob (
> + EFI_RESOURCE_SYSTEM_MEMORY,
> + EFI_RESOURCE_ATTRIBUTE_PRESENT |
> + EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
> + EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
> + EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
> + EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
> + EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE |
> + EFI_RESOURCE_ATTRIBUTE_TESTED,
> + MemoryBase,
> + MemorySize
> + );
> +}
> +
> +
> +VOID
> +AddMemoryRangeHob (
> + EFI_PHYSICAL_ADDRESS MemoryBase,
> + EFI_PHYSICAL_ADDRESS MemoryLimit
> + )
> +{
> + AddMemoryBaseSizeHob (MemoryBase, (UINT64)(MemoryLimit -
> MemoryBase));
> +}
> +
> +
> +VOID
> +AddUntestedMemoryBaseSizeHob (
> + EFI_PHYSICAL_ADDRESS MemoryBase,
> + UINT64 MemorySize
> + )
> +{
> + BuildResourceDescriptorHob (
> + EFI_RESOURCE_SYSTEM_MEMORY,
> + EFI_RESOURCE_ATTRIBUTE_PRESENT |
> + EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
> + EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
> + EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
> + EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
> + EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE,
> + MemoryBase,
> + MemorySize
> + );
> +}
> +
> +
> +VOID
> +AddUntestedMemoryRangeHob (
> + EFI_PHYSICAL_ADDRESS MemoryBase,
> + EFI_PHYSICAL_ADDRESS MemoryLimit
> + )
> +{
> + AddUntestedMemoryBaseSizeHob (MemoryBase, (UINT64)(MemoryLimit -
> MemoryBase));
> +}
> +
> +VOID
> +AddFlashDeviceRange (
> + EFI_PHYSICAL_ADDRESS MemoryBase,
> + UINT64 MemorySize
> + )
> +{
> + BuildResourceDescriptorHob (
> + EFI_RESOURCE_FIRMWARE_DEVICE,
> + (EFI_RESOURCE_ATTRIBUTE_PRESENT |
> + EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
> + EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
> + MemoryBase,
> + MemorySize
> + );
> +
> + BuildMemoryAllocationHob (
> + MemoryBase,
> + MemorySize,
> + EfiMemoryMappedIO
> + );
> +}
> +
> +VOID
> +MemMapInitialization (
> + VOID
> + )
> +{
> + UINT64 PciIoBase;
> + UINT64 PciIoSize;
> +
> + UINT32 TopOfLowRam;
> + UINT64 PciExBarBase;
> + UINT32 PciBase;
> + UINT32 PciSize;
> +
> + PciIoBase = 0xC000;
> + PciIoSize = 0x4000;
> +
> + //
> + // Create Memory Type Information HOB
> + //
> + BuildGuidDataHob (
> + &gEfiMemoryTypeInformationGuid,
> + mDefaultMemoryTypeInformation,
> + sizeof(mDefaultMemoryTypeInformation)
> + );
> +
> + //
> + // Video memory + Legacy BIOS region
> + //
> + AddIoMemoryRangeHob (0x0A0000, BASE_1MB);
> +
> + TopOfLowRam = GetSystemMemorySizeBelow4gb ();
> + PciExBarBase = 0;
> + if (mHostBridgeDevId == INTEL_ICH10_DEVICE_ID) {
> + //
> + // The MMCONFIG area is expected to fall between the top of low RAM and
> + // the base of the 32-bit PCI host aperture.
> + //
> + PciExBarBase = FixedPcdGet64 (PcdPciExpressBaseAddress);
> + ASSERT (TopOfLowRam <= PciExBarBase);
> + ASSERT (PciExBarBase <= MAX_UINT32 - SIZE_256MB);
> + PciBase = (UINT32)(PciExBarBase + SIZE_256MB);
> + } else {
> + PciBase = (TopOfLowRam < BASE_2GB) ? BASE_2GB : TopOfLowRam;
> + }
> +
> + //
> + // address purpose size
> + // ------------ -------- -------------------------
> + // 0x00000000 TopOfLowRam 0xDF000000
> + // 0xDF000000 Tseg+UMA 0x01000000
> + // 0xE0000000 PciExBarBase 0x10000000
> + // 0xF0000000 PciBase 0x0C000000
> + // -------------------------------------------------
> + // max(top, 2g) PCI MMIO 0xFC000000 - max(top, 2g)
> + // 0xFC000000 gap 44 MB
> + // 0xFEC00000 IO-APIC 4 KB
> + // 0xFEC01000 gap 1020 KB
> + // 0xFED00000 HPET 1 KB
> + // 0xFED00400 gap 111 KB
> + // 0xFED1C000 gap (PIIX4) / RCRB (ICH9) 16 KB
> + // 0xFED20000 gap 896 KB
> + // 0xFEE00000 LAPIC 1 MB
> + //
> + PciSize = 0xFC000000 - PciBase;
> + AddIoMemoryBaseSizeHob (PciBase, PciSize);
> + PcdSet64 (PcdPciMmio32Base, PciBase);
> + PcdSet64 (PcdPciMmio32Size, PciSize);
> + AddIoMemoryBaseSizeHob (0xFEC00000, SIZE_4KB);
> + AddIoMemoryBaseSizeHob (0xFED00000, SIZE_1KB);
> + if (mHostBridgeDevId == INTEL_ICH10_DEVICE_ID) {
> + AddIoMemoryBaseSizeHob (ICH10_ROOT_COMPLEX_BASE, SIZE_16KB);
> + //
> + // Note: there should be an
> + //
> + // AddIoMemoryBaseSizeHob (PciExBarBase, SIZE_256MB);
> + // BuildMemoryAllocationHob (PciExBarBase, SIZE_256MB,
> EfiMemoryMappedIO);
> + //
> + // call below, just like the one above for RCBA. However, Linux insists
> + // that the MMCONFIG area be marked in the E820 or UEFI memory map as
> + // "reserved memory" -- Linux does not content itself with a simple gap
> + // in the memory map wherever the MCFG ACPI table points to.
> + //
> + // This appears to be a safety measure. The PCI Firmware Specification
> + // (rev 3.1) says in 4.1.2. "MCFG Table Description": "The resources can
> + // *optionally* be returned in [...] EFIGetMemoryMap as reserved memory
> + // [...]". (Emphasis added here.)
> + //
> + // Normally we add memory resource descriptor HOBs in
> + // QemuInitializeRam(), and pre-allocate from those with memory
> + // allocation HOBs in InitializeRamRegions(). However, the MMCONFIG area
> + // is most definitely not RAM; so, as an exception, cover it with
> + // uncacheable reserved memory right here.
> + //
> + AddReservedMemoryBaseSizeHob (PciExBarBase, SIZE_256MB, FALSE);
> + BuildMemoryAllocationHob (PciExBarBase, SIZE_256MB,
> + EfiReservedMemoryType);
> + }
> + AddIoMemoryBaseSizeHob (PcdGet32(PcdCpuLocalApicBaseAddress),
> SIZE_1MB);
> +
> + // Add PCI IO Port space available for PCI resource allocations.
> + //
> + BuildResourceDescriptorHob (
> + EFI_RESOURCE_IO,
> + EFI_RESOURCE_ATTRIBUTE_PRESENT |
> + EFI_RESOURCE_ATTRIBUTE_INITIALIZED,
> + PciIoBase,
> + PciIoSize
> + );
> + PcdSet64 (PcdPciIoBase, PciIoBase);
> + PcdSet64 (PcdPciIoSize, PciIoSize);
> +
> + //
> + // Add flash range.
> + //
> + AddFlashDeviceRange (PcdGet32(PcdFlashAreaBaseAddress),
> PcdGet32(PcdFlashAreaSize));
> + //
> + // Video memory / ABSEG
> + //
> + AddIoMemoryBaseSizeHob (0x0A0000, 0x20000);
> + //
> + // Legacy BIOS region.
> + //
> + AddReservedMemoryBaseSizeHob (0xC0000, 0x40000, TRUE);
> +}
> +
> +VOID
> +MiscInitialization (
> + VOID
> + )
> +{
> + UINTN PmCmd;
> + UINTN Pmba;
> + UINT32 PmbaAndVal;
> + UINT32 PmbaOrVal;
> + UINTN AcpiCtlReg;
> + UINT8 AcpiEnBit;
> +
> + //
> + // Disable A20 Mask
> + //
> + IoOr8 (0x92, BIT1);
> +
> + //
> + // Build the CPU HOB with guest RAM size dependent address width and 16-
> bits
> + // of IO space. (Side note: unlike other HOBs, the CPU HOB is needed during
> + // S3 resume as well, so we build it unconditionally.)
> + //
> + BuildCpuHob (mPhysMemAddressWidth, 16);
> +
> + //
> + // Determine platform type and save Host Bridge DID to PCD
> + //
> + switch (mHostBridgeDevId) {
> + case INTEL_82441_DEVICE_ID:
> + PmCmd = POWER_MGMT_REGISTER_PIIX4 (PCI_COMMAND_OFFSET);
> + Pmba = POWER_MGMT_REGISTER_PIIX4 (PIIX4_PMBA);
> + PmbaAndVal = ~(UINT32)PIIX4_PMBA_MASK;
> + PmbaOrVal = PIIX4_PMBA_VALUE;
> + AcpiCtlReg = POWER_MGMT_REGISTER_PIIX4 (PIIX4_PMREGMISC);
> + AcpiEnBit = PIIX4_PMREGMISC_PMIOSE;
> + break;
> + case INTEL_ICH10_DEVICE_ID:
> + PmCmd = POWER_MGMT_REGISTER_ICH10 (PCI_COMMAND_OFFSET);
> + Pmba = POWER_MGMT_REGISTER_ICH10 (ICH10_PMBASE);
> + PmbaAndVal = ~(UINT32)ICH10_PMBASE_MASK;
> + PmbaOrVal = ICH10_PMBASE_VALUE;
> + AcpiCtlReg = POWER_MGMT_REGISTER_ICH10 (ICH10_ACPI_CNTL);
> + AcpiEnBit = ICH10_ACPI_CNTL_ACPI_EN;
> + break;
> + default:
> + DEBUG ((EFI_D_ERROR, "%a: Unknown Host Bridge Device ID: 0x%04x\n",
> + __FUNCTION__, mHostBridgeDevId));
> + ASSERT (FALSE);
> + return;
> + }
> + PcdSet16 (PcdSimicsX58HostBridgePciDevId, mHostBridgeDevId);
> +
> + //
> + // If the appropriate IOspace enable bit is set, assume the ACPI PMBA
> + // has been configured and skip the setup here.
> + // This matches the logic in AcpiTimerLibConstructor ().
> + //
> + if ((PciRead8 (AcpiCtlReg) & AcpiEnBit) == 0) {
> + //
> + // The PEI phase should be exited with fully accessibe ACPI PM IO space:
> + // 1. set PMBA
> + //
> + PciAndThenOr32 (Pmba, PmbaAndVal, PmbaOrVal);
> +
> + //
> + // 2. set PCICMD/IOSE
> + //
> + PciOr8 (PmCmd, EFI_PCI_COMMAND_IO_SPACE);
> +
> + //
> + // 3. set ACPI PM IO enable bit (PMREGMISC:PMIOSE or
> ACPI_CNTL:ACPI_EN)
> + //
> + PciOr8 (AcpiCtlReg, AcpiEnBit);
> + }
> +
> + if (mHostBridgeDevId == INTEL_ICH10_DEVICE_ID) {
> + //
> + // Set Root Complex Register Block BAR
> + //
> + PciWrite32 (
> + POWER_MGMT_REGISTER_ICH10 (ICH10_RCBA),
> + ICH10_ROOT_COMPLEX_BASE | ICH10_RCBA_EN
> + );
> +
> + }
> + //
> + // Set the PM I/O base address to 0x400
> + //
> + PciAndThenOr32 (
> + PCI_LIB_ADDRESS (
> + 0,
> + 31,
> + 0,
> + 0x40
> + ),
> + (UINT32) ~0xfc0, ICH10_PMBASE_VALUE
> + );
> + //
> + // Enable AHCI and all ports on the SATA controller.
> + //
> + // Address MAP Reg, setting AHCI mode
> + //
> + PciOr16 (PCI_LIB_ADDRESS (0, 31, 2, 0x90), 0x0060);
> + //
> + //Enabling Ports 0-5
> + //
> + PciOr16 (PCI_LIB_ADDRESS (0, 31, 2, 0x92), 0x003F);
> + //
> + //Disabling Sata Controller 2, bit 25 = 1, bit 0 = 1
> + //
> + MmioWrite32(0xFED1F418, 0x02000001);
> + //
> + //Enable HPET at FED0_0000h – FED0_03FFh
> + //
> + MmioWrite8(ICH10_ROOT_COMPLEX_BASE + 0x3404, 0x80);
> + //
> + //Config and enable APIC
> + //
> + MmioWrite32(0xFEC00000 + 0X0, 0);
> + MmioWrite32(0xFEC00000 + 0X10, PcdGet8(PcdIoApicId)<<24);
> + MmioWrite8(ICH10_ROOT_COMPLEX_BASE + 0x31FF, 0x01);
> +}
> +
> +
> +VOID
> +BootModeInitialization (
> + VOID
> + )
> +{
> + EFI_STATUS Status;
> +
> + DEBUG((EFI_D_INFO, "modeValue = %x\n",
> IoBitFieldRead16(ICH10_PMBASE_IO + 4, 10, 12)));
> + if (IoBitFieldRead16(ICH10_PMBASE_IO + 4, 10, 12) == 0x5) {
> + mBootMode = BOOT_ON_S3_RESUME;
> + }
> +
> + Status = PeiServicesSetBootMode (mBootMode);
> + ASSERT_EFI_ERROR (Status);
> +
> + Status = PeiServicesInstallPpi (mPpiBootMode);
> + ASSERT_EFI_ERROR (Status);
> +}
> +
> +
> +VOID
> +ReserveEmuVariableNvStore (
> + )
> +{
> + EFI_PHYSICAL_ADDRESS VariableStore;
> +
> + //
> + // Allocate storage for NV variables early on so it will be
> + // at a consistent address. Since VM memory is preserved
> + // across reboots, this allows the NV variable storage to survive
> + // a VM reboot.
> + //
> + VariableStore =
> + (EFI_PHYSICAL_ADDRESS)(UINTN)
> + AllocateRuntimePages (
> + EFI_SIZE_TO_PAGES (2 * PcdGet32 (PcdFlashNvStorageFtwSpareSize))
> + );
> + DEBUG ((EFI_D_INFO,
> + "Reserved variable store memory: 0x%lX; size: %dkb\n",
> + VariableStore,
> + (2 * PcdGet32 (PcdFlashNvStorageFtwSpareSize)) / 1024
> + ));
> + PcdSet64 (PcdEmuVariableNvStoreReserved, VariableStore);
> +}
> +
> +
> +VOID
> +SimicsVersionCheck(
> + VOID
> + )
> +{
> +
> + UINTN PciAddrPtr;
> + UINT8 CapOffset;
> + STATIC CHAR8 SimicsStr[0x100];
> + UINTN i;
> + UINT32 MajorVersion;
> + UINT32 MinorVersion;
> + UINT32 ModelNumber;
> +
> + PciAddrPtr = PCI_LIB_ADDRESS(0, SIMICS_SIDEBANDPCI_DEV,
> SIMICS_SIDEBANDPCI_FUNC, 0);
> + CapOffset = PciRead8(PciAddrPtr + PCI_CAPBILITY_POINTER_OFFSET);
> + if (CapOffset != 0xFF) {
> + ModelNumber = PciRead32(PciAddrPtr + CapOffset + 4);
> + MajorVersion = PciRead32(PciAddrPtr + CapOffset + 8);
> + MinorVersion = PciRead32(PciAddrPtr + CapOffset + 0xc);
> + for (i = 0; i < 0x80; i++) {
> + SimicsStr[i] = PciRead8(PciAddrPtr + CapOffset + 0x10 + i);
> + }
> + DEBUG((EFI_D_INFO, "=============SIMICS Version
> info=============\n"));
> + DEBUG((EFI_D_INFO, "Model number = %d\n", ModelNumber));
> + DEBUG((EFI_D_INFO, "Major version = %d\n", MajorVersion));
> + DEBUG((EFI_D_INFO, "Minor version = %d\n", MinorVersion));
> + DEBUG((EFI_D_INFO, "%a\n", SimicsStr));
> + DEBUG((EFI_D_INFO,
> "=============================================\n"));
> + }
> +}
> +
> +VOID
> +DebugDumpCmos (
> + VOID
> + )
> +{
> + UINT32 Loop;
> +
> + DEBUG ((EFI_D_INFO, "CMOS:\n"));
> +
> + for (Loop = 0; Loop < 0x80; Loop++) {
> + if ((Loop % 0x10) == 0) {
> + DEBUG ((EFI_D_INFO, "%02x:", Loop));
> + }
> + DEBUG ((EFI_D_INFO, " %02x", CmosRead8 (Loop)));
> + if ((Loop % 0x10) == 0xf) {
> + DEBUG ((EFI_D_INFO, "\n"));
> + }
> + }
> +}
> +
> +
> +/**
> + Fetch the number of boot CPUs from QEMU and expose it to UefiCpuPkg
> modules.
> + Set the mMaxCpuCount variable.
> +**/
> +VOID
> +MaxCpuCountInitialization (
> + VOID
> + )
> +{
> + mMaxCpuCount = PcdGet32 (PcdCpuMaxLogicalProcessorNumber);
> + return;
> +}
> +
> +/**
> + Determine if S3 support is explicitly enabled.
> +
> + @retval TRUE If S3 support is explicitly enabled. Other functions in this
> + library may be called (subject to their individual
> + restrictions).
> +
> + FALSE Otherwise. This includes unavailability of the firmware
> + configuration interface. No other function in this library
> + must be called.
> +**/
> +BOOLEAN
> +EFIAPI
> +QemuFwCfgS3Enabled(
> + VOID
> +)
> +{
> + //TO DO IF NEEDED
> + return TRUE;
> +}
> +
> +/**
> + Perform Platform PEI initialization.
> +
> + @param FileHandle Handle of the file being invoked.
> + @param PeiServices Describes the list of possible PEI Services.
> +
> + @return EFI_SUCCESS The PEIM initialized successfully.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +InitializePlatform (
> + IN EFI_PEI_FILE_HANDLE FileHandle,
> + IN CONST EFI_PEI_SERVICES **PeiServices
> + )
> +{
> + EFI_STATUS Status;
> +
> + DEBUG ((EFI_D_ERROR, "Platform PEIM Loaded\n"));
> +
> + SimicsVersionCheck ();
> + DebugDumpCmos ();
> +
> + if (QemuFwCfgS3Enabled ()) {
> + DEBUG ((EFI_D_INFO, "S3 support was detected on SIMICS\n"));
> + mS3Supported = TRUE;
> + Status = PcdSetBoolS (PcdAcpiS3Enable, TRUE);
> + ASSERT_EFI_ERROR (Status);
> + }
> + AddressWidthInitialization ();
> + MaxCpuCountInitialization ();
> +
> + mHostBridgeDevId = PciRead16(SIMICS_HOSTBRIDGE_DID);
> +
> + if (FeaturePcdGet (PcdSmmSmramRequire)) {
> + X58TsegMbytesInitialization ();
> + }
> +
> + PublishPeiMemory ();
> +
> + InitializeRamRegions ();
> +
> + if (mBootMode != BOOT_ON_S3_RESUME) {
> + if (!FeaturePcdGet (PcdSmmSmramRequire)) {
> + ReserveEmuVariableNvStore ();
> + }
> + MemMapInitialization ();
> + }
> +
> + MiscInitialization ();
> + InstallFeatureControlCallback ();
> +
> + return EFI_SUCCESS;
> +}
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.
> c
> b/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.
> c
> new file mode 100644
> index 0000000000..7165c0a0c3
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.
> c
> @@ -0,0 +1,148 @@
> +/** @file
> + This driver installs SMBIOS information for QSP
> +
> + Copyright (c) 2011, Bei Guan <gbtju85@gmail.com>
> + Copyright (c) 2011 - 2019, Intel Corporation. All rights reserved.<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "SmbiosPlatformDxe.h"
> +
> +
> +/**
> +Reads 8-bits of CMOS data.
> +
> +Reads the 8-bits of CMOS data at the location specified by Index.
> +The 8-bit read value is returned.
> +
> +@param Index The CMOS location to read.
> +
> +@return The value read.
> +
> +**/
> +UINT8
> +EFIAPI
> +CmosRead8(
> + IN UINTN Index
> + )
> +{
> + IoWrite8(0x70, (UINT8)Index);
> + return IoRead8(0x71);
> +}
> +
> +UINT32
> +GetSystemMemorySizeBelow4gb(
> + VOID
> + )
> +{
> + UINT8 Cmos0x34;
> + UINT8 Cmos0x35;
> +
> + //
> + // CMOS 0x34/0x35 specifies the system memory above 16 MB.
> + // * CMOS(0x35) is the high byte
> + // * CMOS(0x34) is the low byte
> + // * The size is specified in 64kb chunks
> + // * Since this is memory above 16MB, the 16MB must be added
> + // into the calculation to get the total memory size.
> + //
> +
> + Cmos0x34 = (UINT8)CmosRead8(0x34);
> + Cmos0x35 = (UINT8)CmosRead8(0x35);
> +
> + return (UINT32)(((UINTN)((Cmos0x35 << 8) + Cmos0x34) << 16) + SIZE_16MB);
> +}
> +
> +STATIC
> +UINT64
> +GetSystemMemorySizeAbove4gb(
> + VOID
> +)
> +{
> + UINT32 Size;
> + UINTN CmosIndex;
> +
> + //
> + // CMOS 0x5b-0x5d specifies the system memory above 4GB MB.
> + // * CMOS(0x5d) is the most significant size byte
> + // * CMOS(0x5c) is the middle size byte
> + // * CMOS(0x5b) is the least significant size byte
> + // * The size is specified in 64kb chunks
> + //
> +
> + Size = 0;
> + for (CmosIndex = 0x5d; CmosIndex >= 0x5b; CmosIndex--) {
> + Size = (UINT32)(Size << 8) + (UINT32)CmosRead8(CmosIndex);
> + }
> +
> + return LShiftU64(Size, 16);
> +}
> +
> +/**
> + Installs SMBIOS information for SIMICS QSP
> +
> + @param ImageHandle Module's image handle
> + @param SystemTable Pointer of EFI_SYSTEM_TABLE
> +
> + @retval EFI_SUCCESS Smbios data successfully installed
> + @retval Other Smbios data was not installed
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SmbiosTablePublishEntry (
> + IN EFI_HANDLE ImageHandle,
> + IN EFI_SYSTEM_TABLE *SystemTable
> + )
> +{
> + EFI_STATUS Status;
> + EFI_SMBIOS_PROTOCOL *Smbios;
> + SMBIOS_TABLE_TYPE19 *Type19Record;
> + EFI_SMBIOS_HANDLE MemArrayMappedAddrSmbiosHandle;
> + UINT8 NumSlots;
> + UINT64 TotalMemorySize;
> +
> + //
> + // Find the SMBIOS protocol
> + //
> + Status = gBS->LocateProtocol (
> + &gEfiSmbiosProtocolGuid,
> + NULL,
> + (VOID**)&Smbios
> + );
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> + //
> + // Generate Memory Array Mapped Address info
> + //
> + NumSlots = 2;
> + TotalMemorySize = 0;
> + TotalMemorySize = GetSystemMemorySizeBelow4gb();
> + Type19Record = AllocatePool(sizeof(SMBIOS_TABLE_TYPE19));
> + ZeroMem(Type19Record, sizeof(SMBIOS_TABLE_TYPE19));
> + Type19Record->Hdr.Type =
> EFI_SMBIOS_TYPE_MEMORY_ARRAY_MAPPED_ADDRESS;
> + Type19Record->Hdr.Length = sizeof(SMBIOS_TABLE_TYPE19);
> + Type19Record->Hdr.Handle = 0;
> + Type19Record->StartingAddress = 0;
> + Type19Record->EndingAddress = (UINT32)RShiftU64(TotalMemorySize, 10) -
> 1;
> + Type19Record->MemoryArrayHandle = SMBIOS_HANDLE_PI_RESERVED;
> + Type19Record->PartitionWidth = (UINT8)(NumSlots);
> +
> + MemArrayMappedAddrSmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
> + Status = Smbios->Add(Smbios, NULL, &MemArrayMappedAddrSmbiosHandle,
> (EFI_SMBIOS_TABLE_HEADER*)Type19Record);
> + ASSERT_EFI_ERROR(Status);
> +
> + TotalMemorySize = GetSystemMemorySizeAbove4gb();
> + Type19Record->StartingAddress = 0xFFFFFFFF;
> + Type19Record->ExtendedStartingAddress = 0xFFFFFFFF;
> + Type19Record->ExtendedEndingAddress = TotalMemorySize + 0xFFFFFFFF - 1;
> +
> + MemArrayMappedAddrSmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
> + Status = Smbios->Add(Smbios, NULL, &MemArrayMappedAddrSmbiosHandle,
> (EFI_SMBIOS_TABLE_HEADER*)Type19Record);
> + FreePool(Type19Record);
> + ASSERT_EFI_ERROR(Status);
> +
> + return Status;
> +}
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Include/Guid/SimicsBoardConfig.h
> b/Platform/Intel/SimicsOpenBoardPkg/Include/Guid/SimicsBoardConfig.h
> new file mode 100644
> index 0000000000..acb2c4eee4
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/Include/Guid/SimicsBoardConfig.h
> @@ -0,0 +1,18 @@
> +/** @file
> + GUID for UEFI variables that are specific to Simics Board configuration.
> +
> + Copyright (C) 2014, Red Hat, Inc.
> + Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef __SIMICS_BOARD_CONFIG_H__
> +#define __SIMICS_BOARD_CONFIG_H__
> +
> +#define SIMICS_BOARD_CONFIG_GUID \
> +{0x8a318e00, 0xfaf5, 0x499f, { 0x91,0x75, 0xce, 0x4d, 0x8d, 0xa6, 0x70, 0xae}}
> +
> +extern EFI_GUID gSimicsBoardConfigGuid;
> +
> +#endif
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Include/IndustryStandard/I440FxPiix4.h
> b/Platform/Intel/SimicsOpenBoardPkg/Include/IndustryStandard/I440FxPiix4.h
> new file mode 100644
> index 0000000000..a2225493f7
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Include/IndustryStandard/I440FxPiix4.h
> @@ -0,0 +1,50 @@
> +/** @file
> + Various register numbers and value bits based on the following publications:
> + - Intel(R) datasheet 290549-001
> + - Intel(R) datasheet 290562-001
> + - Intel(R) datasheet 297654-006
> + - Intel(R) datasheet 297738-017
> +
> + Copyright (C) 2015, Red Hat, Inc.
> + Copyright (c) 2014, Gabriel L. Somlo <somlo@cmu.edu>
> + Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef __I440FX_PIIX4_H__
> +#define __I440FX_PIIX4_H__
> +
> +#include <Library/PciLib.h>
> +
> +//
> +// Host Bridge Device ID (DID) value for I440FX
> +//
> +#define INTEL_82441_DEVICE_ID 0x1237
> +
> +//
> +// B/D/F/Type: 0/0/0/PCI
> +//
> +#define PMC_REGISTER_PIIX4(Offset) PCI_LIB_ADDRESS (0, 0, 0, (Offset))
> +
> +#define PIIX4_PAM0 0x59
> +#define PIIX4_PAM1 0x5A
> +#define PIIX4_PAM2 0x5B
> +#define PIIX4_PAM3 0x5C
> +#define PIIX4_PAM4 0x5D
> +#define PIIX4_PAM5 0x5E
> +#define PIIX4_PAM6 0x5F
> +
> +//
> +// B/D/F/Type: 0/1/3/PCI
> +//
> +#define POWER_MGMT_REGISTER_PIIX4(Offset) PCI_LIB_ADDRESS (0, 1, 3,
> (Offset))
> +
> +#define PIIX4_PMBA 0x40
> +#define PIIX4_PMBA_MASK (BIT15 | BIT14 | BIT13 | BIT12 | BIT11 | \
> + BIT10 | BIT9 | BIT8 | BIT7 | BIT6)
> +
> +#define PIIX4_PMREGMISC 0x80
> +#define PIIX4_PMREGMISC_PMIOSE BIT0
> +
> +#endif
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Include/IndustryStandard/LinuxBzImage.
> h
> b/Platform/Intel/SimicsOpenBoardPkg/Include/IndustryStandard/LinuxBzImage.
> h
> new file mode 100644
> index 0000000000..2708b1891d
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Include/IndustryStandard/LinuxBzImage.
> h
> @@ -0,0 +1,159 @@
> +/** @file
> +
> + Copyright (c) 2011 - 2019, Intel Corporation. All rights reserved.<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef __LINUX_BZIMAGE_H__
> +#define __LINUX_BZIMAGE_H__
> +
> +#define BOOTSIG 0x1FE
> +#define SETUP_HDR 0x53726448 /* 0x53726448 == "HdrS" */
> +
> +#define E820_RAM 1
> +#define E820_RESERVED 2
> +#define E820_ACPI 3
> +#define E820_NVS 4
> +#define E820_UNUSABLE 5
> +
> +#pragma pack(1)
> +
> +struct setup_header {
> + UINT8 setup_secs; /* Sectors for setup code */
> + UINT16 root_flags;
> + UINT32 sys_size;
> + UINT16 ram_size;
> + UINT16 video_mode;
> + UINT16 root_dev;
> + UINT16 signature; /* Boot signature */
> + UINT16 jump;
> + UINT32 header;
> + UINT16 version;
> + UINT16 su_switch;
> + UINT16 setup_seg;
> + UINT16 start_sys;
> + UINT16 kernel_ver;
> + UINT8 loader_id;
> + UINT8 load_flags;
> + UINT16 movesize;
> + UINT32 code32_start; /* Start of code loaded high */
> + UINT32 ramdisk_start; /* Start of initial ramdisk */
> + UINT32 ramdisk_len; /* Length of initial ramdisk */
> + UINT32 bootsect_kludge;
> + UINT16 heap_end;
> + UINT8 ext_loader_ver; /* Extended boot loader version */
> + UINT8 ext_loader_type; /* Extended boot loader ID */
> + UINT32 cmd_line_ptr; /* 32-bit pointer to the kernel command line */
> + UINT32 ramdisk_max; /* Highest legal initrd address */
> + UINT32 kernel_alignment; /* Physical addr alignment required for kernel */
> + UINT8 relocatable_kernel; /* Whether kernel is relocatable or not */
> + UINT8 min_alignment;
> + UINT16 xloadflags;
> + UINT32 cmdline_size;
> + UINT32 hardware_subarch;
> + UINT64 hardware_subarch_data;
> + UINT32 payload_offset;
> + UINT32 payload_length;
> + UINT64 setup_data;
> + UINT64 pref_address;
> + UINT32 init_size;
> + UINT32 handover_offset;
> +};
> +
> +struct efi_info {
> + UINT32 efi_loader_signature;
> + UINT32 efi_systab;
> + UINT32 efi_memdesc_size;
> + UINT32 efi_memdesc_version;
> + UINT32 efi_memmap;
> + UINT32 efi_memmap_size;
> + UINT32 efi_systab_hi;
> + UINT32 efi_memmap_hi;
> +};
> +
> +struct e820_entry {
> + UINT64 addr; /* start of memory segment */
> + UINT64 size; /* size of memory segment */
> + UINT32 type; /* type of memory segment */
> +};
> +
> +struct screen_info {
> + UINT8 orig_x; /* 0x00 */
> + UINT8 orig_y; /* 0x01 */
> + UINT16 ext_mem_k; /* 0x02 */
> + UINT16 orig_video_page; /* 0x04 */
> + UINT8 orig_video_mode; /* 0x06 */
> + UINT8 orig_video_cols; /* 0x07 */
> + UINT8 flags; /* 0x08 */
> + UINT8 unused2; /* 0x09 */
> + UINT16 orig_video_ega_bx;/* 0x0a */
> + UINT16 unused3; /* 0x0c */
> + UINT8 orig_video_lines; /* 0x0e */
> + UINT8 orig_video_isVGA; /* 0x0f */
> + UINT16 orig_video_points;/* 0x10 */
> +
> + /* VESA graphic mode -- linear frame buffer */
> + UINT16 lfb_width; /* 0x12 */
> + UINT16 lfb_height; /* 0x14 */
> + UINT16 lfb_depth; /* 0x16 */
> + UINT32 lfb_base; /* 0x18 */
> + UINT32 lfb_size; /* 0x1c */
> + UINT16 cl_magic, cl_offset; /* 0x20 */
> + UINT16 lfb_linelength; /* 0x24 */
> + UINT8 red_size; /* 0x26 */
> + UINT8 red_pos; /* 0x27 */
> + UINT8 green_size; /* 0x28 */
> + UINT8 green_pos; /* 0x29 */
> + UINT8 blue_size; /* 0x2a */
> + UINT8 blue_pos; /* 0x2b */
> + UINT8 rsvd_size; /* 0x2c */
> + UINT8 rsvd_pos; /* 0x2d */
> + UINT16 vesapm_seg; /* 0x2e */
> + UINT16 vesapm_off; /* 0x30 */
> + UINT16 pages; /* 0x32 */
> + UINT16 vesa_attributes; /* 0x34 */
> + UINT32 capabilities; /* 0x36 */
> + UINT8 _reserved[6]; /* 0x3a */
> +};
> +
> +struct boot_params {
> +struct screen_info screen_info;
> + UINT8 apm_bios_info[0x14];
> + UINT8 _pad2[4];
> + UINT64 tboot_addr;
> + UINT8 ist_info[0x10];
> + UINT8 _pad3[16];
> + UINT8 hd0_info[16];
> + UINT8 hd1_info[16];
> + UINT8 sys_desc_table[0x10];
> + UINT8 olpc_ofw_header[0x10];
> + UINT8 _pad4[128];
> + UINT8 edid_info[0x80];
> + struct efi_info efi_info;
> + UINT32 alt_mem_k;
> + UINT32 scratch;
> + UINT8 e820_entries;
> + UINT8 eddbuf_entries;
> + UINT8 edd_mbr_sig_buf_entries;
> + UINT8 _pad6[6];
> + struct setup_header hdr;
> + UINT8 _pad7[0x290-0x1f1-sizeof(struct setup_header)];
> + UINT32 edd_mbr_sig_buffer[16];
> + struct e820_entry e820_map[128];
> + UINT8 _pad8[48];
> + UINT8 eddbuf[0x1ec];
> + UINT8 _pad9[276];
> +};
> +
> +typedef struct {
> + UINT16 limit;
> + UINT64 *base;
> +} dt_addr_t;
> +
> +#pragma pack()
> +
> +extern EFI_STATUS setup_graphics(struct boot_params *buf);
> +
> +#endif /* __LINUX_BZIMAGE_H__ */
> diff --git a/Platform/Intel/SimicsOpenBoardPkg/Include/Library/LoadLinuxLib.h
> b/Platform/Intel/SimicsOpenBoardPkg/Include/Library/LoadLinuxLib.h
> new file mode 100644
> index 0000000000..483f8d4b9c
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/Include/Library/LoadLinuxLib.h
> @@ -0,0 +1,205 @@
> +/** @file
> + Load/boot UEFI Linux.
> +
> + Copyright (c) 2011 - 2013, Intel Corporation. All rights reserved.<BR>
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef __LOAD_LINUX_LIB__
> +#define __LOAD_LINUX_LIB__
> +
> +
> +/**
> + Verifies that the kernel setup image is valid and supported.
> + The kernel setup image should be checked before using other library
> + routines which take the kernel setup as an input.
> +
> + @param[in] KernelSetup - The kernel setup image
> + @param[in] KernelSetupSize - The kernel setup size
> +
> + @retval EFI_SUCCESS - The Linux kernel setup is valid and supported
> + @retval EFI_INVALID_PARAMETER - KernelSetup was NULL
> + @retval EFI_UNSUPPORTED - The Linux kernel is not supported
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +LoadLinuxCheckKernelSetup (
> + IN VOID *KernelSetup,
> + IN UINTN KernelSetupSize
> + );
> +
> +
> +/**
> + Gets the initial runtime size of the Linux kernel image by examining
> + the kernel setup image.
> +
> + @param[in] KernelSetup - The kernel setup image
> + @param[in] KernelSize - The kernel size on disk.
> +
> + @retval 0 An error occurred
> + @retval !0 The initial size required by the kernel to
> + begin execution.
> +
> +**/
> +UINTN
> +EFIAPI
> +LoadLinuxGetKernelSize (
> + IN VOID *KernelSetup,
> + IN UINTN KernelSize
> + );
> +
> +
> +/**
> + Loads and boots UEFI Linux.
> +
> + Note: If successful, then this routine will not return
> +
> + @param[in] Kernel - The main kernel image
> + @param[in,out] KernelSetup - The kernel setup image
> +
> + @retval EFI_NOT_FOUND - The Linux kernel was not found
> + @retval EFI_INVALID_PARAMETER - Kernel or KernelSetup was NULL
> + @retval EFI_UNSUPPORTED - The Linux kernel version is not supported
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +LoadLinux (
> + IN VOID *Kernel,
> + IN OUT VOID *KernelSetup
> + );
> +
> +
> +/**
> + Allocates pages for the kernel setup image.
> +
> + @param[in] Pages - The number of pages
> +
> + @retval NULL - Unable to allocate pages
> + @retval !NULL - The address of the pages allocated
> +
> +**/
> +VOID*
> +EFIAPI
> +LoadLinuxAllocateKernelSetupPages (
> + IN UINTN Pages
> + );
> +
> +
> +/**
> + Clears the uninitialised space before and after the struct setup_header
> + in the kernel setup image. The kernel requires that these be zeroed
> + unless explicitly initialised, so this function should be called after
> + the setup_header has been copied in from a bzImage, before setting up
> + anything else.
> +
> + @param[in] KernelSetup - The kernel setup image
> +
> + @retval EFI_SUCCESS - The Linux kernel setup was successfully initialized
> + @retval EFI_INVALID_PARAMETER - KernelSetup was NULL
> + @retval EFI_UNSUPPORTED - The Linux kernel is not supported
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +LoadLinuxInitializeKernelSetup (
> + IN VOID *KernelSetup
> + );
> +
> +/**
> + Allocates pages for the kernel.
> +
> + @param[in] KernelSetup - The kernel setup image
> + @param[in] Pages - The number of pages. (It is recommended to use the
> + size returned from LoadLinuxGetKernelSize.)
> +
> + @retval NULL - Unable to allocate pages
> + @retval !NULL - The address of the pages allocated
> +
> +**/
> +VOID*
> +EFIAPI
> +LoadLinuxAllocateKernelPages (
> + IN VOID *KernelSetup,
> + IN UINTN Pages
> + );
> +
> +
> +/**
> + Allocates pages for the kernel command line.
> +
> + @param[in] Pages - The number of pages.
> +
> + @retval NULL - Unable to allocate pages
> + @retval !NULL - The address of the pages allocated
> +
> +**/
> +VOID*
> +EFIAPI
> +LoadLinuxAllocateCommandLinePages (
> + IN UINTN Pages
> + );
> +
> +
> +/**
> + Allocates pages for the initrd image.
> +
> + @param[in,out] KernelSetup - The kernel setup image
> + @param[in] Pages - The number of pages.
> +
> + @retval NULL - Unable to allocate pages
> + @retval !NULL - The address of the pages allocated
> +
> +**/
> +VOID*
> +EFIAPI
> +LoadLinuxAllocateInitrdPages (
> + IN VOID *KernelSetup,
> + IN UINTN Pages
> + );
> +
> +
> +/**
> + Sets the kernel command line parameter within the setup image.
> +
> + @param[in,out] KernelSetup - The kernel setup image
> + @param[in] CommandLine - The kernel command line
> +
> + @retval EFI_SUCCESS - The Linux kernel setup is valid and supported
> + @retval EFI_INVALID_PARAMETER - KernelSetup was NULL
> + @retval EFI_UNSUPPORTED - The Linux kernel is not supported
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +LoadLinuxSetCommandLine (
> + IN OUT VOID *KernelSetup,
> + IN CHAR8 *CommandLine
> + );
> +
> +
> +/**
> + Sets the kernel initial ram disk pointer within the setup image.
> +
> + @param[in,out] KernelSetup - The kernel setup image
> + @param[in] Initrd - Pointer to the initial ram disk
> + @param[in] InitrdSize - The initial ram disk image size
> +
> + @retval EFI_SUCCESS - The Linux kernel setup is valid and supported
> + @retval EFI_INVALID_PARAMETER - KernelSetup was NULL
> + @retval EFI_UNSUPPORTED - The Linux kernel is not supported
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +LoadLinuxSetInitrd (
> + IN OUT VOID *KernelSetup,
> + IN VOID *Initrd,
> + IN UINTN InitrdSize
> + );
> +
> +
> +#endif
> +
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Include/Library/SerializeVariablesLib.h
> b/Platform/Intel/SimicsOpenBoardPkg/Include/Library/SerializeVariablesLib.h
> new file mode 100644
> index 0000000000..c32f97d787
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Include/Library/SerializeVariablesLib.h
> @@ -0,0 +1,224 @@
> +/** @file
> + Serialize & Deserialize UEFI Variables
> +
> + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef __SERIALIZE_VARIABLES_LIB__
> +#define __SERIALIZE_VARIABLES_LIB__
> +
> +
> +/**
> + Callback function for each variable
> +
> + @param[in] Context - Context as sent to the iteration function
> + @param[in] VariableName - Refer to RuntimeServices GetNextVariableName
> + @param[in] VendorGuid - Refer to RuntimeServices GetNextVariableName
> + @param[in] Attributes - Refer to RuntimeServices GetVariable
> + @param[in] DataSize - Refer to RuntimeServices GetVariable
> + @param[in] Data - Refer to RuntimeServices GetVariable
> +
> + @retval RETURN_SUCCESS Continue iterating through the variables
> + @return Any RETURN_ERROR Stop iterating through the variables
> +
> +**/
> +typedef
> +RETURN_STATUS
> +(EFIAPI *VARIABLE_SERIALIZATION_ITERATION_CALLBACK)(
> + IN VOID *Context,
> + IN CHAR16 *VariableName,
> + IN EFI_GUID *VendorGuid,
> + IN UINT32 Attributes,
> + IN UINTN DataSize,
> + IN VOID *Data
> + );
> +
> +
> +/**
> + Creates a new variable serialization instance
> +
> + @param[out] Handle - Handle for a variable serialization instance
> +
> + @retval RETURN_SUCCESS - The variable serialization instance was
> + successfully created.
> + @retval RETURN_OUT_OF_RESOURCES - There we not enough resources
> to
> + create the variable serialization instance.
> +
> +**/
> +RETURN_STATUS
> +EFIAPI
> +SerializeVariablesNewInstance (
> + OUT EFI_HANDLE *Handle
> + );
> +
> +
> +/**
> + Free memory associated with a variable serialization instance
> +
> + @param[in] Handle - Handle for a variable serialization instance
> +
> + @retval RETURN_SUCCESS - The variable serialization instance was
> + successfully freed.
> + @retval RETURN_INVALID_PARAMETER - Handle was not a valid
> + variable serialization instance.
> +
> +**/
> +RETURN_STATUS
> +EFIAPI
> +SerializeVariablesFreeInstance (
> + IN EFI_HANDLE Handle
> + );
> +
> +
> +/**
> + Creates a new variable serialization instance using the given
> + binary representation of the variables to fill the new instance
> +
> + @param[out] Handle - Handle for a variable serialization instance
> + @param[in] Buffer - A buffer with the serialized representation
> + of the variables. Must be the same format as produced
> + by SerializeVariablesToBuffer.
> + @param[in] Size - This is the size of the binary representation
> + of the variables.
> +
> + @retval RETURN_SUCCESS - The binary representation was successfully
> + imported into a new variable serialization instance
> + @retval RETURN_OUT_OF_RESOURCES - There we not enough resources
> to
> + create the new variable serialization instance
> +
> +**/
> +RETURN_STATUS
> +EFIAPI
> +SerializeVariablesNewInstanceFromBuffer (
> + OUT EFI_HANDLE *Handle,
> + IN VOID *Buffer,
> + IN UINTN Size
> + );
> +
> +
> +/**
> + Iterates all variables found with RuntimeServices GetNextVariableName
> +
> + @param[in] CallbackFunction - Function called for each variable instance
> + @param[in] Context - Passed to each call of CallbackFunction
> +
> + @retval RETURN_SUCCESS - All variables were iterated without the
> + CallbackFunction returning an error
> + @retval RETURN_OUT_OF_RESOURCES - There we not enough resources
> to
> + iterate through the variables
> + @return Any of RETURN_ERROR indicates an error reading the variable
> + or an error was returned from CallbackFunction
> +
> +**/
> +RETURN_STATUS
> +EFIAPI
> +SerializeVariablesIterateSystemVariables (
> + IN VARIABLE_SERIALIZATION_ITERATION_CALLBACK CallbackFunction,
> + IN VOID *Context
> + );
> +
> +
> +/**
> + Iterates all variables found in the variable serialization instance
> +
> + @param[in] Handle - Handle for a variable serialization instance
> + @param[in] CallbackFunction - Function called for each variable instance
> + @param[in] Context - Passed to each call of CallbackFunction
> +
> + @retval RETURN_SUCCESS - All variables were iterated without the
> + CallbackFunction returning an error
> + @retval RETURN_OUT_OF_RESOURCES - There we not enough resources
> to
> + iterate through the variables
> + @return Any of RETURN_ERROR indicates an error reading the variable
> + or an error was returned from CallbackFunction
> +
> +**/
> +RETURN_STATUS
> +EFIAPI
> +SerializeVariablesIterateInstanceVariables (
> + IN EFI_HANDLE Handle,
> + IN VARIABLE_SERIALIZATION_ITERATION_CALLBACK CallbackFunction,
> + IN VOID *Context
> + );
> +
> +
> +/**
> + Sets all variables found in the variable serialization instance
> +
> + @param[in] Handle - Handle for a variable serialization instance
> +
> + @retval RETURN_SUCCESS - All variables were set successfully
> + @retval RETURN_OUT_OF_RESOURCES - There we not enough resources
> to
> + set all the variables
> + @return Any of RETURN_ERROR indicates an error reading the variables
> + or in attempting to set a variable
> +
> +**/
> +RETURN_STATUS
> +EFIAPI
> +SerializeVariablesSetSerializedVariables (
> + IN EFI_HANDLE Handle
> + );
> +
> +
> +/**
> + Adds a variable to the variable serialization instance
> +
> + @param[in] Handle - Handle for a variable serialization instance
> + @param[in] VariableName - Refer to RuntimeServices GetVariable
> + @param[in] VendorGuid - Refer to RuntimeServices GetVariable
> + @param[in] Attributes - Refer to RuntimeServices GetVariable
> + @param[in] DataSize - Refer to RuntimeServices GetVariable
> + @param[in] Data - Refer to RuntimeServices GetVariable
> +
> + @retval RETURN_SUCCESS - All variables were set successfully
> + @retval RETURN_OUT_OF_RESOURCES - There we not enough resources
> to
> + add the variable
> +
> +**/
> +RETURN_STATUS
> +EFIAPI
> +SerializeVariablesAddVariable (
> + IN EFI_HANDLE Handle,
> + IN CHAR16 *VariableName,
> + IN EFI_GUID *VendorGuid,
> + IN UINT32 Attributes,
> + IN UINTN DataSize,
> + IN VOID *Data
> + );
> +
> +
> +/**
> + Serializes the variables known to this instance into the
> + provided buffer.
> +
> + @param[in] Handle - Handle for a variable serialization instance
> + @param[out] Buffer - A buffer to store the binary representation
> + of the variables.
> + @param[in,out] Size - On input this is the size of the buffer.
> + On output this is the size of the binary representation
> + of the variables.
> +
> + @retval RETURN_SUCCESS - The binary representation was successfully
> + completed and returned in the buffer.
> + @retval RETURN_OUT_OF_RESOURCES - There we not enough resources
> to
> + save the variables to the buffer.
> + @retval RETURN_INVALID_PARAMETER - Handle was not a valid
> + variable serialization instance or
> + Size or Buffer were NULL.
> +
> +**/
> +RETURN_STATUS
> +EFIAPI
> +SerializeVariablesToBuffer (
> + IN EFI_HANDLE Handle,
> + OUT VOID *Buffer,
> + IN OUT UINTN *Size
> + );
> +
> +
> +#endif
> +
> diff --git a/Platform/Intel/SimicsOpenBoardPkg/Include/SimicsPlatforms.h
> b/Platform/Intel/SimicsOpenBoardPkg/Include/SimicsPlatforms.h
> new file mode 100644
> index 0000000000..67bb3af584
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/Include/SimicsPlatforms.h
> @@ -0,0 +1,55 @@
> +/** @file
> + Simics Platform definitions
> +
> + Copyright (C) 2015, Red Hat, Inc.
> + Copyright (c) 2014, Gabriel L. Somlo <somlo@cmu.edu>
> + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef __SIMICS_PLATFORMS_H__
> +#define __SIMICS_PLATFORMS_H__
> +
> +#include <Library/PciLib.h>
> +#include <IndustryStandard/Pci22.h>
> +#include <Register/X58Ich10.h>
> +#include <IndustryStandard/I440FxPiix4.h>
> +
> +//
> +// Simics Host Bridge DID Address
> +//
> +#define SIMICS_HOSTBRIDGE_DID \
> + PCI_LIB_ADDRESS (0, 0, 0, PCI_DEVICE_ID_OFFSET)
> +
> +//
> +// Simics SideBand PCI device registers
> +//
> +#define SIMICS_SIDEBANDPCI_DEV 0
> +#define SIMICS_SIDEBANDPCI_FUNC 7
> +#define SIMICS_SIDEBANDPCI_SVID \
> + PCI_LIB_ADDRESS (0, 0, 7, PCI_SVID_OFFSET)
> +#define SIMICS_SIDEBANDPCI_SDID \
> + PCI_LIB_ADDRESS (0, 0, 7, PCI_SID_OFFSET)
> +#define SIMICS_SIDEBANDPCI_CAP \
> + PCI_LIB_ADDRESS (0, 0, 7, PCI_CAPBILITY_POINTER_OFFSET)
> +#define SIMICS_SIDEBANDPCI_CAP_Offset 0x40
> +#define SIMICS_SIDEBANDPCI_CAP_ID 0xFF
> +
> +//
> +// Values we program into the PM base address registers
> +//
> +#define PIIX4_PMBA_VALUE 0xB000
> +#define ICH10_PMBASE_VALUE 0x0400
> +
> +//
> +// Common bits in same-purpose registers
> +//
> +#define PMBA_RTE BIT0
> +
> +//
> +// Common IO ports relative to the Power Management Base Address
> +//
> +#define ACPI_TIMER_OFFSET 0x8
> +
> +#endif
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Library/DxeLogoLib/DxeLogoLib.inf
> b/Platform/Intel/SimicsOpenBoardPkg/Library/DxeLogoLib/DxeLogoLib.inf
> new file mode 100644
> index 0000000000..ff08c385b3
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/Library/DxeLogoLib/DxeLogoLib.inf
> @@ -0,0 +1,55 @@
> +### @file
> +# Module that show progress bar and title above it.
> +#
> +# General BDS defines and produce general interfaces for platform BDS driver
> including:
> +# 1) BDS boot policy interface;
> +# 2) BDS boot device connect interface;
> +# 3) BDS Misc interfaces for mainting boot variable, ouput string, etc.
> +#
> +# Copyright (c) 2007 - 2019 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +###
> +
> +[Defines]
> + INF_VERSION = 0x00010017
> + BASE_NAME = DxeLogoLib
> + FILE_GUID = F5AE5B5C-42E8-4A9B-829D-5B631CD5367A
> + VERSION_STRING = 1.0
> + MODULE_TYPE = DXE_DRIVER
> + LIBRARY_CLASS = LogoLib|DXE_DRIVER UEFI_APPLICATION
> +#
> +# The following information is for reference only and not required by the build
> tools.
> +#
> +# VALID_ARCHITECTURES = IA32 X64 IPF EBC
> +#
> +
> +[LibraryClasses]
> + BaseLib
> + UefiBootServicesTableLib
> + MemoryAllocationLib
> + UefiLib
> + BaseMemoryLib
> + DebugLib
> + PrintLib
> + PcdLib
> + DxeServicesLib
> +
> +[Packages]
> + MdePkg/MdePkg.dec
> + MdeModulePkg/MdeModulePkg.dec
> + SimicsOpenBoardPkg/OpenBoardPkg.dec
> +
> +[FeaturePcd]
> + gEfiMdePkgTokenSpaceGuid.PcdUgaConsumeSupport
> +
> +[Sources]
> + Logo.c
> +
> +[Protocols]
> + gEfiGraphicsOutputProtocolGuid ## SOMETIMES_CONSUMES
> + gEfiUgaDrawProtocolGuid ## SOMETIMES_CONSUMES
> + gEfiBootLogoProtocolGuid ## SOMETIMES_CONSUMES
> + gEfiUserManagerProtocolGuid ## CONSUMES
> + gEfiOemBadgingProtocolGuid ## CONSUMES
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Library/DxeLogoLib/OemBadging.h
> b/Platform/Intel/SimicsOpenBoardPkg/Library/DxeLogoLib/OemBadging.h
> new file mode 100644
> index 0000000000..d2c39c3dfc
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/Library/DxeLogoLib/OemBadging.h
> @@ -0,0 +1,83 @@
> +/** @file
> + The OEM Badging Protocol defines the interface to get the OEM badging
> + image with the display attribute. This protocol can be produced based on OEM
> badging images.
> +
> + Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef __EFI_OEM_BADGING_H__
> +#define __EFI_OEM_BADGING_H__
> +
> +//
> +// GUID for EFI OEM Badging Protocol
> +//
> +#define EFI_OEM_BADGING_PROTOCOL_GUID \
> + { 0x170e13c0, 0xbf1b, 0x4218, {0x87, 0x1d, 0x2a, 0xbd, 0xc6, 0xf8, 0x87,
> 0xbc } }
> +
> +
> +typedef struct _EFI_OEM_BADGING_PROTOCOL
> EFI_OEM_BADGING_PROTOCOL;
> +
> +typedef enum {
> + EfiBadgingFormatBMP,
> + EfiBadgingFormatJPEG,
> + EfiBadgingFormatTIFF,
> + EfiBadgingFormatGIF,
> + EfiBadgingFormatUnknown
> +} EFI_BADGING_FORMAT;
> +
> +typedef enum {
> + EfiBadgingDisplayAttributeLeftTop,
> + EfiBadgingDisplayAttributeCenterTop,
> + EfiBadgingDisplayAttributeRightTop,
> + EfiBadgingDisplayAttributeCenterRight,
> + EfiBadgingDisplayAttributeRightBottom,
> + EfiBadgingDisplayAttributeCenterBottom,
> + EfiBadgingDisplayAttributeLeftBottom,
> + EfiBadgingDisplayAttributeCenterLeft,
> + EfiBadgingDisplayAttributeCenter,
> + EfiBadgingDisplayAttributeCustomized
> +} EFI_BADGING_DISPLAY_ATTRIBUTE;
> +
> +/**
> +
> + Load an OEM badge image and return its data and attributes.
> +
> + @param This The pointer to this protocol instance.
> + @param Instance The visible image instance is found.
> + @param Format The format of the image. Examples: BMP, JPEG.
> + @param ImageData The image data for the badge file. Currently only
> + supports the .bmp file format.
> + @param ImageSize The size of the image returned.
> + @param Attribute The display attributes of the image returned.
> + @param CoordinateX The X coordinate of the image.
> + @param CoordinateY The Y coordinate of the image.
> +
> + @retval EFI_SUCCESS The image was fetched successfully.
> + @retval EFI_NOT_FOUND The specified image could not be found.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_BADGING_GET_IMAGE)(
> + IN EFI_OEM_BADGING_PROTOCOL *This,
> + IN OUT UINT32 *Instance,
> + OUT EFI_BADGING_FORMAT *Format,
> + OUT UINT8 **ImageData,
> + OUT UINTN *ImageSize,
> + OUT EFI_BADGING_DISPLAY_ATTRIBUTE *Attribute,
> + OUT UINTN *CoordinateX,
> + OUT UINTN *CoordinateY
> +);
> +
> +
> +struct _EFI_OEM_BADGING_PROTOCOL {
> + EFI_BADGING_GET_IMAGE GetImage;
> +};
> +
> +
> +extern EFI_GUID gEfiOemBadgingProtocolGuid;
> +
> +#endif
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/DxeLoadLinuxLib.in
> f
> b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/DxeLoadLinuxLib.in
> f
> new file mode 100644
> index 0000000000..cdefeebbdd
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/DxeLoadLinuxLib.in
> f
> @@ -0,0 +1,42 @@
> +## @file
> +#
> +# Copyright (c) 2008 - 2019 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> + INF_VERSION = 0x00010005
> + BASE_NAME = DxeLoadLinuxLib
> + FILE_GUID = 63CC8497-C9D0-46A8-AC08-49DF92A2FF62
> + MODULE_TYPE = BASE
> + VERSION_STRING = 1.0
> + LIBRARY_CLASS = DxeLoadLinuxLib|DXE_DRIVER
> +
> +#
> +# The following information is for reference only and not required by the build
> tools.
> +#
> +# VALID_ARCHITECTURES = IA32 X64
> +#
> +
> +[Sources.common]
> + Linux.c
> + LinuxGdt.c
> +
> +[Sources.IA32]
> + Ia32/JumpToKernel.nasm
> +
> +[Sources.X64]
> + X64/JumpToKernel.nasm
> +
> +[Packages]
> + MdePkg/MdePkg.dec
> + SimicsOpenBoardPkg/OpenBoardPkg.dec
> +
> +[LibraryClasses]
> + BaseLib
> + DebugLib
> + MemoryAllocationLib
> + BaseMemoryLib
> +
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/Ia32/JumpToKerne
> l.nasm
> b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/Ia32/JumpToKerne
> l.nasm
> new file mode 100644
> index 0000000000..c6f1c31a59
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/Ia32/JumpToKerne
> l.nasm
> @@ -0,0 +1,41 @@
> +; @file
> +; Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved. <BR>
> +;
> +; SPDX-License-Identifier: BSD-2-Clause-Patent
> +;
> +
> + SECTION .text
> +
> +;------------------------------------------------------------------------------
> +; VOID
> +; EFIAPI
> +; JumpToKernel (
> +; VOID *KernelStart,
> +; VOID *KernelBootParams
> +; );
> +;------------------------------------------------------------------------------
> +global ASM_PFX(JumpToKernel)
> +ASM_PFX(JumpToKernel):
> +
> + mov esi, [esp + 8]
> + call DWORD [esp + 4]
> + ret
> +
> +;------------------------------------------------------------------------------
> +; VOID
> +; EFIAPI
> +; JumpToUefiKernel (
> +; EFI_HANDLE ImageHandle,
> +; EFI_SYSTEM_TABLE *SystemTable,
> +; VOID *KernelBootParams,
> +; VOID *KernelStart
> +; );
> +;------------------------------------------------------------------------------
> +global ASM_PFX(JumpToUefiKernel)
> +ASM_PFX(JumpToUefiKernel):
> +
> + mov eax, [esp + 12]
> + mov eax, [eax + 0x264]
> + add eax, [esp + 16]
> + jmp eax
> +
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/LoadLinuxLib.h
> b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/LoadLinuxLib.h
> new file mode 100644
> index 0000000000..9c0ab80904
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/LoadLinuxLib.h
> @@ -0,0 +1,52 @@
> +/** @file
> + Boot UEFI Linux.
> +
> + Copyright (c) 2008 - 2019 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _LOAD_LINUX_LIB_INCLUDED_
> +#define _LOAD_LINUX_LIB_INCLUDED_
> +
> +#include <Uefi.h>
> +#include <Library/LoadLinuxLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiRuntimeServicesTableLib.h>
> +
> +#include <IndustryStandard/LinuxBzImage.h>
> +
> +#include <Protocol/GraphicsOutput.h>
> +
> +VOID
> +EFIAPI
> +JumpToKernel (
> + VOID *KernelStart,
> + VOID *KernelBootParams
> + );
> +
> +VOID
> +EFIAPI
> +JumpToUefiKernel (
> + EFI_HANDLE ImageHandle,
> + EFI_SYSTEM_TABLE *SystemTable,
> + VOID *KernelBootParams,
> + VOID *KernelStart
> + );
> +
> +VOID
> +InitLinuxDescriptorTables (
> + VOID
> + );
> +
> +VOID
> +SetLinuxDescriptorTables (
> + VOID
> + );
> +
> +#endif
> +
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/X64/JumpToKernel
> .nasm
> b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/X64/JumpToKernel
> .nasm
> new file mode 100644
> index 0000000000..2b5395f6f8
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/X64/JumpToKernel
> .nasm
> @@ -0,0 +1,85 @@
> +; @file
> +; Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved. <BR>
> +;
> +; SPDX-License-Identifier: BSD-2-Clause-Patent
> +;
> +
> + DEFAULT REL
> + SECTION .text
> +
> +;------------------------------------------------------------------------------
> +; VOID
> +; EFIAPI
> +; JumpToKernel (
> +; VOID *KernelStart, // rcx
> +; VOID *KernelBootParams // rdx
> +; );
> +;------------------------------------------------------------------------------
> +global ASM_PFX(JumpToKernel)
> +ASM_PFX(JumpToKernel):
> +
> + ; Set up for executing kernel. BP in %esi, entry point on the stack
> + ; (64-bit when the 'ret' will use it as 32-bit, but we're little-endian)
> + mov rsi, rdx
> + push rcx
> +
> + ; Jump into the compatibility mode CS
> + push 0x10
> + lea rax, [.0]
> + push rax
> + DB 0x48, 0xcb ; retfq
> +
> +.0:
> + ; Now in compatibility mode.
> +
> + DB 0xb8, 0x18, 0x0, 0x0, 0x0 ; movl $0x18, %eax
> + DB 0x8e, 0xd8 ; movl %eax, %ds
> + DB 0x8e, 0xc0 ; movl %eax, %es
> + DB 0x8e, 0xe0 ; movl %eax, %fs
> + DB 0x8e, 0xe8 ; movl %eax, %gs
> + DB 0x8e, 0xd0 ; movl %eax, %ss
> +
> + ; Disable paging
> + DB 0xf, 0x20, 0xc0 ; movl %cr0, %eax
> + DB 0xf, 0xba, 0xf8, 0x1f ; btcl $31, %eax
> + DB 0xf, 0x22, 0xc0 ; movl %eax, %cr0
> +
> + ; Disable long mode in EFER
> + DB 0xb9, 0x80, 0x0, 0x0, 0xc0 ; movl $0x0c0000080, %ecx
> + DB 0xf, 0x32 ; rdmsr
> + DB 0xf, 0xba, 0xf8, 0x8 ; btcl $8, %eax
> + DB 0xf, 0x30 ; wrmsr
> +
> + ; Disable PAE
> + DB 0xf, 0x20, 0xe0 ; movl %cr4, %eax
> + DB 0xf, 0xba, 0xf8, 0x5 ; btcl $5, %eax
> + DB 0xf, 0x22, 0xe0 ; movl %eax, %cr4
> +
> + DB 0x31, 0xed ; xor %ebp, %ebp
> + DB 0x31, 0xff ; xor %edi, %edi
> + DB 0x31, 0xdb ; xor %ebx, %ebx
> + DB 0xc3 ; ret
> +
> +;------------------------------------------------------------------------------
> +; VOID
> +; EFIAPI
> +; JumpToUefiKernel (
> +; EFI_HANDLE ImageHandle, // rcx
> +; EFI_SYSTEM_TABLE *SystemTable, // rdx
> +; VOID *KernelBootParams // r8
> +; VOID *KernelStart, // r9
> +; );
> +;------------------------------------------------------------------------------
> +global ASM_PFX(JumpToUefiKernel)
> +ASM_PFX(JumpToUefiKernel):
> +
> + mov rdi, rcx
> + mov rsi, rdx
> + mov rdx, r8
> + xor rax, rax
> + mov eax, [r8 + 0x264]
> + add r9, rax
> + add r9, 0x200
> + call r9
> + ret
> +
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/NvVarsFileLib.h
> b/Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/NvVarsFileLib.h
> new file mode 100644
> index 0000000000..80776fd003
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/NvVarsFileLib.h
> @@ -0,0 +1,55 @@
> +/** @file
> + Save Non-Volatile Variables to a file system.
> +
> + Copyright (c) 2009 - 2019 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef __NV_VARS_FILE_LIB_INSTANCE__
> +#define __NV_VARS_FILE_LIB_INSTANCE__
> +
> +#include <Uefi.h>
> +
> +#include <Guid/FileInfo.h>
> +
> +#include <Protocol/SimpleFileSystem.h>
> +
> +#include <Library/BaseLib.h>
> +#include <Library/FileHandleLib.h>
> +#include <Library/SerializeVariablesLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiRuntimeServicesTableLib.h>
> +#include <Library/UefiLib.h>
> +
> +/**
> + Loads the non-volatile variables from the NvVars file on the
> + given file system.
> +
> + @param[in] FsHandle - Handle for a gEfiSimpleFileSystemProtocolGuid
> instance
> +
> + @return EFI_STATUS based on the success or failure of load operation
> +
> +**/
> +EFI_STATUS
> +LoadNvVarsFromFs (
> + EFI_HANDLE FsHandle
> + );
> +
> +
> +/**
> + Saves the non-volatile variables into the NvVars file on the
> + given file system.
> +
> + @param[in] FsHandle - Handle for a gEfiSimpleFileSystemProtocolGuid
> instance
> +
> + @return EFI_STATUS based on the success or failure of load operation
> +
> +**/
> +EFI_STATUS
> +SaveNvVarsToFs (
> + EFI_HANDLE FsHandle
> + );
> +
> +#endif
> +
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/NvVarsFileLib.inf
> b/Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/NvVarsFileLib.inf
> new file mode 100644
> index 0000000000..4731e77865
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/NvVarsFileLib.inf
> @@ -0,0 +1,53 @@
> +## @file
> +# NvVarsFileLib
> +#
> +# This library saves and restores non-volatile variables in a
> +# file within a file system.
> +#
> +# Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> + INF_VERSION = 0x00010005
> + BASE_NAME = NvVarsFileLib
> + FILE_GUID = 8ECD4CC0-1772-4583-8A74-83633A15FAA0
> + MODULE_TYPE = UEFI_DRIVER
> + VERSION_STRING = 1.0
> + LIBRARY_CLASS = NvVarsFileLib|DXE_DRIVER
> DXE_RUNTIME_DRIVER UEFI_DRIVER
> +
> +#
> +# The following information is for reference only and not required by the build
> tools.
> +#
> +# VALID_ARCHITECTURES = IA32 X64 EBC
> +#
> +
> +[Sources]
> + FsAccess.c
> + NvVarsFileLib.c
> +
> +[Packages]
> + MdePkg/MdePkg.dec
> + MdeModulePkg/MdeModulePkg.dec
> + ShellPkg/ShellPkg.dec
> + OvmfPkg/OvmfPkg.dec
> +
> +[LibraryClasses]
> + BaseLib
> + BaseMemoryLib
> + DebugLib
> + FileHandleLib
> + MemoryAllocationLib
> + SerializeVariablesLib
> +
> +[Protocols]
> + gEfiSimpleFileSystemProtocolGuid ## CONSUMES
> +
> +[Guids]
> + gEfiFileInfoGuid
> +
> +[Depex]
> + gEfiVariableWriteArchProtocolGuid
> +
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Library/PciHostBridgeLib/PciHostBridge.
> h
> b/Platform/Intel/SimicsOpenBoardPkg/Library/PciHostBridgeLib/PciHostBridge.
> h
> new file mode 100644
> index 0000000000..0c75430260
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Library/PciHostBridgeLib/PciHostBridge.
> h
> @@ -0,0 +1,68 @@
> +/** @file
> + Header file of OVMF instance of PciHostBridgeLib.
> +
> + Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +PCI_ROOT_BRIDGE *
> +ScanForRootBridges (
> + UINTN *NumberOfRootBridges
> +);
> +
> +/**
> + Initialize a PCI_ROOT_BRIDGE structure.
> +
> + @param[in] Supports Supported attributes.
> +
> + @param[in] Attributes Initial attributes.
> +
> + @param[in] AllocAttributes Allocation attributes.
> +
> + @param[in] RootBusNumber The bus number to store in RootBus.
> +
> + @param[in] MaxSubBusNumber The inclusive maximum bus number that can
> be
> + assigned to any subordinate bus found behind any
> + PCI bridge hanging off this root bus.
> +
> + The caller is repsonsible for ensuring that
> + RootBusNumber <= MaxSubBusNumber. If
> + RootBusNumber equals MaxSubBusNumber, then the
> + root bus has no room for subordinate buses.
> +
> + @param[in] Io IO aperture.
> +
> + @param[in] Mem MMIO aperture.
> +
> + @param[in] MemAbove4G MMIO aperture above 4G.
> +
> + @param[in] PMem Prefetchable MMIO aperture.
> +
> + @param[in] PMemAbove4G Prefetchable MMIO aperture above 4G.
> +
> + @param[out] RootBus The PCI_ROOT_BRIDGE structure (allocated by
> the
> + caller) that should be filled in by this
> + function.
> +
> + @retval EFI_SUCCESS Initialization successful. A device path
> + consisting of an ACPI device path node, with
> + UID = RootBusNumber, has been allocated and
> + linked into RootBus.
> +
> + @retval EFI_OUT_OF_RESOURCES Memory allocation failed.
> +**/
> +EFI_STATUS
> +InitRootBridge (
> + IN UINT64 Supports,
> + IN UINT64 Attributes,
> + IN UINT64 AllocAttributes,
> + IN UINT8 RootBusNumber,
> + IN UINT8 MaxSubBusNumber,
> + IN PCI_ROOT_BRIDGE_APERTURE *Io,
> + IN PCI_ROOT_BRIDGE_APERTURE *Mem,
> + IN PCI_ROOT_BRIDGE_APERTURE *MemAbove4G,
> + IN PCI_ROOT_BRIDGE_APERTURE *PMem,
> + IN PCI_ROOT_BRIDGE_APERTURE *PMemAbove4G,
> + OUT PCI_ROOT_BRIDGE *RootBus
> + );
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Library/PciHostBridgeLib/PciHostBridgeL
> ib.inf
> b/Platform/Intel/SimicsOpenBoardPkg/Library/PciHostBridgeLib/PciHostBridgeL
> ib.inf
> new file mode 100644
> index 0000000000..e1920bd2ff
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Library/PciHostBridgeLib/PciHostBridgeL
> ib.inf
> @@ -0,0 +1,51 @@
> +## @file
> +# Simics's instance of the PCI Host Bridge Library.
> +#
> +# Copyright (C) 2016, Red Hat, Inc.
> +# Copyright (c) 2016 - 2019 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> + INF_VERSION = 0x00010005
> + BASE_NAME = PciHostBridgeLib
> + FILE_GUID = 2F04EC41-C3A0-43EB-AC6A-409F973F4439
> + MODULE_TYPE = DXE_DRIVER
> + VERSION_STRING = 1.0
> + LIBRARY_CLASS = PciHostBridgeLib
> +
> +#
> +# The following information is for reference only and not required by the build
> +# tools.
> +#
> +# VALID_ARCHITECTURES = IA32 X64 EBC
> +#
> +
> +[Sources]
> + PciHostBridgeLib.c
> + PciHostBridge.h
> +
> +[Packages]
> + MdeModulePkg/MdeModulePkg.dec
> + MdePkg/MdePkg.dec
> + SimicsOpenBoardPkg/OpenBoardPkg.dec
> + SimicsIch10Pkg/Ich10Pkg.dec
> +
> +[LibraryClasses]
> + BaseMemoryLib
> + DebugLib
> + DevicePathLib
> + MemoryAllocationLib
> + PciLib
> +
> +[Pcd]
> + gBoardModuleTokenSpaceGuid.PcdPciIoBase
> + gBoardModuleTokenSpaceGuid.PcdPciIoSize
> + gBoardModuleTokenSpaceGuid.PcdPciMmio32Base
> + gBoardModuleTokenSpaceGuid.PcdPciMmio32Size
> + gBoardModuleTokenSpaceGuid.PcdPciMmio64Base
> + gBoardModuleTokenSpaceGuid.PcdPciMmio64Size
> + gBoardModuleTokenSpaceGuid.PcdSimicsX58HostBridgePciDevId
> + gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Library/PeiReportFvLib/PeiReportFvLib.in
> f
> b/Platform/Intel/SimicsOpenBoardPkg/Library/PeiReportFvLib/PeiReportFvLib.in
> f
> new file mode 100644
> index 0000000000..bc85420f97
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Library/PeiReportFvLib/PeiReportFvLib.in
> f
> @@ -0,0 +1,56 @@
> +### @file
> +# Component information file for the Report Firmware Volume (FV) library.
> +#
> +# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +###
> +
> +[Defines]
> + INF_VERSION = 0x00010017
> + BASE_NAME = PeiReportFvLib
> + FILE_GUID = 44328FA5-E4DD-4A15-ABDF-C6584AC363D9
> + VERSION_STRING = 1.0
> + MODULE_TYPE = PEIM
> + LIBRARY_CLASS = ReportFvLib
> +
> +[LibraryClasses]
> + BaseMemoryLib
> + DebugLib
> + HobLib
> + PeiServicesLib
> + PcdLib
> + IoLib
> +
> +[Packages]
> + MdePkg/MdePkg.dec
> + MdeModulePkg/MdeModulePkg.dec
> + MinPlatformPkg/MinPlatformPkg.dec
> + SimicsOpenBoardPkg/OpenBoardPkg.dec
> + SimicsX58SktPkg/SktPkg.dec
> + SimicsIch10Pkg/Ich10Pkg.dec
> +
> +[Sources]
> + PeiReportFvLib.c
> + Fv.c
> +
> +[Pcd]
> + gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaBaseAddress ## CONSUMES
> + gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaSize ## CONSUMES
> + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPostMemoryBase ##
> CONSUMES
> + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPostMemorySize ##
> CONSUMES
> + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvUefiBootBase ## CONSUMES
> + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvUefiBootSize ## CONSUMES
> + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvOsBootBase ## CONSUMES
> + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvOsBootSize ## CONSUMES
> + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvSecurityBase ## CONSUMES
> + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvSecuritySize ## CONSUMES
> + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvAdvancedBase ## CONSUMES
> + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvAdvancedSize ## CONSUMES
> + gBoardModuleTokenSpaceGuid.PcdSimicsPeiMemFvBase
> + gBoardModuleTokenSpaceGuid.PcdSimicsPeiMemFvSize
> + gBoardModuleTokenSpaceGuid.PcdSimicsDxeMemFvBase
> + gBoardModuleTokenSpaceGuid.PcdSimicsDxeMemFvSize
> + gBoardModuleTokenSpaceGuid.PcdSimicsDecompressionScratchEnd
> + gSimicsX58PkgTokenSpaceGuid.PcdSmmSmramRequire
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Library/PlatformBootManagerLib/BdsPla
> tform.h
> b/Platform/Intel/SimicsOpenBoardPkg/Library/PlatformBootManagerLib/BdsPla
> tform.h
> new file mode 100644
> index 0000000000..01ba20d2da
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Library/PlatformBootManagerLib/BdsPla
> tform.h
> @@ -0,0 +1,172 @@
> +/** @file
> + Platform BDS customizations include file.
> +
> + Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PLATFORM_SPECIFIC_BDS_PLATFORM_H_
> +#define _PLATFORM_SPECIFIC_BDS_PLATFORM_H_
> +
> +
> +#include <PiDxe.h>
> +
> +#include <IndustryStandard/Pci.h>
> +#include <IndustryStandard/Acpi.h>
> +#include <IndustryStandard/SmBios.h>
> +#include <IndustryStandard/PeImage.h>
> +
> +#include <Library/DebugLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiRuntimeServicesTableLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/PciLib.h>
> +#include <Library/UefiBootManagerLib.h>
> +#include <Library/BootLogoLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/UefiLib.h>
> +#include <Library/DxeServicesTableLib.h>
> +#include <Library/DevicePathLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/NvVarsFileLib.h>
> +
> +#include <Protocol/Decompress.h>
> +#include <Protocol/PciIo.h>
> +#include <Protocol/FirmwareVolume2.h>
> +#include <Protocol/SimpleFileSystem.h>
> +#include <Protocol/PciRootBridgeIo.h>
> +#include <Protocol/S3SaveState.h>
> +#include <Protocol/DxeSmmReadyToLock.h>
> +#include <Protocol/LoadedImage.h>
> +
> +#include <Guid/Acpi.h>
> +#include <Guid/SmBios.h>
> +#include <Guid/Mps.h>
> +#include <Guid/HobList.h>
> +#include <Guid/GlobalVariable.h>
> +#include <Guid/EventGroup.h>
> +
> +#include <SimicsPlatforms.h>
> +
> +extern EFI_DEVICE_PATH_PROTOCOL *gPlatformConnectSequence[];
> +extern ACPI_HID_DEVICE_PATH gPnpPs2KeyboardDeviceNode;
> +extern ACPI_HID_DEVICE_PATH gPnp16550ComPortDeviceNode;
> +extern UART_DEVICE_PATH gUartDeviceNode;
> +extern VENDOR_DEVICE_PATH gTerminalTypeDeviceNode;
> +
> +#define PCI_DEVICE_PATH_NODE(Func, Dev) \
> + { \
> + { \
> + HARDWARE_DEVICE_PATH, \
> + HW_PCI_DP, \
> + { \
> + (UINT8) (sizeof (PCI_DEVICE_PATH)), \
> + (UINT8) ((sizeof (PCI_DEVICE_PATH)) >> 8) \
> + } \
> + }, \
> + (Func), \
> + (Dev) \
> + }
> +
> +#define PNPID_DEVICE_PATH_NODE(PnpId) \
> + { \
> + { \
> + ACPI_DEVICE_PATH, \
> + ACPI_DP, \
> + { \
> + (UINT8) (sizeof (ACPI_HID_DEVICE_PATH)), \
> + (UINT8) ((sizeof (ACPI_HID_DEVICE_PATH)) >> 8) \
> + }, \
> + }, \
> + EISA_PNP_ID((PnpId)), \
> + 0 \
> + }
> +
> +#define gPciIsaBridge \
> + PCI_DEVICE_PATH_NODE(0, 0x1f)
> +
> +#define gP2PBridge \
> + PCI_DEVICE_PATH_NODE(0, 0x1e)
> +
> +#define gPnpPs2Keyboard \
> + PNPID_DEVICE_PATH_NODE(0x0303)
> +
> +#define gPnp16550ComPort \
> + PNPID_DEVICE_PATH_NODE(0x0501)
> +
> +#define gUart \
> + { \
> + { \
> + MESSAGING_DEVICE_PATH, \
> + MSG_UART_DP, \
> + { \
> + (UINT8) (sizeof (UART_DEVICE_PATH)), \
> + (UINT8) ((sizeof (UART_DEVICE_PATH)) >> 8) \
> + } \
> + }, \
> + 0, \
> + 115200, \
> + 8, \
> + 1, \
> + 1 \
> + }
> +
> +#define gPcAnsiTerminal \
> + { \
> + { \
> + MESSAGING_DEVICE_PATH, \
> + MSG_VENDOR_DP, \
> + { \
> + (UINT8) (sizeof (VENDOR_DEVICE_PATH)), \
> + (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8) \
> + } \
> + }, \
> + DEVICE_PATH_MESSAGING_PC_ANSI \
> + }
> +
> +#define PCI_CLASS_SCC 0x07
> +#define PCI_SUBCLASS_SERIAL 0x00
> +#define PCI_IF_16550 0x02
> +#define IS_PCI_16550SERIAL(_p) IS_CLASS3 (_p, PCI_CLASS_SCC,
> PCI_SUBCLASS_SERIAL, PCI_IF_16550)
> +#define IS_PCI_ISA_PDECODE(_p) IS_CLASS3 (_p, PCI_CLASS_BRIDGE,
> PCI_CLASS_BRIDGE_ISA_PDECODE, 0)
> +
> +typedef struct {
> + EFI_DEVICE_PATH_PROTOCOL *DevicePath;
> + UINTN ConnectType;
> +} PLATFORM_CONSOLE_CONNECT_ENTRY;
> +
> +#define CONSOLE_OUT BIT0
> +#define CONSOLE_IN BIT1
> +#define STD_ERROR BIT2
> +extern PLATFORM_CONSOLE_CONNECT_ENTRY gPlatformConsole[];
> +
> +//
> +// Platform BDS Functions
> +//
> +
> +VOID
> +PlatformInitializeConsole (
> + IN PLATFORM_CONSOLE_CONNECT_ENTRY *PlatformConsole
> + );
> +
> +/**
> + Use SystemTable ConOut to stop video based Simple Text Out consoles from
> going
> + to the video device. Put up LogoFile on every video device that is a console.
> +
> + @param[in] LogoFile The file name of logo to display on the center of the
> screen.
> +
> + @retval EFI_SUCCESS ConsoleControl has been flipped to graphics and logo
> displayed.
> + @retval EFI_UNSUPPORTED Logo not found.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +EnableBootLogo(
> + IN EFI_GUID *LogoFile
> +);
> +
> +#endif // _PLATFORM_SPECIFIC_BDS_PLATFORM_H_
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Library/PlatformBootManagerLib/Platfo
> rmBootManagerLib.inf
> b/Platform/Intel/SimicsOpenBoardPkg/Library/PlatformBootManagerLib/Platfo
> rmBootManagerLib.inf
> new file mode 100644
> index 0000000000..cdb6e242e8
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Library/PlatformBootManagerLib/Platfo
> rmBootManagerLib.inf
> @@ -0,0 +1,72 @@
> +## @file
> +# Platform BDS customizations library.
> +#
> +# Copyright (c) 2007 - 2019 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> + INF_VERSION = 0x00010005
> + BASE_NAME = PlatformBootManagerLib
> + FILE_GUID = 8AE4756F-0C71-4C06-84D4-4C71F204D514
> + MODULE_TYPE = DXE_DRIVER
> + VERSION_STRING = 1.0
> + LIBRARY_CLASS = PlatformBootManagerLib|DXE_DRIVER
> +
> +#
> +# The following information is for reference only and not required by the build
> tools.
> +#
> +# VALID_ARCHITECTURES = IA32 X64 EBC
> +#
> +
> +[Sources]
> + BdsPlatform.c
> + PlatformData.c
> + BdsPlatform.h
> +
> +[Packages]
> + MdePkg/MdePkg.dec
> + MdeModulePkg/MdeModulePkg.dec
> + SimicsOpenBoardPkg/OpenBoardPkg.dec
> + OvmfPkg/OvmfPkg.dec
> + SimicsIch10Pkg/Ich10Pkg.dec
> +
> +[LibraryClasses]
> + BaseLib
> + MemoryAllocationLib
> + UefiBootServicesTableLib
> + BaseMemoryLib
> + DebugLib
> + PcdLib
> + UefiBootManagerLib
> + BootLogoLib
> + DevicePathLib
> + PciLib
> + NvVarsFileLib
> + DxeLoadLinuxLib
> + UefiLib
> + LogoLib
> +
> +[Pcd]
> + gBoardModuleTokenSpaceGuid.PcdEmuVariableEvent
> + gBoardModuleTokenSpaceGuid.PcdOvmfFlashVariablesEnable
> + gBoardModuleTokenSpaceGuid.PcdSimicsX58HostBridgePciDevId
> + gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut
> + gBoardModuleTokenSpaceGuid.PcdShellFile
> + gBoardModuleTokenSpaceGuid.PcdLogoFile
> +
> +[Pcd.IA32, Pcd.X64]
> + gEfiMdePkgTokenSpaceGuid.PcdFSBClock
> +
> +[Protocols]
> + gEfiDecompressProtocolGuid
> + gEfiPciRootBridgeIoProtocolGuid
> + gEfiS3SaveStateProtocolGuid # PROTOCOL
> SOMETIMES_CONSUMED
> + gEfiDxeSmmReadyToLockProtocolGuid # PROTOCOL
> SOMETIMES_PRODUCED
> + gEfiLoadedImageProtocolGuid # PROTOCOL
> SOMETIMES_PRODUCED
> + gEfiFirmwareVolume2ProtocolGuid # PROTOCOL
> SOMETIMES_CONSUMED
> +
> +[Guids]
> + gEfiEndOfDxeEventGroupGuid
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVar
> iablesLib.h
> b/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVar
> iablesLib.h
> new file mode 100644
> index 0000000000..9b4c2a629a
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVar
> iablesLib.h
> @@ -0,0 +1,33 @@
> +/** @file
> + Serialize Variables Library implementation
> +
> + Copyright (c) 2009 - 2019 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef __SERIALIZE_VARIABLES_LIB_INSTANCE__
> +#define __SERIALIZE_VARIABLES_LIB_INSTANCE__
> +
> +#include <Uefi.h>
> +
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/SerializeVariablesLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiRuntimeServicesTableLib.h>
> +
> +#define SV_FROM_HANDLE(a) CR (a, SV_INSTANCE, Signature,
> SV_SIGNATURE)
> +#define SV_SIGNATURE SIGNATURE_32 ('S', 'V', 'A', 'R')
> +
> +typedef struct {
> + UINT32 Signature;
> + VOID *BufferPtr;
> + UINTN BufferSize;
> + UINTN DataSize;
> +} SV_INSTANCE;
> +
> +#endif
> +
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVar
> iablesLib.inf
> b/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVar
> iablesLib.inf
> new file mode 100644
> index 0000000000..08c561f586
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVar
> iablesLib.inf
> @@ -0,0 +1,36 @@
> +## @file
> +# Serialize Variables Library implementation
> +#
> +# This library serializes and deserializes UEFI variables
> +#
> +# Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> + INF_VERSION = 0x00010005
> + BASE_NAME = DxeSerializeVariablesLib
> + FILE_GUID = 266A1434-6B22-441F-A8D2-D54AA8FDF95C
> + MODULE_TYPE = UEFI_DRIVER
> + VERSION_STRING = 1.0
> + LIBRARY_CLASS = SerializeVariablesLib|DXE_DRIVER
> DXE_RUNTIME_DRIVER UEFI_DRIVER
> +
> +[Sources]
> + SerializeVariablesLib.c
> +
> +[Packages]
> + MdePkg/MdePkg.dec
> + MdeModulePkg/MdeModulePkg.dec
> + ShellPkg/ShellPkg.dec
> + SimicsOpenBoardPkg/OpenBoardPkg.dec
> +
> +[LibraryClasses]
> + BaseLib
> + BaseMemoryLib
> + DebugLib
> + MemoryAllocationLib
> + UefiBootServicesTableLib
> + UefiRuntimeServicesTableLib
> +
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyInitLib/Silicon
> PolicyInitLib.inf
> b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyInitLib/Silicon
> PolicyInitLib.inf
> new file mode 100644
> index 0000000000..6be3b301ad
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyInitLib/Silicon
> PolicyInitLib.inf
> @@ -0,0 +1,38 @@
> +## @file
> +#
> +# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> + INF_VERSION = 0x00010005
> + BASE_NAME = SiliconPolicyInitLib
> + FILE_GUID = B494DF39-A5F8-48A1-B2D0-EF523AD91C55
> + MODULE_TYPE = PEIM
> + VERSION_STRING = 1.0
> + LIBRARY_CLASS = SiliconPolicyInitLib
> +
> +[Sources]
> + SiliconPolicyInitLib.c
> +
> +################################################################
> ################
> +#
> +# Package Dependency Section - list of Package files that are required for
> +# this module.
> +#
> +################################################################
> ################
> +[Packages]
> + MdePkg/MdePkg.dec
> +
> +[LibraryClasses]
> + BaseMemoryLib
> + BaseLib
> + DebugLib
> + DebugPrintErrorLevelLib
> + HobLib
> + IoLib
> + MemoryAllocationLib
> + PeiServicesLib
> +
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyUpdateLib/Sili
> conPolicyUpdateLib.inf
> b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyUpdateLib/Sili
> conPolicyUpdateLib.inf
> new file mode 100644
> index 0000000000..4fde3c75a6
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyUpdateLib/Sili
> conPolicyUpdateLib.inf
> @@ -0,0 +1,35 @@
> +## @file
> +#
> +# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> + INF_VERSION = 0x00010005
> + BASE_NAME = SiliconPolicyUpdateLib
> + FILE_GUID = 6EA9585C-3C15-47da-9FFC-25E9E4EA4D0C
> + MODULE_TYPE = PEIM
> + VERSION_STRING = 1.0
> + LIBRARY_CLASS = SiliconPolicyUpdateLib
> +
> +[Sources]
> + SiliconPolicyUpdateLib.c
> +
> +[Packages]
> + MdePkg/MdePkg.dec
> + MdeModulePkg/MdeModulePkg.dec
> +
> +[LibraryClasses]
> + HobLib
> + IoLib
> + PcdLib
> +
> +[Pcd]
> +
> +[FixedPcd]
> +
> +[Ppis]
> +
> +[Guids]
> diff --git a/Platform/Intel/SimicsOpenBoardPkg/SecCore/Ia32/SecEntry.nasm
> b/Platform/Intel/SimicsOpenBoardPkg/SecCore/Ia32/SecEntry.nasm
> new file mode 100644
> index 0000000000..adb87de943
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/SecCore/Ia32/SecEntry.nasm
> @@ -0,0 +1,45 @@
> +; @file
> +; Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved. <BR>
> +;
> +; SPDX-License-Identifier: BSD-2-Clause-Patent
> +;
> +
> +#include <Base.h>
> +
> + SECTION .text
> +
> +extern ASM_PFX(SecCoreStartupWithStack)
> +
> +;
> +; SecCore Entry Point
> +;
> +; Processor is in flat protected mode
> +;
> +; @param[in] EAX Initial value of the EAX register (BIST: Built-in Self Test)
> +; @param[in] DI 'BP': boot-strap processor, or 'AP': application processor
> +; @param[in] EBP Pointer to the start of the Boot Firmware Volume
> +;
> +; @return None This routine does not return
> +;
> +global ASM_PFX(_ModuleEntryPoint)
> +ASM_PFX(_ModuleEntryPoint):
> +
> + ;
> + ; Load temporary RAM stack based on PCDs
> + ;
> + %define SEC_TOP_OF_STACK (FixedPcdGet32
> (PcdSimicsSecPeiTempRamBase) + \
> + FixedPcdGet32 (PcdSimicsSecPeiTempRamSize))
> + mov eax, SEC_TOP_OF_STACK
> + mov esp, eax
> + nop
> +
> + ;
> + ; Setup parameters and call SecCoreStartupWithStack
> + ; [esp] return address for call
> + ; [esp+4] BootFirmwareVolumePtr
> + ; [esp+8] TopOfCurrentStack
> + ;
> + push eax
> + push ebp
> + call ASM_PFX(SecCoreStartupWithStack)
> +
> diff --git a/Platform/Intel/SimicsOpenBoardPkg/SecCore/SecMain.inf
> b/Platform/Intel/SimicsOpenBoardPkg/SecCore/SecMain.inf
> new file mode 100644
> index 0000000000..b1d319c5ea
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/SecCore/SecMain.inf
> @@ -0,0 +1,73 @@
> +## @file
> +# SEC Driver
> +#
> +# Copyright (c) 2008 - 2019 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> + INF_VERSION = 0x00010005
> + BASE_NAME = SecMain
> + FILE_GUID = e67f156f-54c5-47f3-a35d-07c045881e14
> + MODULE_TYPE = SEC
> + VERSION_STRING = 1.0
> + ENTRY_POINT = SecMain
> +
> +#
> +# The following information is for reference only and not required by the build
> tools.
> +#
> +# VALID_ARCHITECTURES = IA32 X64 EBC
> +#
> +
> +[Sources]
> + SecMain.c
> +
> +[Sources.IA32]
> + Ia32/SecEntry.nasm
> +
> +[Sources.X64]
> + X64/SecEntry.nasm
> +
> +[Packages]
> + MdePkg/MdePkg.dec
> + MdeModulePkg/MdeModulePkg.dec
> + UefiCpuPkg/UefiCpuPkg.dec
> + SimicsX58SktPkg/SktPkg.dec
> + SimicsOpenBoardPkg/OpenBoardPkg.dec
> + SimicsIch10Pkg/Ich10Pkg.dec
> +
> +[LibraryClasses]
> + BaseLib
> + DebugLib
> + BaseMemoryLib
> + PeiServicesLib
> + PcdLib
> + UefiCpuLib
> + DebugAgentLib
> + IoLib
> + PeCoffLib
> + PeCoffGetEntryPointLib
> + PeCoffExtraActionLib
> + ExtractGuidedSectionLib
> + LocalApicLib
> + PciCf8Lib
> +
> +[Ppis]
> + gEfiTemporaryRamSupportPpiGuid # PPI ALWAYS_PRODUCED
> +
> +[Pcd]
> + gBoardModuleTokenSpaceGuid.PcdSimicsPeiMemFvBase
> + gBoardModuleTokenSpaceGuid.PcdSimicsPeiMemFvSize
> + gBoardModuleTokenSpaceGuid.PcdSimicsDxeMemFvBase
> + gBoardModuleTokenSpaceGuid.PcdSimicsDxeMemFvSize
> + gBoardModuleTokenSpaceGuid.PcdSimicsSecPageTablesBase
> + gBoardModuleTokenSpaceGuid.PcdSimicsSecPeiTempRamBase
> + gBoardModuleTokenSpaceGuid.PcdSimicsSecPeiTempRamSize
> + gEfiMdePkgTokenSpaceGuid.PcdGuidedExtractHandlerTableAddress
> + gBoardModuleTokenSpaceGuid.PcdGuidedExtractHandlerTableSize
> + gBoardModuleTokenSpaceGuid.PcdSimicsDecompressionScratchEnd
> +
> +[FeaturePcd]
> + gSimicsX58PkgTokenSpaceGuid.PcdSmmSmramRequire
> diff --git a/Platform/Intel/SimicsOpenBoardPkg/SecCore/X64/SecEntry.nasm
> b/Platform/Intel/SimicsOpenBoardPkg/SecCore/X64/SecEntry.nasm
> new file mode 100644
> index 0000000000..2e6d8f618c
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/SecCore/X64/SecEntry.nasm
> @@ -0,0 +1,45 @@
> +; @file
> +; Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved. <BR>
> +;
> +; SPDX-License-Identifier: BSD-2-Clause-Patent
> +;
> +
> +#include <Base.h>
> +
> +DEFAULT REL
> +SECTION .text
> +
> +extern ASM_PFX(SecCoreStartupWithStack)
> +
> +;
> +; SecCore Entry Point
> +;
> +; Processor is in flat protected mode
> +;
> +; @param[in] RAX Initial value of the EAX register (BIST: Built-in Self Test)
> +; @param[in] DI 'BP': boot-strap processor, or 'AP': application processor
> +; @param[in] RBP Pointer to the start of the Boot Firmware Volume
> +;
> +; @return None This routine does not return
> +;
> +global ASM_PFX(_ModuleEntryPoint)
> +ASM_PFX(_ModuleEntryPoint):
> +
> + ;
> + ; Load temporary RAM stack based on PCDs
> + ;
> + %define SEC_TOP_OF_STACK (FixedPcdGet32
> (PcdSimicsSecPeiTempRamBase) + \
> + FixedPcdGet32 (PcdSimicsSecPeiTempRamSize))
> + mov rsp, SEC_TOP_OF_STACK
> + nop
> +
> + ;
> + ; Setup parameters and call SecCoreStartupWithStack
> + ; rcx: BootFirmwareVolumePtr
> + ; rdx: TopOfCurrentStack
> + ;
> + mov rcx, rbp
> + mov rdx, rsp
> + sub rsp, 0x20
> + call ASM_PFX(SecCoreStartupWithStack)
> +
> diff --git a/Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/Platform.h
> b/Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/Platform.h
> new file mode 100644
> index 0000000000..623d8ad2a9
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/Platform.h
> @@ -0,0 +1,38 @@
> +/** @file
> + This driver effectuates QSP platform configuration settings and exposes
> + them via HII.
> +
> + Copyright (C) 2014, Red Hat, Inc.
> + Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PLATFORM_H_
> +#define _PLATFORM_H_
> +
> +//
> +// Macro and type definitions that connect the form with the HII driver code.
> +//
> +#define FORMSTATEID_MAIN_FORM 1
> +#define FORMID_MAIN_FORM 1
> +
> +#define QUESTION_RES_CUR 1
> +#define MAXSIZE_RES_CUR 16
> +
> +#define LABEL_RES_NEXT 1
> +#define QUESTION_RES_NEXT 2
> +
> +#define QUESTION_SAVE_EXIT 3
> +#define QUESTION_DISCARD_EXIT 4
> +
> +//
> +// This structure describes the form state. Its fields relate strictly to the
> +// visual widgets on the form.
> +//
> +typedef struct {
> + UINT16 CurrentPreferredResolution[MAXSIZE_RES_CUR];
> + UINT32 NextPreferredResolution;
> +} MAIN_FORM_STATE;
> +
> +#endif // _PLATFORM_H_
> diff --git a/Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/Platform.uni
> b/Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/Platform.uni
> new file mode 100644
> index 0000000000..3d9af148ec
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/Platform.uni
> @@ -0,0 +1,31 @@
> +// *++
> +//
> +// Copyright (C) 2014, Red Hat, Inc.
> +// Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +//
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +//
> +// Module Name:
> +//
> +// Platform.uni
> +//
> +// Abstract:
> +//
> +// String definitions for PlatformForms.vfr
> +//
> +// --*/
> +
> +/=#
> +
> +#langdef en-US "English"
> +
> +#string STR_FORMSET_TITLE #language en-US "QSP Platform
> Configuration"
> +#string STR_FORMSET_HELP #language en-US "Change various QSP
> platform settings."
> +#string STR_MAIN_FORM_TITLE #language en-US "QSP Settings"
> +#string STR_RES_CUR #language en-US "Preferred Resolution at Next
> Boot"
> +#string STR_RES_CUR_HELP #language en-US "The preferred resolution of
> the Graphics Console at next boot. It might be unset, or even invalid (hence
> ignored) wrt. the video RAM size."
> +#string STR_RES_NEXT #language en-US "Change Preferred Resolution
> for Next Boot"
> +#string STR_RES_NEXT_HELP #language en-US "You can specify a new
> preference for the Graphics Console here. The list is filtered against the video
> RAM size."
> +#string STR_SAVE_EXIT #language en-US "Commit Changes and Exit"
> +#string STR_DISCARD_EXIT #language en-US "Discard Changes and Exit"
> +
> diff --git a/Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/PlatformConfig.h
> b/Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/PlatformConfig.h
> new file mode 100644
> index 0000000000..c2063c427b
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/PlatformConfig.h
> @@ -0,0 +1,52 @@
> +/** @file
> + Utility functions for serializing (persistently storing) and deserializing
> + Simics's platform configuration.
> +
> + Copyright (C) 2014, Red Hat, Inc.
> + Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PLATFORM_CONFIG_H_
> +#define _PLATFORM_CONFIG_H_
> +
> +#include <Base.h>
> +
> +//
> +// This structure participates in driver configuration. It does not
> +// (necessarily) reflect the wire format in the persistent store.
> +//
> +#pragma pack(1)
> +typedef struct {
> + //
> + // preferred graphics console resolution when booting
> + //
> + UINT32 HorizontalResolution;
> + UINT32 VerticalResolution;
> +} PLATFORM_CONFIG;
> +#pragma pack()
> +
> +//
> +// Please see the API documentation near the function definitions.
> +//
> +EFI_STATUS
> +EFIAPI
> +PlatformConfigSave (
> + IN PLATFORM_CONFIG *PlatformConfig
> + );
> +
> +EFI_STATUS
> +EFIAPI
> +PlatformConfigLoad (
> + OUT PLATFORM_CONFIG *PlatformConfig,
> + OUT UINT64 *OptionalElements
> + );
> +
> +//
> +// Feature flags for OptionalElements.
> +//
> +#define PLATFORM_CONFIG_F_GRAPHICS_RESOLUTION BIT0
> +#define PLATFORM_CONFIG_F_DOWNGRADE BIT63
> +
> +#endif // _PLATFORM_CONFIG_H_
> diff --git a/Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/PlatformForms.vfr
> b/Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/PlatformForms.vfr
> new file mode 100644
> index 0000000000..a38521e8d3
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/PlatformForms.vfr
> @@ -0,0 +1,67 @@
> +// *++
> +//
> +// Copyright (C) 2014, Red Hat, Inc.
> +// Copyright (c) 2009 - 2019, Intel Corporation. All rights reserved.<BR>
> +//
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +//
> +// Module Name:
> +//
> +// PlatformForms.vfr
> +//
> +// Abstract:
> +//
> +// Form definitions for exposing some of OVMF's platform knobs via HII.
> +//
> +// --*/
> +
> +#include <Guid/SimicsBoardConfig.h>
> +#include "Platform.h"
> +
> +formset
> + guid = SIMICS_BOARD_CONFIG_GUID,
> + title = STRING_TOKEN(STR_FORMSET_TITLE),
> + help = STRING_TOKEN(STR_FORMSET_HELP),
> +
> + varstore MAIN_FORM_STATE,
> + varid = FORMSTATEID_MAIN_FORM,
> + name = MainFormState,
> + guid = SIMICS_BOARD_CONFIG_GUID;
> +
> + form
> + formid = FORMID_MAIN_FORM,
> + title = STRING_TOKEN(STR_MAIN_FORM_TITLE);
> +
> + //
> + // Display the current preference in a read-only string field.
> + //
> + string
> + varid = MainFormState.CurrentPreferredResolution,
> + questionid = QUESTION_RES_CUR,
> + prompt = STRING_TOKEN(STR_RES_CUR),
> + help = STRING_TOKEN(STR_RES_CUR_HELP),
> + flags = READ_ONLY,
> + minsize = 0,
> + maxsize = MAXSIZE_RES_CUR,
> + endstring;
> +
> + //
> + // We'll dynamically generate a one-of-many selection at this label.
> + //
> + label LABEL_RES_NEXT;
> +
> + text
> + help = STRING_TOKEN(STR_SAVE_EXIT),
> + text = STRING_TOKEN(STR_SAVE_EXIT),
> + flags = INTERACTIVE,
> + key = QUESTION_SAVE_EXIT;
> +
> + text
> + help = STRING_TOKEN(STR_DISCARD_EXIT),
> + text = STRING_TOKEN(STR_DISCARD_EXIT),
> + flags = INTERACTIVE,
> + key = QUESTION_DISCARD_EXIT;
> +
> + endform;
> +
> +endformset;
> diff --git a/Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/SimicsDxe.inf
> b/Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/SimicsDxe.inf
> new file mode 100644
> index 0000000000..eef187d2a7
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/SimicsDxe.inf
> @@ -0,0 +1,65 @@
> +## @file
> +# This driver effectuates Simics X58 platform configuration settings and
> exposes
> +# them via HII.
> +#
> +# Copyright (C) 2014, Red Hat, Inc.
> +# Copyright (c) 2009 - 2019, Intel Corporation. All rights reserved.<BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> + INF_VERSION = 0x00010005
> + BASE_NAME = SimicsDxe
> + FILE_GUID = 74B64DC1-B0B6-4853-A6BD-C6426059AB1E
> + MODULE_TYPE = DXE_DRIVER
> + VERSION_STRING = 1.0
> + ENTRY_POINT = PlatformInit
> + UNLOAD_IMAGE = PlatformUnload
> +
> +[Sources]
> + Platform.c
> + Platform.uni
> + PlatformConfig.c
> + PlatformForms.vfr
> +
> +[Packages]
> + MdePkg/MdePkg.dec
> + MdeModulePkg/MdeModulePkg.dec
> + SimicsOpenBoardPkg/OpenBoardPkg.dec
> + MinPlatformPkg/MinPlatformPkg.dec
> +
> +[LibraryClasses]
> + BaseLib
> + BaseMemoryLib
> + DebugLib
> + DevicePathLib
> + HiiLib
> + MemoryAllocationLib
> + PrintLib
> + UefiBootServicesTableLib
> + UefiHiiServicesLib
> + UefiLib
> + UefiRuntimeServicesTableLib
> + UefiDriverEntryPoint
> + DxeServicesTableLib
> +
> +[Pcd]
> + gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution
> + gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution
> +
> +[Protocols]
> + gEfiDevicePathProtocolGuid ## PRODUCES
> + gEfiGraphicsOutputProtocolGuid ## CONSUMES
> + gEfiHiiConfigAccessProtocolGuid ## PRODUCES
> +
> +[Guids]
> + gEfiIfrTianoGuid
> + gSimicsBoardConfigGuid
> +
> +[Depex]
> + gEfiHiiConfigRoutingProtocolGuid AND
> + gEfiHiiDatabaseProtocolGuid AND
> + gEfiVariableArchProtocolGuid AND
> + gEfiVariableWriteArchProtocolGuid
> diff --git a/Platform/Intel/SimicsOpenBoardPkg/SimicsPei/Cmos.h
> b/Platform/Intel/SimicsOpenBoardPkg/SimicsPei/Cmos.h
> new file mode 100644
> index 0000000000..07fa2e2d11
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/SimicsPei/Cmos.h
> @@ -0,0 +1,50 @@
> +/** @file
> + PC/AT CMOS access routines
> +
> + Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef __CMOS_H__
> +#define __CMOS_H__
> +
> +/**
> + Reads 8-bits of CMOS data.
> +
> + Reads the 8-bits of CMOS data at the location specified by Index.
> + The 8-bit read value is returned.
> +
> + @param Index The CMOS location to read.
> +
> + @return The value read.
> +
> +**/
> +UINT8
> +EFIAPI
> +CmosRead8 (
> + IN UINTN Index
> + );
> +
> +/**
> + Writes 8-bits of CMOS data.
> +
> + Writes 8-bits of CMOS data to the location specified by Index
> + with the value specified by Value and returns Value.
> +
> + @param Index The CMOS location to write.
> + @param Value The value to write to CMOS.
> +
> + @return The value written to CMOS.
> +
> +**/
> +UINT8
> +EFIAPI
> +CmosWrite8 (
> + IN UINTN Index,
> + IN UINT8 Value
> + );
> +
> +
> +#endif
> +
> diff --git a/Platform/Intel/SimicsOpenBoardPkg/SimicsPei/Platform.h
> b/Platform/Intel/SimicsOpenBoardPkg/SimicsPei/Platform.h
> new file mode 100644
> index 0000000000..102d21cd64
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/SimicsPei/Platform.h
> @@ -0,0 +1,88 @@
> +/** @file
> + Platform PEI module include file.
> +
> + Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PLATFORM_PEI_H_INCLUDED_
> +#define _PLATFORM_PEI_H_INCLUDED_
> +
> +VOID
> +AddIoMemoryBaseSizeHob (
> + EFI_PHYSICAL_ADDRESS MemoryBase,
> + UINT64 MemorySize
> + );
> +
> +VOID
> +AddIoMemoryRangeHob (
> + EFI_PHYSICAL_ADDRESS MemoryBase,
> + EFI_PHYSICAL_ADDRESS MemoryLimit
> + );
> +
> +VOID
> +AddMemoryBaseSizeHob (
> + EFI_PHYSICAL_ADDRESS MemoryBase,
> + UINT64 MemorySize
> + );
> +
> +VOID
> +AddMemoryRangeHob (
> + EFI_PHYSICAL_ADDRESS MemoryBase,
> + EFI_PHYSICAL_ADDRESS MemoryLimit
> + );
> +
> +VOID
> +AddUntestedMemoryBaseSizeHob (
> + EFI_PHYSICAL_ADDRESS MemoryBase,
> + UINT64 MemorySize
> + );
> +
> +VOID
> +AddReservedMemoryBaseSizeHob (
> + EFI_PHYSICAL_ADDRESS MemoryBase,
> + UINT64 MemorySize,
> + BOOLEAN Cacheable
> + );
> +
> +VOID
> +AddressWidthInitialization (
> + VOID
> + );
> +
> +VOID
> +X58TsegMbytesInitialization (
> + VOID
> + );
> +
> +EFI_STATUS
> +PublishPeiMemory (
> + VOID
> + );
> +
> +UINT32
> +GetSystemMemorySizeBelow4gb (
> + VOID
> + );
> +
> +VOID
> +InitializeRamRegions (
> + VOID
> + );
> +
> +VOID
> +InstallFeatureControlCallback (
> + VOID
> + );
> +
> +extern EFI_BOOT_MODE mBootMode;
> +
> +extern BOOLEAN mS3Supported;
> +
> +extern UINT8 mPhysMemAddressWidth;
> +
> +extern UINT32 mMaxCpuCount;
> +
> +extern UINT16 mHostBridgeDevId;
> +#endif // _PLATFORM_PEI_H_INCLUDED_
> diff --git a/Platform/Intel/SimicsOpenBoardPkg/SimicsPei/SimicsPei.inf
> b/Platform/Intel/SimicsOpenBoardPkg/SimicsPei/SimicsPei.inf
> new file mode 100644
> index 0000000000..ccc7037d75
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/SimicsPei/SimicsPei.inf
> @@ -0,0 +1,104 @@
> +## @file
> +# Platform PEI driver
> +#
> +# This module provides platform specific function to detect boot mode.
> +# Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> + INF_VERSION = 0x00010005
> + BASE_NAME = SimicsPei
> + FILE_GUID = 05116218-f9f1-41f8-8d17-c2207006ffff
> + MODULE_TYPE = PEIM
> + VERSION_STRING = 1.0
> + ENTRY_POINT = InitializePlatform
> +
> +#
> +# The following information is for reference only and not required by the build
> tools.
> +#
> +# VALID_ARCHITECTURES = IA32 X64 EBC
> +#
> +
> +[Sources]
> + Cmos.c
> + FeatureControl.c
> + MemDetect.c
> + Platform.c
> +
> +[Packages]
> + MdePkg/MdePkg.dec
> + MdeModulePkg/MdeModulePkg.dec
> + UefiCpuPkg/UefiCpuPkg.dec
> + SimicsOpenBoardPkg/OpenBoardPkg.dec
> + MinPlatformPkg/MinPlatformPkg.dec
> + SimicsX58SktPkg/SktPkg.dec
> + SimicsIch10Pkg/Ich10Pkg.dec
> +
> +[Guids]
> + gEfiMemoryTypeInformationGuid
> + gEfiSmmPeiSmramMemoryReserveGuid ## CONSUMES
> +
> +[LibraryClasses]
> + BaseLib
> + DebugLib
> + HobLib
> + IoLib
> + PciLib
> + PeiResourcePublicationLib
> + PeiServicesLib
> + PeiServicesTablePointerLib
> + PeimEntryPoint
> + MtrrLib
> + PcdLib
> +
> +[Pcd]
> + gBoardModuleTokenSpaceGuid.PcdSimicsPeiMemFvBase
> + gBoardModuleTokenSpaceGuid.PcdSimicsPeiMemFvSize
> + gBoardModuleTokenSpaceGuid.PcdSimicsDxeMemFvBase
> + gBoardModuleTokenSpaceGuid.PcdSimicsDxeMemFvSize
> + gBoardModuleTokenSpaceGuid.PcdSimicsLockBoxStorageBase
> + gBoardModuleTokenSpaceGuid.PcdSimicsLockBoxStorageSize
> + gBoardModuleTokenSpaceGuid.PcdSimicsSecPageTablesBase
> + gBoardModuleTokenSpaceGuid.PcdSimicsSecPeiTempRamBase
> + gBoardModuleTokenSpaceGuid.PcdSimicsSecPeiTempRamSize
> + gEfiMdePkgTokenSpaceGuid.PcdGuidedExtractHandlerTableAddress
> + gBoardModuleTokenSpaceGuid.PcdGuidedExtractHandlerTableSize
> + gBoardModuleTokenSpaceGuid.PcdSimicsDecompressionScratchEnd
> + gBoardModuleTokenSpaceGuid.PcdSimicsX58HostBridgePciDevId
> + gBoardModuleTokenSpaceGuid.PcdPciIoBase
> + gBoardModuleTokenSpaceGuid.PcdPciIoSize
> + gBoardModuleTokenSpaceGuid.PcdPciMmio32Base
> + gBoardModuleTokenSpaceGuid.PcdPciMmio32Size
> + gBoardModuleTokenSpaceGuid.PcdPciMmio64Base
> + gBoardModuleTokenSpaceGuid.PcdPciMmio64Size
> + gSimicsX58PkgTokenSpaceGuid.PcdX58TsegMbytes
> + gSimicsX58PkgTokenSpaceGuid.PcdSmmSmramRequire
> + gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize
> + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
> + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
> + gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvStoreReserved
> + gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode
> + gEfiMdeModulePkgTokenSpaceGuid.PcdUse1GPageTable
> + gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiS3Enable
> + gUefiCpuPkgTokenSpaceGuid.PcdCpuLocalApicBaseAddress
> + gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber
> + gUefiCpuPkgTokenSpaceGuid.PcdCpuApInitTimeOutInMicroSeconds
> + gUefiCpuPkgTokenSpaceGuid.PcdCpuApStackSize
> + gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaBaseAddress ## CONSUMES
> + gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaSize ## CONSUMES
> + gMinPlatformPkgTokenSpaceGuid.PcdIoApicId
> +
> +[FixedPcd]
> + gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
> +
> +
> +[Ppis]
> + gEfiPeiMasterBootModePpiGuid
> + gEfiPeiMpServicesPpiGuid
> +
> +[Depex]
> + TRUE
> +
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.
> h
> b/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.
> h
> new file mode 100644
> index 0000000000..f9c641845c
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.
> h
> @@ -0,0 +1,38 @@
> +/** @file
> + This driver installs SMBIOS information for QSP
> +
> + Copyright (c) 2011, Bei Guan <gbtju85@gmail.com>
> + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _SMBIOS_PLATFORM_DXE_H_
> +#define _SMBIOS_PLATFORM_DXE_H_
> +
> +#include <PiDxe.h>
> +
> +#include <Protocol/Smbios.h>
> +#include <IndustryStandard/SmBios.h>
> +#include <Library/DebugLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/IoLib.h>
> +
> +/**
> + Validates the SMBIOS entry point structure
> +
> + @param EntryPointStructure SMBIOS entry point structure
> +
> + @retval TRUE The entry point structure is valid
> + @retval FALSE The entry point structure is not valid
> +
> +**/
> +BOOLEAN
> +IsEntryPointStructureValid (
> + IN SMBIOS_TABLE_ENTRY_POINT *EntryPointStructure
> + );
> +
> +#endif
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.
> inf
> b/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.
> inf
> new file mode 100644
> index 0000000000..1420a315cf
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.
> inf
> @@ -0,0 +1,51 @@
> +## @file
> +# This driver installs SMBIOS information for QSP
> +#
> +# Copyright (c) 2011, Bei Guan <gbtju85@gmail.com>
> +# Copyright (c) 2011 - 2019, Intel Corporation. All rights reserved.<BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> + INF_VERSION = 0x00010005
> + BASE_NAME = SmbiosPlatformDxe
> + FILE_GUID = 4b18323d-2d42-4afa-b9e5-91516a6fe505
> + MODULE_TYPE = DXE_DRIVER
> + VERSION_STRING = 1.0
> +
> + ENTRY_POINT = SmbiosTablePublishEntry
> +
> +#
> +# The following information is for reference only and not required by the build
> tools.
> +#
> +# VALID_ARCHITECTURES = IA32 X64 EBC ARM AARCH64
> +#
> +
> +[Sources]
> + SmbiosPlatformDxe.h
> + SmbiosPlatformDxe.c
> +
> +[Packages]
> + MdePkg/MdePkg.dec
> + MdeModulePkg/MdeModulePkg.dec
> + SimicsOpenBoardPkg/OpenBoardPkg.dec
> + AdvancedFeaturePkg/AdvancedFeaturePkg.dec
> +
> +[LibraryClasses]
> + UefiBootServicesTableLib
> + BaseMemoryLib
> + BaseLib
> + UefiDriverEntryPoint
> + DebugLib
> + HobLib
> + MemoryAllocationLib
> + IoLib
> +
> +[Protocols]
> + gEfiSmbiosProtocolGuid # PROTOCOL ALWAYS_CONSUMED
> +
> +[Depex]
> + gEfiSmbiosProtocolGuid
> +
> --
> 2.16.2.windows.1
next prev parent reply other threads:[~2019-09-04 6:40 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-08-30 21:19 [edk2-platforms PATCH v4 0/7] Add Initial QSP MinPlatform Pkg for SIMICS David Wei
2019-08-30 21:19 ` [edk2-platforms PATCH v4 1/7] SimicsX58SktPkg: Add CPU Pkg for SimicsX58 David Wei
2019-09-03 4:01 ` Nate DeSimone
2019-09-04 6:39 ` [edk2-devel] " Kubacki, Michael A
2019-08-30 21:19 ` [edk2-platforms PATCH v4 2/7] SimicsIch10Pkg: Add ICH Pkg for SimicsICH10 David Wei
2019-09-03 4:01 ` Nate DeSimone
2019-09-04 6:40 ` Kubacki, Michael A
2019-08-30 21:19 ` [edk2-platforms PATCH v4 3/7] SimicsOpenBoardPkg: Add SimicsOpenBoardPkg and its modules David Wei
2019-09-03 4:06 ` Nate DeSimone
2019-09-04 6:40 ` Kubacki, Michael A [this message]
2019-08-30 21:19 ` [edk2-platforms PATCH v4 4/7] SimicsOpenBoardPkg: Add DXE driver for Legacy Sio David Wei
2019-09-03 4:08 ` Nate DeSimone
2019-09-04 6:40 ` Kubacki, Michael A
2019-08-30 21:19 ` [edk2-platforms PATCH v4 5/7] SimicsOpenBoardPkg: Add modules and dec file under SimicsOpenBoardPkg David Wei
2019-09-03 4:13 ` Nate DeSimone
2019-09-04 6:40 ` Kubacki, Michael A
2019-08-30 21:19 ` [edk2-platforms PATCH v4 6/7] Platform/Intel: Add build option for SIMICS QSP Platform David Wei
2019-09-03 4:54 ` Nate DeSimone
2019-09-04 6:40 ` [edk2-devel] " Kubacki, Michael A
2019-08-30 21:19 ` [edk2-platforms PATCH v4 7/7] SimicsOpenBoardPkg/BoardX58Ich10: Add board modules for QSP Build tip David Wei
2019-09-03 4:56 ` Nate DeSimone
2019-09-04 6:40 ` Kubacki, Michael A
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=49AB4ACB9627B8468F29D589A27B745588AA0250@ORSMSX121.amr.corp.intel.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox