Add IntelFspPkg to support create FSP bin based on EDKII.
authorjyao1 <jyao1>
Tue, 29 Jul 2014 02:21:52 +0000 (02:21 +0000)
committerjyao1 <jyao1@6f19259b-4bc3-4df7-8a09-765794883524>
Tue, 29 Jul 2014 02:21:52 +0000 (02:21 +0000)
Contributed-under: TianoCore Contribution Agreement 1.0

Signed off by: Ravi Rangarajan <ravi.p.rangarajan@intel.com>
Reviewed by: Maurice Ma <maurice.ma@intel.com>
Reviewed by: Jiewen Yao <jiewen.yao@intel.com>
Reviewed by: Giri Mudusuru <giri.p.mudusuru@intel.com>
Reviewed by: Liming Gao <liming.gao@intel.com>

git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15705 6f19259b-4bc3-4df7-8a09-765794883524

64 files changed:
IntelFspPkg/FspDxeIpl/DxeIpl.c [new file with mode: 0644]
IntelFspPkg/FspDxeIpl/DxeIpl.h [new file with mode: 0644]
IntelFspPkg/FspDxeIpl/FspDxeIpl.inf [new file with mode: 0644]
IntelFspPkg/FspSecCore/FspSecCore.inf [new file with mode: 0644]
IntelFspPkg/FspSecCore/Ia32/FspApiEntry.asm [new file with mode: 0644]
IntelFspPkg/FspSecCore/Ia32/FspApiEntry.s [new file with mode: 0644]
IntelFspPkg/FspSecCore/Ia32/InitializeFpu.asm [new file with mode: 0644]
IntelFspPkg/FspSecCore/Ia32/InitializeFpu.s [new file with mode: 0644]
IntelFspPkg/FspSecCore/Ia32/ResetVec.asm16 [new file with mode: 0644]
IntelFspPkg/FspSecCore/Ia32/SaveRestoreSse.inc [new file with mode: 0644]
IntelFspPkg/FspSecCore/Ia32/Stack.asm [new file with mode: 0644]
IntelFspPkg/FspSecCore/Ia32/Stacks.s [new file with mode: 0644]
IntelFspPkg/FspSecCore/Ia32/UcodeLoad.inc [new file with mode: 0644]
IntelFspPkg/FspSecCore/SecFsp.c [new file with mode: 0644]
IntelFspPkg/FspSecCore/SecFsp.h [new file with mode: 0644]
IntelFspPkg/FspSecCore/SecMain.c [new file with mode: 0644]
IntelFspPkg/FspSecCore/SecMain.h [new file with mode: 0644]
IntelFspPkg/FspSecCore/Vtf0/Bin/ResetVec.ia32.raw [new file with mode: 0644]
IntelFspPkg/FspSecCore/Vtf0/Build.py [new file with mode: 0644]
IntelFspPkg/FspSecCore/Vtf0/Ia16/ResetVec.asm16 [new file with mode: 0644]
IntelFspPkg/FspSecCore/Vtf0/ResetVectorCode.asm [new file with mode: 0644]
IntelFspPkg/FspSecCore/Vtf0/Tools/FixupForRawSection.py [new file with mode: 0644]
IntelFspPkg/Include/Guid/GuidHobFsp.h [new file with mode: 0644]
IntelFspPkg/Include/Library/CacheAsRamLib.h [new file with mode: 0644]
IntelFspPkg/Include/Library/CacheLib.h [new file with mode: 0644]
IntelFspPkg/Include/Library/DebugDeviceLib.h [new file with mode: 0644]
IntelFspPkg/Include/Library/FspCommonLib.h [new file with mode: 0644]
IntelFspPkg/Include/Library/FspPlatformLib.h [new file with mode: 0644]
IntelFspPkg/Include/Library/FspReturnLib.h [new file with mode: 0644]
IntelFspPkg/Include/Library/FspSwitchStackLib.h [new file with mode: 0644]
IntelFspPkg/Include/Private/FspGlobalData.h [new file with mode: 0644]
IntelFspPkg/Include/Private/FspMeasurePointId.h [new file with mode: 0644]
IntelFspPkg/Include/Private/FspPatchTable.h [new file with mode: 0644]
IntelFspPkg/Include/Private/GuidHobFspGfx.h [new file with mode: 0644]
IntelFspPkg/Include/Private/GuidHobFspMisc.h [new file with mode: 0644]
IntelFspPkg/Include/Private/GuidHobFspTseg.h [new file with mode: 0644]
IntelFspPkg/IntelFspPkg.dec
IntelFspPkg/IntelFspPkg.dsc [new file with mode: 0644]
IntelFspPkg/Library/BaseCacheAsRamLibNull/BaseCacheAsRamLibNull.inf [new file with mode: 0644]
IntelFspPkg/Library/BaseCacheAsRamLibNull/DisableCacheAsRamNull.c [new file with mode: 0644]
IntelFspPkg/Library/BaseCacheLib/BaseCacheLib.inf [new file with mode: 0644]
IntelFspPkg/Library/BaseCacheLib/CacheLib.c [new file with mode: 0644]
IntelFspPkg/Library/BaseCacheLib/CacheLibInternal.h [new file with mode: 0644]
IntelFspPkg/Library/BaseDebugDeviceLibNull/BaseDebugDeviceLibNull.inf [new file with mode: 0644]
IntelFspPkg/Library/BaseDebugDeviceLibNull/DebugDeviceLibNull.c [new file with mode: 0644]
IntelFspPkg/Library/BaseFspCommonLib/BaseFspCommonLib.inf [new file with mode: 0644]
IntelFspPkg/Library/BaseFspCommonLib/FspCommonLib.c [new file with mode: 0644]
IntelFspPkg/Library/BaseFspDebugLibSerialPort/BaseFspDebugLibSerialPort.inf [new file with mode: 0644]
IntelFspPkg/Library/BaseFspDebugLibSerialPort/DebugLib.c [new file with mode: 0644]
IntelFspPkg/Library/BaseFspDebugLibSerialPort/Ia32/FspDebug.asm [new file with mode: 0644]
IntelFspPkg/Library/BaseFspDebugLibSerialPort/Ia32/FspDebug.s [new file with mode: 0644]
IntelFspPkg/Library/BaseFspPlatformLib/BaseFspPlatformLib.inf [new file with mode: 0644]
IntelFspPkg/Library/BaseFspPlatformLib/FspPlatformMemory.c [new file with mode: 0644]
IntelFspPkg/Library/BaseFspPlatformLib/FspPlatformNotify.c [new file with mode: 0644]
IntelFspPkg/Library/BaseFspSwitchStackLib/BaseFspSwitchStackLib.inf [new file with mode: 0644]
IntelFspPkg/Library/BaseFspSwitchStackLib/FspSwitchStackLib.c [new file with mode: 0644]
IntelFspPkg/Library/BaseFspSwitchStackLib/Ia32/Stack.asm [new file with mode: 0644]
IntelFspPkg/Library/BaseFspSwitchStackLib/Ia32/Stack.s [new file with mode: 0644]
IntelFspPkg/Library/SecPlatformSecLibNull/PlatformSecLibNull.c [new file with mode: 0644]
IntelFspPkg/Library/SecPlatformSecLibNull/SecPlatformSecLibNull.inf [new file with mode: 0644]
IntelFspPkg/Tools/GenCfgOpt.py [new file with mode: 0644]
IntelFspPkg/Tools/PatchFv.py [new file with mode: 0644]
IntelFspPkg/Tools/UserManuals/GenCfgOptUserManual.docx [new file with mode: 0644]
IntelFspPkg/Tools/UserManuals/PatchFvUserManual.docx [new file with mode: 0644]

diff --git a/IntelFspPkg/FspDxeIpl/DxeIpl.c b/IntelFspPkg/FspDxeIpl/DxeIpl.c
new file mode 100644 (file)
index 0000000..24e6ef7
--- /dev/null
@@ -0,0 +1,464 @@
+/** @file\r
+\r
+  Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php.\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "DxeIpl.h"\r
+\r
+\r
+//\r
+// Module Globals used in the DXE to PEI hand off\r
+// These must be module globals, so the stack can be switched\r
+//\r
+CONST EFI_DXE_IPL_PPI mDxeIplPpi = {\r
+  DxeLoadCore\r
+};\r
+\r
+CONST EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI mCustomGuidedSectionExtractionPpi = {\r
+  CustomGuidedSectionExtract\r
+};\r
+\r
+CONST EFI_PEI_DECOMPRESS_PPI mDecompressPpi = {\r
+  Decompress\r
+};\r
+\r
+CONST EFI_PEI_PPI_DESCRIPTOR mPpiList[] = {\r
+  {\r
+    EFI_PEI_PPI_DESCRIPTOR_PPI,\r
+    &gEfiDxeIplPpiGuid,\r
+    (VOID *) &mDxeIplPpi\r
+  },\r
+  {\r
+    (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
+    &gEfiPeiDecompressPpiGuid,\r
+    (VOID *) &mDecompressPpi\r
+  }\r
+};\r
+\r
+CONST EFI_PEI_PPI_DESCRIPTOR gEndOfPeiSignalPpi = {\r
+  (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
+  &gEfiEndOfPeiSignalPpiGuid,\r
+  NULL\r
+};\r
+\r
+/**\r
+  Entry point of DXE IPL PEIM.\r
+\r
+  This function installs DXE IPL PPI and Decompress PPI.  It also reloads\r
+  itself to memory on non-S3 resume boot path.\r
+\r
+  @param[in] FileHandle  Handle of the file being invoked.\r
+  @param[in] PeiServices Describes the list of possible PEI Services.\r
+\r
+  @retval EFI_SUCESS  The entry point of DXE IPL PEIM executes successfully.\r
+  @retval Others      Some error occurs during the execution of this function.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+PeimInitializeDxeIpl (\r
+  IN       EFI_PEI_FILE_HANDLE  FileHandle,\r
+  IN CONST EFI_PEI_SERVICES     **PeiServices\r
+  )\r
+{\r
+  EFI_STATUS                                Status;\r
+  EFI_GUID                                  *ExtractHandlerGuidTable;\r
+  UINTN                                     ExtractHandlerNumber;\r
+  EFI_PEI_PPI_DESCRIPTOR                    *GuidPpi;\r
+\r
+  //\r
+  // Get custom extract guided section method guid list\r
+  //\r
+  ExtractHandlerNumber = ExtractGuidedSectionGetGuidList (&ExtractHandlerGuidTable);\r
+\r
+  //\r
+  // Install custom extraction guid PPI\r
+  //\r
+  if (ExtractHandlerNumber > 0) {\r
+    GuidPpi = (EFI_PEI_PPI_DESCRIPTOR *) AllocatePool (ExtractHandlerNumber * sizeof (EFI_PEI_PPI_DESCRIPTOR));\r
+    ASSERT (GuidPpi != NULL);\r
+    while (ExtractHandlerNumber-- > 0) {\r
+      GuidPpi->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;\r
+      GuidPpi->Ppi   = (VOID *) &mCustomGuidedSectionExtractionPpi;\r
+      GuidPpi->Guid  = &ExtractHandlerGuidTable[ExtractHandlerNumber];\r
+      Status = PeiServicesInstallPpi (GuidPpi++);\r
+      ASSERT_EFI_ERROR(Status);\r
+    }\r
+  }\r
+\r
+  //\r
+  // Install DxeIpl and Decompress PPIs.\r
+  //\r
+  Status = PeiServicesInstallPpi (mPpiList);\r
+  ASSERT_EFI_ERROR(Status);\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  The ExtractSection() function processes the input section and\r
+  returns a pointer to the section contents. If the section being\r
+  extracted does not require processing (if the section\r
+  GuidedSectionHeader.Attributes has the\r
+  EFI_GUIDED_SECTION_PROCESSING_REQUIRED field cleared), then\r
+  OutputBuffer is just updated to point to the start of the\r
+  section's contents. Otherwise, *Buffer must be allocated\r
+  from PEI permanent memory.\r
+\r
+  @param[in]  This                   Indicates the\r
+                                     EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI instance.\r
+                                     Buffer containing the input GUIDed section to be\r
+                                     processed. OutputBuffer OutputBuffer is\r
+                                     allocated from PEI permanent memory and contains\r
+                                     the new section stream.\r
+  @param[in]  InputSection           A pointer to the input buffer, which contains\r
+                                     the input section to be processed.\r
+  @param[out] OutputBuffer           A pointer to a caller-allocated buffer, whose\r
+                                     size is specified by the contents of OutputSize.\r
+  @param[out] OutputSize             A pointer to a caller-allocated\r
+                                     UINTN in which the size of *OutputBuffer\r
+                                     allocation is stored. If the function\r
+                                     returns anything other than EFI_SUCCESS,\r
+                                     the value of OutputSize is undefined.\r
+  @param[out] AuthenticationStatus   A pointer to a caller-allocated\r
+                                     UINT32 that indicates the\r
+                                     authentication status of the\r
+                                     output buffer. If the input\r
+                                     section's GuidedSectionHeader.\r
+                                     Attributes field has the\r
+                                     EFI_GUIDED_SECTION_AUTH_STATUS_VALID\r
+                                     bit as clear,\r
+                                     AuthenticationStatus must return\r
+                                     zero. These bits reflect the\r
+                                     status of the extraction\r
+                                     operation. If the function\r
+                                     returns anything other than\r
+                                     EFI_SUCCESS, the value of\r
+                                     AuthenticationStatus is\r
+                                     undefined.\r
+\r
+  @retval EFI_SUCCESS           The InputSection was\r
+                                successfully processed and the\r
+                                section contents were returned.\r
+\r
+  @retval EFI_OUT_OF_RESOURCES  The system has insufficient\r
+                                resources to process the request.\r
+\r
+  @retval EFI_INVALID_PARAMETER The GUID in InputSection does\r
+                                not match this instance of the\r
+                                GUIDed Section Extraction PPI.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+CustomGuidedSectionExtract (\r
+  IN CONST  EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI *This,\r
+  IN CONST  VOID                                  *InputSection,\r
+  OUT       VOID                                  **OutputBuffer,\r
+  OUT       UINTN                                 *OutputSize,\r
+  OUT       UINT32                                *AuthenticationStatus\r
+)\r
+{\r
+  EFI_STATUS      Status;\r
+  UINT8           *ScratchBuffer;\r
+  UINT32          ScratchBufferSize;\r
+  UINT32          OutputBufferSize;\r
+  UINT16          SectionAttribute;\r
+\r
+  //\r
+  // Init local variable\r
+  //\r
+  ScratchBuffer = NULL;\r
+\r
+  //\r
+  // Call GetInfo to get the size and attribute of input guided section data.\r
+  //\r
+  Status = ExtractGuidedSectionGetInfo (\r
+             InputSection,\r
+             &OutputBufferSize,\r
+             &ScratchBufferSize,\r
+             &SectionAttribute\r
+             );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((DEBUG_ERROR, "GetInfo from guided section Failed - %r\n", Status));\r
+    return Status;\r
+  }\r
+\r
+  if (ScratchBufferSize != 0) {\r
+    //\r
+    // Allocate scratch buffer\r
+    //\r
+    ScratchBuffer = AllocatePages (EFI_SIZE_TO_PAGES (ScratchBufferSize));\r
+    if (ScratchBuffer == NULL) {\r
+      return EFI_OUT_OF_RESOURCES;\r
+    }\r
+  }\r
+\r
+  if (((SectionAttribute & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) != 0) && OutputBufferSize > 0) {\r
+    //\r
+    // Allocate output buffer\r
+    //\r
+    *OutputBuffer = AllocatePages (EFI_SIZE_TO_PAGES (OutputBufferSize) + 1);\r
+    if (*OutputBuffer == NULL) {\r
+      return EFI_OUT_OF_RESOURCES;\r
+    }\r
+    DEBUG ((DEBUG_INFO, "Customized Guided section Memory Size required is 0x%x and address is 0x%p\n", OutputBufferSize, *OutputBuffer));\r
+    //\r
+    // *OutputBuffer still is one section. Adjust *OutputBuffer offset,\r
+    // skip EFI section header to make section data at page alignment.\r
+    //\r
+    *OutputBuffer = (VOID *)((UINT8 *) *OutputBuffer + EFI_PAGE_SIZE - sizeof (EFI_COMMON_SECTION_HEADER));\r
+  }\r
+\r
+  Status = ExtractGuidedSectionDecode (\r
+             InputSection,\r
+             OutputBuffer,\r
+             ScratchBuffer,\r
+             AuthenticationStatus\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    //\r
+    // Decode failed\r
+    //\r
+    DEBUG ((DEBUG_ERROR, "Extract guided section Failed - %r\n", Status));\r
+    return Status;\r
+  }\r
+\r
+  *OutputSize = (UINTN) OutputBufferSize;\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+\r
+/**\r
+   Decompresses a section to the output buffer.\r
+\r
+   This function looks up the compression type field in the input section and\r
+   applies the appropriate compression algorithm to compress the section to a\r
+   callee allocated buffer.\r
+\r
+   @param[in]  This                  Points to this instance of the\r
+                                     EFI_PEI_DECOMPRESS_PEI PPI.\r
+   @param[in]  CompressionSection    Points to the compressed section.\r
+   @param[out] OutputBuffer          Holds the returned pointer to the decompressed\r
+                                     sections.\r
+   @param[out] OutputSize            Holds the returned size of the decompress\r
+                                     section streams.\r
+\r
+   @retval EFI_SUCCESS           The section was decompressed successfully.\r
+                                 OutputBuffer contains the resulting data and\r
+                                 OutputSize contains the resulting size.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Decompress (\r
+  IN CONST  EFI_PEI_DECOMPRESS_PPI  *This,\r
+  IN CONST  EFI_COMPRESSION_SECTION *CompressionSection,\r
+  OUT       VOID                    **OutputBuffer,\r
+  OUT       UINTN                   *OutputSize\r
+ )\r
+{\r
+  EFI_STATUS                      Status;\r
+  UINT8                           *DstBuffer;\r
+  UINT8                           *ScratchBuffer;\r
+  UINT32                          DstBufferSize;\r
+  UINT32                          ScratchBufferSize;\r
+  VOID                            *CompressionSource;\r
+  UINT32                          CompressionSourceSize;\r
+  UINT32                          UncompressedLength;\r
+  UINT8                           CompressionType;\r
+\r
+  if (CompressionSection->CommonHeader.Type != EFI_SECTION_COMPRESSION) {\r
+    ASSERT (FALSE);\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (IS_SECTION2 (CompressionSection)) {\r
+    CompressionSource = (VOID *) ((UINT8 *) CompressionSection + sizeof (EFI_COMPRESSION_SECTION2));\r
+    CompressionSourceSize = (UINT32) (SECTION2_SIZE (CompressionSection) - sizeof (EFI_COMPRESSION_SECTION2));\r
+    UncompressedLength = ((EFI_COMPRESSION_SECTION2 *) CompressionSection)->UncompressedLength;\r
+    CompressionType = ((EFI_COMPRESSION_SECTION2 *) CompressionSection)->CompressionType;\r
+  } else {\r
+    CompressionSource = (VOID *) ((UINT8 *) CompressionSection + sizeof (EFI_COMPRESSION_SECTION));\r
+    CompressionSourceSize = (UINT32) (SECTION_SIZE (CompressionSection) - sizeof (EFI_COMPRESSION_SECTION));\r
+    UncompressedLength = CompressionSection->UncompressedLength;\r
+    CompressionType = CompressionSection->CompressionType;\r
+  }\r
+\r
+  //\r
+  // This is a compression set, expand it\r
+  //\r
+  switch (CompressionType) {\r
+  case EFI_STANDARD_COMPRESSION:\r
+    if (TRUE) {\r
+      //\r
+      // Load EFI standard compression.\r
+      // For compressed data, decompress them to destination buffer.\r
+      //\r
+      Status = UefiDecompressGetInfo (\r
+                 CompressionSource,\r
+                 CompressionSourceSize,\r
+                 &DstBufferSize,\r
+                 &ScratchBufferSize\r
+                 );\r
+      if (EFI_ERROR (Status)) {\r
+        //\r
+        // GetInfo failed\r
+        //\r
+        DEBUG ((DEBUG_ERROR, "Decompress GetInfo Failed - %r\n", Status));\r
+        return EFI_NOT_FOUND;\r
+      }\r
+      //\r
+      // Allocate scratch buffer\r
+      //\r
+      ScratchBuffer = AllocatePages (EFI_SIZE_TO_PAGES (ScratchBufferSize));\r
+      if (ScratchBuffer == NULL) {\r
+        return EFI_OUT_OF_RESOURCES;\r
+      }\r
+      //\r
+      // Allocate destination buffer, extra one page for adjustment\r
+      //\r
+      DstBuffer = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize) + 1);\r
+      if (DstBuffer == NULL) {\r
+        return EFI_OUT_OF_RESOURCES;\r
+      }\r
+      //\r
+      // DstBuffer still is one section. Adjust DstBuffer offset, skip EFI section header\r
+      // to make section data at page alignment.\r
+      //\r
+      DstBuffer = DstBuffer + EFI_PAGE_SIZE - sizeof (EFI_COMMON_SECTION_HEADER);\r
+      //\r
+      // Call decompress function\r
+      //\r
+      Status = UefiDecompress (\r
+                  CompressionSource,\r
+                  DstBuffer,\r
+                  ScratchBuffer\r
+                  );\r
+      if (EFI_ERROR (Status)) {\r
+        //\r
+        // Decompress failed\r
+        //\r
+        DEBUG ((DEBUG_ERROR, "Decompress Failed - %r\n", Status));\r
+        return EFI_NOT_FOUND;\r
+      }\r
+      break;\r
+    } else {\r
+      //\r
+      // PcdDxeIplSupportUefiDecompress is FALSE\r
+      // Don't support UEFI decompression algorithm.\r
+      //\r
+      ASSERT (FALSE);\r
+      return EFI_NOT_FOUND;\r
+    }\r
+\r
+  case EFI_NOT_COMPRESSED:\r
+    //\r
+    // Allocate destination buffer\r
+    //\r
+    DstBufferSize = UncompressedLength;\r
+    DstBuffer     = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize) + 1);\r
+    if (DstBuffer == NULL) {\r
+      return EFI_OUT_OF_RESOURCES;\r
+    }\r
+    //\r
+    // Adjust DstBuffer offset, skip EFI section header\r
+    // to make section data at page alignment.\r
+    //\r
+    DstBuffer = DstBuffer + EFI_PAGE_SIZE - sizeof (EFI_COMMON_SECTION_HEADER);\r
+    //\r
+    // stream is not actually compressed, just encapsulated.  So just copy it.\r
+    //\r
+    CopyMem (DstBuffer, CompressionSource, DstBufferSize);\r
+    break;\r
+\r
+  default:\r
+    //\r
+    // Don't support other unknown compression type.\r
+    //\r
+    ASSERT (FALSE);\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  *OutputSize = DstBufferSize;\r
+  *OutputBuffer = DstBuffer;\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+   Main entry point to last PEIM.\r
+\r
+   This function finds DXE Core in the firmware volume and transfer the control to\r
+   DXE core.\r
+\r
+   @param[in] This          Entry point for DXE IPL PPI.\r
+   @param[in] PeiServices   General purpose services available to every PEIM.\r
+   @param[in] HobList       Address to the Pei HOB list.\r
+\r
+   @return EFI_SUCCESS              DXE core was successfully loaded.\r
+   @return EFI_OUT_OF_RESOURCES     There are not enough resources to load DXE core.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+DxeLoadCore (\r
+  IN CONST EFI_DXE_IPL_PPI *This,\r
+  IN EFI_PEI_SERVICES      **PeiServices,\r
+  IN EFI_PEI_HOB_POINTERS  HobList\r
+  )\r
+{\r
+  EFI_STATUS   Status;\r
+\r
+  DEBUG ((DEBUG_INFO | DEBUG_INIT, "FSP HOB is located at 0x%08X\n", HobList));\r
+\r
+  //\r
+  // Give control back to bootloader after FspInit\r
+  //\r
+  DEBUG ((DEBUG_INFO | DEBUG_INIT, "FSP is waiting for NOTIFY\n"));\r
+  FspInitDone ();\r
+\r
+  //\r
+  // Bootloader called FSP again through NotifyPhase\r
+  //\r
+  FspWaitForNotify ();\r
+\r
+  //\r
+  // End of PEI phase signal\r
+  //\r
+  Status = PeiServicesInstallPpi (&gEndOfPeiSignalPpi);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  //\r
+  // Give control back to the boot loader framework caller\r
+  //\r
+  DEBUG ((DEBUG_INFO | DEBUG_INIT,   "============= PEIM FSP is Completed =============\n\n"));\r
+\r
+  SetFspApiReturnStatus(EFI_SUCCESS);\r
+\r
+  SetFspMeasurePoint (FSP_PERF_ID_API_NOTIFY_RDYBOOT_EXIT);\r
+\r
+  Pei2LoaderSwitchStack();\r
+\r
+  //\r
+  // Should not come here\r
+  //\r
+  while (TRUE) {\r
+    DEBUG ((DEBUG_ERROR, "No FSP API should be called after FSP is DONE!\n"));\r
+    SetFspApiReturnStatus(EFI_UNSUPPORTED);\r
+    Pei2LoaderSwitchStack();\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
diff --git a/IntelFspPkg/FspDxeIpl/DxeIpl.h b/IntelFspPkg/FspDxeIpl/DxeIpl.h
new file mode 100644 (file)
index 0000000..0aded72
--- /dev/null
@@ -0,0 +1,192 @@
+/** @file\r
+\r
+  Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php.\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef __PEI_DXEIPL_H__\r
+#define __PEI_DXEIPL_H__\r
+\r
+#include <PiPei.h>\r
+#include <Ppi/DxeIpl.h>\r
+#include <Ppi/EndOfPeiPhase.h>\r
+#include <Ppi/MemoryDiscovered.h>\r
+#include <Ppi/Decompress.h>\r
+#include <Ppi/FirmwareVolumeInfo.h>\r
+#include <Ppi/GuidedSectionExtraction.h>\r
+\r
+#include <Library/DebugLib.h>\r
+#include <Library/PeimEntryPoint.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/HobLib.h>\r
+#include <Library/PeiServicesLib.h>\r
+#include <Library/ReportStatusCodeLib.h>\r
+#include <Library/UefiDecompressLib.h>\r
+#include <Library/ExtractGuidedSectionLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/PcdLib.h>\r
+#include <Library/FspSwitchStackLib.h>\r
+#include <Library/FspCommonLib.h>\r
+#include <Library/FspPlatformLib.h>\r
+\r
+/**\r
+   Main entry point to last PEIM.\r
+\r
+   This function finds DXE Core in the firmware volume and transfer the control to\r
+   DXE core.\r
+\r
+   @param[in] This          Entry point for DXE IPL PPI.\r
+   @param[in] PeiServices   General purpose services available to every PEIM.\r
+   @param[in] HobList       Address to the Pei HOB list.\r
+\r
+   @return EFI_SUCCESS              DXE core was successfully loaded.\r
+   @return EFI_OUT_OF_RESOURCES     There are not enough resources to load DXE core.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+DxeLoadCore (\r
+  IN CONST EFI_DXE_IPL_PPI *This,\r
+  IN EFI_PEI_SERVICES      **PeiServices,\r
+  IN EFI_PEI_HOB_POINTERS  HobList\r
+  );\r
+\r
+\r
+\r
+/**\r
+   Transfers control to DxeCore.\r
+\r
+   This function performs a CPU architecture specific operations to execute\r
+   the entry point of DxeCore with the parameters of HobList.\r
+   It also installs EFI_END_OF_PEI_PPI to signal the end of PEI phase.\r
+\r
+   @param[in] DxeCoreEntryPoint         The entry point of DxeCore.\r
+   @param[in] HobList                   The start of HobList passed to DxeCore.\r
+\r
+**/\r
+VOID\r
+HandOffToDxeCore (\r
+  IN EFI_PHYSICAL_ADDRESS   DxeCoreEntryPoint,\r
+  IN EFI_PEI_HOB_POINTERS   HobList\r
+  );\r
+\r
+\r
+\r
+/**\r
+   Updates the Stack HOB passed to DXE phase.\r
+\r
+   This function traverses the whole HOB list and update the stack HOB to\r
+   reflect the real stack that is used by DXE core.\r
+\r
+   @param[in] BaseAddress           The lower address of stack used by DxeCore.\r
+   @param[in] Length                The length of stack used by DxeCore.\r
+\r
+**/\r
+VOID\r
+UpdateStackHob (\r
+  IN EFI_PHYSICAL_ADDRESS        BaseAddress,\r
+  IN UINT64                      Length\r
+  );\r
+\r
+/**\r
+  The ExtractSection() function processes the input section and\r
+  returns a pointer to the section contents. If the section being\r
+  extracted does not require processing (if the section\r
+  GuidedSectionHeader.Attributes has the\r
+  EFI_GUIDED_SECTION_PROCESSING_REQUIRED field cleared), then\r
+  OutputBuffer is just updated to point to the start of the\r
+  section's contents. Otherwise, *Buffer must be allocated\r
+  from PEI permanent memory.\r
+\r
+  @param[in]  This                   Indicates the\r
+                                     EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI instance.\r
+                                     Buffer containing the input GUIDed section to be\r
+                                     processed. OutputBuffer OutputBuffer is\r
+                                     allocated from PEI permanent memory and contains\r
+                                     the new section stream.\r
+  @param[in]  InputSection           A pointer to the input buffer, which contains\r
+                                     the input section to be processed.\r
+  @param[out] OutputBuffer           A pointer to a caller-allocated buffer, whose\r
+                                     size is specified by the contents of OutputSize.\r
+  @param[out] OutputSize             A pointer to a caller-allocated\r
+                                     UINTN in which the size of *OutputBuffer\r
+                                     allocation is stored. If the function\r
+                                     returns anything other than EFI_SUCCESS,\r
+                                     the value of OutputSize is undefined.\r
+  @param[out] AuthenticationStatus   A pointer to a caller-allocated\r
+                                     UINT32 that indicates the\r
+                                     authentication status of the\r
+                                     output buffer. If the input\r
+                                     section's GuidedSectionHeader.\r
+                                     Attributes field has the\r
+                                     EFI_GUIDED_SECTION_AUTH_STATUS_VALID\r
+                                     bit as clear,\r
+                                     AuthenticationStatus must return\r
+                                     zero. These bits reflect the\r
+                                     status of the extraction\r
+                                     operation. If the function\r
+                                     returns anything other than\r
+                                     EFI_SUCCESS, the value of\r
+                                     AuthenticationStatus is\r
+                                     undefined.\r
+\r
+  @retval EFI_SUCCESS           The InputSection was\r
+                                successfully processed and the\r
+                                section contents were returned.\r
+\r
+  @retval EFI_OUT_OF_RESOURCES  The system has insufficient\r
+                                resources to process the request.\r
+\r
+  @retval EFI_INVALID_PARAMETER The GUID in InputSection does\r
+                                not match this instance of the\r
+                                GUIDed Section Extraction PPI.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+CustomGuidedSectionExtract (\r
+  IN CONST  EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI *This,\r
+  IN CONST  VOID                                  *InputSection,\r
+  OUT       VOID                                  **OutputBuffer,\r
+  OUT       UINTN                                 *OutputSize,\r
+  OUT       UINT32                                *AuthenticationStatus\r
+  );\r
+\r
+/**\r
+   Decompresses a section to the output buffer.\r
+\r
+   This function looks up the compression type field in the input section and\r
+   applies the appropriate compression algorithm to compress the section to a\r
+   callee allocated buffer.\r
+\r
+   @param[in]  This                  Points to this instance of the\r
+                                     EFI_PEI_DECOMPRESS_PEI PPI.\r
+   @param[in]  CompressionSection    Points to the compressed section.\r
+   @param[out] OutputBuffer          Holds the returned pointer to the decompressed\r
+                                     sections.\r
+   @param[out] OutputSize            Holds the returned size of the decompress\r
+                                     section streams.\r
+\r
+   @retval EFI_SUCCESS           The section was decompressed successfully.\r
+                                 OutputBuffer contains the resulting data and\r
+                                 OutputSize contains the resulting size.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Decompress (\r
+  IN CONST  EFI_PEI_DECOMPRESS_PPI  *This,\r
+  IN CONST  EFI_COMPRESSION_SECTION *CompressionSection,\r
+  OUT       VOID                    **OutputBuffer,\r
+  OUT       UINTN                   *OutputSize\r
+  );\r
+\r
+#endif\r
diff --git a/IntelFspPkg/FspDxeIpl/FspDxeIpl.inf b/IntelFspPkg/FspDxeIpl/FspDxeIpl.inf
new file mode 100644 (file)
index 0000000..49317af
--- /dev/null
@@ -0,0 +1,70 @@
+## @file\r
+#\r
+#  Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>\r
+#\r
+#  This program and the accompanying materials\r
+#  are licensed and made available under the terms and conditions of the BSD License\r
+#  which accompanies this distribution. The full text of the license may be found at\r
+#  http://opensource.org/licenses/bsd-license.php.\r
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+##\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = FspDxeIpl\r
+  FILE_GUID                      = 86D70125-BAA3-4296-A62F-602BEBBB9081\r
+  MODULE_TYPE                    = PEIM\r
+  VERSION_STRING                 = 1.0\r
+\r
+  ENTRY_POINT                    = PeimInitializeDxeIpl\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+#  VALID_ARCHITECTURES           = IA32\r
+#\r
+\r
+[Sources]\r
+  DxeIpl.h\r
+  DxeIpl.c\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  IntelFspPkg/IntelFspPkg.dec\r
+\r
+[LibraryClasses]\r
+  PcdLib\r
+  MemoryAllocationLib\r
+  BaseMemoryLib\r
+  ExtractGuidedSectionLib\r
+  UefiDecompressLib\r
+  ReportStatusCodeLib\r
+  PeiServicesLib\r
+  HobLib\r
+  BaseLib\r
+  PeimEntryPoint\r
+  DebugLib\r
+  FspSwitchStackLib\r
+  UefiDecompressLib\r
+  FspCommonLib\r
+  FspPlatformLib\r
+\r
+[Ppis]\r
+  gEfiDxeIplPpiGuid                       ## PRODUCES\r
+  gEfiEndOfPeiSignalPpiGuid               ## SOMETIMES_PRODUCES(Not produced on S3 boot path)\r
+  gEfiPeiDecompressPpiGuid\r
+\r
+[Protocols]\r
+  gEfiPciEnumerationCompleteProtocolGuid  # ALWAYS_PRODUCED\r
+\r
+[Guids]\r
+  gEfiEventReadyToBootGuid                # ALWAYS_PRODUCED\r
+\r
+[FixedPcd]\r
+  gIntelFspPkgTokenSpaceGuid.PcdFspMaxPatchEntry\r
+  gIntelFspPkgTokenSpaceGuid.PcdFspMaxPerfEntry\r
+\r
+[Depex]\r
+  gEfiPeiMemoryDiscoveredPpiGuid AND gEfiPeiLoadFilePpiGuid\r
diff --git a/IntelFspPkg/FspSecCore/FspSecCore.inf b/IntelFspPkg/FspSecCore/FspSecCore.inf
new file mode 100644 (file)
index 0000000..d3ec2fc
--- /dev/null
@@ -0,0 +1,76 @@
+## @file\r
+#\r
+#  Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>\r
+#\r
+#  This program and the accompanying materials\r
+#  are licensed and made available under the terms and conditions of the BSD License\r
+#  which accompanies this distribution. The full text of the license may be found at\r
+#  http://opensource.org/licenses/bsd-license.php.\r
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+##\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = FspSecCore\r
+  FILE_GUID                      = 1BA0062E-C779-4582-8566-336AE8F78F09\r
+  MODULE_TYPE                    = SEC\r
+  VERSION_STRING                 = 1.0\r
+\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+#  VALID_ARCHITECTURES           = IA32\r
+#\r
+\r
+[Sources]\r
+  SecMain.c\r
+  SecMain.h\r
+  SecFsp.c\r
+  SecFsp.h\r
+\r
+[Sources.IA32]\r
+  Ia32/ResetVec.asm16 | MSFT\r
+  Ia32/Stack.asm  | MSFT\r
+  Ia32/InitializeFpu.asm  | MSFT\r
+  Ia32/FspApiEntry.asm  | MSFT\r
+\r
+  Ia32/Stacks.s | GCC\r
+  Ia32/InitializeFpu.s | GCC\r
+  Ia32/FspApiEntry.s | GCC\r
+\r
+[Binaries.Ia32]\r
+  RAW|Vtf0/Bin/ResetVec.ia32.raw |GCC\r
+\r
+[Binaries.X64]\r
+  RAW|Vtf0/Bin/ResetVec.x64.raw |GCC\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  IntelFspPkg/IntelFspPkg.dec\r
+\r
+[LibraryClasses]\r
+  BaseMemoryLib\r
+  DebugLib\r
+  BaseLib\r
+  PciCf8Lib\r
+  SerialPortLib\r
+  FspSwitchStackLib\r
+  FspCommonLib\r
+\r
+[Pcd]\r
+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress\r
+  gIntelFspPkgTokenSpaceGuid.PcdGlobalDataPointerAddress\r
+  gIntelFspPkgTokenSpaceGuid.PcdTemporaryRamBase\r
+  gIntelFspPkgTokenSpaceGuid.PcdTemporaryRamSize\r
+  gIntelFspPkgTokenSpaceGuid.PcdFspTemporaryRamSize\r
+\r
+[FixedPcd]\r
+  gIntelFspPkgTokenSpaceGuid.PcdFspMaxPatchEntry\r
+  gIntelFspPkgTokenSpaceGuid.PcdFspMaxPerfEntry\r
+\r
+[Ppis]\r
+  gEfiTemporaryRamSupportPpiGuid                # PPI ALWAYS_PRODUCED\r
+\r
diff --git a/IntelFspPkg/FspSecCore/Ia32/FspApiEntry.asm b/IntelFspPkg/FspSecCore/Ia32/FspApiEntry.asm
new file mode 100644 (file)
index 0000000..8ad9744
--- /dev/null
@@ -0,0 +1,552 @@
+;------------------------------------------------------------------------------\r
+;\r
+; Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>\r
+; This program and the accompanying materials\r
+; are licensed and made available under the terms and conditions of the BSD License\r
+; which accompanies this distribution.  The full text of the license may be found at\r
+; http://opensource.org/licenses/bsd-license.php.\r
+;\r
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+;\r
+; Abstract:\r
+;\r
+;   Provide FSP API entry points.\r
+;\r
+;------------------------------------------------------------------------------\r
+\r
+    .586p\r
+    .model  flat,C\r
+    .code\r
+    .xmm\r
+\r
+INCLUDE    SaveRestoreSse.inc\r
+INCLUDE    UcodeLoad.inc\r
+\r
+;\r
+; Following are fixed PCDs\r
+;\r
+EXTERN   PcdGet32(PcdTemporaryRamBase):DWORD\r
+EXTERN   PcdGet32(PcdTemporaryRamSize):DWORD\r
+EXTERN   PcdGet32(PcdFspTemporaryRamSize):DWORD\r
+\r
+;\r
+; Following functions will be provided in C\r
+;\r
+EXTERN   FspImageSizeOffset:DWORD\r
+EXTERN   SecStartup:PROC\r
+EXTERN   FspApiCallingCheck:PROC\r
+\r
+;\r
+; Following functions will be provided in PlatformSecLib\r
+;\r
+EXTERN   GetFspBaseAddress:PROC\r
+EXTERN   GetBootFirmwareVolumeOffset:PROC\r
+EXTERN   PlatformTempRamInit:PROC\r
+EXTERN   Pei2LoaderSwitchStack:PROC\r
+EXTERN   FspSelfCheck(FspSelfCheckDflt):PROC\r
+EXTERN   PlatformBasicInit(PlatformBasicInitDflt):PROC\r
+EXTERN   LoadUcode(LoadUcodeDflt):PROC\r
+\r
+;\r
+; Define the data length that we saved on the stack top\r
+;\r
+DATA_LEN_OF_PER0         EQU   18h\r
+DATA_LEN_OF_MCUD         EQU   18h\r
+DATA_LEN_AT_STACK_TOP    EQU   (DATA_LEN_OF_PER0 + DATA_LEN_OF_MCUD + 4)\r
+\r
+;------------------------------------------------------------------------------\r
+FspSelfCheckDflt PROC NEAR PUBLIC\r
+   ; Inputs:\r
+   ;   eax -> Return address\r
+   ; Outputs:\r
+   ;   eax -> 0 - Successful, Non-zero - Failed.\r
+   ; Register Usage:\r
+   ;   eax is cleared and ebp is used for return address.\r
+   ;   All others reserved.\r
+\r
+   ; Save return address to EBP\r
+   mov   ebp, eax\r
+\r
+   xor   eax, eax\r
+exit:\r
+   jmp   ebp\r
+FspSelfCheckDflt   ENDP\r
+\r
+;------------------------------------------------------------------------------\r
+PlatformBasicInitDflt PROC NEAR PUBLIC\r
+   ; Inputs:\r
+   ;   eax -> Return address\r
+   ; Outputs:\r
+   ;   eax -> 0 - Successful, Non-zero - Failed.\r
+   ; Register Usage:\r
+   ;   eax is cleared and ebp is used for return address.\r
+   ;   All others reserved.\r
+\r
+   ; Save return address to EBP\r
+   mov   ebp, eax\r
+\r
+   xor   eax, eax\r
+exit:\r
+   jmp   ebp\r
+PlatformBasicInitDflt   ENDP\r
+\r
+;------------------------------------------------------------------------------\r
+LoadUcodeDflt   PROC  NEAR PUBLIC\r
+   ; Inputs:\r
+   ;   esp -> LOAD_UCODE_PARAMS pointer\r
+   ; Register Usage:\r
+   ;   esp  Preserved\r
+   ;   All others destroyed\r
+   ; Assumptions:\r
+   ;   No memory available, stack is hard-coded and used for return address\r
+   ;   Executed by SBSP and NBSP\r
+   ;   Beginning of microcode update region starts on paragraph boundary\r
+\r
+   ;\r
+   ;\r
+   ; Save return address to EBP\r
+   mov    ebp, eax\r
+\r
+   cmp    esp, 0\r
+   jz     paramerror\r
+   mov    eax, dword ptr [esp]    ; Parameter pointer\r
+   cmp    eax, 0\r
+   jz     paramerror\r
+   mov    esp, eax\r
+   mov    esi, [esp].LOAD_UCODE_PARAMS.ucode_code_addr\r
+   cmp    esi, 0\r
+   jnz    check_main_header\r
+\r
+paramerror:\r
+   mov    eax, 080000002h\r
+   jmp    exit\r
+\r
+   mov    esi, [esp].LOAD_UCODE_PARAMS.ucode_code_addr\r
+\r
+check_main_header:\r
+   ; Get processor signature and platform ID from the installed processor\r
+   ; and save into registers for later use\r
+   ; ebx = processor signature\r
+   ; edx = platform ID\r
+   mov   eax, 1\r
+   cpuid\r
+   mov   ebx, eax\r
+   mov   ecx, MSR_IA32_PLATFORM_ID\r
+   rdmsr\r
+   mov   ecx, edx\r
+   shr   ecx, 50-32\r
+   and   ecx, 7h\r
+   mov   edx, 1\r
+   shl   edx, cl\r
+\r
+   ; Current register usage\r
+   ; esp -> stack with paramters\r
+   ; esi -> microcode update to check\r
+   ; ebx = processor signature\r
+   ; edx = platform ID\r
+\r
+   ; Check for valid microcode header\r
+   ; Minimal test checking for header version and loader version as 1\r
+   mov   eax, dword ptr 1\r
+   cmp   [esi].ucode_hdr.version, eax\r
+   jne   advance_fixed_size\r
+   cmp   [esi].ucode_hdr.loader, eax\r
+   jne   advance_fixed_size\r
+\r
+   ; Check if signature and plaform ID match\r
+   cmp   ebx, [esi].ucode_hdr.processor\r
+   jne   @f\r
+   test  edx, [esi].ucode_hdr.flags\r
+   jnz   load_check  ; Jif signature and platform ID match\r
+\r
+@@:\r
+   ; Check if extended header exists\r
+   ; First check if total_size and data_size are valid\r
+   xor   eax, eax\r
+   cmp   [esi].ucode_hdr.total_size, eax\r
+   je    next_microcode\r
+   cmp   [esi].ucode_hdr.data_size, eax\r
+   je    next_microcode\r
+\r
+   ; Then verify total size - sizeof header > data size\r
+   mov   ecx, [esi].ucode_hdr.total_size\r
+   sub   ecx, sizeof ucode_hdr\r
+   cmp   ecx, [esi].ucode_hdr.data_size\r
+   jng   next_microcode    ; Jif extended header does not exist\r
+\r
+   ; Set edi -> extended header\r
+   mov   edi, esi\r
+   add   edi, sizeof ucode_hdr\r
+   add   edi, [esi].ucode_hdr.data_size\r
+\r
+   ; Get count of extended structures\r
+   mov   ecx, [edi].ext_sig_hdr.count\r
+\r
+   ; Move pointer to first signature structure\r
+   add   edi, sizeof ext_sig_hdr\r
+\r
+check_ext_sig:\r
+   ; Check if extended signature and platform ID match\r
+   cmp   [edi].ext_sig.processor, ebx\r
+   jne   @f\r
+   test  [edi].ext_sig.flags, edx\r
+   jnz   load_check     ; Jif signature and platform ID match\r
+@@:\r
+   ; Check if any more extended signatures exist\r
+   add   edi, sizeof ext_sig\r
+   loop  check_ext_sig\r
+\r
+next_microcode:\r
+   ; Advance just after end of this microcode\r
+   xor   eax, eax\r
+   cmp   [esi].ucode_hdr.total_size, eax\r
+   je    @f\r
+   add   esi, [esi].ucode_hdr.total_size\r
+   jmp   check_address\r
+@@:\r
+   add   esi, dword ptr 2048\r
+   jmp   check_address\r
+\r
+advance_fixed_size:\r
+   ; Advance by 4X dwords\r
+   add   esi, dword ptr 1024\r
+\r
+check_address:\r
+   ; Is valid Microcode start point ?\r
+   cmp   dword ptr [esi], 0ffffffffh\r
+   jz    done\r
+\r
+   ; Address >= microcode region address + microcode region size?\r
+   mov   eax, [esp].LOAD_UCODE_PARAMS.ucode_code_addr\r
+   add   eax, [esp].LOAD_UCODE_PARAMS.ucode_code_size\r
+   cmp   esi, eax\r
+   jae   done        ;Jif address is outside of ucode region\r
+   jmp   check_main_header\r
+\r
+load_check:\r
+   ; Get the revision of the current microcode update loaded\r
+   mov   ecx, MSR_IA32_BIOS_SIGN_ID\r
+   xor   eax, eax               ; Clear EAX\r
+   xor   edx, edx               ; Clear EDX\r
+   wrmsr                        ; Load 0 to MSR at 8Bh\r
+\r
+   mov   eax, 1\r
+   cpuid\r
+   mov   ecx, MSR_IA32_BIOS_SIGN_ID\r
+   rdmsr                         ; Get current microcode signature\r
+\r
+   ; Verify this microcode update is not already loaded\r
+   cmp   [esi].ucode_hdr.revision, edx\r
+   je    continue\r
+\r
+load_microcode:\r
+   ; EAX contains the linear address of the start of the Update Data\r
+   ; EDX contains zero\r
+   ; ECX contains 79h (IA32_BIOS_UPDT_TRIG)\r
+   ; Start microcode load with wrmsr\r
+   mov   eax, esi\r
+   add   eax, sizeof ucode_hdr\r
+   xor   edx, edx\r
+   mov   ecx, MSR_IA32_BIOS_UPDT_TRIG\r
+   wrmsr\r
+   mov   eax, 1\r
+   cpuid\r
+\r
+continue:\r
+   jmp   next_microcode\r
+\r
+done:\r
+   mov   eax, 1\r
+   cpuid\r
+   mov   ecx, MSR_IA32_BIOS_SIGN_ID\r
+   rdmsr                         ; Get current microcode signature\r
+   xor   eax, eax\r
+   cmp   edx, 0\r
+   jnz   exit\r
+   mov   eax, 08000000Eh\r
+\r
+exit:\r
+   jmp   ebp\r
+\r
+LoadUcodeDflt   ENDP\r
+\r
+;----------------------------------------------------------------------------\r
+; TempRamInit API\r
+;\r
+; This FSP API will load the microcode update, enable code caching for the\r
+; region specified by the boot loader and also setup a temporary stack to be\r
+; used till main memory is initialized.\r
+;\r
+;----------------------------------------------------------------------------\r
+TempRamInitApi   PROC    NEAR    PUBLIC\r
+  ;\r
+  ; Ensure SSE is enabled\r
+  ;\r
+  ENABLE_SSE\r
+\r
+  ;\r
+  ; Save EBP, EBX, ESI, EDI & ESP in XMM7 & XMM6\r
+  ;\r
+  SAVE_REGS\r
+\r
+  ;\r
+  ; Save timestamp into XMM4 & XMM5\r
+  ;\r
+  rdtsc\r
+  SAVE_EAX\r
+  SAVE_EDX\r
+\r
+  ;\r
+  ; Check Parameter\r
+  ;\r
+  mov       eax, dword ptr [esp + 4]\r
+  cmp       eax, 0\r
+  mov       eax, 80000002h\r
+  jz        NemInitExit\r
+\r
+  ;\r
+  ; CPUID/DeviceID check\r
+  ;\r
+  mov       eax, @F\r
+  jmp       FspSelfCheck  ; Note: ESP can not be changed.\r
+@@:\r
+  cmp       eax, 0\r
+  jnz       NemInitExit\r
+\r
+  ;\r
+  ; Platform Basic Init.\r
+  ;\r
+  mov       eax, @F\r
+  jmp       PlatformBasicInit\r
+@@:\r
+  cmp       eax, 0\r
+  jnz       NemInitExit\r
+\r
+  ;\r
+  ; Load microcode\r
+  ;\r
+  mov       eax, @F\r
+  add       esp, 4\r
+  jmp       LoadUcode\r
+@@:\r
+  LOAD_ESP\r
+  cmp       eax, 0\r
+  jnz       NemInitExit\r
+\r
+  ;\r
+  ; Call platform NEM init\r
+  ;\r
+  mov       eax, @F\r
+  add       esp, 4\r
+  jmp       PlatformTempRamInit\r
+@@:\r
+  LOAD_ESP\r
+  cmp       eax, 0\r
+  jnz       NemInitExit\r
+\r
+  ;\r
+  ; Save parameter pointer in edx\r
+  ;\r
+  mov       edx, dword ptr [esp + 4]\r
+\r
+  ;\r
+  ; Enable FSP STACK\r
+  ;\r
+  mov       esp, PcdGet32(PcdTemporaryRamBase)\r
+  add       esp, PcdGet32(PcdTemporaryRamSize)\r
+\r
+  push      DATA_LEN_OF_MCUD     ; Size of the data region\r
+  push      4455434Dh            ; Signature of the  data region 'MCUD'\r
+  push      dword ptr [edx +  4] ; Microcode size\r
+  push      dword ptr [edx +  0] ; Microcode base\r
+  push      dword ptr [edx + 12] ; Code size\r
+  push      dword ptr [edx + 8]  ; Code base\r
+\r
+  ;\r
+  ; Save API entry/exit timestamp into stack\r
+  ;\r
+  push      DATA_LEN_OF_PER0     ; Size of the data region\r
+  push      30524550h            ; Signature of the  data region 'PER0'\r
+  rdtsc\r
+  push      edx\r
+  push      eax\r
+  LOAD_EAX\r
+  LOAD_EDX\r
+  push      edx\r
+  push      eax\r
+\r
+  ;\r
+  ; Terminator for the data on stack\r
+  ;\r
+  push      0\r
+\r
+  ;\r
+  ; Set ECX/EDX to the bootloader temporary memory range\r
+  ;\r
+  mov       ecx, PcdGet32(PcdTemporaryRamBase)\r
+  mov       edx, ecx\r
+  add       edx, PcdGet32(PcdTemporaryRamSize)\r
+  sub       edx, PcdGet32(PcdFspTemporaryRamSize)\r
+\r
+  xor       eax, eax\r
+\r
+NemInitExit:\r
+  ;\r
+  ; Load EBP, EBX, ESI, EDI & ESP from XMM7 & XMM6\r
+  ;\r
+  LOAD_REGS\r
+  ret\r
+TempRamInitApi   ENDP\r
+\r
+;----------------------------------------------------------------------------\r
+; FspInit API\r
+;\r
+; This FSP API will perform the processor and chipset initialization.\r
+; This API will not return.  Instead, it transfers the control to the\r
+; ContinuationFunc provided in the parameter.\r
+;\r
+;----------------------------------------------------------------------------\r
+FspInitApi   PROC    NEAR    PUBLIC\r
+  ;\r
+  ; Stack must be ready\r
+  ;\r
+  push   087654321h\r
+  pop    eax\r
+  cmp    eax, 087654321h\r
+  jz     @F\r
+  mov    eax, 080000003h\r
+  jmp    exit\r
+\r
+@@:\r
+  ;\r
+  ; Additional check\r
+  ;\r
+  pushad\r
+  push   1\r
+  call   FspApiCallingCheck\r
+  add    esp, 4\r
+  mov    dword ptr [esp + 4 * 7],  eax\r
+  popad\r
+  cmp    eax, 0\r
+  jz     @F\r
+  jmp    exit\r
+\r
+@@:\r
+  ;\r
+  ; Store the address in FSP which will return control to the BL\r
+  ;\r
+  push   offset exit\r
+\r
+  ;\r
+  ; Create a Task Frame in the stack for the Boot Loader\r
+  ;\r
+  pushfd     ; 2 pushf for 4 byte alignment\r
+  cli\r
+  pushad\r
+\r
+  ; Reserve 8 bytes for IDT save/restore\r
+  sub     esp, 8\r
+  sidt    fword ptr [esp]\r
+\r
+  ;\r
+  ; Setup new FSP stack\r
+  ;\r
+  mov     eax, esp\r
+  mov     esp, PcdGet32(PcdTemporaryRamBase)\r
+  add     esp, PcdGet32(PcdTemporaryRamSize)\r
+  sub     esp, (DATA_LEN_AT_STACK_TOP + 40h)\r
+\r
+  ;\r
+  ; Save the bootloader's stack pointer\r
+  ;\r
+  push    eax\r
+\r
+  ;\r
+  ; Pass entry point of the PEI core\r
+  ;\r
+  call    GetFspBaseAddress\r
+  mov     edi, FspImageSizeOffset\r
+  mov     edi, DWORD PTR [eax + edi]\r
+  add     edi, eax\r
+  sub     edi, 20h\r
+  add     eax, DWORD PTR [edi]\r
+  push    eax\r
+\r
+  ;\r
+  ; Pass BFV into the PEI Core\r
+  ; It uses relative address to calucate the actual boot FV base\r
+  ; For FSP impleantion with single FV, PcdFlashFvRecoveryBase and\r
+  ; PcdFspAreaBaseAddress are the same. For FSP with mulitple FVs,\r
+  ; they are different. The code below can handle both cases.\r
+  ;\r
+  call    GetFspBaseAddress\r
+  mov     edi, eax\r
+  call    GetBootFirmwareVolumeOffset\r
+  add     eax, edi\r
+  push    eax\r
+\r
+  ;\r
+  ; Pass stack base and size into the PEI Core\r
+  ;\r
+  mov     eax,  PcdGet32(PcdTemporaryRamBase)\r
+  add     eax,  PcdGet32(PcdTemporaryRamSize)\r
+  sub     eax,  PcdGet32(PcdFspTemporaryRamSize)\r
+  push    eax\r
+  push    PcdGet32(PcdFspTemporaryRamSize)\r
+\r
+  ;\r
+  ; Pass Control into the PEI Core\r
+  ;\r
+  call    SecStartup\r
+\r
+exit:\r
+  ret\r
+\r
+FspInitApi   ENDP\r
+\r
+;----------------------------------------------------------------------------\r
+; NotifyPhase API\r
+;\r
+; This FSP API will notify the FSP about the different phases in the boot\r
+; process\r
+;\r
+;----------------------------------------------------------------------------\r
+NotifyPhaseApi   PROC C PUBLIC\r
+  ;\r
+  ; Stack must be ready\r
+  ;\r
+  push   087654321h\r
+  pop    eax\r
+  cmp    eax, 087654321h\r
+  jz     @F\r
+  mov    eax, 080000003h\r
+  jmp    err_exit\r
+\r
+@@:\r
+  ;\r
+  ; Verify the calling condition\r
+  ;\r
+  pushad\r
+  push   2\r
+  call   FspApiCallingCheck\r
+  add    esp, 4\r
+  mov    dword ptr [esp + 4 * 7],  eax\r
+  popad\r
+\r
+  cmp    eax, 0\r
+  jz     @F\r
+\r
+  ;\r
+  ; Error return\r
+  ;\r
+err_exit:\r
+  ret\r
+\r
+@@:\r
+  jmp    Pei2LoaderSwitchStack\r
+\r
+NotifyPhaseApi   ENDP\r
+\r
+\r
+END\r
diff --git a/IntelFspPkg/FspSecCore/Ia32/FspApiEntry.s b/IntelFspPkg/FspSecCore/Ia32/FspApiEntry.s
new file mode 100644 (file)
index 0000000..433ef92
--- /dev/null
@@ -0,0 +1,611 @@
+#------------------------------------------------------------------------------\r
+#\r
+# Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>\r
+# This program and the accompanying materials\r
+# are licensed and made available under the terms and conditions of the BSD License\r
+# which accompanies this distribution.  The full text of the license may be found at\r
+# http://opensource.org/licenses/bsd-license.php.\r
+#\r
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+# Abstract:\r
+#\r
+#   Provide FSP API entry points.\r
+#\r
+#------------------------------------------------------------------------------\r
+\r
+#.INCLUDE "UcodeLoad.inc"\r
+\r
+#\r
+# Following are fixed PCDs\r
+#\r
+\r
+.equ MSR_IA32_PLATFORM_ID,     0x000000017\r
+.equ MSR_IA32_BIOS_UPDT_TRIG,    0x000000079\r
+.equ MSR_IA32_BIOS_SIGN_ID,     0x00000008b\r
+\r
+ASM_GLOBAL    ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamBase)\r
+ASM_GLOBAL    ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamSize)\r
+ASM_GLOBAL    ASM_PFX(_gPcd_FixedAtBuild_PcdFspTemporaryRamSize)\r
+ASM_GLOBAL    ASM_PFX(_gPcd_FixedAtBuild_PcdFspAreaSize)\r
+\r
+\r
+#\r
+# Following functions will be provided in C\r
+#\r
+#EXTERNDEF   SecStartup:PROC\r
+#EXTERNDEF   FspApiCallingCheck:PROC\r
+\r
+#\r
+# Following functions will be provided in PlatformSecLib\r
+#\r
+#EXTERNDEF   GetFspBaseAddress:PROC\r
+#EXTERNDEF   GetBootFirmwareVolumeOffset:PROC\r
+#EXTERNDEF   PlatformTempRamInit:PROC\r
+#EXTERNDEF   Pei2LoaderSwitchStack:PROC\r
+#EXTERN      FspSelfCheck(FspSelfCheckDflt):PROC\r
+#EXTERN      PlatformBasicInit(PlatformBasicInitDflt):PROC\r
+\r
+#\r
+# Define the data length that we saved on the stack top\r
+#\r
+.equ                     DATA_LEN_OF_PER0, 0x018\r
+.equ                     DATA_LEN_OF_MCUD, 0x018\r
+.equ                     DATA_LEN_AT_STACK_TOP, (DATA_LEN_OF_PER0 + DATA_LEN_OF_MCUD + 4)\r
+\r
+#\r
+# Define SSE macros\r
+#\r
+.macro ENABLE_SSE\r
+  movl        %cr4, %eax\r
+  orl         $0x00000600,%eax      # Set OSFXSR bit (bit #9) & OSXMMEXCPT bit (bit #10)\r
+  movl        %eax,%cr4\r
+.endm\r
+\r
+.macro SAVE_REGS\r
+  movd       %ebp, %xmm7\r
+  pshufd     $0x93, %xmm7, %xmm7\r
+  movd       %ebx, %xmm6\r
+  por        %xmm6, %xmm7\r
+  pshufd     $0x93, %xmm7, %xmm7\r
+  movd       %esi,%xmm6\r
+  por        %xmm6, %xmm7\r
+  pshufd     $0x93, %xmm7, %xmm7\r
+  movd       %edi, %xmm6\r
+  por        %xmm6, %xmm7\r
+  movd       %esp, %xmm6\r
+.endm\r
+\r
+.macro LOAD_REGS\r
+  movd       %xmm6, %esp\r
+  movd       %xmm7, %edi\r
+  pshufd     $0x39,%xmm7, %xmm7\r
+  movd       %xmm7, %esi\r
+  pshufd     $0x39,%xmm7, %xmm7\r
+  movd       %xmm7, %ebx\r
+  pshufd     $0x39, %xmm7, %xmm7\r
+  movd       %xmm7, %ebp\r
+.endm\r
+\r
+.macro LOAD_ESP\r
+  movd       %xmm6, %esp\r
+.endm\r
+\r
+#------------------------------------------------------------------------------\r
+ASM_GLOBAL ASM_PFX(FspSelfCheckDflt)\r
+ASM_PFX(FspSelfCheckDflt):\r
+   # Inputs:\r
+   #   eax -> Return address\r
+   # Outputs:\r
+   #   eax -> 0 - Successful, Non-zero - Failed.\r
+   # Register Usage:\r
+   #   eax is cleared and ebp is used for return address.\r
+   #   All others reserved.\r
+\r
+   # Save return address to EBP\r
+   movl  %eax, %ebp\r
+   xorl  %eax, %eax\r
+exit:\r
+   jmp   *%ebp\r
+#FspSelfCheckDflt   ENDP\r
+\r
+#------------------------------------------------------------------------------\r
+ASM_GLOBAL ASM_PFX(PlatformBasicInitDflt)\r
+ASM_PFX(PlatformBasicInitDflt):\r
+   # Inputs:\r
+   #   eax -> Return address\r
+   # Outputs:\r
+   #   eax -> 0 - Successful, Non-zero - Failed.\r
+   # Register Usage:\r
+   #   eax is cleared and ebp is used for return address.\r
+   #   All others reserved.\r
+\r
+   # Save return address to EBP\r
+   movl   %eax, %ebp\r
+   xorl   %eax, %eax\r
+exit2:\r
+   jmp   *%ebp\r
+#PlatformBasicInitDflt   ENDP\r
+\r
+#------------------------------------------------------------------------------\r
+ASM_GLOBAL ASM_PFX(LoadUcode)\r
+ASM_PFX(LoadUcode):\r
+   # Inputs:\r
+   #   esp -> LOAD_UCODE_PARAMS pointer\r
+   # Register Usage:\r
+   #   esp  Preserved\r
+   #   All others destroyed\r
+   # Assumptions:\r
+   #   No memory available, stack is hard-coded and used for return address\r
+   #   Executed by SBSP and NBSP\r
+   #   Beginning of microcode update region starts on paragraph boundary\r
+\r
+   #\r
+   #\r
+   # Save return address to EBP\r
+   movl   %eax, %ebp\r
+   cmpl   $0, %esp\r
+   jz     paramerror\r
+   movl   (%esp), %eax        #dword ptr []     Parameter pointer\r
+   cmpl   $0, %eax\r
+   jz     paramerror\r
+   movl   %eax, %esp\r
+   movl   (%esp), %esi        #LOAD_UCODE_PARAMS.ucode_code_addr\r
+   cmpl   $0, %esi\r
+   jnz    L0\r
+\r
+paramerror:\r
+   movl    $0x080000002, %eax\r
+   jmp     exit4\r
+\r
+   movl   (%esp), %esi     #.LOAD_UCODE_PARAMS.ucode_code_addr\r
+\r
+check_main_header:\r
+   # Get processor signature and platform ID from the installed processor\r
+   # and save into registers for later use\r
+   # ebx = processor signature\r
+   # edx = platform ID\r
+   movl  $1, %eax\r
+   cpuid\r
+   movl   %eax, %ebx\r
+   movl   MSR_IA32_PLATFORM_ID, %ecx\r
+   rdmsr\r
+   movl  %edx, %ecx\r
+   #--------------------------------------------------------------------------------------------------------------------\r
+   shrl  $18, %ecx      #($50-$32)\r
+   andl  $0x7, %ecx\r
+   movl  $1, %edx\r
+   shll  %cl,%edx\r
+\r
+   # Current register usage\r
+   # esp -> stack with paramters\r
+   # esi -> microcode update to check\r
+   # ebx = processor signature\r
+   # edx = platform ID\r
+\r
+   # Check for valid microcode header\r
+   # Minimal test checking for header version and loader version as 1\r
+   movl  $1, %eax\r
+   cmpl  %eax, (%esi)           #.ucode_hdr.version\r
+   jne   advance_fixed_size\r
+   cmpl  %eax, 0x18(%esi)       #.ucode_hdr.loader\r
+   jne   advance_fixed_size\r
+\r
+   # Check if signature and plaform ID match\r
+   #--------------------------------------------------------------------------------------------------------------------------\r
+   cmpl  0x10(%esi), %ebx      #(%esi).ucode_hdr.processor\r
+   jne   L0\r
+   testl 0x1c(%esi) , %edx     #(%esi).ucode_hdr.flags\r
+   jnz   load_check  # Jif signature and platform ID match\r
+\r
+L0:\r
+   # Check if extended header exists\r
+   # First check if total_size and data_size are valid\r
+   xorl    %eax, %eax\r
+   cmpl    %eax,0x24(%esi)      #(%esi).ucode_hdr.total_size\r
+   je      next_microcode\r
+   cmpl    %eax,0x20(%esi)      #(%esi) .ucode_hdr.data_size\r
+   je      next_microcode\r
+\r
+   # Then verify total size - sizeof header > data size\r
+   movl  0x24(%esi), %ecx        #(%esi).ucode_hdr.total_size\r
+   subl  $0x30, %ecx             #sizeof ucode_hdr = 48\r
+   cmpl  0x20(%esi), %ecx        #(%esi).ucode_hdr.data_size\r
+   jz    load_check\r
+   jb    next_microcode    # Jif extended header does not exist\r
+\r
+   # Check if total size fits in microcode region\r
+   movl    %esi , %edi\r
+   addl    0x24(%esi), %edi       # (%esi).ucode_hdr.total_size\r
+   movl    (%esp), %ecx           # (%esp).LOAD_UCODE_PARAMS.ucode_code_addr\r
+   addl    4(%esp), %ecx          #.LOAD_UCODE_PARAMS.ucode_code_size\r
+   cmpl    %ecx , %edi\r
+   xorl    %eax,  %eax\r
+   ja      exit4              # Jif address is outside of ucode region\r
+\r
+   # Set edi -> extended header\r
+   movl   %esi , %edi\r
+   addl   $0x30 , %edi               #sizeof ucode_hdr = 48\r
+   addl   0x20(%esi), %edi           #%esi.ucode_hdr.data_size\r
+\r
+   # Get count of extended structures\r
+   movl   (%edi), %ecx               #(%edi).ext_sig_hdr.count\r
+\r
+   # Move pointer to first signature structure\r
+   addl  $0x20, %edi                      # sizeof ext_sig_hdr = 20\r
+\r
+check_ext_sig:\r
+   # Check if extended signature and platform ID match\r
+   cmpl   %ebx, (%edi)                #[edi].ext_sig.processor\r
+   jne   L1\r
+   test  %edx, 4(%edi)                #[edi].ext_sig.flags\r
+   jnz   load_check     # Jif signature and platform ID match\r
+L9:\r
+   # Check if any more extended signatures exist\r
+   addl   $0xc, %edi                  #sizeof ext_sig = 12\r
+   loop   check_ext_sig\r
+\r
+next_microcode:\r
+   # Advance just after end of this microcode\r
+   xorl   %eax, %eax\r
+   cmpl   %eax, 0x24(%esi)            #(%esi).ucode_hdr.total_size\r
+   je     L2\r
+   add    0x24(%esi) ,  %esi          #(%esi).ucode_hdr.total_size\r
+   jmp    check_address\r
+L10:\r
+   addl  $0x800, %esi\r
+   jmp   check_address\r
+\r
+advance_fixed_size:\r
+   # Advance by 4X dwords\r
+   addl   $0x400, %esi\r
+\r
+check_address:\r
+   # Is valid Microcode start point ?\r
+   cmp   $0x0ffffffff , %esi\r
+   jz    done\r
+\r
+   # Address >= microcode region address + microcode region size?\r
+   movl   (%esp), %eax                  #(%esp).LOAD_UCODE_PARAMS.ucode_code_addr\r
+   addl   4(%esp), %eax                   #(%esp).LOAD_UCODE_PARAMS.ucode_code_size\r
+   cmpl   %eax, %esi\r
+   jae    done        #Jif address is outside of ucode region\r
+   jmp    check_main_header\r
+\r
+load_check:\r
+   # Get the revision of the current microcode update loaded\r
+   movl   MSR_IA32_BIOS_SIGN_ID, %ecx\r
+   xorl   %eax, %eax               # Clear EAX\r
+   xorl   %edx, %edx               # Clear EDX\r
+   wrmsr                           # Load 0 to MSR at 8Bh\r
+\r
+   movl   $1, %eax\r
+   cpuid\r
+   movl   MSR_IA32_BIOS_SIGN_ID, %ecx\r
+   rdmsr                         # Get current microcode signature\r
+\r
+   # Verify this microcode update is not already loaded\r
+   cmpl   %edx,  4(%esi)         #(%esi).ucode_hdr.revision\r
+   je    continue\r
+\r
+load_microcode:\r
+   # EAX contains the linear address of the start of the Update Data\r
+   # EDX contains zero\r
+   # ECX contains 79h (IA32_BIOS_UPDT_TRIG)\r
+   # Start microcode load with wrmsr\r
+   mov   %esi, %eax\r
+   add   $0x30, %eax                    #sizeof ucode_hdr = 48\r
+   xorl  %edx, %edx\r
+   mov   MSR_IA32_BIOS_UPDT_TRIG,%ecx\r
+   wrmsr\r
+   mov  $1, %eax\r
+   cpuid\r
+\r
+continue:\r
+   jmp   next_microcode\r
+\r
+done:\r
+   mov   $1, %eax\r
+   cpuid\r
+   mov   MSR_IA32_BIOS_SIGN_ID, %ecx\r
+   rdmsr                         # Get current microcode signature\r
+   xorl   %eax, %eax\r
+   cmp    $0 , %edx\r
+   jnz   exit4\r
+   mov   $0x08000000E, %eax\r
+\r
+exit4:\r
+   jmp   *%ebp\r
+\r
+#LoadUcode   ENDP\r
+\r
+#----------------------------------------------------------------------------\r
+# TempRamInit API\r
+#\r
+# This FSP API will load the microcode update, enable code caching for the\r
+# region specified by the boot loader and also setup a temporary stack to be\r
+# used till main memory is initialized.\r
+#\r
+#----------------------------------------------------------------------------\r
+ASM_GLOBAL ASM_PFX(TempRamInitApi)\r
+ASM_PFX(TempRamInitApi):\r
+  #\r
+  # Ensure SSE is enabled\r
+  #\r
+  ENABLE_SSE\r
+\r
+  #\r
+  # Save EBP, EBX, ESI, EDI & ESP in XMM7 & XMM6\r
+  #\r
+  SAVE_REGS\r
+\r
+  #\r
+  # Save timestamp into XMM4 & XMM5\r
+  #\r
+  rdtsc\r
+  movd      %edx, %xmm4\r
+  movd      %eax, %xmm5\r
+\r
+  #\r
+  # CPUID/DeviceID check\r
+  #\r
+  movl       L11, %eax\r
+  jmp       ASM_PFX(FspSelfCheck)  # Note: ESP can not be changed.\r
+L11:\r
+  cmpl       $0, %eax\r
+  jnz       NemInitExit\r
+\r
+  #\r
+  # Platform Basic Init.\r
+  #\r
+  movl       L1, %eax\r
+  jmp       ASM_PFX(PlatformBasicInitDflt)\r
+L1:\r
+  cmp       $0, %eax\r
+  jnz       NemInitExit\r
+\r
+  #\r
+  # Load microcode\r
+  #\r
+  movl       L2, %eax\r
+  addl       $4, %esp\r
+  jmp       LoadUcode\r
+L2:\r
+  LOAD_ESP\r
+  cmpl       $0, %eax\r
+  jnz       NemInitExit\r
+\r
+  #\r
+  # Call platform NEM init\r
+  #-------------------------------------------------------------------------------------------------------------------------\r
+  movl       L3, %eax\r
+  addl       $4, %esp\r
+  jmp       ASM_PFX(PlatformTempRamInit)\r
+L3:\r
+  subl       $4, %esp\r
+  cmpl       $0, %eax\r
+  jnz       NemInitExit\r
+\r
+  #\r
+  # Save parameter pointer in edx\r
+  #\r
+  movl       4(%esp), %edx\r
+\r
+  #\r
+  # Enable FSP STACK\r
+  #\r
+  movl       ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamBase), %esp\r
+  addl       ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamSize), %esp\r
+\r
+  pushl      $DATA_LEN_OF_MCUD     # Size of the data region\r
+  pushl      0x4455434D            # Signature of the  data region 'MCUD'\r
+  pushl      12(%edx)             # Code size\r
+  pushl      8(%edx)               # Code base\r
+  cmpl       $0, %edx              # Is parameter pointer valid ?\r
+  jz         InvalidMicrocodeRegion\r
+  pushl      4(%edx)               # Microcode size\r
+  pushl      (%edx)                # Microcode base\r
+  jmp        L4\r
+\r
+InvalidMicrocodeRegion:\r
+  pushl      $0                    # Microcode size\r
+  pushl      $0                    # Microcode base\r
+\r
+L4:\r
+  #\r
+  # Save API entry/exit timestamp into stack\r
+  #\r
+  pushl      DATA_LEN_OF_PER0      # Size of the data region\r
+  pushl      0x30524550            # Signature of the  data region 'PER0'\r
+  movd       %xmm4, %eax\r
+  pushl      %eax\r
+  movd       %xmm5, %eax\r
+  pushl      %eax\r
+  rdtsc\r
+  pushl      %edx\r
+  pushl      %eax\r
+\r
+  #\r
+  # Terminator for the data on stack\r
+  #\r
+  pushl      $0\r
+\r
+  #\r
+  # Set ECX/EDX to the bootloader temporary memory range\r
+  #\r
+  movl       ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamBase), %ecx\r
+  movl       %ecx, %edx\r
+  addl       ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamSize), %edx\r
+  subl       ASM_PFX(_gPcd_FixedAtBuild_PcdFspTemporaryRamSize), %edx\r
+\r
+  xorl       %eax, %eax\r
+\r
+NemInitExit:\r
+  #\r
+  # Load EBP, EBX, ESI, EDI & ESP from XMM7 & XMM6\r
+  #\r
+  LOAD_REGS\r
+  ret\r
+#TempRamInitApi   ENDP\r
+\r
+#----------------------------------------------------------------------------\r
+# FspInit API\r
+#\r
+# This FSP API will perform the processor and chipset initialization.\r
+# This API will not return.  Instead, it transfers the control to the\r
+# ContinuationFunc provided in the parameter.\r
+#\r
+#----------------------------------------------------------------------------\r
+ASM_GLOBAL ASM_PFX(FspInitApi)\r
+ASM_PFX(FspInitApi):\r
+  #\r
+  # Stack must be ready\r
+  #\r
+  pushl   $0x087654321\r
+  pop     %eax\r
+  cmpl    $0x087654321, %eax\r
+  jz     L5\r
+  movl    $0x080000003, %eax\r
+  jmp    exit3\r
+\r
+L5:\r
+  #\r
+  # Additional check\r
+  #\r
+  pusha\r
+  pushl   $1\r
+  call    ASM_PFX(FspApiCallingCheck)\r
+  addl    $4,    %esp\r
+  movl    %eax,  28(%esp)\r
+  popa\r
+  cmpl    $0 , %eax\r
+  jz      L6\r
+  jmp     exit3\r
+\r
+L6:\r
+  #\r
+  # Save the Platform Data Pointer in EDI\r
+  #\r
+  movl    4(%esp), %edi\r
+\r
+  #\r
+  # Store the address in FSP which will return control to the BL\r
+  #\r
+  pushl   $exit3\r
+\r
+  #\r
+  # Create a Task Frame in the stack for the Boot Loader\r
+  #\r
+  pushfl\r
+  pushfl     # 2 pushf for 4 byte alignment\r
+  cli\r
+  pushal\r
+\r
+  # Reserve 8 bytes for IDT save/restore\r
+  pushl    $0\r
+  pushl    $0\r
+  sidt     (%esp)\r
+\r
+  #\r
+  # Setup new FSP stack\r
+  #\r
+  movl     %esp, %eax\r
+  movl     ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamBase), %esp\r
+  addl     ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamSize)  , %esp\r
+  subl     DATA_LEN_AT_STACK_TOP, %esp\r
+  addl     $0x0FFFFFFC0, %esp\r
+\r
+  #\r
+  # Save the bootloader's stack pointer\r
+  #\r
+  pushl    %eax\r
+\r
+  #\r
+  # Pass entry point of the PEI core\r
+  #\r
+  call     ASM_PFX(GetFspBaseAddress)\r
+  movl     %eax, %edi\r
+  addl     ASM_PFX(_gPcd_FixedAtBuild_PcdFspAreaSize), %edi\r
+  subl     $0x20, %edi\r
+  addl     %ds:(%edi), %eax\r
+  pushl    %eax\r
+\r
+  #\r
+  # Pass BFV into the PEI Core\r
+  # It uses relative address to calucate the actual boot FV base\r
+  # For FSP impleantion with single FV, PcdFlashFvRecoveryBase and\r
+  # PcdFspAreaBaseAddress are the same. For FSP with mulitple FVs,\r
+  # they are different. The code below can handle both cases.\r
+  #\r
+  call     ASM_PFX(GetFspBaseAddress)\r
+  movl     %eax , %edi\r
+  call     ASM_PFX(GetBootFirmwareVolumeOffset)\r
+  addl     %edi ,%eax\r
+  pushl    %eax\r
+\r
+  #\r
+  # Pass stack base and size into the PEI Core\r
+  #\r
+  movl     ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamBase), %eax\r
+  addl     ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamSize), %eax\r
+  subl     ASM_PFX(_gPcd_FixedAtBuild_PcdFspTemporaryRamSize), %eax\r
+  pushl    %eax\r
+  pushl    ASM_PFX(_gPcd_FixedAtBuild_PcdFspTemporaryRamSize)\r
+\r
+  #\r
+  # Pass Control into the PEI Core\r
+  #\r
+  call    ASM_PFX(SecStartup)\r
+\r
+exit3:\r
+  ret\r
+\r
+# FspInitApi   ENDP\r
+\r
+#----------------------------------------------------------------------------\r
+# NotifyPhase API\r
+#\r
+# This FSP API will notify the FSP about the different phases in the boot\r
+# process\r
+#\r
+#----------------------------------------------------------------------------\r
+ASM_GLOBAL ASM_PFX(NotifyPhaseApi)\r
+ASM_PFX(NotifyPhaseApi):\r
+  #\r
+  # Stack must be ready\r
+  #\r
+  pushl  $0x0087654321\r
+  pop    %eax\r
+  cmpl   $0x087654321, %eax\r
+  jz     L7\r
+  movl   $0x080000003, %eax\r
+  jmp    err_exit\r
+\r
+L7:\r
+  #\r
+  # Verify the calling condition\r
+  #\r
+  pusha\r
+  pushl   $2\r
+  call    ASM_PFX(FspApiCallingCheck)\r
+  add     $4, %esp\r
+  mov     %eax, 28(%esp)\r
+  popa\r
+\r
+  cmpl   $0, %eax\r
+  jz     L8\r
+\r
+  #\r
+  # Error return\r
+  #\r
+err_exit:\r
+  ret\r
+\r
+L8:\r
+  jmp    ASM_PFX(Pei2LoaderSwitchStack)\r
+\r
+#NotifyPhaseApi   ENDP\r
+\r
+\r
+#END\r
diff --git a/IntelFspPkg/FspSecCore/Ia32/InitializeFpu.asm b/IntelFspPkg/FspSecCore/Ia32/InitializeFpu.asm
new file mode 100644 (file)
index 0000000..07f504d
--- /dev/null
@@ -0,0 +1,79 @@
+;------------------------------------------------------------------------------\r
+;\r
+; Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>\r
+; This program and the accompanying materials\r
+; are licensed and made available under the terms and conditions of the BSD License\r
+; which accompanies this distribution.  The full text of the license may be found at\r
+; http://opensource.org/licenses/bsd-license.php.\r
+;\r
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+;\r
+; Abstract:\r
+;\r
+;------------------------------------------------------------------------------\r
+\r
+    .686\r
+    .model  flat,C\r
+    .const\r
+;\r
+; Float control word initial value:\r
+; all exceptions masked, double-precision, round-to-nearest\r
+;\r
+mFpuControlWord       DW      027Fh\r
+;\r
+; Multimedia-extensions control word:\r
+; all exceptions masked, round-to-nearest, flush to zero for masked underflow\r
+;\r
+mMmxControlWord       DD      01F80h\r
+\r
+    .xmm\r
+    .code\r
+\r
+;\r
+; Initializes floating point units for requirement of UEFI specification.\r
+;\r
+; This function initializes floating-point control word to 0x027F (all exceptions\r
+; masked,double-precision, round-to-nearest) and multimedia-extensions control word\r
+; (if supported) to 0x1F80 (all exceptions masked, round-to-nearest, flush to zero\r
+; for masked underflow).\r
+;\r
+InitializeFloatingPointUnits PROC PUBLIC\r
+\r
+    push    ebx\r
+\r
+    ;\r
+    ; Initialize floating point units\r
+    ;\r
+    finit\r
+    fldcw   mFpuControlWord\r
+\r
+    ;\r
+    ; Use CpuId instructuion (CPUID.01H:EDX.SSE[bit 25] = 1) to test\r
+    ; whether the processor supports SSE instruction.\r
+    ;\r
+    mov     eax, 1\r
+    cpuid\r
+    bt      edx, 25\r
+    jnc     Done\r
+\r
+    ;\r
+    ; Set OSFXSR bit 9 in CR4\r
+    ;\r
+    mov     eax, cr4\r
+    or      eax, BIT9\r
+    mov     cr4, eax\r
+\r
+    ;\r
+    ; The processor should support SSE instruction and we can use\r
+    ; ldmxcsr instruction\r
+    ;\r
+    ldmxcsr mMmxControlWord\r
+Done:\r
+    pop     ebx\r
+\r
+    ret\r
+\r
+InitializeFloatingPointUnits ENDP\r
+\r
+END\r
diff --git a/IntelFspPkg/FspSecCore/Ia32/InitializeFpu.s b/IntelFspPkg/FspSecCore/Ia32/InitializeFpu.s
new file mode 100644 (file)
index 0000000..cfec8d7
--- /dev/null
@@ -0,0 +1,73 @@
+#------------------------------------------------------------------------------\r
+#\r
+# Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>\r
+# This program and the accompanying materials\r
+# are licensed and made available under the terms and conditions of the BSD License\r
+# which accompanies this distribution.  The full text of the license may be found at\r
+# http://opensource.org/licenses/bsd-license.php.\r
+#\r
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+# Abstract:\r
+#\r
+#------------------------------------------------------------------------------\r
+\r
+#\r
+# Float control word initial value:\r
+# all exceptions masked, double-precision, round-to-nearest\r
+#\r
+ASM_PFX(mFpuControlWord): .word     0x027F\r
+#\r
+# Multimedia-extensions control word:\r
+# all exceptions masked, round-to-nearest, flush to zero for masked underflow\r
+#\r
+ASM_PFX(mMmxControlWord): .long     0x01F80\r
+\r
+\r
+\r
+#\r
+# Initializes floating point units for requirement of UEFI specification.\r
+#\r
+# This function initializes floating-point control word to 0x027F (all exceptions\r
+# masked,double-precision, round-to-nearest) and multimedia-extensions control word\r
+# (if supported) to 0x1F80 (all exceptions masked, round-to-nearest, flush to zero\r
+# for masked underflow).\r
+#\r
+ASM_GLOBAL ASM_PFX(InitializeFloatingPointUnits)\r
+ASM_PFX(InitializeFloatingPointUnits):\r
+\r
+    pushl   %ebx\r
+\r
+    #\r
+    # Initialize floating point units\r
+    #\r
+    finit\r
+    fldcw   ASM_PFX(mFpuControlWord)\r
+\r
+    #\r
+    # Use CpuId instructuion (CPUID.01H:EDX.SSE[bit 25] = 1) to test\r
+    # whether the processor supports SSE instruction.\r
+    #\r
+    movl    $1,  %eax\r
+    cpuid\r
+    btl     $25, %edx\r
+    jnc     Done\r
+\r
+    #\r
+    # Set OSFXSR bit 9 in CR4\r
+    #\r
+    movl    %cr4, %eax\r
+    or      BIT9, %eax\r
+    movl    %eax, %cr4\r
+\r
+    #\r
+    # The processor should support SSE instruction and we can use\r
+    # ldmxcsr instruction\r
+    #\r
+    ldmxcsr ASM_PFX(mMmxControlWord)\r
+\r
+Done:\r
+    popl    %ebx\r
+\r
+    ret\r
diff --git a/IntelFspPkg/FspSecCore/Ia32/ResetVec.asm16 b/IntelFspPkg/FspSecCore/Ia32/ResetVec.asm16
new file mode 100644 (file)
index 0000000..f77c9a4
--- /dev/null
@@ -0,0 +1,103 @@
+;------------------------------------------------------------------------------\r
+;\r
+; Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>\r
+; This program and the accompanying materials\r
+; are licensed and made available under the terms and conditions of the BSD License\r
+; which accompanies this distribution.  The full text of the license may be found at\r
+; http://opensource.org/licenses/bsd-license.php.\r
+;\r
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+;\r
+; Abstract:\r
+;\r
+;  Reset Vector Data structure\r
+;  This structure is located at 0xFFFFFFC0\r
+;\r
+;------------------------------------------------------------------------------\r
+\r
+    .model  tiny\r
+    .686p\r
+    .stack  0h\r
+    .code\r
+\r
+;\r
+; The layout of this file is fixed. The build tool makes assumption of the layout.\r
+;\r
+\r
+    ORG     0h\r
+;\r
+; Reserved\r
+;\r
+ReservedData         DD 0eeeeeeeeh, 0eeeeeeeeh\r
+\r
+    ORG     10h\r
+;\r
+; This is located at 0xFFFFFFD0h\r
+;\r
+    mov     di, "AP"\r
+    jmp     ApStartup\r
+\r
+    ORG     20h\r
+;\r
+; Pointer to the entry point of the PEI core\r
+; It is located at 0xFFFFFFE0, and is fixed up by some build tool\r
+; So if the value 8..1 appears in the final FD image, tool failure occurs.\r
+;\r
+PeiCoreEntryPoint       DD      12345678h\r
+\r
+;\r
+; This is the handler for all kinds of exceptions. Since it's for debugging\r
+; purpose only, nothing except a deadloop would be done here. Developers could\r
+; analyze the cause of the exception if a debugger had been attached.\r
+;\r
+InterruptHandler    PROC\r
+    jmp     $\r
+    iret\r
+InterruptHandler    ENDP\r
+\r
+    ORG     30h\r
+;\r
+; For IA32, the reset vector must be at 0xFFFFFFF0, i.e., 4G-16 byte\r
+; Execution starts here upon power-on/platform-reset.\r
+;\r
+ResetHandler:\r
+    nop\r
+    nop\r
+\r
+ApStartup:\r
+    ;\r
+    ; Jmp Rel16 instruction\r
+    ; Use machine code directly in case of the assembler optimization\r
+    ; SEC entry point relatvie address will be fixed up by some build tool.\r
+    ;\r
+    ; Typically, SEC entry point is the function _ModuleEntryPoint() defined in\r
+    ; SecEntry.asm\r
+    ;\r
+    DB      0e9h\r
+    DW      -3\r
+\r
+\r
+    ORG     38h\r
+;\r
+; Ap reset vector segment address is at 0xFFFFFFF8\r
+; This will be fixed up by some build tool,\r
+; so if the value 1..8 appears in the final FD image,\r
+; tool failure occurs\r
+;\r
+ApSegAddress    dd      12345678h\r
+\r
+    ORG     3ch\r
+;\r
+; BFV Base is at 0xFFFFFFFC\r
+; This will be fixed up by some build tool,\r
+; so if the value 1..8 appears in the final FD image,\r
+; tool failure occurs.\r
+;\r
+BfvBase     DD      12345678h\r
+\r
+;\r
+; Nothing can go here, otherwise the layout of this file would change.\r
+;\r
+\r
+    END\r
diff --git a/IntelFspPkg/FspSecCore/Ia32/SaveRestoreSse.inc b/IntelFspPkg/FspSecCore/Ia32/SaveRestoreSse.inc
new file mode 100644 (file)
index 0000000..a3d5c47
--- /dev/null
@@ -0,0 +1,103 @@
+;------------------------------------------------------------------------------\r
+;\r
+; Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>\r
+; This program and the accompanying materials\r
+; are licensed and made available under the terms and conditions of the BSD License\r
+; which accompanies this distribution.  The full text of the license may be found at\r
+; http://opensource.org/licenses/bsd-license.php.\r
+;\r
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+;\r
+; Abstract:\r
+;\r
+;   Provide macro for register save/restore using SSE registers\r
+;\r
+;------------------------------------------------------------------------------\r
+\r
+;\r
+; Define SSE instruction set\r
+;\r
+IFDEF USE_SSE41_FLAG\r
+;\r
+; Define SSE macros using SSE 4.1 instructions\r
+;\r
+SXMMN        MACRO   XMM, IDX, REG\r
+             pinsrd  XMM, REG, (IDX AND 3)\r
+             ENDM\r
+\r
+LXMMN        MACRO   XMM, REG, IDX\r
+             pextrd  REG, XMM, (IDX AND 3)\r
+             ENDM\r
+ELSE\r
+;\r
+; Define SSE macros using SSE 2 instructions\r
+;\r
+SXMMN        MACRO   XMM, IDX, REG\r
+             pinsrw  XMM, REG, (IDX AND 3) * 2\r
+             ror     REG, 16\r
+             pinsrw  XMM, REG, (IDX AND 3) * 2 + 1\r
+             rol     REG, 16\r
+             ENDM\r
+\r
+LXMMN        MACRO   XMM, REG, IDX\r
+             pshufd  XMM, XMM,  (0E4E4E4h SHR (IDX * 2))  AND 0FFh\r
+             movd    REG, XMM\r
+             pshufd  XMM, XMM,  (0E4E4E4h SHR (IDX * 2 + (IDX AND 1) * 4)) AND 0FFh\r
+             ENDM\r
+ENDIF\r
+\r
+\r
+SAVE_REGS    MACRO\r
+  SXMMN      xmm7, 0, ebp\r
+  SXMMN      xmm7, 1, ebx\r
+  SXMMN      xmm7, 2, esi\r
+  SXMMN      xmm7, 3, edi\r
+  SAVE_ESP\r
+             ENDM\r
+\r
+LOAD_REGS    MACRO\r
+  LXMMN      xmm7, ebp, 0\r
+  LXMMN      xmm7, ebx, 1\r
+  LXMMN      xmm7, esi, 2\r
+  LXMMN      xmm7, edi, 3\r
+  LOAD_ESP\r
+             ENDM\r
+\r
+LOAD_EAX     MACRO\r
+  LXMMN      xmm6, eax, 1\r
+             ENDM\r
+\r
+SAVE_EAX     MACRO\r
+  SXMMN      xmm6, 1, eax\r
+             ENDM\r
+\r
+LOAD_EDX     MACRO\r
+  LXMMN      xmm6, edx, 2\r
+             ENDM\r
+\r
+SAVE_EDX     MACRO\r
+  SXMMN      xmm6, 2, edx\r
+             ENDM\r
+\r
+SAVE_ECX     MACRO\r
+  SXMMN      xmm6, 3, ecx\r
+             ENDM\r
+\r
+LOAD_ECX     MACRO\r
+  LXMMN      xmm6, ecx, 3\r
+             ENDM\r
+\r
+SAVE_ESP     MACRO\r
+  SXMMN      xmm6, 0, esp\r
+             ENDM\r
+\r
+LOAD_ESP     MACRO\r
+  movd       esp,  xmm6\r
+             ENDM\r
+\r
+ENABLE_SSE   MACRO\r
+  mov        eax, cr4\r
+  or         eax, 00000600h\r
+  mov        cr4, eax\r
+             ENDM\r
diff --git a/IntelFspPkg/FspSecCore/Ia32/Stack.asm b/IntelFspPkg/FspSecCore/Ia32/Stack.asm
new file mode 100644 (file)
index 0000000..f96a55f
--- /dev/null
@@ -0,0 +1,82 @@
+;------------------------------------------------------------------------------\r
+;\r
+; Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>\r
+; This program and the accompanying materials\r
+; are licensed and made available under the terms and conditions of the BSD License\r
+; which accompanies this distribution.  The full text of the license may be found at\r
+; http://opensource.org/licenses/bsd-license.php.\r
+;\r
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+;\r
+; Abstract:\r
+;\r
+;   Switch the stack from temporary memory to permenent memory.\r
+;\r
+;------------------------------------------------------------------------------\r
+\r
+    .586p\r
+    .model  flat,C\r
+    .code\r
+\r
+;------------------------------------------------------------------------------\r
+; VOID\r
+; EFIAPI\r
+; SecSwitchStack (\r
+;   UINT32   TemporaryMemoryBase,\r
+;   UINT32   PermenentMemoryBase\r
+;   );\r
+;------------------------------------------------------------------------------\r
+SecSwitchStack   PROC\r
+    ;\r
+    ; Save three register: eax, ebx, ecx\r
+    ;\r
+    push  eax\r
+    push  ebx\r
+    push  ecx\r
+    push  edx\r
+\r
+    ;\r
+    ; !!CAUTION!! this function address's is pushed into stack after\r
+    ; migration of whole temporary memory, so need save it to permenent\r
+    ; memory at first!\r
+    ;\r
+\r
+    mov   ebx, [esp + 20]          ; Save the first parameter\r
+    mov   ecx, [esp + 24]          ; Save the second parameter\r
+\r
+    ;\r
+    ; Save this function's return address into permenent memory at first.\r
+    ; Then, Fixup the esp point to permenent memory\r
+    ;\r
+    mov   eax, esp\r
+    sub   eax, ebx\r
+    add   eax, ecx\r
+    mov   edx, dword ptr [esp]         ; copy pushed register's value to permenent memory\r
+    mov   dword ptr [eax], edx\r
+    mov   edx, dword ptr [esp + 4]\r
+    mov   dword ptr [eax + 4], edx\r
+    mov   edx, dword ptr [esp + 8]\r
+    mov   dword ptr [eax + 8], edx\r
+    mov   edx, dword ptr [esp + 12]\r
+    mov   dword ptr [eax + 12], edx\r
+    mov   edx, dword ptr [esp + 16]    ; Update this function's return address into permenent memory\r
+    mov   dword ptr [eax + 16], edx\r
+    mov   esp, eax                     ; From now, esp is pointed to permenent memory\r
+\r
+    ;\r
+    ; Fixup the ebp point to permenent memory\r
+    ;\r
+    mov   eax, ebp\r
+    sub   eax, ebx\r
+    add   eax, ecx\r
+    mov   ebp, eax                ; From now, ebp is pointed to permenent memory\r
+\r
+    pop   edx\r
+    pop   ecx\r
+    pop   ebx\r
+    pop   eax\r
+    ret\r
+SecSwitchStack   ENDP\r
+\r
+    END\r
diff --git a/IntelFspPkg/FspSecCore/Ia32/Stacks.s b/IntelFspPkg/FspSecCore/Ia32/Stacks.s
new file mode 100644 (file)
index 0000000..6c36c25
--- /dev/null
@@ -0,0 +1,88 @@
+#------------------------------------------------------------------------------\r
+#\r
+# Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>\r
+# This program and the accompanying materials\r
+# are licensed and made available under the terms and conditions of the BSD License\r
+# which accompanies this distribution.  The full text of the license may be found at\r
+# http://opensource.org/licenses/bsd-license.php.\r
+#\r
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+# Abstract:\r
+#\r
+#   Switch the stack from temporary memory to permenent memory.\r
+#\r
+#------------------------------------------------------------------------------\r
+\r
+ASM_GLOBAL ASM_PFX(SecSwitchStack)\r
+\r
+#------------------------------------------------------------------------------\r
+# VOID\r
+# EFIAPI\r
+# SecSwitchStack (\r
+#   UINT32   TemporaryMemoryBase,\r
+#   UINT32   PermenentMemoryBase\r
+#   )\r
+#------------------------------------------------------------------------------\r
+ASM_GLOBAL ASM_PFX(SecSwitchStack)\r
+ASM_PFX(SecSwitchStack):\r
+#\r
+# Save three register: eax, ebx, ecx\r
+#\r
+    push  %eax\r
+    push  %ebx\r
+    push  %ecx\r
+    push  %edx\r
+\r
+#\r
+# !!CAUTION!! this function address's is pushed into stack after\r
+# migration of whole temporary memory, so need save it to permenent\r
+# memory at first!\r
+#\r
+\r
+    movl  20(%esp), %ebx            # Save the first parameter\r
+    movl  24(%esp), %ecx            # Save the second parameter\r
+\r
+#\r
+# Save this function's return address into permenent memory at first.\r
+# Then, Fixup the esp point to permenent memory\r
+#\r
+\r
+    movl  %esp, %eax\r
+    subl  %ebx, %eax\r
+    addl  %ecx, %eax\r
+    movl  (%esp), %edx                 # copy pushed register's value to permenent memory\r
+    movl  %edx, (%eax)\r
+    movl  4(%esp), %edx\r
+    movl  %edx, 4(%eax)\r
+    movl  8(%esp), %edx\r
+    movl  %edx, 8(%eax)\r
+    movl  12(%esp), %edx\r
+    movl  %edx, 12(%eax)\r
+    movl  16(%esp), %edx               # Update this function's return address into permenent memory\r
+    movl  %edx, 16(%eax)\r
+    movl  %eax, %esp                   # From now, esp is pointed to permenent memory\r
+\r
+#\r
+# Fixup the ebp point to permenent memory\r
+#\r
+\r
+    movl   %ebp, %eax\r
+    subl   %ebx, %eax\r
+    addl   %ecx, %eax\r
+    movl   %eax, %ebp                  # From now, ebp is pointed to permenent memory\r
+\r
+#\r
+# Fixup callee's ebp point for PeiDispatch\r
+#\r
+    movl   %ebp, %eax\r
+    subl   %ebx, %eax\r
+    addl   %ecx, %eax\r
+    movl   %eax, %ebp                #  From now, ebp is pointed to permenent memory\r
+\r
+    pop   %edx\r
+    pop   %ecx\r
+    pop   %ebx\r
+    pop   %eax\r
+    ret
\ No newline at end of file
diff --git a/IntelFspPkg/FspSecCore/Ia32/UcodeLoad.inc b/IntelFspPkg/FspSecCore/Ia32/UcodeLoad.inc
new file mode 100644 (file)
index 0000000..6be6ed0
--- /dev/null
@@ -0,0 +1,63 @@
+;------------------------------------------------------------------------------\r
+;\r
+; Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>\r
+; This program and the accompanying materials\r
+; are licensed and made available under the terms and conditions of the BSD License\r
+; which accompanies this distribution.  The full text of the license may be found at\r
+; http://opensource.org/licenses/bsd-license.php.\r
+;\r
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+;\r
+; Abstract:\r
+;\r
+;------------------------------------------------------------------------------\r
+\r
+MSR_IA32_PLATFORM_ID        EQU     000000017h\r
+MSR_IA32_BIOS_UPDT_TRIG     EQU     000000079h\r
+MSR_IA32_BIOS_SIGN_ID       EQU     00000008bh\r
+\r
+ucode                       STRUCT 1t\r
+    version                 DWORD     ?\r
+    revision                DWORD     ?\r
+    date                    DWORD     ?\r
+    processor               DWORD     ?\r
+    checksum                DWORD     ?\r
+    loader                  DWORD     ?\r
+    rsvd                    DWORD     6t DUP (?)\r
+    data                    DWORD     500t DUP (?)\r
+ucode                       ENDS\r
+ucode_t                     TYPEDEF     ucode\r
+\r
+ucode_hdr                   STRUCT 1t\r
+    version                 DWORD     ?\r
+    revision                DWORD     ?\r
+    date                    DWORD     ?\r
+    processor               DWORD     ?\r
+    checksum                DWORD     ?\r
+    loader                  DWORD     ?\r
+    flags                   DWORD     ?\r
+    data_size               DWORD     ?\r
+    total_size              DWORD     ?\r
+    rsvd                    DWORD     3t DUP (?)\r
+ucode_hdr                   ENDS\r
+ucode_hdr_t                 TYPEDEF     ucode_hdr\r
+\r
+ext_sig_hdr                 STRUCT 1t\r
+    count                   DWORD     ?\r
+    checksum                DWORD     ?\r
+    rsvd                    DWORD     3t DUP (?)\r
+ext_sig_hdr                 ENDS\r
+ext_sig_hdr_t               TYPEDEF     ext_sig_hdr\r
+\r
+ext_sig                     STRUCT 1t\r
+    processor               DWORD     ?\r
+    flags                   DWORD     ?\r
+    checksum                DWORD     ?\r
+ext_sig                     ENDS\r
+ext_sig_t                   TYPEDEF     ext_sig\r
+\r
+LOAD_UCODE_PARAMS           STRUCT 1t\r
+    ucode_code_addr         DWORD          ?\r
+    ucode_code_size         DWORD          ?\r
+LOAD_UCODE_PARAMS           ENDS\r
diff --git a/IntelFspPkg/FspSecCore/SecFsp.c b/IntelFspPkg/FspSecCore/SecFsp.c
new file mode 100644 (file)
index 0000000..00eb224
--- /dev/null
@@ -0,0 +1,268 @@
+/** @file\r
+\r
+  Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php.\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "SecFsp.h"\r
+\r
+UINT32  FspImageSizeOffset = FSP_INFO_HEADER_OFF + OFFSET_IN_FSP_INFO_HEADER(ImageSize);\r
+\r
+/**\r
+\r
+  Calculate the FSP IDT gate descriptor.\r
+\r
+  @param[in] IdtEntryTemplate     IDT gate descriptor template.\r
+\r
+  @return                     FSP specific IDT gate descriptor.\r
+\r
+**/\r
+UINT64\r
+FspGetExceptionHandler(\r
+  IN  UINT64  IdtEntryTemplate\r
+  )\r
+{\r
+  UINT32                    Entry;\r
+  UINT64                    ExceptionHandler;\r
+  IA32_IDT_GATE_DESCRIPTOR *IdtGateDescriptor;\r
+  FSP_INFO_HEADER          *FspInfoHeader;\r
+\r
+  FspInfoHeader     = (FSP_INFO_HEADER *)(GetFspBaseAddress() + FSP_INFO_HEADER_OFF);\r
+  ExceptionHandler  = IdtEntryTemplate;\r
+  IdtGateDescriptor = (IA32_IDT_GATE_DESCRIPTOR *)&ExceptionHandler;\r
+  Entry = (IdtGateDescriptor->Bits.OffsetHigh << 16) | IdtGateDescriptor->Bits.OffsetLow;\r
+  Entry = FspInfoHeader->ImageBase + FspInfoHeader->ImageSize - (~Entry + 1);\r
+  IdtGateDescriptor->Bits.OffsetHigh = (UINT16)(Entry >> 16);\r
+  IdtGateDescriptor->Bits.OffsetLow  = (UINT16)Entry;\r
+\r
+  return ExceptionHandler;\r
+}\r
+\r
+/**\r
+  This function gets the FSP UPD region offset in flash.\r
+\r
+  @return the offset of the UPD region.\r
+\r
+**/\r
+UINT32\r
+EFIAPI\r
+GetFspUpdRegionOffset (\r
+  VOID\r
+  )\r
+{\r
+  FSP_GLOBAL_DATA                   *FspData;\r
+  UINT32                            *Offset;\r
+\r
+  FspData       = GetFspGlobalDataPointer ();\r
+\r
+  //\r
+  // It is required to put PcdUpdRegionOffset at offset 0x000C\r
+  // for all FSPs.\r
+  // gPlatformFspPkgTokenSpaceGuid.PcdUpdRegionOffset       | 0x000C | 0x12345678\r
+  //\r
+  Offset        = (UINT32 *)(FspData->FspInfoHeader->ImageBase + \\r
+                             FspData->FspInfoHeader->CfgRegionOffset + 0x0C);\r
+\r
+  return  *Offset;\r
+}\r
+\r
+/**\r
+  This interface fills platform specific data.\r
+\r
+  @param[in,out]  FspData           Pointer to the FSP global data.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+SecGetPlatformData (\r
+  IN OUT  FSP_GLOBAL_DATA    *FspData\r
+  )\r
+{\r
+  FSP_PLAT_DATA    *FspPlatformData;\r
+  UINT32            TopOfCar;\r
+  UINT32           *StackPtr;\r
+  UINT32            DwordSize;\r
+\r
+  FspPlatformData = &FspData->PlatformData;\r
+\r
+  //\r
+  // The entries of platform information, together with the number of them,\r
+  // reside in the bottom of stack, left untouched by normal stack operation.\r
+  //\r
+  TopOfCar = PcdGet32 (PcdTemporaryRamBase) + PcdGet32 (PcdTemporaryRamSize);\r
+\r
+  FspPlatformData->DataPtr   = NULL;\r
+  FspPlatformData->CodeRegionSize      = 0;\r
+  FspPlatformData->CodeRegionBase      = 0;\r
+  FspPlatformData->MicorcodeRegionBase = 0;\r
+  FspPlatformData->MicorcodeRegionSize = 0;\r
+\r
+  //\r
+  // Pointer to the size field\r
+  //\r
+  StackPtr  = (UINT32 *)(TopOfCar - sizeof(UINT32));\r
+\r
+  while (*StackPtr != 0) {\r
+    if (*(StackPtr - 1) == FSP_MCUD_SIGNATURE) {\r
+      //\r
+      // This following data was pushed onto stack after TempRamInit API\r
+      //\r
+      DwordSize = 4;\r
+      StackPtr  = StackPtr - 1 - DwordSize;\r
+      CopyMem (&(FspPlatformData->CodeRegionBase), StackPtr, (DwordSize << 2));\r
+      StackPtr--;\r
+    } else if (*(StackPtr - 1) == FSP_PER0_SIGNATURE) {\r
+      //\r
+      // This is the performance data for InitTempMemory API entry/exit\r
+      //\r
+      DwordSize = 4;\r
+      StackPtr  = StackPtr - 1 - DwordSize;\r
+      CopyMem (FspData->PerfData, StackPtr, (DwordSize << 2));\r
+      ((UINT8 *)(&FspData->PerfData[0]))[7] = FSP_PERF_ID_API_TMPRAMINIT_ENTRY;\r
+      ((UINT8 *)(&FspData->PerfData[1]))[7] = FSP_PERF_ID_API_TMPRAMINIT_EXIT;\r
+      StackPtr--;\r
+    } else {\r
+      StackPtr -= (*StackPtr);\r
+    }\r
+  }\r
+}\r
+\r
+/**\r
+\r
+  Initialize the FSP global data region.\r
+  It needs to be done as soon as possible after the stack is setup.\r
+\r
+  @param[in,out] PeiFspData             Pointer of the FSP global data.\r
+  @param[in]     BootFirmwareVolume     Point to the address of BootFirmwareVolume in stack.\r
+\r
+**/\r
+VOID\r
+FspGlobalDataInit (\r
+  IN OUT  FSP_GLOBAL_DATA    *PeiFspData,\r
+  IN      VOID              **BootFirmwareVolume\r
+  )\r
+{\r
+  VOID              *UpdDataRgnPtr;\r
+  FSP_INIT_PARAMS   *FspInitParams;\r
+  CHAR8              ImageId[9];\r
+  UINTN              Idx;\r
+\r
+  //\r
+  // Init PCIE_BAR with value and set global FSP data pointer.\r
+  // PciExpress Base should have been programmed by platform already.\r
+  //\r
+  SetFspGlobalDataPointer    (PeiFspData);\r
+  ZeroMem  ((VOID *)PeiFspData, sizeof(FSP_GLOBAL_DATA));\r
+\r
+  PeiFspData->Signature          = FSP_GLOBAL_DATA_SIGNATURE;\r
+  PeiFspData->CoreStack          = *(UINTN *)(BootFirmwareVolume + 2);\r
+  PeiFspData->PerfIdx            = 2;\r
+\r
+  SetFspMeasurePoint (FSP_PERF_ID_API_FSPINIT_ENTRY);\r
+\r
+  //\r
+  // Get FSP Header offset\r
+  // It may have multiple FVs, so look into the last one for FSP header\r
+  //\r
+  PeiFspData->FspInfoHeader      = (FSP_INFO_HEADER *)(GetFspBaseAddress() + FSP_INFO_HEADER_OFF);\r
+  SecGetPlatformData (PeiFspData);\r
+\r
+  //\r
+  // Initialize UPD pointer.\r
+  //\r
+  FspInitParams = (FSP_INIT_PARAMS *)GetFspApiParameter ();\r
+  UpdDataRgnPtr = ((FSP_INIT_RT_COMMON_BUFFER *)FspInitParams->RtBufferPtr)->UpdDataRgnPtr;\r
+  if (UpdDataRgnPtr == NULL) {\r
+    UpdDataRgnPtr = (VOID *)(PeiFspData->FspInfoHeader->ImageBase + GetFspUpdRegionOffset());\r
+  }\r
+  SetFspUpdDataPointer (UpdDataRgnPtr);\r
+\r
+  //\r
+  // Initialize serial port\r
+  // It might have been done in ProcessLibraryConstructorList(), however,\r
+  // the FSP global data is not initialized at that time. So do it again\r
+  // for safe.\r
+  //\r
+  SerialPortInitialize ();\r
+\r
+  //\r
+  // Ensure the golbal data pointer is valid\r
+  //\r
+  ASSERT (GetFspGlobalDataPointer () == PeiFspData);\r
+\r
+  for (Idx = 0; Idx < 8; Idx++) {\r
+    ImageId[Idx] = PeiFspData->FspInfoHeader->ImageId[Idx];\r
+  }\r
+  ImageId[Idx] = 0;\r
+\r
+  DEBUG ((DEBUG_INFO | DEBUG_INIT, "\n============= PEIM FSP  (%a 0x%08X) =============\n", \\r
+         ImageId, PeiFspData->FspInfoHeader->ImageRevision));\r
+\r
+}\r
+\r
+/**\r
+\r
+  Adjust the FSP data pointers after the stack is migrated to memory.\r
+\r
+  @param[in] OffsetGap             The offset gap between the old stack and the new stack.\r
+\r
+**/\r
+VOID\r
+FspDataPointerFixUp (\r
+  IN UINT32   OffsetGap\r
+  )\r
+{\r
+  FSP_GLOBAL_DATA  *NewFspData;\r
+\r
+  NewFspData = (FSP_GLOBAL_DATA *)((UINTN)GetFspGlobalDataPointer() + (UINTN)OffsetGap);\r
+  SetFspGlobalDataPointer (NewFspData);\r
+}\r
+\r
+/**\r
+  This function check the FSP API calling condition.\r
+\r
+  @param[in]  ApiIdx           Internal index of the FSP API.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FspApiCallingCheck (\r
+  UINT32   ApiIdx\r
+  )\r
+{\r
+  EFI_STATUS       Status;\r
+  FSP_GLOBAL_DATA *FspData;\r
+\r
+  Status = EFI_SUCCESS;\r
+  FspData  = GetFspGlobalDataPointer ();\r
+  if (ApiIdx == 1) {\r
+    //\r
+    // FspInit check\r
+    //\r
+    if ((UINT32)FspData != 0xFFFFFFFF) {\r
+      Status = EFI_UNSUPPORTED;\r
+    }\r
+  } else if (ApiIdx == 2) {\r
+    //\r
+    // NotifyPhase check\r
+    //\r
+    if ((FspData == NULL) || ((UINT32)FspData == 0xFFFFFFFF)) {\r
+      Status = EFI_UNSUPPORTED;\r
+    } else {\r
+      if (FspData->Signature != FSP_GLOBAL_DATA_SIGNATURE) {\r
+        Status = EFI_UNSUPPORTED;\r
+      }\r
+    }\r
+  } else {\r
+    Status = EFI_UNSUPPORTED;\r
+  }\r
+\r
+  return Status;\r
+}\r
diff --git a/IntelFspPkg/FspSecCore/SecFsp.h b/IntelFspPkg/FspSecCore/SecFsp.h
new file mode 100644 (file)
index 0000000..9e129e4
--- /dev/null
@@ -0,0 +1,97 @@
+/** @file\r
+\r
+  Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php.\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef _SEC_FSP_H_\r
+#define _SEC_FSPE_H_\r
+\r
+#include <PiPei.h>\r
+#include <Library/PcdLib.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/SerialPortLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/FspCommonLib.h>\r
+\r
+#include <FspApi.h>\r
+\r
+#define FSP_MCUD_SIGNATURE  SIGNATURE_32 ('M', 'C', 'U', 'D')\r
+#define FSP_PER0_SIGNATURE  SIGNATURE_32 ('P', 'E', 'R', '0')\r
+\r
+/**\r
+\r
+  Calculate the FSP IDT gate descriptor.\r
+\r
+  @param[in] IdtEntryTemplate     IDT gate descriptor template.\r
+\r
+  @return                     FSP specific IDT gate descriptor.\r
+\r
+**/\r
+UINT64\r
+FspGetExceptionHandler(\r
+  IN  UINT64  IdtEntryTemplate\r
+  );\r
+\r
+/**\r
+\r
+  Initialize the FSP global data region.\r
+  It needs to be done as soon as possible after the stack is setup.\r
+\r
+  @param[in,out] PeiFspData             Pointer of the FSP global data.\r
+  @param[in]     BootFirmwareVolume     Point to the address of BootFirmwareVolume in stack.\r
+\r
+**/\r
+VOID\r
+FspGlobalDataInit (\r
+  IN OUT  FSP_GLOBAL_DATA    *PeiFspData,\r
+  IN      VOID              **BootFirmwareVolume\r
+  );\r
+\r
+\r
+/**\r
+\r
+  Adjust the FSP data pointers after the stack is migrated to memory.\r
+\r
+  @param[in] OffsetGap             The offset gap between the old stack and the new stack.\r
+\r
+**/\r
+VOID\r
+FspDataPointerFixUp (\r
+  IN UINT32   OffsetGap\r
+  );\r
+\r
+\r
+/**\r
+  This interface returns the base address of FSP binary.\r
+\r
+  @return   FSP binary base address.\r
+\r
+**/\r
+UINT32\r
+EFIAPI\r
+GetFspBaseAddress (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  This function gets the FSP UPD region offset in flash.\r
+\r
+  @return the offset of the UPD region.\r
+\r
+**/\r
+UINT32\r
+EFIAPI\r
+GetFspUpdRegionOffset (\r
+  VOID\r
+  );\r
+\r
+#endif\r
diff --git a/IntelFspPkg/FspSecCore/SecMain.c b/IntelFspPkg/FspSecCore/SecMain.c
new file mode 100644 (file)
index 0000000..22706c8
--- /dev/null
@@ -0,0 +1,208 @@
+/** @file\r
+\r
+  Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php.\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "SecMain.h"\r
+#include "SecFsp.h"\r
+\r
+EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI gSecTemporaryRamSupportPpi = {\r
+  SecTemporaryRamSupport\r
+};\r
+\r
+EFI_PEI_PPI_DESCRIPTOR            mPeiSecPlatformInformationPpi[] = {\r
+  {\r
+    (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
+    &gEfiTemporaryRamSupportPpiGuid,\r
+    &gSecTemporaryRamSupportPpi\r
+  }\r
+};\r
+\r
+//\r
+// These are IDT entries pointing to 08:FFFFFFE4h.\r
+//\r
+UINT64  mIdtEntryTemplate = 0xffff8e000008ffe4ULL;\r
+\r
+/**\r
+\r
+  Entry point to the C language phase of SEC. After the SEC assembly\r
+  code has initialized some temporary memory and set up the stack,\r
+  the control is transferred to this function.\r
+\r
+\r
+  @param[in] SizeOfRam          Size of the temporary memory available for use.\r
+  @param[in] TempRamBase        Base address of tempory ram\r
+  @param[in] BootFirmwareVolume Base address of the Boot Firmware Volume.\r
+\r
+  @return This function never returns.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+SecStartup (\r
+  IN UINT32                   SizeOfRam,\r
+  IN UINT32                   TempRamBase,\r
+  IN VOID                    *BootFirmwareVolume\r
+  )\r
+{\r
+  EFI_SEC_PEI_HAND_OFF        SecCoreData;\r
+  IA32_DESCRIPTOR             IdtDescriptor;\r
+  SEC_IDT_TABLE               IdtTableInStack;\r
+  UINT32                      Index;\r
+  FSP_GLOBAL_DATA             PeiFspData;\r
+  PEI_CORE_ENTRY              PeiCore;\r
+  UINT64                      ExceptionHandler;\r
+\r
+  //\r
+  // Process all libraries constructor function linked to SecCore.\r
+  //\r
+  ProcessLibraryConstructorList ();\r
+\r
+  //\r
+  // Initialize floating point operating environment\r
+  // to be compliant with UEFI spec.\r
+  //\r
+  InitializeFloatingPointUnits ();\r
+\r
+\r
+  // |-------------------|---->\r
+  // |Idt Table          |\r
+  // |-------------------|\r
+  // |PeiService Pointer |    PeiStackSize\r
+  // |-------------------|\r
+  // |                   |\r
+  // |      Stack        |\r
+  // |-------------------|---->\r
+  // |                   |\r
+  // |                   |\r
+  // |      Heap         |    PeiTemporayRamSize\r
+  // |                   |\r
+  // |                   |\r
+  // |-------------------|---->  TempRamBase\r
+  IdtTableInStack.PeiService  = NULL;\r
+  ExceptionHandler = FspGetExceptionHandler(mIdtEntryTemplate);\r
+  for (Index = 0; Index < SEC_IDT_ENTRY_COUNT; Index ++) {\r
+    CopyMem ((VOID*)&IdtTableInStack.IdtTable[Index], (VOID*)&ExceptionHandler, sizeof (UINT64));\r
+  }\r
+\r
+  IdtDescriptor.Base  = (UINTN) &IdtTableInStack.IdtTable;\r
+  IdtDescriptor.Limit = (UINT16)(sizeof (IdtTableInStack.IdtTable) - 1);\r
+\r
+  AsmWriteIdtr (&IdtDescriptor);\r
+\r
+  //\r
+  // Iniitalize the global FSP data region\r
+  //\r
+  FspGlobalDataInit (&PeiFspData, &BootFirmwareVolume);\r
+\r
+  //\r
+  // Update the base address and length of Pei temporary memory\r
+  //\r
+  SecCoreData.DataSize               = sizeof (EFI_SEC_PEI_HAND_OFF);\r
+  SecCoreData.BootFirmwareVolumeBase = BootFirmwareVolume;\r
+  SecCoreData.BootFirmwareVolumeSize = (UINT32)((EFI_FIRMWARE_VOLUME_HEADER *)BootFirmwareVolume)->FvLength;\r
+  SecCoreData.TemporaryRamBase       = (VOID*)(UINTN) TempRamBase;\r
+  SecCoreData.TemporaryRamSize       = SizeOfRam;\r
+  SecCoreData.PeiTemporaryRamBase    = SecCoreData.TemporaryRamBase;\r
+  SecCoreData.PeiTemporaryRamSize    = SizeOfRam >> 1;\r
+  SecCoreData.StackBase              = (VOID*)(UINTN)(TempRamBase + SecCoreData.PeiTemporaryRamSize);\r
+  SecCoreData.StackSize              = SizeOfRam >> 1;\r
+\r
+  //\r
+  // Call PeiCore Entry\r
+  //\r
+  PeiCore = (PEI_CORE_ENTRY)(*(UINTN *)((&BootFirmwareVolume) + 1));\r
+  PeiCore (&SecCoreData, mPeiSecPlatformInformationPpi);\r
+\r
+  //\r
+  // Should never be here\r
+  //\r
+  CpuDeadLoop ();\r
+}\r
+\r
+/**\r
+  This service of the TEMPORARY_RAM_SUPPORT_PPI that migrates temporary RAM into\r
+  permanent memory.\r
+\r
+  @param[in] PeiServices            Pointer to the PEI Services Table.\r
+  @param[in] TemporaryMemoryBase    Source Address in temporary memory from which the SEC or PEIM will copy the\r
+                                Temporary RAM contents.\r
+  @param[in] PermanentMemoryBase    Destination Address in permanent memory into which the SEC or PEIM will copy the\r
+                                Temporary RAM contents.\r
+  @param[in] CopySize               Amount of memory to migrate from temporary to permanent memory.\r
+\r
+  @retval EFI_SUCCESS           The data was successfully returned.\r
+  @retval EFI_INVALID_PARAMETER PermanentMemoryBase + CopySize > TemporaryMemoryBase when\r
+                                TemporaryMemoryBase > PermanentMemoryBase.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+SecTemporaryRamSupport (\r
+  IN CONST EFI_PEI_SERVICES   **PeiServices,\r
+  IN EFI_PHYSICAL_ADDRESS     TemporaryMemoryBase,\r
+  IN EFI_PHYSICAL_ADDRESS     PermanentMemoryBase,\r
+  IN UINTN                    CopySize\r
+  )\r
+{\r
+  IA32_DESCRIPTOR   IdtDescriptor;\r
+  VOID*             OldHeap;\r
+  VOID*             NewHeap;\r
+  VOID*             OldStack;\r
+  VOID*             NewStack;\r
+\r
+  OldHeap = (VOID*)(UINTN)TemporaryMemoryBase;\r
+  NewHeap = (VOID*)((UINTN)PermanentMemoryBase + CopySize / 2);\r
+\r
+  OldStack = (VOID*)((UINTN)TemporaryMemoryBase + CopySize / 2);\r
+  NewStack = (VOID*)(UINTN)PermanentMemoryBase;\r
+\r
+  //\r
+  // Migrate Heap\r
+  //\r
+  CopyMem (NewHeap, OldHeap, CopySize / 2);\r
+\r
+  //\r
+  // Migrate Stack\r
+  //\r
+  CopyMem (NewStack, OldStack, CopySize / 2);\r
+\r
+\r
+  //\r
+  // We need *not* fix the return address because currently,\r
+  // The PeiCore is executed in flash.\r
+  //\r
+\r
+  //\r
+  // Rebase IDT table in permanent memory\r
+  //\r
+  AsmReadIdtr (&IdtDescriptor);\r
+  IdtDescriptor.Base = IdtDescriptor.Base - (UINTN)OldStack + (UINTN)NewStack;\r
+\r
+  AsmWriteIdtr (&IdtDescriptor);\r
+\r
+  //\r
+  // Fixed the FSP data pointer\r
+  //\r
+  FspDataPointerFixUp ((UINTN)NewStack - (UINTN)OldStack);\r
+\r
+  //\r
+  // SecSwitchStack function must be invoked after the memory migration\r
+  // immediatly, also we need fixup the stack change caused by new call into\r
+  // permenent memory.\r
+  //\r
+  SecSwitchStack (\r
+    (UINT32) (UINTN) OldStack,\r
+    (UINT32) (UINTN) NewStack\r
+    );\r
+\r
+  return EFI_SUCCESS;\r
+}\r
diff --git a/IntelFspPkg/FspSecCore/SecMain.h b/IntelFspPkg/FspSecCore/SecMain.h
new file mode 100644 (file)
index 0000000..4dfbc85
--- /dev/null
@@ -0,0 +1,134 @@
+/** @file\r
+\r
+  Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php.\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef _SEC_CORE_H_\r
+#define _SEC_CORE_H_\r
+\r
+\r
+#include <PiPei.h>\r
+#include <Ppi/TemporaryRamSupport.h>\r
+\r
+#include <Library/BaseLib.h>\r
+#include <Library/IoLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/PcdLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/PciCf8Lib.h>\r
+#include <Library/SerialPortLib.h>\r
+#include <Library/FspSwitchStackLib.h>\r
+#include <Library/FspCommonLib.h>\r
+#include <FspApi.h>\r
+\r
+#define SEC_IDT_ENTRY_COUNT    34\r
+\r
+typedef VOID (*PEI_CORE_ENTRY) ( \\r
+  IN CONST  EFI_SEC_PEI_HAND_OFF    *SecCoreData, \\r
+  IN CONST  EFI_PEI_PPI_DESCRIPTOR  *PpiList \\r
+);\r
+\r
+typedef struct _SEC_IDT_TABLE {\r
+  EFI_PEI_SERVICES  *PeiService;\r
+  UINT64            IdtTable[SEC_IDT_ENTRY_COUNT];\r
+} SEC_IDT_TABLE;\r
+\r
+/**\r
+  Switch the stack in the temporary memory to the one in the permanent memory.\r
+\r
+  This function must be invoked after the memory migration immediately. The relative\r
+  position of the stack in the temporary and permanent memory is same.\r
+\r
+  @param[in] TemporaryMemoryBase  Base address of the temporary memory.\r
+  @param[in] PermenentMemoryBase  Base address of the permanent memory.\r
+**/\r
+VOID\r
+EFIAPI\r
+SecSwitchStack (\r
+  IN UINT32   TemporaryMemoryBase,\r
+  IN UINT32   PermenentMemoryBase\r
+  );\r
+\r
+/**\r
+  This service of the TEMPORARY_RAM_SUPPORT_PPI that migrates temporary RAM into\r
+  permanent memory.\r
+\r
+  @param[in] PeiServices            Pointer to the PEI Services Table.\r
+  @param[in] TemporaryMemoryBase    Source Address in temporary memory from which the SEC or PEIM will copy the\r
+                                Temporary RAM contents.\r
+  @param[in] PermanentMemoryBase    Destination Address in permanent memory into which the SEC or PEIM will copy the\r
+                                Temporary RAM contents.\r
+  @param[in] CopySize               Amount of memory to migrate from temporary to permanent memory.\r
+\r
+  @retval EFI_SUCCESS           The data was successfully returned.\r
+  @retval EFI_INVALID_PARAMETER PermanentMemoryBase + CopySize > TemporaryMemoryBase when\r
+                                TemporaryMemoryBase > PermanentMemoryBase.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+SecTemporaryRamSupport (\r
+  IN CONST EFI_PEI_SERVICES   **PeiServices,\r
+  IN EFI_PHYSICAL_ADDRESS     TemporaryMemoryBase,\r
+  IN EFI_PHYSICAL_ADDRESS     PermanentMemoryBase,\r
+  IN UINTN                    CopySize\r
+  );\r
+\r
+/**\r
+  Initializes floating point units for requirement of UEFI specification.\r
+\r
+  This function initializes floating-point control word to 0x027F (all exceptions\r
+  masked,double-precision, round-to-nearest) and multimedia-extensions control word\r
+  (if supported) to 0x1F80 (all exceptions masked, round-to-nearest, flush to zero\r
+  for masked underflow).\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+InitializeFloatingPointUnits (\r
+  VOID\r
+  );\r
+\r
+/**\r
+\r
+  Entry point to the C language phase of SEC. After the SEC assembly\r
+  code has initialized some temporary memory and set up the stack,\r
+  the control is transferred to this function.\r
+\r
+\r
+  @param[in] SizeOfRam          Size of the temporary memory available for use.\r
+  @param[in] TempRamBase        Base address of tempory ram\r
+  @param[in] BootFirmwareVolume Base address of the Boot Firmware Volume.\r
+\r
+  @return This function never returns.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+SecStartup (\r
+  IN UINT32                   SizeOfRam,\r
+  IN UINT32                   TempRamBase,\r
+  IN VOID                    *BootFirmwareVolume\r
+  );\r
+\r
+/**\r
+  Autogenerated function that calls the library constructors for all of the module's\r
+  dependent libraries.  This function must be called by the SEC Core once a stack has\r
+  been established.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+ProcessLibraryConstructorList (\r
+  VOID\r
+  );\r
+\r
+#endif\r
diff --git a/IntelFspPkg/FspSecCore/Vtf0/Bin/ResetVec.ia32.raw b/IntelFspPkg/FspSecCore/Vtf0/Bin/ResetVec.ia32.raw
new file mode 100644 (file)
index 0000000..2dc9f17
Binary files /dev/null and b/IntelFspPkg/FspSecCore/Vtf0/Bin/ResetVec.ia32.raw differ
diff --git a/IntelFspPkg/FspSecCore/Vtf0/Build.py b/IntelFspPkg/FspSecCore/Vtf0/Build.py
new file mode 100644 (file)
index 0000000..3018391
--- /dev/null
@@ -0,0 +1,53 @@
+## @file\r
+#  Automate the process of building the various reset vector types\r
+#\r
+#  Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>\r
+#\r
+#  This program and the accompanying materials\r
+#  are licensed and made available under the terms and conditions of the BSD License\r
+#  which accompanies this distribution.  The full text of the license may be found at\r
+#  http://opensource.org/licenses/bsd-license.php\r
+#\r
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+\r
+import glob\r
+import os\r
+import subprocess\r
+import sys\r
+\r
+def RunCommand(commandLine):\r
+    #print ' '.join(commandLine)\r
+    return subprocess.call(commandLine)\r
+\r
+for filename in glob.glob(os.path.join('Bin', '*.raw')):\r
+    os.remove(filename)\r
+\r
+arch = 'ia32'\r
+debugType = None\r
+output = os.path.join('Bin', 'ResetVec')\r
+output += '.' + arch\r
+if debugType is not None:\r
+    output += '.' + debugType\r
+output += '.raw'\r
+commandLine = (\r
+    'nasm',\r
+    '-D', 'ARCH_%s' % arch.upper(),\r
+    '-D', 'DEBUG_%s' % str(debugType).upper(),\r
+    '-o', output,\r
+    'ResetVectorCode.asm',\r
+    )\r
+ret = RunCommand(commandLine)\r
+print '\tASM\t' + output\r
+if ret != 0: sys.exit(ret)\r
+\r
+commandLine = (\r
+    'python',\r
+    'Tools/FixupForRawSection.py',\r
+    output,\r
+    )\r
+print '\tFIXUP\t' + output\r
+ret = RunCommand(commandLine)\r
+if ret != 0: sys.exit(ret)\r
+\r
diff --git a/IntelFspPkg/FspSecCore/Vtf0/Ia16/ResetVec.asm16 b/IntelFspPkg/FspSecCore/Vtf0/Ia16/ResetVec.asm16
new file mode 100644 (file)
index 0000000..585876f
--- /dev/null
@@ -0,0 +1,103 @@
+;; @file\r
+;  Reset Vector Data structure\r
+;  This structure is located at 0xFFFFFFC0\r
+;\r
+; Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>\r
+; This program and the accompanying materials\r
+; are licensed and made available under the terms and conditions of the BSD License\r
+; which accompanies this distribution.  The full text of the license may be found at\r
+; http://opensource.org/licenses/bsd-license.php.\r
+;\r
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+;\r
+;;\r
+\r
+BITS    16\r
+\r
+\r
+;\r
+; The layout of this file is fixed. The build tool makes assumption of the layout.\r
+;\r
+\r
+ORG     0x0\r
+;\r
+; Reserved\r
+;\r
+ReservedData:         DD 0eeeeeeeeh, 0eeeeeeeeh\r
+\r
+ ;  ORG     0x10\r
+ TIMES 0x10-($-$$) DB 0\r
+;\r
+; This is located at 0xFFFFFFD0h\r
+;\r
+    mov     di, "AP"\r
+    jmp     ApStartup\r
+\r
+ ;   ORG     0x20\r
+\r
+ TIMES 0x20-($-$$) DB 0\r
+\r
+; Pointer to the entry point of the PEI core\r
+; It is located at 0xFFFFFFE0, and is fixed up by some build tool\r
+; So if the value 8..1 appears in the final FD image, tool failure occurs.\r
+;\r
+PeiCoreEntryPoint:       DD      0x12345678\r
+\r
+;\r
+; This is the handler for all kinds of exceptions. Since it's for debugging\r
+; purpose only, nothing except a deadloop would be done here. Developers could\r
+; analyze the cause of the exception if a debugger had been attached.\r
+;\r
+InterruptHandler:\r
+    jmp     $\r
+    iret\r
+\r
+  ;  ORG     0x30\r
+ TIMES 0x30-($-$$) DB 0\r
+;\r
+; For IA32, the reset vector must be at 0xFFFFFFF0, i.e., 4G-16 byte\r
+; Execution starts here upon power-on/platform-reset.\r
+;\r
+ResetHandler:\r
+    nop\r
+    nop\r
+\r
+ApStartup:\r
+    ;\r
+    ; Jmp Rel16 instruction\r
+    ; Use machine code directly in case of the assembler optimization\r
+    ; SEC entry point relatvie address will be fixed up by some build tool.\r
+    ;\r
+    ; Typically, SEC entry point is the function _ModuleEntryPoint() defined in\r
+    ; SecEntry.asm\r
+    ;\r
+    DB      0x0e9\r
+    DW      -3\r
+\r
+  ; ORG     0x38\r
+\r
+ TIMES 0x38-($-$$) DB 0\r
+;\r
+; Ap reset vector segment address is at 0xFFFFFFF8\r
+; This will be fixed up by some build tool,\r
+; so if the value 1..8 appears in the final FD image,\r
+; tool failure occurs\r
+;\r
+ApSegAddress:    dd      0x12345678\r
+\r
+ ;   ORG     0x3c\r
+ TIMES 0x3c-($-$$) DB 0\r
+;\r
+; BFV Base is at 0xFFFFFFFC\r
+; This will be fixed up by some build tool,\r
+; so if the value 1..8 appears in the final FD image,\r
+; tool failure occurs.\r
+;\r
+BfvBase:     DD      0x12345678\r
+\r
+;\r
+; Nothing can go here, otherwise the layout of this file would change.\r
+;\r
+\r
+   ; END\r
diff --git a/IntelFspPkg/FspSecCore/Vtf0/ResetVectorCode.asm b/IntelFspPkg/FspSecCore/Vtf0/ResetVectorCode.asm
new file mode 100644 (file)
index 0000000..72b2524
--- /dev/null
@@ -0,0 +1,17 @@
+;------------------------------------------------------------------------------\r
+; @file\r
+; This file includes all other code files to assemble the reset vector code\r
+;\r
+; Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>\r
+; This program and the accompanying materials\r
+; are licensed and made available under the terms and conditions of the BSD License\r
+; which accompanies this distribution.  The full text of the license may be found at\r
+; http://opensource.org/licenses/bsd-license.php\r
+;\r
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+;\r
+;------------------------------------------------------------------------------\r
+\r
+\r
+%include "Ia16/ResetVec.asm16"\r
diff --git a/IntelFspPkg/FspSecCore/Vtf0/Tools/FixupForRawSection.py b/IntelFspPkg/FspSecCore/Vtf0/Tools/FixupForRawSection.py
new file mode 100644 (file)
index 0000000..8e7c20b
--- /dev/null
@@ -0,0 +1,110 @@
+## @file\r
+#  Apply fixup to VTF binary image for FFS Raw section\r
+#\r
+#  Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>\r
+#\r
+#  This program and the accompanying materials\r
+#  are licensed and made available under the terms and conditions of the BSD License\r
+#  which accompanies this distribution.  The full text of the license may be found at\r
+#  http://opensource.org/licenses/bsd-license.php\r
+#\r
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+\r
+import sys\r
+\r
+filename = sys.argv[1]\r
+\r
+if filename.lower().find('ia32') >= 0:\r
+    d = open(sys.argv[1], 'rb').read()\r
+    c = ((len(d) + 4 + 7) & ~7) - 4\r
+    if c > len(d):\r
+        c -= len(d)\r
+        f = open(sys.argv[1], 'wb')\r
+        f.write('\x90' * c)\r
+        f.write(d)\r
+        f.close()\r
+else:\r
+    from struct import pack\r
+\r
+    PAGE_PRESENT             =     0x01\r
+    PAGE_READ_WRITE          =     0x02\r
+    PAGE_USER_SUPERVISOR     =     0x04\r
+    PAGE_WRITE_THROUGH       =     0x08\r
+    PAGE_CACHE_DISABLE       =    0x010\r
+    PAGE_ACCESSED            =    0x020\r
+    PAGE_DIRTY               =    0x040\r
+    PAGE_PAT                 =    0x080\r
+    PAGE_GLOBAL              =   0x0100\r
+    PAGE_2M_MBO              =    0x080\r
+    PAGE_2M_PAT              =  0x01000\r
+\r
+    def NopAlign4k(s):\r
+        c = ((len(s) + 0xfff) & ~0xfff) - len(s)\r
+        return ('\x90' * c) + s\r
+\r
+    def PageDirectoryEntries4GbOf2MbPages(baseAddress):\r
+\r
+        s = ''\r
+        for i in range(0x800):\r
+            i = (\r
+                    baseAddress + long(i << 21) +\r
+                    PAGE_2M_MBO +\r
+                    PAGE_CACHE_DISABLE +\r
+                    PAGE_ACCESSED +\r
+                    PAGE_DIRTY +\r
+                    PAGE_READ_WRITE +\r
+                    PAGE_PRESENT\r
+                )\r
+            s += pack('Q', i)\r
+        return s\r
+\r
+    def PageDirectoryPointerTable4GbOf2MbPages(pdeBase):\r
+        s = ''\r
+        for i in range(0x200):\r
+            i = (\r
+                    pdeBase +\r
+                    (min(i, 3) << 12) +\r
+                    PAGE_CACHE_DISABLE +\r
+                    PAGE_ACCESSED +\r
+                    PAGE_READ_WRITE +\r
+                    PAGE_PRESENT\r
+                )\r
+            s += pack('Q', i)\r
+        return s\r
+\r
+    def PageMapLevel4Table4GbOf2MbPages(pdptBase):\r
+        s = ''\r
+        for i in range(0x200):\r
+            i = (\r
+                    pdptBase +\r
+                    (min(i, 0) << 12) +\r
+                    PAGE_CACHE_DISABLE +\r
+                    PAGE_ACCESSED +\r
+                    PAGE_READ_WRITE +\r
+                    PAGE_PRESENT\r
+                )\r
+            s += pack('Q', i)\r
+        return s\r
+\r
+    def First4GbPageEntries(topAddress):\r
+        PDE = PageDirectoryEntries4GbOf2MbPages(0L)\r
+        pml4tBase = topAddress - 0x1000\r
+        pdptBase = pml4tBase - 0x1000\r
+        pdeBase = pdptBase - len(PDE)\r
+        PDPT = PageDirectoryPointerTable4GbOf2MbPages(pdeBase)\r
+        PML4T = PageMapLevel4Table4GbOf2MbPages(pdptBase)\r
+        return PDE + PDPT + PML4T\r
+\r
+    def AlignAndAddPageTables():\r
+        d = open(sys.argv[1], 'rb').read()\r
+        code = NopAlign4k(d)\r
+        topAddress = 0x100000000 - len(code)\r
+        d = ('\x90' * 4) + First4GbPageEntries(topAddress) + code\r
+        f = open(sys.argv[1], 'wb')\r
+        f.write(d)\r
+        f.close()\r
+\r
+    AlignAndAddPageTables()\r
+\r
diff --git a/IntelFspPkg/Include/Guid/GuidHobFsp.h b/IntelFspPkg/Include/Guid/GuidHobFsp.h
new file mode 100644 (file)
index 0000000..4b1c2b1
--- /dev/null
@@ -0,0 +1,22 @@
+/** @file\r
+\r
+  Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php.\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef __GUID_HOB_FSP_GUID__\r
+#define __GUID_HOB_FSP_GUID__\r
+\r
+#include <Guid/GuidHobFspEas.h>\r
+#include <GuidHobFspGfx.h>\r
+#include <GuidHobFspTseg.h>\r
+#include <GuidHobFspMisc.h>\r
+\r
+#endif\r
diff --git a/IntelFspPkg/Include/Library/CacheAsRamLib.h b/IntelFspPkg/Include/Library/CacheAsRamLib.h
new file mode 100644 (file)
index 0000000..6f3d068
--- /dev/null
@@ -0,0 +1,30 @@
+/** @file\r
+\r
+  Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php.\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef _CACHE_AS_RAM_LIB_H_\r
+#define _CACHE_AS_RAM_LIB_H_\r
+\r
+/**\r
+  This function disable CAR.\r
+\r
+  @param[in] DisableCar       TRUE means use INVD, FALSE means use WBINVD\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+DisableCacheAsRam (\r
+  IN BOOLEAN                   DisableCar\r
+  );\r
+\r
+#endif\r
+\r
diff --git a/IntelFspPkg/Include/Library/CacheLib.h b/IntelFspPkg/Include/Library/CacheLib.h
new file mode 100644 (file)
index 0000000..909ae92
--- /dev/null
@@ -0,0 +1,62 @@
+/** @file\r
+\r
+  Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php.\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef _CACHE_LIB_H_\r
+#define _CACHE_LIB_H_\r
+\r
+//\r
+// EFI_MEMORY_CACHE_TYPE\r
+//\r
+typedef INT32 EFI_MEMORY_CACHE_TYPE;\r
+\r
+#define EFI_CACHE_UNCACHEABLE                 0\r
+#define EFI_CACHE_WRITECOMBINING              1\r
+#define EFI_CACHE_WRITETHROUGH                4\r
+#define EFI_CACHE_WRITEPROTECTED              5\r
+#define EFI_CACHE_WRITEBACK                   6\r
+\r
+/**\r
+ Reset all the MTRRs to a known state.\r
+\r
+  @retval  EFI_SUCCESS All MTRRs have been reset successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ResetCacheAttributes (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Given the memory range and cache type, programs the MTRRs.\r
+\r
+  @param[in] MemoryAddress           Base Address of Memory to program MTRR.\r
+  @param[in] MemoryLength            Length of Memory to program MTRR.\r
+  @param[in] MemoryCacheType         Cache Type.\r
+\r
+  @retval EFI_SUCCESS            Mtrr are set successfully.\r
+  @retval EFI_LOAD_ERROR         No empty MTRRs to use.\r
+  @retval EFI_INVALID_PARAMETER  The input parameter is not valid.\r
+  @retval others                 An error occurs when setting MTTR.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+SetCacheAttributes (\r
+  IN  EFI_PHYSICAL_ADDRESS      MemoryAddress,\r
+  IN  UINT64                    MemoryLength,\r
+  IN  EFI_MEMORY_CACHE_TYPE     MemoryCacheType\r
+  );\r
+\r
+#endif\r
+\r
diff --git a/IntelFspPkg/Include/Library/DebugDeviceLib.h b/IntelFspPkg/Include/Library/DebugDeviceLib.h
new file mode 100644 (file)
index 0000000..5c35eda
--- /dev/null
@@ -0,0 +1,29 @@
+/** @file\r
+\r
+  Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php.\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef __DEBUG_DEVICE_LIB_H__\r
+#define __DEBUG_DEVICE_LIB_H__\r
+\r
+/**\r
+  Returns the debug print device enable state.\r
+\r
+  @return  Debug print device enable state.\r
+\r
+**/\r
+UINT8\r
+EFIAPI\r
+GetDebugPrintDeviceEnable (\r
+  VOID\r
+  );\r
+\r
+#endif\r
diff --git a/IntelFspPkg/Include/Library/FspCommonLib.h b/IntelFspPkg/Include/Library/FspCommonLib.h
new file mode 100644 (file)
index 0000000..50e9b26
--- /dev/null
@@ -0,0 +1,173 @@
+/** @file\r
+\r
+  Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php.\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef _FSP_COMMON_LIB_H_\r
+#define _FSP_COMMON_LIB_H_\r
+\r
+#include <FspGlobalData.h>\r
+#include <FspMeasurePointId.h>\r
+\r
+/**\r
+  This function sets the FSP global data pointer.\r
+\r
+  @param[in] FspData       Fsp global data pointer.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+SetFspGlobalDataPointer (\r
+  IN FSP_GLOBAL_DATA   *FspData\r
+  );\r
+\r
+/**\r
+  This function gets the FSP global data pointer.\r
+\r
+**/\r
+FSP_GLOBAL_DATA *\r
+EFIAPI\r
+GetFspGlobalDataPointer (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  This function gets back the FSP API paramter passed by the bootlaoder.\r
+\r
+  @retval ApiParameter FSP API paramter passed by the bootlaoder.\r
+**/\r
+UINT32\r
+EFIAPI\r
+GetFspApiParameter (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  This function sets the FSP API paramter in the stack.\r
+\r
+   @param[in] Value       New parameter value.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+SetFspApiParameter (\r
+  IN UINT32      Value\r
+  );\r
+\r
+/**\r
+  This function sets the FSP continuation function parameters in the stack.\r
+\r
+  @param[in] Value             New parameter value to set.\r
+  @param[in] Index             Parameter index.\r
+**/\r
+VOID\r
+EFIAPI\r
+SetFspContinuationFuncParameter (\r
+  IN UINT32      Value,\r
+  IN UINT32      Index\r
+  );\r
+\r
+/**\r
+  This function changes the Bootloader return address in stack.\r
+\r
+  @param[in] ReturnAddress       Address to return.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+SetFspApiReturnAddress (\r
+  IN UINT32  ReturnAddress\r
+  );\r
+\r
+/**\r
+  This function set the API status code returned to the bootloader.\r
+\r
+  @param[in] ReturnStatus       Status code to return.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+SetFspApiReturnStatus (\r
+  IN UINT32  ReturnStatus\r
+  );\r
+\r
+/**\r
+  This function sets the context switching stack to a new stack frame.\r
+\r
+  @param[in] NewStackTop       New core stack to be set.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+SetFspCoreStackPointer (\r
+  IN VOID   *NewStackTop\r
+  );\r
+\r
+/**\r
+  This function sets the platform specific data pointer.\r
+\r
+  @param[in] PlatformData       Fsp platform specific data pointer.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+SetFspPlatformDataPointer (\r
+  IN VOID   *PlatformData\r
+  );\r
+\r
+/**\r
+  This function gets the platform specific data pointer.\r
+\r
+   @param[in] PlatformData       Fsp platform specific data pointer.\r
+\r
+**/\r
+VOID *\r
+EFIAPI\r
+GetFspPlatformDataPointer (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  This function sets the UPD data pointer.\r
+\r
+  @param[in] UpdDataRgnPtr   UPD data pointer.\r
+**/\r
+VOID\r
+EFIAPI\r
+SetFspUpdDataPointer (\r
+  IN VOID    *UpdDataRgnPtr\r
+  );\r
+\r
+/**\r
+  This function gets the UPD data pointer.\r
+\r
+  @return UpdDataRgnPtr   UPD data pointer.\r
+**/\r
+VOID *\r
+EFIAPI\r
+GetFspUpdDataPointer (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Set FSP measurement point timestamp.\r
+\r
+  @param[in] Id       Measurement point ID.\r
+\r
+  @return performance timestamp.\r
+**/\r
+UINT64\r
+EFIAPI\r
+SetFspMeasurePoint (\r
+  IN UINT8  Id\r
+  );\r
+\r
+#endif\r
diff --git a/IntelFspPkg/Include/Library/FspPlatformLib.h b/IntelFspPkg/Include/Library/FspPlatformLib.h
new file mode 100644 (file)
index 0000000..8550178
--- /dev/null
@@ -0,0 +1,64 @@
+/** @file\r
+\r
+  Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php.\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef _FSP_PLATFORM_LIB_H_\r
+#define _FSP_PLATFORM_LIB_H_\r
+\r
+/**\r
+  Get system memory from HOB.\r
+\r
+  @param[in,out] LowMemoryLength   less than 4G memory length\r
+  @param[in,out] HighMemoryLength  greater than 4G memory length\r
+**/\r
+VOID\r
+EFIAPI\r
+FspGetSystemMemorySize (\r
+  IN OUT UINT64              *LowMemoryLength,\r
+  IN OUT UINT64              *HighMemoryLength\r
+  );\r
+\r
+/**\r
+  Migrate bootloader data before destroying CAR.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+FspMigrateTemporaryMemory (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  This function transfer control to the ContinuationFunc passed in by the\r
+  bootloader.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+FspInitDone (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  This function handle NotifyPhase API call from the bootloader.\r
+  It gives control back to the bootloader after it is handled. If the\r
+  Notification code is a ReadyToBoot event, this function will return\r
+  and FSP continues the remaining execution until it reaches the DxeIpl.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+FspWaitForNotify (\r
+  VOID\r
+  );\r
+\r
+#endif\r
diff --git a/IntelFspPkg/Include/Library/FspReturnLib.h b/IntelFspPkg/Include/Library/FspReturnLib.h
new file mode 100644 (file)
index 0000000..40b69a8
--- /dev/null
@@ -0,0 +1,27 @@
+/** @file\r
+\r
+  Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php.\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef _FSP_RETURN_LIB_H_\r
+#define _FSP_RETURN_LIB_H_\r
+\r
+/**\r
+  Return the control from FSP to the Caller.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+AsmFspReturn (\r
+  VOID\r
+  );\r
+\r
+#endif\r
diff --git a/IntelFspPkg/Include/Library/FspSwitchStackLib.h b/IntelFspPkg/Include/Library/FspSwitchStackLib.h
new file mode 100644 (file)
index 0000000..e90b13e
--- /dev/null
@@ -0,0 +1,45 @@
+/** @file\r
+\r
+  Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php.\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef _FSP_SWITCH_STACK_LIB_H_\r
+#define _FSP_SWITCH_STACK_LIB_H_\r
+\r
+/**\r
+\r
+  This funciton will switch the current stack to the previous saved stack.\r
+  Before calling the previous stack has to be set in  FSP_GLOBAL_DATA.CoreStack.\r
+                    EIP\r
+                    FLAGS  16 bit  FLAGS  16 bit\r
+                    EDI\r
+                    ESI\r
+                    EBP\r
+                    ESP\r
+                    EBX\r
+                    EDX\r
+                    ECX\r
+                    EAX\r
+                    DWORD     IDT base1\r
+  StackPointer:     DWORD     IDT base2\r
+\r
+  @return ReturnKey          After switching to the saved stack,\r
+                             this value will be saved in eax before returning.\r
+\r
+\r
+**/\r
+UINT32\r
+EFIAPI\r
+Pei2LoaderSwitchStack (\r
+  VOID\r
+  );\r
+\r
+#endif\r
diff --git a/IntelFspPkg/Include/Private/FspGlobalData.h b/IntelFspPkg/Include/Private/FspGlobalData.h
new file mode 100644 (file)
index 0000000..7a6ec6d
--- /dev/null
@@ -0,0 +1,44 @@
+/** @file\r
+\r
+  Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php.\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef _FSP_GLOBAL_DATA_H_\r
+#define _FSP_GLOBAL_DATA_H_\r
+\r
+#include <FspInfoHeader.h>\r
+\r
+#pragma pack(1)\r
+\r
+typedef struct  {\r
+   VOID               *DataPtr;\r
+   UINT32             CodeRegionBase;\r
+   UINT32             CodeRegionSize;\r
+   UINT32             MicorcodeRegionBase;\r
+   UINT32             MicorcodeRegionSize;\r
+} FSP_PLAT_DATA;\r
+\r
+#define FSP_GLOBAL_DATA_SIGNATURE  SIGNATURE_32 ('F', 'S', 'P', 'D')\r
+\r
+typedef struct  {\r
+   UINT32             Signature;\r
+   UINT32             CoreStack;\r
+   FSP_PLAT_DATA      PlatformData;\r
+   FSP_INFO_HEADER    *FspInfoHeader;\r
+   VOID               *UpdDataRgnPtr;\r
+   UINT32             PerfIdx;\r
+   UINT64             PerfData[32];\r
+//   UINT64             PerfData[FixedPcdGet32(PcdFspMaxPerfEntry)];\r
+} FSP_GLOBAL_DATA;\r
+\r
+#pragma pack()\r
+\r
+#endif\r
diff --git a/IntelFspPkg/Include/Private/FspMeasurePointId.h b/IntelFspPkg/Include/Private/FspMeasurePointId.h
new file mode 100644 (file)
index 0000000..765bd0b
--- /dev/null
@@ -0,0 +1,48 @@
+/** @file\r
+\r
+  Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php.\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef _FSP_MEASURE_POINT_ID_H_\r
+#define _FSP_MEASURE_POINT_ID_H_\r
+\r
+//\r
+// 0xD0 - 0xEF are reserved for FSP common measure point\r
+//\r
+#define  FSP_PERF_ID_MRCINIT_ENTRY               0xD0\r
+#define  FSP_PERF_ID_MRCINIT_EXIT                (FSP_PERF_ID_MRCINIT_ENTRY +  1)\r
+\r
+#define  FSP_PERF_ID_SOCINIT_ENTRY               0xD8\r
+#define  FSP_PERF_ID_SOCINIT_EXIT                (FSP_PERF_ID_SOCINIT_ENTRY +  1)\r
+\r
+#define  FSP_PERF_ID_PCHINIT_ENTRY               0xDA\r
+#define  FSP_PERF_ID_PCHINIT_EXIT                (FSP_PERF_ID_PCHINIT_ENTRY +  1)\r
+\r
+#define  FSP_PERF_ID_CPUINIT_ENTRY               0xE0\r
+#define  FSP_PERF_ID_CPUINIT_EXIT                (FSP_PERF_ID_CPUINIT_ENTRY +  1)\r
+\r
+\r
+//\r
+// 0xF0 - 0xFF are reserved for FSP API\r
+//\r
+#define  FSP_PERF_ID_API_TMPRAMINIT_ENTRY        0xF0\r
+#define  FSP_PERF_ID_API_TMPRAMINIT_EXIT         (FSP_PERF_ID_API_TMPRAMINIT_ENTRY + 1)\r
+\r
+#define  FSP_PERF_ID_API_FSPINIT_ENTRY           0xF2\r
+#define  FSP_PERF_ID_API_FSPINIT_EXIT            (FSP_PERF_ID_API_FSPINIT_ENTRY + 1)\r
+\r
+#define  FSP_PERF_ID_API_NOTIFY_POSTPCI_ENTRY    0xF4\r
+#define  FSP_PERF_ID_API_NOTIFY_POSTPCI_EXIT     (FSP_PERF_ID_API_NOTIFY_POSTPCI_ENTRY + 1)\r
+\r
+#define  FSP_PERF_ID_API_NOTIFY_RDYBOOT_ENTRY    0xF6\r
+#define  FSP_PERF_ID_API_NOTIFY_RDYBOOT_EXIT     (FSP_PERF_ID_API_NOTIFY_RDYBOOT_ENTRY + 1)\r
+\r
+#endif\r
diff --git a/IntelFspPkg/Include/Private/FspPatchTable.h b/IntelFspPkg/Include/Private/FspPatchTable.h
new file mode 100644 (file)
index 0000000..ec93994
--- /dev/null
@@ -0,0 +1,32 @@
+/** @file\r
+\r
+  Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php.\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef _FSP_PATCH_TABLE_H_\r
+#define _FSP_PATCH_TABLE_H_\r
+\r
+#pragma pack(1)\r
+\r
+#define FSP_PATCH_TABLE_SIGNATURE  SIGNATURE_32 ('F', 'S', 'P', 'P')\r
+\r
+typedef struct  {\r
+  UINT32  Signature;\r
+  UINT16  HeaderLength;\r
+  UINT8   HeaderRevision;\r
+  UINT8   Reserved;\r
+  UINT32  PatchEntryNum;\r
+  UINT32  PatchData[FixedPcdGet32(PcdFspMaxPatchEntry)];\r
+} FSP_PATCH_TABLE;\r
+\r
+#pragma pack()\r
+\r
+#endif\r
diff --git a/IntelFspPkg/Include/Private/GuidHobFspGfx.h b/IntelFspPkg/Include/Private/GuidHobFspGfx.h
new file mode 100644 (file)
index 0000000..4ac47ba
--- /dev/null
@@ -0,0 +1,19 @@
+/** @file\r
+\r
+  Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php.\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef __GUID_HOB_FSP_GFX_GUID__\r
+#define __GUID_HOB_FSP_GFX_GUID__\r
+\r
+extern EFI_GUID gFspReservedMemoryResourceHobGfxGuid;\r
+\r
+#endif\r
diff --git a/IntelFspPkg/Include/Private/GuidHobFspMisc.h b/IntelFspPkg/Include/Private/GuidHobFspMisc.h
new file mode 100644 (file)
index 0000000..97b75af
--- /dev/null
@@ -0,0 +1,19 @@
+/** @file\r
+\r
+  Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php.\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef __GUID_HOB_FSP_MISC_GUID__\r
+#define __GUID_HOB_FSP_MISC_GUID__\r
+\r
+extern EFI_GUID gFspReservedMemoryResourceHobMiscGuid;\r
+\r
+#endif\r
diff --git a/IntelFspPkg/Include/Private/GuidHobFspTseg.h b/IntelFspPkg/Include/Private/GuidHobFspTseg.h
new file mode 100644 (file)
index 0000000..a44a8f6
--- /dev/null
@@ -0,0 +1,19 @@
+/** @file\r
+\r
+  Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php.\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef __GUID_HOB_FSP_TSEG_GUID__\r
+#define __GUID_HOB_FSP_TSEG_GUID__\r
+\r
+extern EFI_GUID gFspReservedMemoryResourceHobTsegGuid;\r
+\r
+#endif\r
index ef942a7..d16eaad 100644 (file)
 \r
 [Includes]\r
   Include\r
+  Include/Private\r
 \r
 [Guids]\r
+  #\r
+  # GUID defined in package\r
+  #\r
+  gIntelFspPkgTokenSpaceGuid           = { 0x834c0c5f, 0xadb3, 0x4372, { 0xae, 0xeb, 0x03, 0xe4, 0xe9, 0xe6, 0xc5, 0x91 } }\r
+\r
   # Guid define in FSP EAS\r
   gFspHeaderFileGuid                    = { 0x912740BE, 0x2284, 0x4734, { 0xB9, 0x71, 0x84, 0xB0, 0x27, 0x35, 0x3F, 0x0C } }\r
   gFspBootLoaderTemporaryMemoryGuid     = { 0xbbcff46c, 0xc8d3, 0x4113, { 0x89, 0x85, 0xb9, 0xd4, 0xf3, 0xb3, 0xf6, 0x4e } }\r
   gFspReservedMemoryResourceHobGuid     = { 0x69a79759, 0x1373, 0x4367, { 0xa6, 0xc4, 0xc7, 0xf5, 0x9e, 0xfd, 0x98, 0x6e } }\r
   gFspNonVolatileStorageHobGuid         = { 0x721acf02, 0x4d77, 0x4c2a, { 0xb3, 0xdc, 0x27, 0x0b, 0x7b, 0xa9, 0xe4, 0xb0 } }\r
 \r
+  # Guid defined by platform\r
+  gFspReservedMemoryResourceHobTsegGuid = { 0xd038747c, 0xd00c, 0x4980, { 0xb3, 0x19, 0x49, 0x01, 0x99, 0xa4, 0x7d, 0x55 } }\r
+  gFspReservedMemoryResourceHobGfxGuid  = { 0x9c7c3aa7, 0x5332, 0x4917, { 0x82, 0xb9, 0x56, 0xa5, 0xf3, 0xe6, 0x2a, 0x07 } }\r
+  gFspReservedMemoryResourceHobMiscGuid = { 0x00d6b14b, 0x7dd0, 0x4062, { 0x88, 0x21, 0xe5, 0xf9, 0x6a, 0x2a, 0x1b, 0x00 } }\r
+\r
+[PcdsFixedAtBuild]\r
+  gIntelFspPkgTokenSpaceGuid.PcdGlobalDataPointerAddress|0xFED00108|UINT32|0x00000001\r
+  gIntelFspPkgTokenSpaceGuid.PcdTemporaryRamBase        |0xFEF00000|UINT32|0x10001001\r
+  gIntelFspPkgTokenSpaceGuid.PcdTemporaryRamSize        |    0x2000|UINT32|0x10001002\r
+  gIntelFspPkgTokenSpaceGuid.PcdFspTemporaryRamSize     |    0x1000|UINT32|0x10001003\r
+  gIntelFspPkgTokenSpaceGuid.PcdFspMaxPerfEntry         |        32|UINT32|0x00002001\r
+  gIntelFspPkgTokenSpaceGuid.PcdFspMaxPatchEntry        |         5|UINT32|0x00002002\r
+\r
+[PcdsFixedAtBuild,PcdsDynamic,PcdsDynamicEx]\r
+  gIntelFspPkgTokenSpaceGuid.PcdFspReservedMemoryLength |0x00100000|UINT32|0x46530000\r
+  gIntelFspPkgTokenSpaceGuid.PcdBootLoaderEntry         |0xFFFFFFE4|UINT32|0x46530100\r
diff --git a/IntelFspPkg/IntelFspPkg.dsc b/IntelFspPkg/IntelFspPkg.dsc
new file mode 100644 (file)
index 0000000..1f497ff
--- /dev/null
@@ -0,0 +1,75 @@
+## @file\r
+#\r
+# Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>\r
+# This program and the accompanying materials are licensed and made available under\r
+# the terms and conditions of the BSD License that accompanies this distribution.\r
+# The full text of the license may be found at\r
+# http://opensource.org/licenses/bsd-license.php.\r
+#\r
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+##\r
+\r
+[Defines]\r
+  PLATFORM_NAME                  = IntelFspPkg\r
+  PLATFORM_GUID                  = 29C6791F-9EBC-4470-A126-2BB47431AE5E\r
+  PLATFORM_VERSION               = 0.1\r
+  DSC_SPECIFICATION              = 0x00010005\r
+  OUTPUT_DIRECTORY               = Build/IntelFspPkg\r
+  SUPPORTED_ARCHITECTURES        = IA32\r
+  BUILD_TARGETS                  = DEBUG|RELEASE\r
+  SKUID_IDENTIFIER               = DEFAULT\r
+\r
+[LibraryClasses]\r
+  BaseLib|MdePkg/Library/BaseLib/BaseLib.inf\r
+  BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf\r
+  PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf\r
+  PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf\r
+  DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf\r
+  PciCf8Lib|MdePkg/Library/BasePciCf8Lib/BasePciCf8Lib.inf\r
+  IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf\r
+  UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf\r
+\r
+  # Dummy - test build only\r
+  SerialPortLib|MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.inf\r
+  ReportStatusCodeLib|MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.inf\r
+  DebugDeviceLib|IntelFspPkg/Library/BaseDebugDeviceLibNull/BaseDebugDeviceLibNull.inf\r
+\r
+  # FSP override\r
+  DebugLib|IntelFspPkg/Library/BaseFspDebugLibSerialPort/BaseFspDebugLibSerialPort.inf\r
+\r
+  # FSP specific lib\r
+  CacheAsRamLib|IntelFspPkg/Library/BaseCacheAsRamLibNull/BaseCacheAsRamLibNull.inf\r
+  CacheLib|IntelFspPkg/Library/BaseCacheLib/BaseCacheLib.inf\r
+  FspCommonLib|IntelFspPkg/Library/BaseFspCommonLib/BaseFspCommonLib.inf\r
+  FspPlatformLib|IntelFspPkg/Library/BaseFspPlatformLib/BaseFspPlatformLib.inf\r
+  FspSwitchStackLib|IntelFspPkg/Library/BaseFspSwitchStackLib/BaseFspSwitchStackLib.inf\r
+\r
+[LibraryClasses.common.PEIM]\r
+  PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf\r
+  PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf\r
+  PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf\r
+  MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf\r
+  ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf\r
+\r
+  HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf\r
+\r
+[Components]\r
+  IntelFspPkg/Library/BaseCacheAsRamLibNull/BaseCacheAsRamLibNull.inf\r
+  IntelFspPkg/Library/BaseCacheLib/BaseCacheLib.inf\r
+  IntelFspPkg/Library/BaseFspCommonLib/BaseFspCommonLib.inf\r
+  IntelFspPkg/Library/BaseFspDebugLibSerialPort/BaseFspDebugLibSerialPort.inf\r
+  IntelFspPkg/Library/BaseFspPlatformLib/BaseFspPlatformLib.inf\r
+  IntelFspPkg/Library/BaseFspSwitchStackLib/BaseFspSwitchStackLib.inf\r
+\r
+  IntelFspPkg/FspSecCore/FspSecCore.inf {\r
+    <LibraryClasses>\r
+    NULL|IntelFspPkg/Library/SecPlatformSecLibNull/SecPlatformSecLibNull.inf\r
+  }\r
+  IntelFspPkg/FspDxeIpl/FspDxeIpl.inf\r
+\r
+[PcdsFixedAtBuild.common]\r
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x1f\r
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80080046\r
+  gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x07\r
diff --git a/IntelFspPkg/Library/BaseCacheAsRamLibNull/BaseCacheAsRamLibNull.inf b/IntelFspPkg/Library/BaseCacheAsRamLibNull/BaseCacheAsRamLibNull.inf
new file mode 100644 (file)
index 0000000..7c8492c
--- /dev/null
@@ -0,0 +1,30 @@
+## @file\r
+#\r
+#  Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>\r
+#\r
+#  This program and the accompanying materials\r
+#  are licensed and made available under the terms and conditions of the BSD License\r
+#  which accompanies this distribution. The full text of the license may be found at\r
+#  http://opensource.org/licenses/bsd-license.php.\r
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+##\r
+\r
+[defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = BaseCacheAsRamLibNull\r
+  FILE_GUID                      = FBB4A01B-947E-4d82-B27D-1E207C070053\r
+  MODULE_TYPE                    = BASE\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = CacheAsRamLib\r
+\r
+[sources.common]\r
+  DisableCacheAsRamNull.c\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  IntelFspPkg/IntelFspPkg.dec\r
+\r
+[LibraryClasses]\r
+\r
diff --git a/IntelFspPkg/Library/BaseCacheAsRamLibNull/DisableCacheAsRamNull.c b/IntelFspPkg/Library/BaseCacheAsRamLibNull/DisableCacheAsRamNull.c
new file mode 100644 (file)
index 0000000..9b45163
--- /dev/null
@@ -0,0 +1,41 @@
+/** @file\r
+\r
+  Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php.\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <Uefi.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/CacheAsRamLib.h>\r
+\r
+/**\r
+  This function disable CAR.\r
+\r
+  @param[in] DisableCar       TRUE means use INVD, FALSE means use WBINVD\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+DisableCacheAsRam (\r
+  IN BOOLEAN                   DisableCar\r
+  )\r
+{\r
+  //\r
+  // Disable CAR\r
+  //\r
+\r
+  if (DisableCar) {\r
+    AsmInvd ();\r
+  } else {\r
+    AsmWbinvd();\r
+  }\r
+\r
+  return ;\r
+}\r
diff --git a/IntelFspPkg/Library/BaseCacheLib/BaseCacheLib.inf b/IntelFspPkg/Library/BaseCacheLib/BaseCacheLib.inf
new file mode 100644 (file)
index 0000000..d76a32b
--- /dev/null
@@ -0,0 +1,32 @@
+## @file\r
+#\r
+#  Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>\r
+#\r
+#  This program and the accompanying materials\r
+#  are licensed and made available under the terms and conditions of the BSD License\r
+#  which accompanies this distribution. The full text of the license may be found at\r
+#  http://opensource.org/licenses/bsd-license.php.\r
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+##\r
+\r
+[defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = BaseCacheLib\r
+  FILE_GUID                      = 01359d99-9446-456d-ada4-50a711c03adb\r
+  MODULE_TYPE                    = BASE\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = CacheLib\r
+\r
+[sources.IA32]\r
+  CacheLib.c\r
+  CacheLibInternal.h\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  IntelFspPkg/IntelFspPkg.dec\r
+\r
+[LibraryClasses]\r
+  BaseMemoryLib\r
+\r
diff --git a/IntelFspPkg/Library/BaseCacheLib/CacheLib.c b/IntelFspPkg/Library/BaseCacheLib/CacheLib.c
new file mode 100644 (file)
index 0000000..aaaeb8b
--- /dev/null
@@ -0,0 +1,749 @@
+/** @file\r
+\r
+  Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php.\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <Uefi.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/CacheLib.h>\r
+#include <Library/CacheAsRamLib.h>\r
+#include "CacheLibInternal.h"\r
+\r
+/**\r
+  Calculate the maximum value which is a power of 2, but less the Input.\r
+\r
+  @param[in]  Input        The number to pass in.\r
+  @return The maximum value which is align to power of 2 and less the Input\r
+**/\r
+UINT32\r
+SetPower2 (\r
+  IN  UINT32                    Input\r
+  );\r
+\r
+/**\r
+  Search the memory cache type for specific memory from MTRR.\r
+\r
+  @param[in]  MemoryAddress         the address of target memory\r
+  @param[in]  MemoryLength          the length of target memory\r
+  @param[in]  ValidMtrrAddressMask  the MTRR address mask\r
+  @param[out] UsedMsrNum            the used MSR number\r
+  @param[out] UsedMemoryCacheType   the cache type for the target memory\r
+\r
+  @retval EFI_SUCCESS    The memory is found in MTRR and cache type is returned\r
+  @retval EFI_NOT_FOUND  The memory is not found in MTRR\r
+\r
+**/\r
+EFI_STATUS\r
+SearchForExactMtrr (\r
+  IN  EFI_PHYSICAL_ADDRESS      MemoryAddress,\r
+  IN  UINT64                    MemoryLength,\r
+  IN  UINT64                    ValidMtrrAddressMask,\r
+  OUT UINT32                    *UsedMsrNum,\r
+  OUT EFI_MEMORY_CACHE_TYPE     *MemoryCacheType\r
+  );\r
+\r
+/**\r
+  Check if CacheType match current default setting.\r
+\r
+  @param[in] MemoryCacheType  input cache type to be checked.\r
+\r
+  @retval TRUE MemoryCacheType is default MTRR setting.\r
+  @retval TRUE MemoryCacheType is NOT default MTRR setting.\r
+**/\r
+BOOLEAN\r
+IsDefaultType (\r
+  IN  EFI_MEMORY_CACHE_TYPE     MemoryCacheType\r
+  );\r
+\r
+/**\r
+  Return MTRR alignment requirement for base address and size.\r
+\r
+  @param[in]  BaseAddress     Base address.\r
+  @param[in]  Size            Size.\r
+\r
+  @retval Zero      Alligned.\r
+  @retval Non-Zero  Not alligned.\r
+\r
+**/\r
+UINT32\r
+CheckMtrrAlignment (\r
+  IN  UINT64                    BaseAddress,\r
+  IN  UINT64                    Size\r
+  );\r
+\r
+typedef struct {\r
+  UINT32    Msr;\r
+  UINT32    BaseAddress;\r
+  UINT32    Length;\r
+} EFI_FIXED_MTRR;\r
+\r
+EFI_FIXED_MTRR mFixedMtrrTable[] = {\r
+  { EFI_MSR_IA32_MTRR_FIX64K_00000, 0,       0x10000},\r
+  { EFI_MSR_IA32_MTRR_FIX16K_80000, 0x80000, 0x4000},\r
+  { EFI_MSR_IA32_MTRR_FIX16K_A0000, 0xA0000, 0x4000},\r
+  { EFI_MSR_IA32_MTRR_FIX4K_C0000,  0xC0000, 0x1000},\r
+  { EFI_MSR_IA32_MTRR_FIX4K_C8000,  0xC8000, 0x1000},\r
+  { EFI_MSR_IA32_MTRR_FIX4K_D0000,  0xD0000, 0x1000},\r
+  { EFI_MSR_IA32_MTRR_FIX4K_D8000,  0xD8000, 0x1000},\r
+  { EFI_MSR_IA32_MTRR_FIX4K_E0000,  0xE0000, 0x1000},\r
+  { EFI_MSR_IA32_MTRR_FIX4K_E8000,  0xE8000, 0x1000},\r
+  { EFI_MSR_IA32_MTRR_FIX4K_F0000,  0xF0000, 0x1000},\r
+  { EFI_MSR_IA32_MTRR_FIX4K_F8000,  0xF8000, 0x1000}\r
+};\r
+\r
+/**\r
+  Given the input, check if the number of MTRR is lesser.\r
+  if positive or subtractive.\r
+\r
+  @param[in]  Input   Length of Memory to program MTRR.\r
+\r
+  @retval  Zero      do positive.\r
+  @retval  Non-Zero  do subtractive.\r
+\r
+**/\r
+INT8\r
+CheckDirection (\r
+  IN  UINT64                    Input\r
+  )\r
+{\r
+  return 0;\r
+}\r
+\r
+/**\r
+  Disable cache and its mtrr.\r
+\r
+  @param[out]  OldMtrr To return the Old MTRR value\r
+\r
+**/\r
+VOID\r
+EfiDisableCacheMtrr (\r
+  OUT UINT64                   *OldMtrr\r
+  )\r
+{\r
+  UINT64  TempQword;\r
+\r
+  //\r
+  // Disable Cache MTRR\r
+  //\r
+  *OldMtrr = AsmReadMsr64(EFI_MSR_CACHE_IA32_MTRR_DEF_TYPE);\r
+  TempQword = (*OldMtrr) & ~B_EFI_MSR_GLOBAL_MTRR_ENABLE & ~B_EFI_MSR_FIXED_MTRR_ENABLE;\r
+  AsmWriteMsr64(EFI_MSR_CACHE_IA32_MTRR_DEF_TYPE, TempQword);\r
+  AsmDisableCache ();\r
+}\r
+\r
+/**\r
+  Recover cache MTRR.\r
+\r
+  @param[in] EnableMtrr Whether to enable the MTRR\r
+  @param[in] OldMtrr    The saved old MTRR value to restore when not to enable the MTRR\r
+\r
+**/\r
+VOID\r
+EfiRecoverCacheMtrr (\r
+  IN BOOLEAN                  EnableMtrr,\r
+  IN UINT64                   OldMtrr\r
+  )\r
+{\r
+  UINT64  TempQword;\r
+\r
+  //\r
+  // Enable Cache MTRR\r
+  //\r
+  if (EnableMtrr) {\r
+    TempQword = AsmReadMsr64(EFI_MSR_CACHE_IA32_MTRR_DEF_TYPE);\r
+    TempQword |= (B_EFI_MSR_GLOBAL_MTRR_ENABLE | B_EFI_MSR_FIXED_MTRR_ENABLE);\r
+  } else {\r
+    TempQword = OldMtrr;\r
+  }\r
+\r
+  AsmWriteMsr64 (EFI_MSR_CACHE_IA32_MTRR_DEF_TYPE, TempQword);\r
+\r
+  AsmEnableCache ();\r
+}\r
+\r
+/**\r
+  Programming MTRR according to Memory address, length, and type.\r
+\r
+  @param[in] MtrrNumber           the variable MTRR index number\r
+  @param[in] MemoryAddress        the address of target memory\r
+  @param[in] MemoryLength         the length of target memory\r
+  @param[in] MemoryCacheType      the cache type of target memory\r
+  @param[in] ValidMtrrAddressMask the MTRR address mask\r
+\r
+**/\r
+VOID\r
+EfiProgramMtrr (\r
+  IN  UINTN                     MtrrNumber,\r
+  IN  EFI_PHYSICAL_ADDRESS      MemoryAddress,\r
+  IN  UINT64                    MemoryLength,\r
+  IN  EFI_MEMORY_CACHE_TYPE     MemoryCacheType,\r
+  IN  UINT64                    ValidMtrrAddressMask\r
+  )\r
+{\r
+  UINT64                        TempQword;\r
+  UINT64                        OldMtrr;\r
+\r
+  if (MemoryLength == 0) {\r
+    return;\r
+  }\r
+\r
+  EfiDisableCacheMtrr (&OldMtrr);\r
+\r
+  //\r
+  // MTRR Physical Base\r
+  //\r
+  TempQword = (MemoryAddress & ValidMtrrAddressMask) | MemoryCacheType;\r
+  AsmWriteMsr64 (MtrrNumber, TempQword);\r
+\r
+  //\r
+  // MTRR Physical Mask\r
+  //\r
+  TempQword = ~(MemoryLength - 1);\r
+  AsmWriteMsr64 (MtrrNumber + 1, (TempQword & ValidMtrrAddressMask) | B_EFI_MSR_CACHE_MTRR_VALID);\r
+\r
+  EfiRecoverCacheMtrr (TRUE, OldMtrr);\r
+}\r
+\r
+/**\r
+  Calculate the maximum value which is a power of 2, but less the MemoryLength.\r
+\r
+  @param[in]  MemoryAddress       Memory address.\r
+  @param[in]  MemoryLength        The number to pass in.\r
+\r
+  @return The maximum value which is align to power of 2 and less the MemoryLength\r
+\r
+**/\r
+UINT64\r
+Power2MaxMemory (\r
+  IN UINT64                 MemoryAddress,\r
+  IN UINT64                 MemoryLength\r
+  )\r
+{\r
+  UINT64                    Result;\r
+\r
+  if (MemoryLength == 0) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // Compute inital power of 2 size to return\r
+  //\r
+  if (RShiftU64(MemoryLength, 32)) {\r
+    Result = LShiftU64((UINT64)SetPower2((UINT32) RShiftU64(MemoryLength, 32)), 32);\r
+  } else {\r
+    Result = (UINT64)SetPower2((UINT32)MemoryLength);\r
+  }\r
+\r
+  //\r
+  // Special case base of 0 as all ranges are valid\r
+  //\r
+  if (MemoryAddress == 0) {\r
+    return Result;\r
+  }\r
+\r
+  //\r
+  // Loop till a value that can be mapped to this base address is found\r
+  //\r
+  while (CheckMtrrAlignment (MemoryAddress, Result) != 0) {\r
+    //\r
+    // Need to try the next smaller power of 2\r
+    //\r
+    Result = RShiftU64 (Result, 1);\r
+  }\r
+\r
+  return Result;\r
+}\r
+\r
+/**\r
+  Return MTRR alignment requirement for base address and size.\r
+\r
+  @param[in]  BaseAddress     Base address.\r
+  @param[in]  Size            Size.\r
+\r
+  @retval Zero      Alligned.\r
+  @retval Non-Zero  Not alligned.\r
+\r
+**/\r
+UINT32\r
+CheckMtrrAlignment (\r
+  IN  UINT64    BaseAddress,\r
+  IN  UINT64    Size\r
+  )\r
+{\r
+  UINT32      ShiftedBase;\r
+  UINT32      ShiftedSize;\r
+\r
+  //\r
+  // Shift base and size right 12 bits to allow for larger memory sizes.  The\r
+  // MTRRs do not use the first 12 bits so this is safe for now.  Only supports\r
+  // up to 52 bits of physical address space.\r
+  //\r
+  ShiftedBase = (UINT32) RShiftU64 (BaseAddress, 12);\r
+  ShiftedSize = (UINT32) RShiftU64 (Size, 12);\r
+\r
+  //\r
+  // Return the results to the caller of the MOD\r
+  //\r
+  return ShiftedBase % ShiftedSize;\r
+}\r
+\r
+/**\r
+  Calculate the maximum value which is a power of 2, but less the Input.\r
+\r
+  @param[in]  Input        The number to pass in.\r
+\r
+  @return The maximum value which is align to power of 2 and less the Input.\r
+**/\r
+UINT32\r
+SetPower2 (\r
+  IN UINT32 Input\r
+  )\r
+{\r
+  UINT32 Result;\r
+\r
+  Result = 0;\r
+#if defined(__GCC__)\r
+  asm("bsr %1, \\r
+      %%eax; \\r
+     bts %%eax, \\r
+      %0;" :"=r"(Result) :\r
+    "r"(Input)\r
+  );\r
+#elif defined(_MSC_VER)\r
+  _asm {\r
+    bsr eax, Input\r
+    bts Result, eax\r
+  }\r
+#endif\r
+  return Result;\r
+}\r
+\r
+/**\r
+  Programs fixed MTRRs registers.\r
+\r
+  @param[in]  MemoryCacheType  The memory type to set.\r
+  @param[in]  Base             The base address of memory range.\r
+  @param[in]  Length           The length of memory range.\r
+\r
+  @retval RETURN_SUCCESS      The cache type was updated successfully\r
+  @retval RETURN_UNSUPPORTED  The requested range or cache type was invalid\r
+                              for the fixed MTRRs.\r
+\r
+**/\r
+EFI_STATUS\r
+ProgramFixedMtrr (\r
+  IN  EFI_MEMORY_CACHE_TYPE     MemoryCacheType,\r
+  IN  UINT64                    *Base,\r
+  IN  UINT64                    *Len\r
+  )\r
+{\r
+  UINT32                      MsrNum;\r
+  UINT32                      ByteShift;\r
+  UINT64                      TempQword;\r
+  UINT64                      OrMask;\r
+  UINT64                      ClearMask;\r
+\r
+  TempQword = 0;\r
+  OrMask =  0;\r
+  ClearMask = 0;\r
+\r
+  for (MsrNum = 0; MsrNum < V_EFI_FIXED_MTRR_NUMBER; MsrNum++) {\r
+    if ((*Base >= mFixedMtrrTable[MsrNum].BaseAddress) &&\r
+        (*Base < (mFixedMtrrTable[MsrNum].BaseAddress + 8 * mFixedMtrrTable[MsrNum].Length))) {\r
+      break;\r
+    }\r
+  }\r
+  if (MsrNum == V_EFI_FIXED_MTRR_NUMBER ) {\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+  //\r
+  // We found the fixed MTRR to be programmed\r
+  //\r
+  for (ByteShift=0; ByteShift < 8; ByteShift++) {\r
+    if ( *Base == (mFixedMtrrTable[MsrNum].BaseAddress + ByteShift * mFixedMtrrTable[MsrNum].Length)) {\r
+      break;\r
+    }\r
+  }\r
+  if (ByteShift == 8 ) {\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+  for (; ((ByteShift<8) && (*Len >= mFixedMtrrTable[MsrNum].Length));ByteShift++) {\r
+    OrMask |= LShiftU64((UINT64) MemoryCacheType, (UINT32) (ByteShift* 8));\r
+    ClearMask |= LShiftU64((UINT64) 0xFF, (UINT32) (ByteShift * 8));\r
+    *Len -= mFixedMtrrTable[MsrNum].Length;\r
+    *Base += mFixedMtrrTable[MsrNum].Length;\r
+  }\r
+  TempQword = AsmReadMsr64 (mFixedMtrrTable[MsrNum].Msr) & (~ClearMask | OrMask);\r
+  AsmWriteMsr64 (mFixedMtrrTable[MsrNum].Msr, TempQword);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Check if there is a valid variable MTRR that overlaps the given range.\r
+\r
+  @param[in]  Start  Base Address of the range to check.\r
+  @param[in]  End    End address of the range to check.\r
+\r
+  @retval TRUE   Mtrr overlap.\r
+  @retval FALSE  Mtrr not overlap.\r
+**/\r
+BOOLEAN\r
+CheckMtrrOverlap (\r
+  IN  EFI_PHYSICAL_ADDRESS      Start,\r
+  IN  EFI_PHYSICAL_ADDRESS      End\r
+  )\r
+{\r
+  return FALSE;\r
+}\r
+\r
+/**\r
+  Given the memory range and cache type, programs the MTRRs.\r
+\r
+  @param[in] MemoryAddress           Base Address of Memory to program MTRR.\r
+  @param[in] MemoryLength            Length of Memory to program MTRR.\r
+  @param[in] MemoryCacheType         Cache Type.\r
+\r
+  @retval EFI_SUCCESS            Mtrr are set successfully.\r
+  @retval EFI_LOAD_ERROR         No empty MTRRs to use.\r
+  @retval EFI_INVALID_PARAMETER  The input parameter is not valid.\r
+  @retval others                 An error occurs when setting MTTR.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+SetCacheAttributes (\r
+  IN  EFI_PHYSICAL_ADDRESS      MemoryAddress,\r
+  IN  UINT64                    MemoryLength,\r
+  IN  EFI_MEMORY_CACHE_TYPE     MemoryCacheType\r
+  )\r
+{\r
+  EFI_STATUS            Status;\r
+  UINT32                MsrNum, MsrNumEnd;\r
+  UINT64                TempQword;\r
+  UINT32                LastVariableMtrrForBios;\r
+  UINT64                OldMtrr;\r
+  UINT32                UsedMsrNum;\r
+  EFI_MEMORY_CACHE_TYPE UsedMemoryCacheType;\r
+  UINT64                ValidMtrrAddressMask;\r
+  UINT32                Cpuid_RegEax;\r
+\r
+  AsmCpuid (CPUID_EXTENDED_FUNCTION, &Cpuid_RegEax, NULL, NULL, NULL);\r
+  if (Cpuid_RegEax >= CPUID_VIR_PHY_ADDRESS_SIZE) {\r
+    AsmCpuid (CPUID_VIR_PHY_ADDRESS_SIZE, &Cpuid_RegEax, NULL, NULL, NULL);\r
+    ValidMtrrAddressMask = (LShiftU64((UINT64) 1, (Cpuid_RegEax & 0xFF)) - 1) & (~(UINT64)0x0FFF);\r
+  } else {\r
+    ValidMtrrAddressMask = (LShiftU64((UINT64) 1, 36) - 1) & (~(UINT64)0x0FFF);\r
+  }\r
+\r
+  //\r
+  // Check for invalid parameter\r
+  //\r
+  if ((MemoryAddress & ~ValidMtrrAddressMask) != 0 || (MemoryLength & ~ValidMtrrAddressMask) != 0) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (MemoryLength == 0) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  switch (MemoryCacheType) {\r
+    case EFI_CACHE_UNCACHEABLE:\r
+    case EFI_CACHE_WRITECOMBINING:\r
+    case EFI_CACHE_WRITETHROUGH:\r
+    case EFI_CACHE_WRITEPROTECTED:\r
+    case EFI_CACHE_WRITEBACK:\r
+      break;\r
+\r
+    default:\r
+      return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // Check if Fixed MTRR\r
+  //\r
+  if ((MemoryAddress + MemoryLength) <= (1 << 20)) {\r
+    Status = EFI_SUCCESS;\r
+    EfiDisableCacheMtrr (&OldMtrr);\r
+    while ((MemoryLength > 0) && (Status == EFI_SUCCESS)) {\r
+      Status = ProgramFixedMtrr (MemoryCacheType, &MemoryAddress, &MemoryLength);\r
+    }\r
+    EfiRecoverCacheMtrr (TRUE, OldMtrr);\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Search if the range attribute has been set before\r
+  //\r
+  Status = SearchForExactMtrr(\r
+                              MemoryAddress,\r
+                              MemoryLength,\r
+                              ValidMtrrAddressMask,\r
+                              &UsedMsrNum,\r
+                              &UsedMemoryCacheType\r
+                              );\r
+\r
+  if (!EFI_ERROR(Status)) {\r
+    //\r
+    // Compare if it has the same type as current setting\r
+    //\r
+    if (UsedMemoryCacheType == MemoryCacheType) {\r
+      return EFI_SUCCESS;\r
+    } else {\r
+      //\r
+      // Different type\r
+      //\r
+\r
+      //\r
+      // Check if the set type is the same as Default Type\r
+      //\r
+      if (IsDefaultType(MemoryCacheType)) {\r
+        //\r
+        // Clear the MTRR\r
+        //\r
+        AsmWriteMsr64(UsedMsrNum, 0);\r
+        AsmWriteMsr64(UsedMsrNum + 1, 0);\r
+\r
+        return EFI_SUCCESS;\r
+      } else {\r
+        //\r
+        // Modify the MTRR type\r
+        //\r
+        EfiProgramMtrr(UsedMsrNum,\r
+                       MemoryAddress,\r
+                       MemoryLength,\r
+                       MemoryCacheType,\r
+                       ValidMtrrAddressMask\r
+                       );\r
+        return EFI_SUCCESS;\r
+      }\r
+    }\r
+  }\r
+\r
+#if 0\r
+  //\r
+  // @bug - Need to create memory map so that when checking for overlap we\r
+  //        can determine if an overlap exists based on all caching requests.\r
+  //\r
+  // Don't waste a variable MTRR if the caching attrib is same as default in MTRR_DEF_TYPE\r
+  //\r
+  if (MemoryCacheType == (AsmReadMsr64(EFI_MSR_CACHE_IA32_MTRR_DEF_TYPE) & B_EFI_MSR_CACHE_MEMORY_TYPE))  {\r
+    if (!CheckMtrrOverlap (MemoryAddress, MemoryAddress+MemoryLength-1)) {\r
+      return EFI_SUCCESS;\r
+    }\r
+  }\r
+#endif\r
+\r
+  //\r
+  // Find first unused MTRR\r
+  //\r
+  MsrNumEnd = EFI_MSR_CACHE_VARIABLE_MTRR_BASE + (2 * (UINT32)(AsmReadMsr64(EFI_MSR_IA32_MTRR_CAP) & B_EFI_MSR_IA32_MTRR_CAP_VARIABLE_SUPPORT));\r
+  for (MsrNum = EFI_MSR_CACHE_VARIABLE_MTRR_BASE; MsrNum < MsrNumEnd; MsrNum +=2) {\r
+    if ((AsmReadMsr64(MsrNum+1) & B_EFI_MSR_CACHE_MTRR_VALID) == 0 ) {\r
+      break;\r
+    }\r
+  }\r
+\r
+  //\r
+  // Reserve 1 MTRR pair for OS.\r
+  //\r
+  LastVariableMtrrForBios = MsrNumEnd - 1 - (EFI_CACHE_NUM_VAR_MTRR_PAIRS_FOR_OS * 2);\r
+  if (MsrNum > LastVariableMtrrForBios) {\r
+    return EFI_LOAD_ERROR;\r
+  }\r
+\r
+  //\r
+  // Special case for 1 MB base address\r
+  //\r
+  if (MemoryAddress == BASE_1MB) {\r
+    MemoryAddress = 0;\r
+  }\r
+\r
+  //\r
+  // Program MTRRs\r
+  //\r
+  TempQword = MemoryLength;\r
+\r
+  if (TempQword == Power2MaxMemory(MemoryAddress, TempQword)) {\r
+    EfiProgramMtrr(MsrNum,\r
+                   MemoryAddress,\r
+                   MemoryLength,\r
+                   MemoryCacheType,\r
+                   ValidMtrrAddressMask\r
+                   );\r
+\r
+  } else {\r
+    //\r
+    // Fill in MTRRs with values.  Direction can not be checked for this method\r
+    // as we are using WB as the default cache type and only setting areas to UC.\r
+    //\r
+    do {\r
+      //\r
+      // Do boundary check so we don't go past last MTRR register\r
+      // for BIOS use.  Leave one MTRR pair for OS use.\r
+      //\r
+      if (MsrNum > LastVariableMtrrForBios) {\r
+        return EFI_LOAD_ERROR;\r
+      }\r
+\r
+      //\r
+      // Set next power of 2 region\r
+      //\r
+      MemoryLength = Power2MaxMemory(MemoryAddress, TempQword);\r
+      EfiProgramMtrr(MsrNum,\r
+                     MemoryAddress,\r
+                     MemoryLength,\r
+                     MemoryCacheType,\r
+                     ValidMtrrAddressMask\r
+                     );\r
+      MemoryAddress += MemoryLength;\r
+      TempQword -= MemoryLength;\r
+      MsrNum += 2;\r
+    } while (TempQword != 0);\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Reset all the MTRRs to a known state.\r
+\r
+  @retval  EFI_SUCCESS All MTRRs have been reset successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ResetCacheAttributes (\r
+  VOID\r
+  )\r
+{\r
+  UINT32                      MsrNum, MsrNumEnd;\r
+  UINT16                      Index;\r
+  UINT64                      OldMtrr;\r
+  UINT64                      CacheType;\r
+  BOOLEAN                     DisableCar;\r
+  Index = 0;\r
+  DisableCar = TRUE;\r
+\r
+  //\r
+  // Determine default cache type\r
+  //\r
+  CacheType = EFI_CACHE_UNCACHEABLE;\r
+\r
+  //\r
+  // Set default cache type\r
+  //\r
+  AsmWriteMsr64(EFI_MSR_CACHE_IA32_MTRR_DEF_TYPE, CacheType);\r
+\r
+  //\r
+  // Disable CAR\r
+  //\r
+  DisableCacheAsRam (DisableCar);\r
+\r
+  EfiDisableCacheMtrr (&OldMtrr);\r
+\r
+  //\r
+  // Reset Fixed MTRRs\r
+  //\r
+  for (Index = 0; Index < V_EFI_FIXED_MTRR_NUMBER; Index++) {\r
+    AsmWriteMsr64 (mFixedMtrrTable[Index].Msr, 0);\r
+  }\r
+\r
+  //\r
+  // Reset Variable MTRRs\r
+  //\r
+  MsrNumEnd = EFI_MSR_CACHE_VARIABLE_MTRR_BASE + (2 * (UINT32)(AsmReadMsr64(EFI_MSR_IA32_MTRR_CAP) & B_EFI_MSR_IA32_MTRR_CAP_VARIABLE_SUPPORT));\r
+  for (MsrNum = EFI_MSR_CACHE_VARIABLE_MTRR_BASE; MsrNum < MsrNumEnd; MsrNum++) {\r
+    AsmWriteMsr64 (MsrNum, 0);\r
+  }\r
+\r
+  //\r
+  // Enable Fixed and Variable MTRRs\r
+  //\r
+  EfiRecoverCacheMtrr (TRUE, OldMtrr);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Search the memory cache type for specific memory from MTRR.\r
+\r
+  @param[in]  MemoryAddress         the address of target memory\r
+  @param[in]  MemoryLength          the length of target memory\r
+  @param[in]  ValidMtrrAddressMask  the MTRR address mask\r
+  @param[out] UsedMsrNum            the used MSR number\r
+  @param[out] UsedMemoryCacheType   the cache type for the target memory\r
+\r
+  @retval EFI_SUCCESS    The memory is found in MTRR and cache type is returned\r
+  @retval EFI_NOT_FOUND  The memory is not found in MTRR\r
+\r
+**/\r
+EFI_STATUS\r
+SearchForExactMtrr (\r
+  IN  EFI_PHYSICAL_ADDRESS      MemoryAddress,\r
+  IN  UINT64                    MemoryLength,\r
+  IN  UINT64                    ValidMtrrAddressMask,\r
+  OUT UINT32                    *UsedMsrNum,\r
+  OUT EFI_MEMORY_CACHE_TYPE     *UsedMemoryCacheType\r
+  )\r
+{\r
+  UINT32                      MsrNum, MsrNumEnd;\r
+  UINT64                      TempQword;\r
+\r
+  if (MemoryLength == 0) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  MsrNumEnd = EFI_MSR_CACHE_VARIABLE_MTRR_BASE + (2 * (UINT32)(AsmReadMsr64(EFI_MSR_IA32_MTRR_CAP) & B_EFI_MSR_IA32_MTRR_CAP_VARIABLE_SUPPORT));\r
+  for (MsrNum = EFI_MSR_CACHE_VARIABLE_MTRR_BASE; MsrNum < MsrNumEnd; MsrNum +=2) {\r
+    TempQword = AsmReadMsr64(MsrNum+1);\r
+    if ((TempQword & B_EFI_MSR_CACHE_MTRR_VALID) == 0) {\r
+      continue;\r
+    }\r
+\r
+    if ((TempQword & ValidMtrrAddressMask) != ((~(MemoryLength - 1)) & ValidMtrrAddressMask)) {\r
+      continue;\r
+    }\r
+\r
+    TempQword = AsmReadMsr64 (MsrNum);\r
+    if ((TempQword & ValidMtrrAddressMask) != (MemoryAddress & ValidMtrrAddressMask)) {\r
+      continue;\r
+    }\r
+\r
+    *UsedMemoryCacheType = (EFI_MEMORY_CACHE_TYPE)(TempQword & B_EFI_MSR_CACHE_MEMORY_TYPE);\r
+    *UsedMsrNum = MsrNum;\r
+\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  return EFI_NOT_FOUND;\r
+}\r
+\r
+/**\r
+  Check if CacheType match current default setting.\r
+\r
+  @param[in] MemoryCacheType  input cache type to be checked.\r
+\r
+  @retval TRUE MemoryCacheType is default MTRR setting.\r
+  @retval TRUE MemoryCacheType is NOT default MTRR setting.\r
+**/\r
+BOOLEAN\r
+IsDefaultType (\r
+  IN  EFI_MEMORY_CACHE_TYPE     MemoryCacheType\r
+  )\r
+{\r
+  if ((AsmReadMsr64(EFI_MSR_CACHE_IA32_MTRR_DEF_TYPE) & B_EFI_MSR_CACHE_MEMORY_TYPE) != MemoryCacheType) {\r
+    return FALSE;\r
+  }\r
+\r
+  return TRUE;\r
+}\r
+\r
diff --git a/IntelFspPkg/Library/BaseCacheLib/CacheLibInternal.h b/IntelFspPkg/Library/BaseCacheLib/CacheLibInternal.h
new file mode 100644 (file)
index 0000000..fbbf551
--- /dev/null
@@ -0,0 +1,59 @@
+/** @file\r
+\r
+  Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php.\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef _CACHE_LIB_INTERNAL_H_\r
+#define _CACHE_LIB_INTERNAL_H_\r
+\r
+#define EFI_MSR_CACHE_VARIABLE_MTRR_BASE       0x00000200\r
+#define EFI_MSR_CACHE_VARIABLE_MTRR_END        0x0000020F\r
+#define   V_EFI_FIXED_MTRR_NUMBER                                      11\r
+\r
+#define EFI_MSR_IA32_MTRR_FIX64K_00000         0x00000250\r
+#define EFI_MSR_IA32_MTRR_FIX16K_80000         0x00000258\r
+#define EFI_MSR_IA32_MTRR_FIX16K_A0000         0x00000259\r
+#define EFI_MSR_IA32_MTRR_FIX4K_C0000          0x00000268\r
+#define EFI_MSR_IA32_MTRR_FIX4K_C8000          0x00000269\r
+#define EFI_MSR_IA32_MTRR_FIX4K_D0000          0x0000026A\r
+#define EFI_MSR_IA32_MTRR_FIX4K_D8000          0x0000026B\r
+#define EFI_MSR_IA32_MTRR_FIX4K_E0000          0x0000026C\r
+#define EFI_MSR_IA32_MTRR_FIX4K_E8000          0x0000026D\r
+#define EFI_MSR_IA32_MTRR_FIX4K_F0000          0x0000026E\r
+#define EFI_MSR_IA32_MTRR_FIX4K_F8000          0x0000026F\r
+#define EFI_MSR_CACHE_IA32_MTRR_DEF_TYPE       0x000002FF\r
+#define   B_EFI_MSR_CACHE_MTRR_VALID                                   BIT11\r
+#define   B_EFI_MSR_GLOBAL_MTRR_ENABLE                                 BIT11\r
+#define   B_EFI_MSR_FIXED_MTRR_ENABLE                                  BIT10\r
+#define   B_EFI_MSR_CACHE_MEMORY_TYPE                                  (BIT2 | BIT1 | BIT0)\r
+\r
+#define EFI_MSR_VALID_MASK                     0xFFFFFFFFF\r
+#define EFI_CACHE_VALID_ADDRESS                0xFFFFFF000\r
+#define EFI_SMRR_CACHE_VALID_ADDRESS           0xFFFFF000\r
+#define EFI_CACHE_VALID_EXTENDED_ADDRESS       0xFFFFFFFFFF000\r
+\r
+// Leave one MTRR pairs for OS use\r
+#define EFI_CACHE_NUM_VAR_MTRR_PAIRS_FOR_OS   1\r
+#define EFI_CACHE_LAST_VARIABLE_MTRR_FOR_BIOS (EFI_MSR_CACHE_VARIABLE_MTRR_END) - \\r
+        (EFI_CACHE_NUM_VAR_MTRR_PAIRS_FOR_OS * 2)\r
+\r
+#define EFI_MSR_IA32_MTRR_CAP                  0x000000FE\r
+#define   B_EFI_MSR_IA32_MTRR_CAP_EMRR_SUPPORT                         BIT12\r
+#define   B_EFI_MSR_IA32_MTRR_CAP_SMRR_SUPPORT                         BIT11\r
+#define   B_EFI_MSR_IA32_MTRR_CAP_WC_SUPPORT                           BIT10\r
+#define   B_EFI_MSR_IA32_MTRR_CAP_FIXED_SUPPORT                        BIT8\r
+#define   B_EFI_MSR_IA32_MTRR_CAP_VARIABLE_SUPPORT                     (BIT7 | BIT6 | BIT5 | BIT4 | BIT3 | BIT2 | BIT1 | BIT0)\r
+\r
+#define CPUID_VIR_PHY_ADDRESS_SIZE                                    0x80000008\r
+#define CPUID_EXTENDED_FUNCTION                                       0x80000000\r
+\r
+#endif\r
+\r
diff --git a/IntelFspPkg/Library/BaseDebugDeviceLibNull/BaseDebugDeviceLibNull.inf b/IntelFspPkg/Library/BaseDebugDeviceLibNull/BaseDebugDeviceLibNull.inf
new file mode 100644 (file)
index 0000000..58930bd
--- /dev/null
@@ -0,0 +1,34 @@
+## @file\r
+#  Debug device library instance that retrieves the current enabling state for\r
+#  the platform debug output device.\r
+#\r
+#  Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>\r
+#\r
+#  This program and the accompanying materials\r
+#  are licensed and made available under the terms and conditions of the BSD License\r
+#  which accompanies this distribution. The full text of the license may be found at\r
+#  http://opensource.org/licenses/bsd-license.php.\r
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+##\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = BaseDebugDeviceLibNull\r
+  FILE_GUID                      = 455D16DC-E3AF-4b5f-A9AD-A4BC198085BD\r
+  MODULE_TYPE                    = BASE\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = DebugDeviceLib\r
+\r
+#\r
+#  VALID_ARCHITECTURES           = IA32\r
+#\r
+\r
+[Sources]\r
+  DebugDeviceLibNull.c\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  IntelFspPkg/IntelFspPkg.dec\r
+\r
diff --git a/IntelFspPkg/Library/BaseDebugDeviceLibNull/DebugDeviceLibNull.c b/IntelFspPkg/Library/BaseDebugDeviceLibNull/DebugDeviceLibNull.c
new file mode 100644 (file)
index 0000000..95c1004
--- /dev/null
@@ -0,0 +1,31 @@
+/** @file\r
+  Debug device library instance that retrieves the current enabling state for\r
+  the platform debug output device.\r
+\r
+  Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php.\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <Base.h>\r
+\r
+/**\r
+  Returns the debug print device enable state.\r
+\r
+  @return  Debug print device enable state.\r
+\r
+**/\r
+UINT8\r
+EFIAPI\r
+GetDebugPrintDeviceEnable (\r
+  VOID\r
+  )\r
+{\r
+  return 1;\r
+}\r
diff --git a/IntelFspPkg/Library/BaseFspCommonLib/BaseFspCommonLib.inf b/IntelFspPkg/Library/BaseFspCommonLib/BaseFspCommonLib.inf
new file mode 100644 (file)
index 0000000..0fa8c6a
--- /dev/null
@@ -0,0 +1,37 @@
+## @file\r
+#\r
+#  Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>\r
+#\r
+#  This program and the accompanying materials\r
+#  are licensed and made available under the terms and conditions of the BSD License\r
+#  which accompanies this distribution. The full text of the license may be found at\r
+#  http://opensource.org/licenses/bsd-license.php.\r
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+##\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = BaseFspCommonLib\r
+  FILE_GUID                      = 54607F66-D728-448e-A282-49E0404A557F\r
+  MODULE_TYPE                    = BASE\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = FspCommonLib\r
+\r
+[Sources]\r
+  FspCommonLib.c\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  IntelFspPkg/IntelFspPkg.dec\r
+\r
+[LibraryClasses]\r
+  BaseMemoryLib\r
+\r
+[Pcd]\r
+  gIntelFspPkgTokenSpaceGuid.PcdGlobalDataPointerAddress\r
+\r
+[FixedPcd]\r
+  gIntelFspPkgTokenSpaceGuid.PcdFspMaxPatchEntry\r
+  gIntelFspPkgTokenSpaceGuid.PcdFspMaxPerfEntry\r
diff --git a/IntelFspPkg/Library/BaseFspCommonLib/FspCommonLib.c b/IntelFspPkg/Library/BaseFspCommonLib/FspCommonLib.c
new file mode 100644 (file)
index 0000000..958a732
--- /dev/null
@@ -0,0 +1,318 @@
+/** @file\r
+\r
+  Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php.\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <PiPei.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/PcdLib.h>\r
+#include <FspGlobalData.h>\r
+#include <FspApi.h>\r
+\r
+#pragma pack(1)\r
+\r
+//\r
+//   Cont Func Parameter 2        +0x3C\r
+//   Cont Func Parameter 1        +0x38\r
+//\r
+//   API Parameter                +0x34\r
+//   API return address           +0x30\r
+//\r
+//   push    offset exit          +0x2C\r
+//   pushfd                       +0x28\r
+//   cli\r
+//   pushad                       +0x24\r
+//   sub     esp, 8               +0x00\r
+//   sidt    fword ptr [esp]\r
+//\r
+typedef struct {\r
+  UINT16    IdtrLimit;\r
+  UINT32    IdtrBase;\r
+  UINT16    Reserved;\r
+  UINT32    Edi;\r
+  UINT32    Esi;\r
+  UINT32    Ebp;\r
+  UINT32    Esp;\r
+  UINT32    Ebx;\r
+  UINT32    Edx;\r
+  UINT32    Ecx;\r
+  UINT32    Eax;\r
+  UINT16    Flags[2];\r
+  UINT32    ExitOff;\r
+  UINT32    ApiRet;\r
+  UINT32    ApiParam;\r
+} CONTEXT_STACK;\r
+\r
+#define CONTEXT_STACK_OFFSET(x)  (UINT32)&((CONTEXT_STACK *)(UINTN)0)->x\r
+\r
+#pragma pack()\r
+\r
+/**\r
+  This function sets the FSP global data pointer.\r
+\r
+  @param[in] FspData       Fsp global data pointer.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+SetFspGlobalDataPointer (\r
+  IN FSP_GLOBAL_DATA   *FspData\r
+  )\r
+{\r
+  ASSERT (FspData != NULL);\r
+  *((volatile UINT32 *)(UINTN)PcdGet32(PcdGlobalDataPointerAddress)) = (UINT32)(UINTN)FspData;\r
+}\r
+\r
+/**\r
+  This function gets the FSP global data pointer.\r
+\r
+**/\r
+FSP_GLOBAL_DATA *\r
+EFIAPI\r
+GetFspGlobalDataPointer (\r
+  VOID\r
+  )\r
+{\r
+  FSP_GLOBAL_DATA   *FspData;\r
+\r
+  FspData = *(FSP_GLOBAL_DATA  **)(UINTN)PcdGet32(PcdGlobalDataPointerAddress);\r
+  return FspData;\r
+}\r
+\r
+/**\r
+  This function gets back the FSP API paramter passed by the bootlaoder.\r
+\r
+  @retval ApiParameter FSP API paramter passed by the bootlaoder.\r
+**/\r
+UINT32\r
+EFIAPI\r
+GetFspApiParameter (\r
+  VOID\r
+  )\r
+{\r
+  FSP_GLOBAL_DATA  *FspData;\r
+\r
+  FspData  = GetFspGlobalDataPointer ();\r
+  return *(UINT32 *)(UINTN)(FspData->CoreStack + CONTEXT_STACK_OFFSET(ApiParam));\r
+}\r
+\r
+/**\r
+  This function sets the FSP API paramter in the stack.\r
+\r
+   @param[in] Value       New parameter value.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+SetFspApiParameter (\r
+  IN UINT32      Value\r
+  )\r
+{\r
+  FSP_GLOBAL_DATA  *FspData;\r
+\r
+  FspData  = GetFspGlobalDataPointer ();\r
+  *(UINT32 *)(UINTN)(FspData->CoreStack + CONTEXT_STACK_OFFSET(ApiParam)) = Value;\r
+}\r
+\r
+/**\r
+  This function sets the FSP continuation function parameters in the stack.\r
+\r
+  @param[in] Value             New parameter value to set.\r
+  @param[in] Index             Parameter index.\r
+**/\r
+VOID\r
+EFIAPI\r
+SetFspContinuationFuncParameter (\r
+  IN UINT32      Value,\r
+  IN UINT32      Index\r
+  )\r
+{\r
+  FSP_GLOBAL_DATA  *FspData;\r
+\r
+  FspData  = GetFspGlobalDataPointer ();\r
+  *(UINT32 *)(UINTN)(FspData->CoreStack + CONTEXT_STACK_OFFSET(ApiParam) + (Index + 1) * sizeof(UINT32)) = Value;\r
+}\r
+\r
+\r
+/**\r
+  This function changes the Bootloader return address in stack.\r
+\r
+  @param[in] ReturnAddress       Address to return.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+SetFspApiReturnAddress (\r
+  IN UINT32  ReturnAddress\r
+  )\r
+{\r
+  FSP_GLOBAL_DATA  *FspData;\r
+\r
+  FspData  = GetFspGlobalDataPointer ();\r
+  *(UINT32 *)(UINTN)(FspData->CoreStack + CONTEXT_STACK_OFFSET(ApiRet)) = ReturnAddress;\r
+}\r
+\r
+/**\r
+  This function set the API status code returned to the bootloader.\r
+\r
+  @param[in] ReturnStatus       Status code to return.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+SetFspApiReturnStatus (\r
+  IN UINT32  ReturnStatus\r
+  )\r
+{\r
+  FSP_GLOBAL_DATA  *FspData;\r
+\r
+  FspData  = GetFspGlobalDataPointer ();\r
+  *(UINT32 *)(UINTN)(FspData->CoreStack + CONTEXT_STACK_OFFSET(Eax)) = ReturnStatus;\r
+}\r
+\r
+/**\r
+  This function sets the context switching stack to a new stack frame.\r
+\r
+  @param[in] NewStackTop       New core stack to be set.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+SetFspCoreStackPointer (\r
+  IN VOID   *NewStackTop\r
+  )\r
+{\r
+  FSP_GLOBAL_DATA  *FspData;\r
+  UINT32           *OldStack;\r
+  UINT32           *NewStack;\r
+  UINT32           StackContextLen;\r
+\r
+  FspData  = GetFspGlobalDataPointer ();\r
+  StackContextLen = sizeof(CONTEXT_STACK) / sizeof(UINT32);\r
+\r
+  //\r
+  // Reserve space for the ContinuationFunc two parameters\r
+  //\r
+  OldStack = (UINT32 *)FspData->CoreStack;\r
+  NewStack = (UINT32 *)NewStackTop - StackContextLen - 2;\r
+  FspData->CoreStack = (UINT32)NewStack;\r
+  while (StackContextLen-- != 0) {\r
+    *NewStack++ = *OldStack++;\r
+  }\r
+}\r
+\r
+/**\r
+  This function sets the platform specific data pointer.\r
+\r
+  @param[in] PlatformData       Fsp platform specific data pointer.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+SetFspPlatformDataPointer (\r
+  IN VOID   *PlatformData\r
+  )\r
+{\r
+  FSP_GLOBAL_DATA  *FspData;\r
+\r
+  FspData  = GetFspGlobalDataPointer ();\r
+  FspData->PlatformData.DataPtr = PlatformData;\r
+}\r
+\r
+\r
+/**\r
+  This function gets the platform specific data pointer.\r
+\r
+   @param[in] PlatformData       Fsp platform specific data pointer.\r
+\r
+**/\r
+VOID *\r
+EFIAPI\r
+GetFspPlatformDataPointer (\r
+  VOID\r
+  )\r
+{\r
+  FSP_GLOBAL_DATA  *FspData;\r
+\r
+  FspData  = GetFspGlobalDataPointer ();\r
+  return FspData->PlatformData.DataPtr;\r
+}\r
+\r
+\r
+/**\r
+  This function sets the UPD data pointer.\r
+\r
+  @param[in] UpdDataRgnPtr   UPD data pointer.\r
+**/\r
+VOID\r
+EFIAPI\r
+SetFspUpdDataPointer (\r
+  IN VOID    *UpdDataRgnPtr\r
+  )\r
+{\r
+  FSP_GLOBAL_DATA  *FspData;\r
+\r
+  //\r
+  // Get the Fsp Global Data Pointer\r
+  //\r
+  FspData  = GetFspGlobalDataPointer ();\r
+\r
+  //\r
+  // Set the UPD pointer.\r
+  //\r
+  FspData->UpdDataRgnPtr = UpdDataRgnPtr;\r
+}\r
+\r
+/**\r
+  This function gets the UPD data pointer.\r
+\r
+  @return UpdDataRgnPtr   UPD data pointer.\r
+**/\r
+VOID *\r
+EFIAPI\r
+GetFspUpdDataPointer (\r
+  VOID\r
+  )\r
+{\r
+  FSP_GLOBAL_DATA  *FspData;\r
+\r
+  FspData  = GetFspGlobalDataPointer ();\r
+  return FspData->UpdDataRgnPtr;\r
+}\r
+\r
+/**\r
+  Set FSP measurement point timestamp.\r
+\r
+  @param[in] Id       Measurement point ID.\r
+\r
+  @return performance timestamp.\r
+**/\r
+UINT64\r
+EFIAPI\r
+SetFspMeasurePoint (\r
+  IN UINT8  Id\r
+  )\r
+{\r
+  FSP_GLOBAL_DATA  *FspData;\r
+\r
+  //\r
+  // Bit [55: 0]  will be the timestamp\r
+  // Bit [63:56]  will be the ID\r
+  //\r
+  FspData  = GetFspGlobalDataPointer ();\r
+  if (FspData->PerfIdx < sizeof(FspData->PerfData) / sizeof(FspData->PerfData[0])) {\r
+    FspData->PerfData[FspData->PerfIdx] = AsmReadTsc ();\r
+    ((UINT8 *)(&FspData->PerfData[FspData->PerfIdx]))[7] = Id;\r
+  }\r
+\r
+  return FspData->PerfData[(FspData->PerfIdx)++];\r
+}\r
diff --git a/IntelFspPkg/Library/BaseFspDebugLibSerialPort/BaseFspDebugLibSerialPort.inf b/IntelFspPkg/Library/BaseFspDebugLibSerialPort/BaseFspDebugLibSerialPort.inf
new file mode 100644 (file)
index 0000000..d3df6c3
--- /dev/null
@@ -0,0 +1,49 @@
+## @file\r
+#\r
+#  Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>\r
+#\r
+#  This program and the accompanying materials\r
+#  are licensed and made available under the terms and conditions of the BSD License\r
+#  which accompanies this distribution. The full text of the license may be found at\r
+#  http://opensource.org/licenses/bsd-license.php.\r
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+##\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = BaseFspDebugLibSerialPort\r
+  FILE_GUID                      = BB83F95F-EDBC-4884-A520-CD42AF388FAE\r
+  MODULE_TYPE                    = BASE\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = DebugLib\r
+\r
+#\r
+#  VALID_ARCHITECTURES           = IA32\r
+#\r
+\r
+[Sources]\r
+  DebugLib.c\r
+\r
+[Sources.Ia32]\r
+  Ia32/FspDebug.asm | MSFT\r
+  Ia32/FspDebug.s | GCC\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  IntelFspPkg/IntelFspPkg.dec\r
+\r
+[LibraryClasses]\r
+  SerialPortLib\r
+  BaseMemoryLib\r
+  PcdLib\r
+  PrintLib\r
+  BaseLib\r
+  DebugDeviceLib\r
+  DebugPrintErrorLevelLib\r
+\r
+[Pcd]\r
+  gEfiMdePkgTokenSpaceGuid.PcdDebugClearMemoryValue\r
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask\r
+\r
diff --git a/IntelFspPkg/Library/BaseFspDebugLibSerialPort/DebugLib.c b/IntelFspPkg/Library/BaseFspDebugLibSerialPort/DebugLib.c
new file mode 100644 (file)
index 0000000..467d59d
--- /dev/null
@@ -0,0 +1,305 @@
+/** @file\r
+\r
+  Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php.\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <Base.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/PrintLib.h>\r
+#include <Library/PcdLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/SerialPortLib.h>\r
+#include <Library/DebugDeviceLib.h>\r
+#include <Library/DebugPrintErrorLevelLib.h>\r
+\r
+//\r
+// Define the maximum debug and assert message length that this library supports\r
+//\r
+#define MAX_DEBUG_MESSAGE_LENGTH  0x100\r
+\r
+CONST CHAR8  *mHexTable = "0123456789ABCDEF";\r
+\r
+/**\r
+  Get stack frame pointer of function call.\r
+\r
+  @return StackFramePointer  stack frame pointer of function call.\r
+**/\r
+UINT32 *\r
+EFIAPI\r
+GetStackFramePointer (\r
+  VOID\r
+  );\r
+\r
+\r
+/**\r
+  Prints a debug message to the debug output device if the specified error level is enabled.\r
+\r
+  If any bit in ErrorLevel is also set in DebugPrintErrorLevelLib function\r
+  GetDebugPrintErrorLevel (), then print the message specified by Format and the\r
+  associated variable argument list to the debug output device.\r
+\r
+  If Format is NULL, then ASSERT().\r
+\r
+  @param  ErrorLevel  The error level of the debug message.\r
+  @param  Format      Format string for the debug message to print.\r
+  @param  ...         Variable argument list whose contents are accessed\r
+                      based on the format string specified by Format.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+DebugPrint (\r
+  IN  UINTN        ErrorLevel,\r
+  IN  CONST CHAR8  *Format,\r
+  ...\r
+  )\r
+{\r
+  CHAR8    Buffer[MAX_DEBUG_MESSAGE_LENGTH];\r
+  VA_LIST  Marker;\r
+\r
+  //\r
+  // If Format is NULL, then ASSERT().\r
+  //\r
+  if (!GetDebugPrintDeviceEnable ()) {\r
+    return;\r
+  }\r
+\r
+  //\r
+  // Check driver debug mask value and global mask\r
+  //\r
+  if ((ErrorLevel & GetDebugPrintErrorLevel ()) == 0) {\r
+    return;\r
+  }\r
+\r
+  //\r
+  // If Format is NULL, then ASSERT().\r
+  //\r
+  ASSERT (Format != NULL);\r
+\r
+  //\r
+  // Convert the DEBUG() message to an ASCII String\r
+  //\r
+  VA_START (Marker, Format);\r
+  AsciiVSPrint (Buffer, sizeof (Buffer), Format, Marker);\r
+  VA_END (Marker);\r
+\r
+  //\r
+  // Send the print string to a Serial Port\r
+  //\r
+  SerialPortWrite ((UINT8 *)Buffer, AsciiStrLen (Buffer));\r
+}\r
+\r
+/**\r
+  Convert an UINT32 value into HEX string sepcified by Buffer.\r
+\r
+  @param  Value   The HEX value to convert to string\r
+  @param  Buffer  The pointer to the target buffer to be filled with HEX string\r
+\r
+**/\r
+VOID\r
+FillHex (\r
+  UINT32   Value,\r
+  CHAR8   *Buffer\r
+  )\r
+{\r
+  INTN  Idx;\r
+  for (Idx = 7; Idx >= 0; Idx--) {\r
+    Buffer[Idx] = mHexTable[Value & 0x0F];\r
+    Value >>= 4;\r
+  }\r
+}\r
+\r
+/**\r
+  Prints an assert message containing a filename, line number, and description.\r
+  This may be followed by a breakpoint or a dead loop.\r
+\r
+  Print a message of the form "ASSERT <FileName>(<LineNumber>): <Description>\n"\r
+  to the debug output device.  If DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED bit of\r
+  PcdDebugProperyMask is set then CpuBreakpoint() is called. Otherwise, if\r
+  DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED bit of PcdDebugProperyMask is set then\r
+  CpuDeadLoop() is called.  If neither of these bits are set, then this function\r
+  returns immediately after the message is printed to the debug output device.\r
+  DebugAssert() must actively prevent recursion.  If DebugAssert() is called while\r
+  processing another DebugAssert(), then DebugAssert() must return immediately.\r
+\r
+  If FileName is NULL, then a <FileName> string of "(NULL) Filename" is printed.\r
+  If Description is NULL, then a <Description> string of "(NULL) Description" is printed.\r
+\r
+**/\r
+VOID\r
+DebugAssertInternal (\r
+  VOID\r
+  )\r
+{\r
+  CHAR8     Buffer[MAX_DEBUG_MESSAGE_LENGTH];\r
+  UINT32   *Frame;\r
+\r
+  Frame = (UINT32 *)GetStackFramePointer ();\r
+\r
+  //\r
+  // Generate the ASSERT() message in Ascii format\r
+  //\r
+  AsciiStrCpy (Buffer, "-> EBP:0x00000000  EIP:0x00000000\n");\r
+  SerialPortWrite ((UINT8 *)"ASSERT DUMP:\n", 13);\r
+  while (Frame != NULL) {\r
+    FillHex ((UINT32)Frame, Buffer + 9);\r
+    FillHex (Frame[1], Buffer + 9 + 8 + 8);\r
+    SerialPortWrite ((UINT8 *)Buffer, AsciiStrLen (Buffer));\r
+    if ((Frame[0] > (UINT32)Frame) && (Frame[0] < (UINT32)Frame + 0x00100000)) {\r
+      Frame = (UINT32 *)Frame[0];\r
+    } else {\r
+      Frame = NULL;\r
+    }\r
+  }\r
+\r
+  //\r
+  // Dead loop\r
+  //\r
+  CpuDeadLoop ();\r
+}\r
+\r
+/**\r
+  Prints an assert message containing a filename, line number, and description.\r
+  This may be followed by a breakpoint or a dead loop.\r
+\r
+  Print a message of the form "ASSERT <FileName>(<LineNumber>): <Description>\n"\r
+  to the debug output device.  If DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED bit of\r
+  PcdDebugProperyMask is set then CpuBreakpoint() is called. Otherwise, if\r
+  DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED bit of PcdDebugProperyMask is set then\r
+  CpuDeadLoop() is called.  If neither of these bits are set, then this function\r
+  returns immediately after the message is printed to the debug output device.\r
+  DebugAssert() must actively prevent recursion.  If DebugAssert() is called while\r
+  processing another DebugAssert(), then DebugAssert() must return immediately.\r
+\r
+  If FileName is NULL, then a <FileName> string of "(NULL) Filename" is printed.\r
+  If Description is NULL, then a <Description> string of "(NULL) Description" is printed.\r
+\r
+  @param  FileName     The pointer to the name of the source file that generated the assert condition.\r
+  @param  LineNumber   The line number in the source file that generated the assert condition\r
+  @param  Description  The pointer to the description of the assert condition.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+DebugAssert (\r
+  IN CONST CHAR8  *FileName,\r
+  IN UINTN        LineNumber,\r
+  IN CONST CHAR8  *Description\r
+  )\r
+{\r
+  DebugAssertInternal ();\r
+}\r
+\r
+\r
+/**\r
+  Fills a target buffer with PcdDebugClearMemoryValue, and returns the target buffer.\r
+\r
+  This function fills Length bytes of Buffer with the value specified by\r
+  PcdDebugClearMemoryValue, and returns Buffer.\r
+\r
+  If Buffer is NULL, then ASSERT().\r
+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().\r
+\r
+  @param   Buffer  The pointer to the target buffer to be filled with PcdDebugClearMemoryValue.\r
+  @param   Length  The number of bytes in Buffer to fill with zeros PcdDebugClearMemoryValue.\r
+\r
+  @return  Buffer  The pointer to the target buffer filled with PcdDebugClearMemoryValue.\r
+\r
+**/\r
+VOID *\r
+EFIAPI\r
+DebugClearMemory (\r
+  OUT VOID  *Buffer,\r
+  IN UINTN  Length\r
+  )\r
+{\r
+  return Buffer;\r
+}\r
+\r
+\r
+/**\r
+  Returns TRUE if ASSERT() macros are enabled.\r
+\r
+  This function returns TRUE if the DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of\r
+  PcdDebugProperyMask is set.  Otherwise FALSE is returned.\r
+\r
+  @retval  TRUE    The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugProperyMask is set.\r
+  @retval  FALSE   The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugProperyMask is clear.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+DebugAssertEnabled (\r
+  VOID\r
+  )\r
+{\r
+  return (BOOLEAN) ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED) != 0);\r
+}\r
+\r
+\r
+/**\r
+  Returns TRUE if DEBUG() macros are enabled.\r
+\r
+  This function returns TRUE if the DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of\r
+  PcdDebugProperyMask is set.  Otherwise FALSE is returned.\r
+\r
+  @retval  TRUE    The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugProperyMask is set.\r
+  @retval  FALSE   The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugProperyMask is clear.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+DebugPrintEnabled (\r
+  VOID\r
+  )\r
+{\r
+  return (BOOLEAN) ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_PRINT_ENABLED) != 0);\r
+}\r
+\r
+/**\r
+  Returns TRUE if DEBUG_CODE() macros are enabled.\r
+\r
+  This function returns TRUE if the DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of\r
+  PcdDebugProperyMask is set.  Otherwise FALSE is returned.\r
+\r
+  @retval  TRUE    The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask is set.\r
+  @retval  FALSE   The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask is clear.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+DebugCodeEnabled (\r
+  VOID\r
+  )\r
+{\r
+  return (BOOLEAN) ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_CODE_ENABLED) != 0);\r
+}\r
+\r
+\r
+/**\r
+  Returns TRUE if DEBUG_CLEAR_MEMORY() macro is enabled.\r
+\r
+  This function returns TRUE if the DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of\r
+  PcdDebugProperyMask is set.  Otherwise FALSE is returned.\r
+\r
+  @retval  TRUE    The DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of PcdDebugProperyMask is set.\r
+  @retval  FALSE   The DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of PcdDebugProperyMask is clear.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+DebugClearMemoryEnabled (\r
+  VOID\r
+  )\r
+{\r
+  return (BOOLEAN) ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED) != 0);\r
+}\r
diff --git a/IntelFspPkg/Library/BaseFspDebugLibSerialPort/Ia32/FspDebug.asm b/IntelFspPkg/Library/BaseFspDebugLibSerialPort/Ia32/FspDebug.asm
new file mode 100644 (file)
index 0000000..8ac18ec
--- /dev/null
@@ -0,0 +1,34 @@
+;------------------------------------------------------------------------------\r
+;\r
+; Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>\r
+; This program and the accompanying materials\r
+; are licensed and made available under the terms and conditions of the BSD License\r
+; which accompanies this distribution.  The full text of the license may be found at\r
+; http://opensource.org/licenses/bsd-license.php.\r
+;\r
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+;\r
+; Abstract:\r
+;\r
+;   FSP Debug functions\r
+;\r
+;------------------------------------------------------------------------------\r
+\r
+    .386\r
+    .model  flat,C\r
+    .code\r
+\r
+;------------------------------------------------------------------------------\r
+; UINT32 *\r
+; EFIAPI\r
+; GetStackFramePointer (\r
+;   VOID\r
+;   );\r
+;------------------------------------------------------------------------------\r
+GetStackFramePointer  PROC  PUBLIC\r
+    mov     eax, ebp\r
+    ret\r
+GetStackFramePointer  ENDP\r
+\r
+    END\r
diff --git a/IntelFspPkg/Library/BaseFspDebugLibSerialPort/Ia32/FspDebug.s b/IntelFspPkg/Library/BaseFspDebugLibSerialPort/Ia32/FspDebug.s
new file mode 100644 (file)
index 0000000..0f8475f
--- /dev/null
@@ -0,0 +1,30 @@
+#------------------------------------------------------------------------------\r
+#\r
+# Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>\r
+# This program and the accompanying materials\r
+# are licensed and made available under the terms and conditions of the BSD License\r
+# which accompanies this distribution.  The full text of the license may be found at\r
+# http://opensource.org/licenses/bsd-license.php.\r
+#\r
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+# Abstract:\r
+#\r
+#   FSP Debug functions\r
+#\r
+#------------------------------------------------------------------------------\r
+\r
+#------------------------------------------------------------------------------\r
+# UINT32 *\r
+# EFIAPI\r
+# GetStackFramePointer (\r
+#   VOID\r
+#   )\r
+#------------------------------------------------------------------------------\r
+ASM_GLOBAL ASM_PFX(GetStackFramePointer)\r
+ASM_PFX(GetStackFramePointer):\r
+    mov    %ebp, %eax\r
+    ret\r
+\r
+\r
diff --git a/IntelFspPkg/Library/BaseFspPlatformLib/BaseFspPlatformLib.inf b/IntelFspPkg/Library/BaseFspPlatformLib/BaseFspPlatformLib.inf
new file mode 100644 (file)
index 0000000..debce76
--- /dev/null
@@ -0,0 +1,41 @@
+## @file\r
+#\r
+#  Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>\r
+#\r
+#  This program and the accompanying materials\r
+#  are licensed and made available under the terms and conditions of the BSD License\r
+#  which accompanies this distribution. The full text of the license may be found at\r
+#  http://opensource.org/licenses/bsd-license.php.\r
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+##\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = BaseFspPlatformLib\r
+  FILE_GUID                      = 7DECCDAF-361F-4ec1-9714-260BAAF6F384\r
+  MODULE_TYPE                    = BASE\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = FspPlatformLib\r
+\r
+[Sources]\r
+  FspPlatformMemory.c\r
+  FspPlatformNotify.c\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  IntelFspPkg/IntelFspPkg.dec\r
+\r
+[LibraryClasses]\r
+  BaseMemoryLib\r
+\r
+[Pcd]\r
+  gIntelFspPkgTokenSpaceGuid.PcdGlobalDataPointerAddress\r
+  gIntelFspPkgTokenSpaceGuid.PcdTemporaryRamBase\r
+  gIntelFspPkgTokenSpaceGuid.PcdTemporaryRamSize\r
+  gIntelFspPkgTokenSpaceGuid.PcdFspTemporaryRamSize\r
+\r
+[FixedPcd]\r
+  gIntelFspPkgTokenSpaceGuid.PcdFspMaxPatchEntry\r
+  gIntelFspPkgTokenSpaceGuid.PcdFspMaxPerfEntry\r
diff --git a/IntelFspPkg/Library/BaseFspPlatformLib/FspPlatformMemory.c b/IntelFspPkg/Library/BaseFspPlatformLib/FspPlatformMemory.c
new file mode 100644 (file)
index 0000000..2f1c0b1
--- /dev/null
@@ -0,0 +1,155 @@
+/** @file\r
+\r
+  Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php.\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <PiPei.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/PcdLib.h>\r
+#include <Library/HobLib.h>\r
+#include <Library/PeiServicesLib.h>\r
+#include <Library/FspCommonLib.h>\r
+#include <Guid/GuidHobFsp.h>\r
+#include <FspGlobalData.h>\r
+#include <FspApi.h>\r
+\r
+/**\r
+  Get system memory from HOB.\r
+\r
+  @param[in,out] LowMemoryLength   less than 4G memory length\r
+  @param[in,out] HighMemoryLength  greater than 4G memory length\r
+**/\r
+VOID\r
+EFIAPI\r
+FspGetSystemMemorySize (\r
+  IN OUT UINT64              *LowMemoryLength,\r
+  IN OUT UINT64              *HighMemoryLength\r
+  )\r
+{\r
+  EFI_PEI_HOB_POINTERS    Hob;\r
+\r
+  *HighMemoryLength = 0;\r
+  *LowMemoryLength  = SIZE_1MB;\r
+  //\r
+  // Get the HOB list for processing\r
+  //\r
+  Hob.Raw = GetHobList ();\r
+\r
+  //\r
+  // Collect memory ranges\r
+  //\r
+  while (!END_OF_HOB_LIST (Hob)) {\r
+    if (Hob.Header->HobType == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {\r
+      if (Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) {\r
+        //\r
+        // Need memory above 1MB to be collected here\r
+        //\r
+        if (Hob.ResourceDescriptor->PhysicalStart >= BASE_1MB &&\r
+            Hob.ResourceDescriptor->PhysicalStart < (EFI_PHYSICAL_ADDRESS) BASE_4GB) {\r
+          *LowMemoryLength += (UINT64) (Hob.ResourceDescriptor->ResourceLength);\r
+        } else if (Hob.ResourceDescriptor->PhysicalStart >= (EFI_PHYSICAL_ADDRESS) BASE_4GB) {\r
+          *HighMemoryLength += (UINT64) (Hob.ResourceDescriptor->ResourceLength);\r
+        }\r
+      }\r
+    }\r
+    Hob.Raw = GET_NEXT_HOB (Hob);\r
+  }\r
+}\r
+\r
+/**\r
+  Migrate bootloader data before destroying CAR.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+FspMigrateTemporaryMemory (\r
+  VOID\r
+ )\r
+{\r
+  FSP_INIT_RT_COMMON_BUFFER  *FspInitRtBuffer;\r
+  UINT32             BootLoaderTempRamStart;\r
+  UINT32             BootLoaderTempRamEnd;\r
+  UINT32             BootLoaderTempRamSize;\r
+  UINT32             OffsetGap;\r
+  UINT32             FspParamPtr;\r
+  FSP_INIT_PARAMS   *FspInitParams;\r
+  UINT32            *NewStackTop;\r
+  VOID              *BootLoaderTempRamHob;\r
+  VOID              *UpdDataRgnPtr;\r
+  VOID              *PlatformDataPtr;\r
+\r
+  //\r
+  // Get the temporary memory range used by the bootloader\r
+  //\r
+  BootLoaderTempRamStart = PcdGet32(PcdTemporaryRamBase);\r
+  BootLoaderTempRamSize  = PcdGet32(PcdTemporaryRamSize) - PcdGet32(PcdFspTemporaryRamSize);\r
+  BootLoaderTempRamEnd   = BootLoaderTempRamStart +  BootLoaderTempRamSize;\r
+\r
+  //\r
+  // Build a Boot Loader Temporary Memory GUID HOB\r
+  //\r
+  BootLoaderTempRamHob = BuildGuidHob (&gFspBootLoaderTemporaryMemoryGuid, BootLoaderTempRamSize);\r
+  CopyMem (BootLoaderTempRamHob, (VOID *)BootLoaderTempRamStart, BootLoaderTempRamSize);\r
+  OffsetGap = (UINT32)BootLoaderTempRamHob - BootLoaderTempRamStart;\r
+\r
+  //\r
+  // Set a new stack frame for the continuation function\r
+  //\r
+  FspInitParams   = (FSP_INIT_PARAMS *)GetFspApiParameter ();\r
+  FspInitRtBuffer = (FSP_INIT_RT_COMMON_BUFFER *)FspInitParams->RtBufferPtr;\r
+  NewStackTop     = (UINT32 *)FspInitRtBuffer->StackTop - 1;\r
+  SetFspCoreStackPointer (NewStackTop);\r
+\r
+  //\r
+  // Fix the FspInit Parameter Pointers to the new location.\r
+  //\r
+  FspParamPtr = GetFspApiParameter ();\r
+  if (FspParamPtr >= BootLoaderTempRamStart && FspParamPtr < BootLoaderTempRamEnd) {\r
+    SetFspApiParameter(FspParamPtr + OffsetGap);\r
+  }\r
+\r
+  FspInitParams = (FSP_INIT_PARAMS *)GetFspApiParameter ();\r
+  if ((UINT32)(FspInitParams->RtBufferPtr) >= BootLoaderTempRamStart &&\r
+      (UINT32)(FspInitParams->RtBufferPtr) <  BootLoaderTempRamEnd) {\r
+    FspInitParams->RtBufferPtr = (VOID *)((UINT32)(FspInitParams->RtBufferPtr) + OffsetGap);\r
+  }\r
+\r
+  if ((UINT32)(FspInitParams->NvsBufferPtr) >= BootLoaderTempRamStart &&\r
+      (UINT32)(FspInitParams->NvsBufferPtr) <  BootLoaderTempRamEnd) {\r
+    FspInitParams->NvsBufferPtr = (VOID *)((UINT32)(FspInitParams->NvsBufferPtr) + OffsetGap);\r
+  }\r
+\r
+  if ((UINT32)(((FSP_INIT_RT_COMMON_BUFFER *)(FspInitParams->RtBufferPtr))->UpdDataRgnPtr) >= BootLoaderTempRamStart &&\r
+      (UINT32)(((FSP_INIT_RT_COMMON_BUFFER *)(FspInitParams->RtBufferPtr))->UpdDataRgnPtr) <  BootLoaderTempRamEnd) {\r
+    ((FSP_INIT_RT_COMMON_BUFFER *)(FspInitParams->RtBufferPtr))->UpdDataRgnPtr = \\r
+           (VOID *)((UINT32)(((FSP_INIT_RT_COMMON_BUFFER *)(FspInitParams->RtBufferPtr))->UpdDataRgnPtr) + OffsetGap);\r
+  }\r
+\r
+  //\r
+  // Update UPD pointer in FSP Global Data\r
+  //\r
+  UpdDataRgnPtr = ((FSP_INIT_RT_COMMON_BUFFER *)FspInitParams->RtBufferPtr)->UpdDataRgnPtr;\r
+  if (UpdDataRgnPtr != NULL) {\r
+    SetFspUpdDataPointer (UpdDataRgnPtr);\r
+  }\r
+\r
+  //\r
+  // Update Platform data pointer in FSP Global Data\r
+  //\r
+  PlatformDataPtr = GetFspPlatformDataPointer ();\r
+  if (((UINT32)PlatformDataPtr >= BootLoaderTempRamStart) &&\r
+      ((UINT32)PlatformDataPtr <  BootLoaderTempRamEnd)) {\r
+    SetFspPlatformDataPointer ((UINT8 *)PlatformDataPtr + OffsetGap);\r
+  }\r
+\r
+}\r
diff --git a/IntelFspPkg/Library/BaseFspPlatformLib/FspPlatformNotify.c b/IntelFspPkg/Library/BaseFspPlatformLib/FspPlatformNotify.c
new file mode 100644 (file)
index 0000000..3488fbc
--- /dev/null
@@ -0,0 +1,178 @@
+/** @file\r
+\r
+  Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php.\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <PiPei.h>\r
+#include <Library/PeiServicesLib.h>\r
+#include <Library/PeiServicesTablePointerLib.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/PcdLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/HobLib.h>\r
+#include <Library/FspSwitchStackLib.h>\r
+#include <Library/FspCommonLib.h>\r
+#include <Guid/EventGroup.h>\r
+#include <FspApi.h>\r
+#include <Protocol/PciEnumerationComplete.h>\r
+\r
+EFI_PEI_PPI_DESCRIPTOR      mPeiPostPciEnumerationPpi = {\r
+  (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
+  &gEfiPciEnumerationCompleteProtocolGuid,\r
+  NULL\r
+};\r
+\r
+EFI_PEI_PPI_DESCRIPTOR      mPeiReadyToBootPpi = {\r
+  (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
+  &gEfiEventReadyToBootGuid,\r
+  NULL\r
+};\r
+\r
+\r
+UINT32  mFspNotfifySequence[] = {\r
+  EnumInitPhaseAfterPciEnumeration,\r
+  EnumInitPhaseReadyToBoot\r
+};\r
+\r
+/**\r
+  Install FSP notification.\r
+\r
+  @param[in] NotificatonCode  FSP notification code\r
+\r
+  @retval EFI_SUCCESS            Notify FSP successfully\r
+  @retval EFI_INVALID_PARAMETER  NotificatonCode is invalid\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FspNotificationHandler (\r
+  IN  UINT32     NotificatonCode\r
+  )\r
+{\r
+  EFI_STATUS                Status;\r
+\r
+  Status   = EFI_SUCCESS;\r
+\r
+  switch (NotificatonCode) {\r
+  case EnumInitPhaseAfterPciEnumeration:\r
+    //\r
+    // Do POST PCI initialization if needed\r
+    //\r
+    DEBUG ((DEBUG_INFO | DEBUG_INIT, "FSP Post PCI Enumeration ...\n"));\r
+    PeiServicesInstallPpi (&mPeiPostPciEnumerationPpi);\r
+    break;\r
+\r
+  case EnumInitPhaseReadyToBoot:\r
+    //\r
+    // Ready To Boot\r
+    //\r
+    DEBUG ((DEBUG_INFO| DEBUG_INIT, "FSP Ready To Boot ...\n"));\r
+    PeiServicesInstallPpi (&mPeiReadyToBootPpi);\r
+    break;\r
+\r
+  default:\r
+    Status = EFI_INVALID_PARAMETER;\r
+    break;\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  This function transfer control to the ContinuationFunc passed in by the\r
+  bootloader.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+FspInitDone (\r
+  VOID\r
+  )\r
+{\r
+  FSP_INIT_PARAMS           *FspInitParams;\r
+\r
+  FspInitParams   = (FSP_INIT_PARAMS *)GetFspApiParameter ();\r
+\r
+  //\r
+  // Modify the parameters for ContinuationFunc\r
+  //\r
+  SetFspContinuationFuncParameter(EFI_SUCCESS, 0);\r
+  SetFspContinuationFuncParameter((UINT32)GetHobList(), 1);\r
+\r
+  //\r
+  // Modify the return address to ContinuationFunc\r
+  //\r
+  SetFspApiReturnAddress((UINT32)FspInitParams->ContinuationFunc);\r
+\r
+  //\r
+  // Give control back to the boot loader framework caller after FspInit is done\r
+  // It is done throught the continuation function\r
+  //\r
+  SetFspMeasurePoint (FSP_PERF_ID_API_FSPINIT_EXIT);\r
+  Pei2LoaderSwitchStack();\r
+}\r
+\r
+/**\r
+  This function handle NotifyPhase API call from the bootloader.\r
+  It gives control back to the bootloader after it is handled. If the\r
+  Notification code is a ReadyToBoot event, this function will return\r
+  and FSP continues the remaining execution until it reaches the DxeIpl.\r
+\r
+**/\r
+VOID\r
+FspWaitForNotify (\r
+  VOID\r
+  )\r
+{\r
+  EFI_STATUS                 Status;\r
+  UINT32                     NotificatonValue;\r
+  UINT32                     NotificatonCount;\r
+  UINT8                      Count;\r
+\r
+  NotificatonCount = 0;\r
+  while (NotificatonCount < sizeof(mFspNotfifySequence) / sizeof(UINT32)) {\r
+\r
+    Count = (NotificatonCount << 1) & 0x07;\r
+    SetFspMeasurePoint (FSP_PERF_ID_API_NOTIFY_POSTPCI_ENTRY + Count);\r
+\r
+    NotificatonValue = ((NOTIFY_PHASE_PARAMS *)(UINTN)GetFspApiParameter ())->Phase;\r
+    DEBUG ((DEBUG_INFO, "FSP Got Notification. Notification Value : 0x%08X\n", NotificatonValue));\r
+\r
+    if (mFspNotfifySequence[NotificatonCount] != NotificatonValue) {\r
+      //\r
+      // Notify code does not follow the predefined order\r
+      //\r
+      SetFspApiReturnStatus(EFI_UNSUPPORTED);\r
+    } else {\r
+      //\r
+      // Process Notification and Give control back to the boot loader framework caller\r
+      //\r
+      Status = FspNotificationHandler (NotificatonValue);\r
+      SetFspApiReturnStatus(Status);\r
+      if (!EFI_ERROR(Status)) {\r
+        NotificatonCount++;\r
+        SetFspApiReturnStatus(EFI_SUCCESS);\r
+        if (NotificatonValue == EnumInitPhaseReadyToBoot) {\r
+          break;\r
+        }\r
+      }\r
+    }\r
+    SetFspMeasurePoint (FSP_PERF_ID_API_NOTIFY_POSTPCI_EXIT + Count);\r
+    Pei2LoaderSwitchStack();\r
+  }\r
+\r
+  //\r
+  // Control goes back to the PEI Core and it dispatches further PEIMs.\r
+  // DXEIPL is the final one to transfer control back to the boot loader.\r
+  //\r
+}\r
+\r
diff --git a/IntelFspPkg/Library/BaseFspSwitchStackLib/BaseFspSwitchStackLib.inf b/IntelFspPkg/Library/BaseFspSwitchStackLib/BaseFspSwitchStackLib.inf
new file mode 100644 (file)
index 0000000..c3b47b5
--- /dev/null
@@ -0,0 +1,42 @@
+## @file\r
+#\r
+#  Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>\r
+#\r
+#  This program and the accompanying materials\r
+#  are licensed and made available under the terms and conditions of the BSD License\r
+#  which accompanies this distribution. The full text of the license may be found at\r
+#  http://opensource.org/licenses/bsd-license.php.\r
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+##\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = BaseFspSwitchStackLib\r
+  FILE_GUID                      = 8A5EA987-27F9-4ad0-B07C-D61882BFF4FF\r
+  MODULE_TYPE                    = BASE\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = FspSwitchStackLib\r
+\r
+[Sources.IA32]\r
+  FspSwitchStackLib.c\r
+\r
+[Sources.IA32]\r
+  Ia32/Stack.asm | MSFT\r
+  Ia32/Stack.s | GCC\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  IntelFspPkg/IntelFspPkg.dec\r
+\r
+[LibraryClasses]\r
+  BaseLib\r
+  IoLib\r
+\r
+[FixedPcd]\r
+  gIntelFspPkgTokenSpaceGuid.PcdFspMaxPatchEntry\r
+  gIntelFspPkgTokenSpaceGuid.PcdFspMaxPerfEntry\r
+\r
+\r
+\r
diff --git a/IntelFspPkg/Library/BaseFspSwitchStackLib/FspSwitchStackLib.c b/IntelFspPkg/Library/BaseFspSwitchStackLib/FspSwitchStackLib.c
new file mode 100644 (file)
index 0000000..42a57a2
--- /dev/null
@@ -0,0 +1,42 @@
+/** @file\r
+\r
+  Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php.\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <Base.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/FspCommonLib.h>\r
+\r
+/**\r
+\r
+  Switch the current stack to the previous saved stack.\r
+\r
+  @param[in]  NewStack         The new stack to be switched.\r
+\r
+  @return OldStack         After switching to the saved stack,\r
+                           this value will be saved in eax before returning.\r
+\r
+\r
+**/\r
+UINT32\r
+SwapStack (\r
+  IN  UINT32 NewStack\r
+  )\r
+{\r
+  FSP_GLOBAL_DATA  *FspData;\r
+  UINT32         OldStack;\r
+\r
+  FspData  = GetFspGlobalDataPointer ();\r
+  OldStack = FspData->CoreStack;\r
+  FspData->CoreStack = NewStack;\r
+  return OldStack;\r
+}\r
+\r
diff --git a/IntelFspPkg/Library/BaseFspSwitchStackLib/Ia32/Stack.asm b/IntelFspPkg/Library/BaseFspSwitchStackLib/Ia32/Stack.asm
new file mode 100644 (file)
index 0000000..d04f229
--- /dev/null
@@ -0,0 +1,65 @@
+;------------------------------------------------------------------------------\r
+;\r
+; Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>\r
+; This program and the accompanying materials\r
+; are licensed and made available under the terms and conditions of the BSD License\r
+; which accompanies this distribution.  The full text of the license may be found at\r
+; http://opensource.org/licenses/bsd-license.php.\r
+;\r
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+;\r
+; Abstract:\r
+;\r
+;   Switch the stack from temporary memory to permenent memory.\r
+;\r
+;------------------------------------------------------------------------------\r
+\r
+    .586p\r
+    .model  flat,C\r
+    .code\r
+\r
+;------------------------------------------------------------------------------\r
+; UINT32\r
+; EFIAPI\r
+; Pei2LoaderSwitchStack (\r
+;   VOID\r
+;   )\r
+;------------------------------------------------------------------------------\r
+EXTERNDEF  C   MeasurePoint:PROC\r
+Pei2LoaderSwitchStack   PROC C PUBLIC\r
+    jmp     Loader2PeiSwitchStack\r
+Pei2LoaderSwitchStack   ENDP\r
+\r
+;------------------------------------------------------------------------------\r
+; UINT32\r
+; EFIAPI\r
+; Loader2PeiSwitchStack (\r
+;   VOID\r
+;   )\r
+;------------------------------------------------------------------------------\r
+EXTERNDEF  C   SwapStack:PROC\r
+Loader2PeiSwitchStack   PROC C PUBLIC\r
+    ; Save current contexts\r
+    push    offset exit\r
+    pushfd\r
+    cli\r
+    pushad\r
+    sub     esp, 8\r
+    sidt    fword ptr [esp]\r
+\r
+    ; Load new stack\r
+    push    esp\r
+    call    SwapStack\r
+    mov     esp, eax\r
+\r
+    ; Restore previous contexts\r
+    lidt    fword ptr [esp]\r
+    add     esp, 8\r
+    popad\r
+    popfd\r
+exit:\r
+    ret\r
+Loader2PeiSwitchStack   ENDP\r
+\r
+    END\r
diff --git a/IntelFspPkg/Library/BaseFspSwitchStackLib/Ia32/Stack.s b/IntelFspPkg/Library/BaseFspSwitchStackLib/Ia32/Stack.s
new file mode 100644 (file)
index 0000000..6932cd8
--- /dev/null
@@ -0,0 +1,64 @@
+#------------------------------------------------------------------------------\r
+#\r
+# Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>\r
+# This program and the accompanying materials\r
+# are licensed and made available under the terms and conditions of the BSD License\r
+# which accompanies this distribution.  The full text of the license may be found at\r
+# http://opensource.org/licenses/bsd-license.php.\r
+#\r
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+# Abstract:\r
+#\r
+#   Switch the stack from temporary memory to permenent memory.\r
+#\r
+#------------------------------------------------------------------------------\r
+\r
+ASM_GLOBAL ASM_PFX(Pei2LoaderSwitchStack)\r
+ASM_GLOBAL ASM_PFX(Loader2PeiSwitchStack)\r
+\r
+#------------------------------------------------------------------------------\r
+# UINT32\r
+# EFIAPI\r
+# Pei2LoaderSwitchStack (\r
+#   VOID\r
+#   )\r
+#------------------------------------------------------------------------------\r
+ASM_GLOBAL ASM_PFX(Pei2LoaderSwitchStack)\r
+ASM_PFX(Pei2LoaderSwitchStack):\r
+    jmp     ASM_PFX(Loader2PeiSwitchStack)\r
+\r
+#------------------------------------------------------------------------------\r
+# UINT32\r
+# EFIAPI\r
+# Loader2PeiSwitchStack (\r
+#   )\r
+#------------------------------------------------------------------------------\r
+ASM_GLOBAL ASM_PFX(Loader2PeiSwitchStack)\r
+ASM_PFX(Loader2PeiSwitchStack):\r
+#Save current contexts\r
+    push    $exit\r
+    pushf\r
+    pushf\r
+    cli\r
+    pusha\r
+    push    $0x0\r
+    push    $0x0\r
+    sidt    (%esp)\r
+\r
+    # Load new stack\r
+    push   %esp\r
+    call   ASM_PFX(SwapStack)\r
+    mov    %eax,%esp\r
+\r
+    # Restore previous contexts\r
+    lidt    (%esp)\r
+    add     $8,%esp\r
+    popa\r
+    popf\r
+    popf\r
+exit:\r
+    ret\r
+\r
+\r
diff --git a/IntelFspPkg/Library/SecPlatformSecLibNull/PlatformSecLibNull.c b/IntelFspPkg/Library/SecPlatformSecLibNull/PlatformSecLibNull.c
new file mode 100644 (file)
index 0000000..af41a61
--- /dev/null
@@ -0,0 +1,29 @@
+/** @file\r
+  Null instance of Platform Sec Lib.\r
+\r
+  Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php.\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <PiPei.h>\r
+\r
+/**\r
+  This function provides dummy function so that SecCore can pass pass build\r
+  Validation in Ia32FamilyCpuPkg. All real platform library instances needs\r
+  to implement the real entry point in assembly.\r
+**/\r
+VOID\r
+EFIAPI\r
+_ModuleEntryPoint (\r
+  VOID\r
+  )\r
+{\r
+  return;\r
+}\r
diff --git a/IntelFspPkg/Library/SecPlatformSecLibNull/SecPlatformSecLibNull.inf b/IntelFspPkg/Library/SecPlatformSecLibNull/SecPlatformSecLibNull.inf
new file mode 100644 (file)
index 0000000..72006c5
--- /dev/null
@@ -0,0 +1,53 @@
+## @file\r
+#\r
+#  Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>\r
+#\r
+#  This program and the accompanying materials\r
+#  are licensed and made available under the terms and conditions of the BSD License\r
+#  which accompanies this distribution. The full text of the license may be found at\r
+#  http://opensource.org/licenses/bsd-license.php.\r
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+##\r
+\r
+################################################################################\r
+#\r
+# Defines Section - statements that will be processed to create a Makefile.\r
+#\r
+################################################################################\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = SecPlatformSecLibNull\r
+  FILE_GUID                      = 6695974D-968C-420b-80B9-7870CD20118F\r
+  MODULE_TYPE                    = SEC\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = NULL\r
+\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64\r
+#\r
+\r
+################################################################################\r
+#\r
+# Sources Section - list of files that are required for the build to succeed.\r
+#\r
+################################################################################\r
+\r
+[Sources]\r
+  PlatformSecLibNull.c\r
+\r
+\r
+################################################################################\r
+#\r
+# Package Dependency Section - list of Package files that are required for\r
+#                              this module.\r
+#\r
+################################################################################\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+\r
diff --git a/IntelFspPkg/Tools/GenCfgOpt.py b/IntelFspPkg/Tools/GenCfgOpt.py
new file mode 100644 (file)
index 0000000..4417bc3
--- /dev/null
@@ -0,0 +1,894 @@
+## @ GenCfgOpt.py\r
+#\r
+# Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>\r
+# This program and the accompanying materials are licensed and made available under\r
+# the terms and conditions of the BSD License that accompanies this distribution.\r
+# The full text of the license may be found at\r
+# http://opensource.org/licenses/bsd-license.php.\r
+#\r
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+##\r
+\r
+import os\r
+import re\r
+import sys\r
+import struct\r
+from   datetime import date\r
+\r
+# Generated file copyright header\r
+\r
+__copyright_txt__ = """## @file\r
+#\r
+#  THIS IS AUTO-GENERATED FILE BY BUILD TOOLS AND PLEASE DO NOT MAKE MODIFICATION.\r
+#\r
+#  This file lists all VPD informations for a platform collected by build.exe.\r
+#\r
+# Copyright (c) %4d, Intel Corporation. All rights reserved.<BR>\r
+# This program and the accompanying materials\r
+# are licensed and made available under the terms and conditions of the BSD License\r
+# which accompanies this distribution.  The full text of the license may be found at\r
+# http://opensource.org/licenses/bsd-license.php\r
+#\r
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+"""\r
+\r
+__copyright_bsf__ = """/** @file\r
+\r
+  Boot Setting File for Platform Configuration.\r
+\r
+  Copyright (c) %4d, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+  This file is automatically generated. Please do NOT modify !!!\r
+\r
+**/\r
+\r
+"""\r
+\r
+__copyright_h__ = """/** @file\r
+\r
+Copyright (c) %4d, Intel Corporation. All rights reserved.<BR>\r
+\r
+Redistribution and use in source and binary forms, with or without modification,\r
+are permitted provided that the following conditions are met:\r
+\r
+* Redistributions of source code must retain the above copyright notice, this\r
+  list of conditions and the following disclaimer.\r
+* Redistributions in binary form must reproduce the above copyright notice, this\r
+  list of conditions and the following disclaimer in the documentation and/or\r
+  other materials provided with the distribution.\r
+* Neither the name of Intel Corporation nor the names of its contributors may\r
+  be used to endorse or promote products derived from this software without\r
+  specific prior written permission.\r
+\r
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"\r
+  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
+  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
+  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\r
+  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
+  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
+  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
+  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
+  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\r
+  THE POSSIBILITY OF SUCH DAMAGE.\r
+\r
+  This file is automatically generated. Please do NOT modify !!!\r
+\r
+**/\r
+"""\r
+\r
+class CGenCfgOpt:\r
+    def __init__(self):\r
+        self.Error          = ''\r
+\r
+        self._GlobalDataDef = """\r
+GlobalDataDef\r
+    SKUID = 0, "DEFAULT"\r
+EndGlobalData\r
+\r
+"""\r
+        self._BuidinOptionTxt = """\r
+List &EN_DIS\r
+    Selection 0x1 , "Enabled"\r
+    Selection 0x0 , "Disabled"\r
+EndList\r
+\r
+"""\r
+\r
+        self._BsfKeyList    = ['FIND','NAME','HELP','TYPE','PAGE','OPTION','ORDER']\r
+        self._HdrKeyList    = ['HEADER','STRUCT']\r
+        self._BuidinOption  = {'$EN_DIS' : 'EN_DIS'}\r
+\r
+        self._MacroDict   = {}\r
+        self._CfgBlkDict  = {}\r
+        self._CfgPageDict = {}\r
+        self._CfgItemList = []\r
+        self._DscFile     = ''\r
+        self._FvDir       = ''\r
+        self._MapVer      = 0\r
+\r
+    def ParseMacros (self, MacroDefStr):\r
+        # ['-DABC=1', '-D', 'CFG_DEBUG=1', '-D', 'CFG_OUTDIR=Build']\r
+        self._MacroDict = {}\r
+        IsExpression = False\r
+        for Macro in MacroDefStr:\r
+            if Macro.startswith('-D'):\r
+                IsExpression = True\r
+                if len(Macro) > 2:\r
+                    Macro = Macro[2:]\r
+                else :\r
+                    continue\r
+            if IsExpression:\r
+                IsExpression = False\r
+                Match = re.match("(\w+)=(.+)", Macro)\r
+                if Match:\r
+                    self._MacroDict[Match.group(1)] = Match.group(2)\r
+                else:\r
+                    Match = re.match("(\w+)", Macro)\r
+                    if Match:\r
+                        self._MacroDict[Match.group(1)] = ''\r
+        if len(self._MacroDict) == 0:\r
+            self.Error = "Invalid MACRO arguments"\r
+            Error = 1\r
+        else:\r
+            Error = 0\r
+        return Error\r
+\r
+\r
+    def ParseDscFile (self, DscFile, FvDir):\r
+        self._CfgItemList = []\r
+        self._CfgPageDict = {}\r
+        self._CfgBlkDict  = {}\r
+        self._DscFile     = DscFile\r
+        self._FvDir       = FvDir\r
+\r
+        IsDefSect       = False\r
+        IsUpdSect       = False\r
+        IsVpdSect       = False\r
+        Found           = False\r
+\r
+        IfStack         = [True]\r
+        ElifStack       = []\r
+        Error           = 0\r
+\r
+        DscFd        = open(DscFile, "r")\r
+        DscLines     = DscFd.readlines()\r
+        DscFd.close()\r
+\r
+        ConfigDict      = {}\r
+\r
+        for DscLine in DscLines:\r
+            Handle     = False\r
+            DscLine = DscLine.strip()\r
+            Match = re.match("^\[(.+)\]", DscLine)\r
+            if Match is not None:\r
+                if  Match.group(1).lower() == "Defines".lower():\r
+                    IsDefSect = True\r
+                    IsVpdSect = False\r
+                    IsUpdSect = False\r
+                elif Match.group(1).lower() == "PcdsDynamicVpd".lower():\r
+                    ConfigDict = {}\r
+                    ConfigDict['header']  = 'ON'\r
+                    ConfigDict['region']  = 'VPD'\r
+                    ConfigDict['order']   = -1\r
+                    ConfigDict['page']    = ''\r
+                    ConfigDict['name']    = ''\r
+                    ConfigDict['find']    = ''\r
+                    ConfigDict['struct']  = ''\r
+                    ConfigDict['subreg']  = []\r
+                    IsDefSect = False\r
+                    IsVpdSect = True\r
+                    IsUpdSect = False\r
+                elif Match.group(1).lower() == "PcdsDynamicVpd.Upd".lower():\r
+                    ConfigDict = {}\r
+                    ConfigDict['header']  = 'ON'\r
+                    ConfigDict['region']  = 'UPD'\r
+                    ConfigDict['order']   = -1\r
+                    ConfigDict['page']    = ''\r
+                    ConfigDict['name']    = ''\r
+                    ConfigDict['find']    = ''\r
+                    ConfigDict['struct']  = ''\r
+                    ConfigDict['subreg']  = []\r
+                    IsDefSect = False\r
+                    IsUpdSect = True\r
+                    IsVpdSect = False\r
+                    Found     = True\r
+                else:\r
+                    IsDefSect = False\r
+                    IsUpdSect = False\r
+                    IsVpdSect = False\r
+            else:\r
+                if IsDefSect or IsUpdSect or IsVpdSect:\r
+                    if DscLine == "!else":\r
+                        IfStack[-1] = not IfStack[-1]\r
+                    elif DscLine == "!endif":\r
+                        IfStack.pop()\r
+                        Level = ElifStack.pop()\r
+                        while Level > 0:\r
+                            IfStack.pop()\r
+                            Level = Level - 1\r
+                    else:\r
+                        Result = False\r
+                        Match = re.match("!(ifdef|ifndef)\s+\$\((\w+)\)", DscLine)\r
+                        if Match is not None:\r
+                            if Match.group(2) in self._MacroDict:\r
+                                if Match.group(1) == 'ifdef':\r
+                                    Result = True\r
+                            else:\r
+                                if Match.group(1) == 'ifndef':\r
+                                    Result = True\r
+                            ElifStack.append(0)\r
+                            IfStack.append(Result)\r
+                        else:\r
+                            Match = re.match("!(if|elseif)\s+\$\\((\w+)\)\s*==\s*(\w+|\$\(\w+\))", DscLine)\r
+                            if Match is not None:\r
+                                if Match.group(2) in self._MacroDict:\r
+                                    MacroName = self._MacroDict[Match.group(2)]\r
+                                else:\r
+                                    MacroName = ''\r
+                                Value = Match.group(3)\r
+                                if Value.startswith('$'):\r
+                                    if Value[2:-1] in self._MacroDict:\r
+                                        Value = self._MacroDict[Value[2:-1]]\r
+                                    else:\r
+                                        Value = ''\r
+                                if MacroName == Value:\r
+                                    Result = True\r
+                                if Match.group(1) == "if":\r
+                                    ElifStack.append(0)\r
+                                    IfStack.append(Result)\r
+                                else:   #elseif\r
+                                    IfStack[-1] = not IfStack[-1]\r
+                                    IfStack.append(Result)\r
+                                    ElifStack[-1] = ElifStack[-1] + 1\r
+                            else:\r
+                                if len(DscLine) > 0 and DscLine[0] == '!':\r
+                                    self.Error = "Invalid DscLine '%s'" % DscLine\r
+                                    Error = 3\r
+                                    break;\r
+                                else:\r
+                                    if reduce(lambda x,y: x and y, IfStack):\r
+                                        Handle = True\r
+\r
+            if not Handle:\r
+                continue\r
+\r
+            if IsDefSect:\r
+                #DEFINE UPD_TOOL_GUID = 8C3D856A-9BE6-468E-850A-24F7A8D38E09\r
+                Match = re.match("^\s*(?:DEFINE\s+)*(\w+)\s*=\s*([-\w]+)", DscLine)\r
+                if Match:\r
+                    self._MacroDict[Match.group(1)] = Match.group(2)\r
+            else:\r
+                Match = re.match("^\s*#\s+!(BSF|HDR)\s+(.+)", DscLine)\r
+                if Match:\r
+                    Remaining = Match.group(2)\r
+                    if Match.group(1) == 'BSF':\r
+                        Match = re.match("(?:^|.+\s+)PAGES:{(.+?)}", Remaining)\r
+                        if Match:\r
+                            # !BSF PAGES:{HSW:"Haswell System Agent", LPT:"Lynx Point PCH"}\r
+                            PageList = Match.group(1).split(',')\r
+                            for Page in PageList:\r
+                                Page  = Page.strip()\r
+                                Match = re.match("(\w+):\"(.+)\"", Page)\r
+                                self._CfgPageDict[Match.group(1)] = Match.group(2)\r
+\r
+                        Match = re.match("(?:^|.+\s+)BLOCK:{NAME:\"(.+)\"\s*,\s*VER:\"(.+)\"\s*}", Remaining)\r
+                        if Match:\r
+                            self._CfgBlkDict['name'] = Match.group(1)\r
+                            self._CfgBlkDict['ver']  = Match.group(2)\r
+\r
+                        for Key in self._BsfKeyList:\r
+                            Match = re.match("(?:^|.+\s+)%s:{(.+?)}" % Key, Remaining)\r
+                            if Match:\r
+                                if Key in ['HELP', 'OPTION'] and Match.group(1).startswith('+'):\r
+                                    ConfigDict[Key.lower()] += Match.group(1)[1:]\r
+                                else:\r
+                                    ConfigDict[Key.lower()]  = Match.group(1)\r
+                    else:\r
+                        for Key in self._HdrKeyList:\r
+                            Match = re.match("(?:^|.+\s+)%s:{(.+?)}" % Key, Remaining)\r
+                            if Match:\r
+                                ConfigDict[Key.lower()]  = Match.group(1)\r
+\r
+                # Check VPD/UPD\r
+                if IsUpdSect:\r
+                    Match = re.match("^([_a-zA-Z0-9]+).([_a-zA-Z0-9]+)\s*\|\s*(0x[0-9A-F]{4})\s*\|\s*(\d+|0x[0-9a-fA-F]+)\s*\|\s*(.+)",DscLine)\r
+                else:\r
+                    Match = re.match("^([_a-zA-Z0-9]+).([_a-zA-Z0-9]+)\s*\|\s*(0x[0-9A-F]+)(?:\s*\|\s*(.+))?",  DscLine)\r
+                if Match:\r
+                    ConfigDict['space']  = Match.group(1)\r
+                    ConfigDict['cname']  = Match.group(2)\r
+                    ConfigDict['offset'] = int (Match.group(3), 16)\r
+                    if ConfigDict['order'] == -1:\r
+                        ConfigDict['order'] = ConfigDict['offset'] << 8\r
+                    else:\r
+                        (Major, Minor) = ConfigDict['order'].split('.')\r
+                        ConfigDict['order'] = (int (Major, 16) << 8 ) +  int (Minor, 16)\r
+                    if IsUpdSect:\r
+                        Value = Match.group(5).strip()\r
+                        if Match.group(4).startswith("0x"):\r
+                            Length  = int (Match.group(4), 16)\r
+                        else :\r
+                            Length  = int (Match.group(4))\r
+                    else:\r
+                        Value = Match.group(4)\r
+                        if Value is None:\r
+                            Value = ''\r
+                        Value = Value.strip()\r
+                        if '|' in Value:\r
+                            Match = re.match("^.+\s*\|\s*(.+)", Value)\r
+                            if Match:\r
+                                Value = Match.group(1)\r
+                        Length = -1\r
+\r
+                    ConfigDict['length'] = Length\r
+                    Match = re.match("\$\((\w+)\)", Value)\r
+                    if Match:\r
+                        if Match.group(1) in self._MacroDict:\r
+                            Value = self._MacroDict[Match.group(1)]\r
+                    ConfigDict['value']  = Value\r
+                    if ConfigDict['name']  == '':\r
+                        # Clear BSF specific items\r
+                        ConfigDict['help']   = ''\r
+                        ConfigDict['type']   = ''\r
+                        ConfigDict['option'] = ''\r
+\r
+                    self._CfgItemList.append(ConfigDict.copy())\r
+                    ConfigDict['name']   = ''\r
+                    ConfigDict['find']   = ''\r
+                    ConfigDict['struct'] = ''\r
+                    ConfigDict['order']  = -1\r
+                    ConfigDict['subreg'] = []\r
+                else:\r
+                    # It could be a virtual item as below\r
+                    # !BSF FIELD:{1:SerialDebugPortAddress0}\r
+                    Match = re.match("^\s*#\s+!BSF\s+FIELD:{(.+):(\d+)}", DscLine)\r
+                    if Match:\r
+                        SubCfgDict = ConfigDict\r
+                        SubCfgDict['cname']  = Match.group(1)\r
+                        SubCfgDict['length'] = int (Match.group(2))\r
+                        if SubCfgDict['length'] > 0:\r
+                            LastItem =  self._CfgItemList[-1]\r
+                            if len(LastItem['subreg']) == 0:\r
+                                SubOffset  = 0\r
+                            else:\r
+                                SubOffset += LastItem['subreg'][-1]['length']\r
+                            SubCfgDict['offset'] = SubOffset\r
+                            LastItem['subreg'].append (SubCfgDict.copy())\r
+                        ConfigDict['name']   = ''\r
+        return Error\r
+\r
+    def UpdateSubRegionDefaultValue (self):\r
+        Error = 0\r
+        for Item in self._CfgItemList:\r
+            if len(Item['subreg']) == 0:\r
+                continue\r
+            bytearray = []\r
+            if Item['value'][0] == '{':\r
+                binlist = Item['value'][1:-1].split(',')\r
+                for each in binlist:\r
+                    each = each.strip()\r
+                    if each.startswith('0x'):\r
+                        value = int(each, 16)\r
+                    else:\r
+                        value = int(each)\r
+                    bytearray.append(value)\r
+            else:\r
+                if Item['value'].startswith('0x'):\r
+                    value = int(Item['value'], 16)\r
+                else:\r
+                    value = int(Item['value'])\r
+                idx = 0;\r
+                while  idx < Item['length']:\r
+                    bytearray.append(value & 0xFF)\r
+                    value = value >> 8\r
+                    idx = idx + 1\r
+            for SubItem in Item['subreg']:\r
+                if SubItem['length'] in (1,2,4,8):\r
+                    valuelist = [b for b in bytearray[SubItem['offset']:SubItem['offset']+SubItem['length']]]\r
+                    valuelist.reverse()\r
+                    valuestr = "".join('%02X' % b for b in valuelist)\r
+                    SubItem['value'] = '0x%s' % valuestr\r
+                else:\r
+                    valuestr = ",".join('0x%02X' % b for b in bytearray[SubItem['offset']:SubItem['offset']+SubItem['length']])\r
+                    SubItem['value'] = '{%s}' % valuestr\r
+        return Error\r
+\r
+    def UpdateVpdSizeField (self):\r
+        FvDir = self._FvDir;\r
+\r
+        if 'VPD_TOOL_GUID' not in self._MacroDict:\r
+            self.Error = "VPD_TOOL_GUID definition is missing in DSC file"\r
+            return 1\r
+\r
+        VpdMapFile = os.path.join(FvDir, self._MacroDict['VPD_TOOL_GUID'] + '.map')\r
+        if not os.path.exists(VpdMapFile):\r
+            self.Error = "VPD MAP file '%s' does not exist" % VpdMapFile\r
+            return 2\r
+\r
+        MapFd       = open(VpdMapFile, "r")\r
+        MapLines    = MapFd.readlines()\r
+        MapFd.close()\r
+\r
+        VpdDict  = {}\r
+        PcdDict  = {}\r
+        for MapLine in MapLines:\r
+            #gPlatformFspPkgTokenSpaceGuid.PcdVpdRegionSign | DEFAULT | 0x0000 | 8 | 0x534450565F425346\r
+            #gPlatformFspPkgTokenSpaceGuid.PcdVpdRegionSign | 0x0000 | 8 | 0x534450565F425346\r
+            #gPlatformFspPkgTokenSpaceGuid.PcdTest          | 0x0008 | 5 | {0x01,0x02,0x03,0x04,0x05}\r
+            Match = re.match("([_a-zA-Z0-9]+).([_a-zA-Z0-9]+)(\s\|\sDEFAULT)?\s\|\s(0x[0-9A-F]{4})\s\|\s(\d+|0x[0-9a-fA-F]+)\s\|\s(\{?[x0-9a-fA-F,\s]+\}?)", MapLine)\r
+            if Match:\r
+                Space  = Match.group(1)\r
+                Name   = Match.group(2)\r
+                if (self._MapVer == 0) and (Match.group(3) != None):\r
+                    self._MapVer = 1\r
+                Offset = int (Match.group(4), 16)\r
+                if Match.group(5).startswith("0x"):\r
+                    Length = int (Match.group(5), 16)\r
+                else :\r
+                    Length = int (Match.group(5))\r
+                PcdDict["len"]   = Length\r
+                PcdDict["value"]   = Match.group(6)\r
+                VpdDict[Space+'.'+Name] = dict(PcdDict)\r
+\r
+        for Item in self._CfgItemList:\r
+            if Item['value'] == '':\r
+                Item['value']  = VpdDict[Item['space']+'.'+Item['cname']]['value']\r
+            if Item['length'] == -1:\r
+                Item['length'] = VpdDict[Item['space']+'.'+Item['cname']]['len']\r
+            if Item['struct'] != '':\r
+                Type = Item['struct'].strip()\r
+                if Type.endswith('*') and (Item['length'] != 4):\r
+                    self.Error = "Struct pointer '%s' has invalid size" % Type\r
+                    return 3\r
+\r
+        return 0\r
+\r
+    def CreateUpdTxtFile (self, UpdTxtFile):\r
+        FvDir = self._FvDir\r
+        if 'UPD_TOOL_GUID' not in self._MacroDict:\r
+            self.Error = "UPD_TOOL_GUID definition is missing in DSC file"\r
+            return 1\r
+\r
+        if UpdTxtFile == '':\r
+            UpdTxtFile = os.path.join(FvDir, self._MacroDict['UPD_TOOL_GUID'] + '.txt')\r
+\r
+        ReCreate = False\r
+        if not os.path.exists(UpdTxtFile):\r
+            ReCreate = True\r
+        else:\r
+            DscTime = os.path.getmtime(self._DscFile)\r
+            TxtTime = os.path.getmtime(UpdTxtFile)\r
+            if DscTime > TxtTime:\r
+                ReCreate = True\r
+\r
+        if not  ReCreate:\r
+            # DSC has not been modified yet\r
+            # So don't have to re-generate other files\r
+            self.Error = 'No DSC file change, skip to create UPD TXT file'\r
+            return 256\r
+\r
+        TxtFd = open(UpdTxtFile, "w")\r
+        TxtFd.write("%s\n"   % (__copyright_txt__ % date.today().year))\r
+\r
+        NextOffset = 0\r
+        SpaceIdx   = 0\r
+        if self._MapVer == 1:\r
+            Default = 'DEFAULT|'\r
+        else:\r
+            Default = ''\r
+        for Item in self._CfgItemList:\r
+            if Item['region'] != 'UPD':\r
+                continue\r
+            Offset = Item['offset']\r
+            if NextOffset < Offset:\r
+                # insert one line\r
+                TxtFd.write("%s.UnusedUpdSpace%d|%s0x%04X|0x%04X|{0}\n" % (Item['space'], SpaceIdx, Default, NextOffset, Offset - NextOffset))\r
+                SpaceIdx = SpaceIdx + 1\r
+            NextOffset = Offset + Item['length']\r
+            TxtFd.write("%s.%s|%s0x%04X|%s|%s\n" % (Item['space'],Item['cname'],Default,Item['offset'],Item['length'],Item['value']))\r
+        TxtFd.close()\r
+        return 0\r
+\r
+    def CreateField (self, Name, Length, Offset, Struct):\r
+        PosName    = 28\r
+        PosComment = 30\r
+\r
+        IsArray = False\r
+        if Length == 1:\r
+            Type = "UINT8"\r
+        elif Length == 2:\r
+            Type = "UINT16"\r
+        elif Length == 4:\r
+            Type = "UINT32"\r
+        elif Length == 8:\r
+            Type = "UINT64"\r
+        else:\r
+            Type = "UINT8"\r
+            IsArray = True\r
+\r
+        if Struct != '':\r
+            IsArray = False\r
+            Type = Struct\r
+\r
+        if IsArray:\r
+            Name = Name + '[%d]' % Length\r
+\r
+        if len(Type) < PosName:\r
+            Space1 = PosName - len(Type)\r
+        else:\r
+            Space1 = 1\r
+\r
+        if len(Name) < PosComment:\r
+            Space2 = PosComment - len(Name)\r
+        else:\r
+            Space2 = 1\r
+\r
+        return "  %s%s%s;%s/* Offset 0x%04X */\n" % (Type, ' ' * Space1, Name, ' ' * Space2, Offset)\r
+\r
+\r
+    def CreateHeaderFile (self, InputHeaderFile, IsInternal):\r
+        Error = 0\r
+        FvDir = self._FvDir\r
+\r
+        if IsInternal:\r
+            HeaderFile = os.path.join(FvDir, 'VpdHeader.h')\r
+        else:\r
+            HeaderFile = os.path.join(FvDir, 'fsp_vpd.h')\r
+\r
+        # Check if header needs to be recreated\r
+        ReCreate = False\r
+        if IsInternal:\r
+            if not os.path.exists(HeaderFile):\r
+                ReCreate = True\r
+            else:\r
+                DscTime  = os.path.getmtime(self._DscFile)\r
+                HeadTime = os.path.getmtime(HeaderFile)\r
+                if not os.path.exists(InputHeaderFile):\r
+                    InpTime =  HeadTime\r
+                else:\r
+                    InpTime  = os.path.getmtime(InputHeaderFile)\r
+                if DscTime > HeadTime or InpTime > HeadTime:\r
+                    ReCreate = True\r
+\r
+            if not ReCreate:\r
+                self.Error = "No DSC or input header file is changed, skip the header file generating"\r
+                return 256\r
+\r
+        HeaderFd = open(HeaderFile, "w")\r
+        FileBase = os.path.basename(HeaderFile)\r
+        FileName = FileBase.replace(".", "_").upper()\r
+        HeaderFd.write("%s\n"   % (__copyright_h__ % date.today().year))\r
+        HeaderFd.write("#ifndef __%s__\n"   % FileName)\r
+        HeaderFd.write("#define __%s__\n\n" % FileName)\r
+        HeaderFd.write("#pragma pack(1)\n\n")\r
+\r
+        if InputHeaderFile != '':\r
+            if not os.path.exists(InputHeaderFile):\r
+                 self.Error = "Input header file '%s' does not exist" % InputHeaderFile\r
+                 return 2\r
+\r
+            InFd         = open(InputHeaderFile, "r")\r
+            IncLines     = InFd.readlines()\r
+            InFd.close()\r
+\r
+            Export = False\r
+            for Line in IncLines:\r
+                Match = re.search ("!EXPORT\s+EXTERNAL_BOOTLOADER_STRUCT_(BEGIN|END)\s+", Line)\r
+                if Match:\r
+                    if Match.group(1) == "BEGIN":\r
+                        Export = True\r
+                        continue\r
+                    else:\r
+                        Export = False\r
+                        continue\r
+                if Export:\r
+                    HeaderFd.write(Line)\r
+            HeaderFd.write("\n\n")\r
+\r
+        for Region in ['UPD', 'VPD']:\r
+\r
+            # Write  PcdVpdRegionSign and PcdImageRevision\r
+            if Region[0] == 'V':\r
+                if 'VPD_TOOL_GUID' not in self._MacroDict:\r
+                    self.Error = "VPD_TOOL_GUID definition is missing in DSC file"\r
+                    Error = 1\r
+                    break\r
+\r
+                BinFile = os.path.join(FvDir, self._MacroDict['VPD_TOOL_GUID'] + ".bin")\r
+                if not os.path.exists(BinFile):\r
+                    self.Error = "VPD binary file '%s' does not exist" % BinFile\r
+                    Error = 2\r
+                    break\r
+\r
+                BinFd = open(BinFile, "rb")\r
+                IdStr    = BinFd.read(0x08)\r
+                ImageId  = struct.unpack('Q', IdStr)\r
+                ImageRev = struct.unpack('L', BinFd.read(0x04))\r
+                BinFd.close()\r
+\r
+                HeaderFd.write("#define VPD_IMAGE_ID    0x%016X        /* '%s' */\n" % (ImageId[0], IdStr))\r
+                HeaderFd.write("#define VPD_IMAGE_REV   0x%08X \n\n" % ImageRev[0])\r
+\r
+            HeaderFd.write("typedef struct _" + Region[0]  + "PD_DATA_REGION {\n")\r
+            NextOffset  = 0\r
+            SpaceIdx    = 0\r
+            Offset      = 0\r
+\r
+            LastVisible = True\r
+            ResvOffset  = 0\r
+            ResvIdx     = 0\r
+            LineBuffer  = []\r
+            for Item in self._CfgItemList:\r
+                if Item['region'] != Region:\r
+                    continue\r
+\r
+                NextVisible = LastVisible\r
+                if not IsInternal:\r
+                    if LastVisible and (Item['header'] == 'OFF'):\r
+                        NextVisible = False\r
+                        ResvOffset  = Item['offset']\r
+                    elif (not LastVisible) and Item['header'] == 'ON':\r
+                        NextVisible = True\r
+                        Name = "Reserved" + Region[0] + "pdSpace%d" % ResvIdx\r
+                        ResvIdx = ResvIdx + 1\r
+                        HeaderFd.write(self.CreateField (Name, Item["offset"] - ResvOffset, ResvOffset, ''))\r
+\r
+                if  Offset < Item["offset"]:\r
+                    if IsInternal or LastVisible:\r
+                        Name = "Unused" + Region[0] + "pdSpace%d" % SpaceIdx\r
+                        LineBuffer.append(self.CreateField (Name, Item["offset"] - Offset, Offset, ''))\r
+                    SpaceIdx = SpaceIdx + 1\r
+                    Offset   = Item["offset"]\r
+\r
+                if Offset != Item["offset"]:\r
+                    print "Unsorted offset 0x%04X\n" % Item["offset"]\r
+                    error = 2\r
+                    break;\r
+\r
+                LastVisible = NextVisible\r
+\r
+                Offset = Offset + Item["length"]\r
+                if IsInternal or LastVisible:\r
+                    for Each in LineBuffer:\r
+                        HeaderFd.write (Each)\r
+                    LineBuffer = []\r
+                    HeaderFd.write(self.CreateField (Item["cname"], Item["length"], Item["offset"], Item['struct']))\r
+\r
+            HeaderFd.write("} " + Region[0] + "PD_DATA_REGION;\n\n")\r
+        HeaderFd.write("#pragma pack()\n\n")\r
+        HeaderFd.write("#endif\n")\r
+        HeaderFd.close()\r
+\r
+        return Error\r
+\r
+    def WriteBsfStruct  (self, BsfFd, Item):\r
+        if Item['type'] == "None":\r
+            Space = "gPlatformFspPkgTokenSpaceGuid"\r
+        else:\r
+            Space = Item['space']\r
+        Line = "    $%s_%s" % (Space, Item['cname'])\r
+        Match = re.match("\s*\{([x0-9a-fA-F,\s]+)\}\s*", Item['value'])\r
+        if Match:\r
+            DefaultValue = Match.group(1).strip()\r
+        else:\r
+            DefaultValue = Item['value'].strip()\r
+        BsfFd.write("    %s%s%4d bytes    $_DEFAULT_ = %s\n" % (Line, ' ' * (64 - len(Line)), Item['length'], DefaultValue))\r
+        TmpList = []\r
+        if  Item['type'] == "Combo":\r
+            if not Item['option'] in self._BuidinOption:\r
+                OptList = Item['option'].split(',')\r
+                for Option in OptList:\r
+                    Option = Option.strip()\r
+                    (OpVal, OpStr) = Option.split(':')\r
+                    TmpList.append((OpVal, OpStr))\r
+        return  TmpList\r
+\r
+    def WriteBsfOption  (self, BsfFd, Item):\r
+        PcdName   = Item['space'] + '_' + Item['cname']\r
+        WriteHelp = 0\r
+        if Item['type'] == "Combo":\r
+            if Item['option'] in self._BuidinOption:\r
+                Options = self._BuidinOption[Item['option']]\r
+            else:\r
+                Options = PcdName\r
+            BsfFd.write('    %s $%s, "%s", &%s,\n' % (Item['type'], PcdName, Item['name'], Options));\r
+            WriteHelp = 1\r
+        elif Item['type'].startswith("EditNum"):\r
+            Match = re.match("EditNum\s*,\s*(HEX|DEC)\s*,\s*\((\d+|0x[0-9A-Fa-f]+)\s*,\s*(\d+|0x[0-9A-Fa-f]+)\)", Item['type'])\r
+            if Match:\r
+                BsfFd.write('    EditNum $%s, "%s", %s,\n' % (PcdName, Item['name'], Match.group(1)));\r
+                WriteHelp = 2\r
+        elif Item['type'].startswith("EditText"):\r
+            BsfFd.write('    %s $%s, "%s",\n' % (Item['type'], PcdName, Item['name']));\r
+            WriteHelp = 1\r
+\r
+        if WriteHelp  > 0:\r
+            HelpLines = Item['help'].split('\\n\\r')\r
+            FirstLine = True\r
+            for HelpLine in HelpLines:\r
+                if FirstLine:\r
+                    FirstLine = False\r
+                    BsfFd.write('        Help "%s"\n' % (HelpLine));\r
+                else:\r
+