]> git.proxmox.com Git - mirror_edk2.git/commitdiff
Add IntelFsp2Pkg and IntelFsp2WrapperPkg.
authorJiewen Yao <jiewen.yao@intel.com>
Fri, 13 May 2016 05:00:53 +0000 (13:00 +0800)
committerJiewen Yao <jiewen.yao@intel.com>
Fri, 13 May 2016 05:00:53 +0000 (13:00 +0800)
Add FSP2.0 support.
This series of patch is to support FSP2.0 specification at
https://firmware.intel.com/sites/default/files/FSP_EAS_v2.0_Draft%20External.pdf

Some major updates include:
1) One FSP binary is separated to multiple components:
FSP-T, FSP-M, FSP-S, and optional FSP-O.
Each component has its own configuration data region.
2) All FSP-APIs use same UPD format - FSP_UPD_HEADER.
3) Add EnumInitPhaseEndOfFirmware notifyphase.
4) FSP1.1/FSP1.0 compatibility is NOT maintained.
5) We also add rename Fsp* to FspWrapper* in IntelFsp2WrapperPkg,
to indicate that it is for FspWrapper only.

IntelFspPkg and IntelFspWrapperPkg will be deprecated.
The new Intel platform will follow FSP2.0 and use IntelFsp2Pkg
and IntelFsp2WrapperPkg.
The old platform can still use IntelFspPkg and IntelFspWrapperPkg
for compatibility consideration.

Cc: Giri P Mudusuru <giri.p.mudusuru@intel.com>
Cc: Maurice Ma <maurice.ma@intel.com>
Cc: Ravi P Rangarajan <ravi.p.rangarajan@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
Reviewed-by: Giri P Mudusuru <giri.p.mudusuru@intel.com>
Reviewed-by: Maurice Ma <maurice.ma@intel.com>
Reviewed-by: Ravi P Rangarajan <ravi.p.rangarajan@intel.com>
118 files changed:
IntelFsp2Pkg/Contributions.txt [new file with mode: 0644]
IntelFsp2Pkg/FspNotifyPhase/FspNotifyPhasePeim.c [new file with mode: 0644]
IntelFsp2Pkg/FspNotifyPhase/FspNotifyPhasePeim.h [new file with mode: 0644]
IntelFsp2Pkg/FspNotifyPhase/FspNotifyPhasePeim.inf [new file with mode: 0644]
IntelFsp2Pkg/FspSecCore/FspSecCoreM.inf [new file with mode: 0644]
IntelFsp2Pkg/FspSecCore/FspSecCoreS.inf [new file with mode: 0644]
IntelFsp2Pkg/FspSecCore/FspSecCoreT.inf [new file with mode: 0644]
IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryCommon.nasm [new file with mode: 0644]
IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryM.nasm [new file with mode: 0644]
IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryS.nasm [new file with mode: 0644]
IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryT.nasm [new file with mode: 0644]
IntelFsp2Pkg/FspSecCore/Ia32/FspHelper.nasm [new file with mode: 0644]
IntelFsp2Pkg/FspSecCore/Ia32/InitializeFpu.nasm [new file with mode: 0644]
IntelFsp2Pkg/FspSecCore/Ia32/MicrocodeLoadNasm.inc [new file with mode: 0644]
IntelFsp2Pkg/FspSecCore/Ia32/SaveRestoreSseNasm.inc [new file with mode: 0644]
IntelFsp2Pkg/FspSecCore/Ia32/Stack.nasm [new file with mode: 0644]
IntelFsp2Pkg/FspSecCore/SecFsp.c [new file with mode: 0644]
IntelFsp2Pkg/FspSecCore/SecFsp.h [new file with mode: 0644]
IntelFsp2Pkg/FspSecCore/SecFspApiChk.c [new file with mode: 0644]
IntelFsp2Pkg/FspSecCore/SecMain.c [new file with mode: 0644]
IntelFsp2Pkg/FspSecCore/SecMain.h [new file with mode: 0644]
IntelFsp2Pkg/FspSecCore/Vtf0/Bin/ResetVec.ia32.raw [new file with mode: 0644]
IntelFsp2Pkg/FspSecCore/Vtf0/Build.py [new file with mode: 0644]
IntelFsp2Pkg/FspSecCore/Vtf0/Ia16/ResetVec.asm16 [new file with mode: 0644]
IntelFsp2Pkg/FspSecCore/Vtf0/ResetVectorCode.asm [new file with mode: 0644]
IntelFsp2Pkg/FspSecCore/Vtf0/Tools/FixupForRawSection.py [new file with mode: 0644]
IntelFsp2Pkg/Include/FspDataTable.h [new file with mode: 0644]
IntelFsp2Pkg/Include/FspEas.h [new file with mode: 0644]
IntelFsp2Pkg/Include/FspEas/FspApi.h [new file with mode: 0644]
IntelFsp2Pkg/Include/FspGlobalData.h [new file with mode: 0644]
IntelFsp2Pkg/Include/FspMeasurePointId.h [new file with mode: 0644]
IntelFsp2Pkg/Include/FspStatusCode.h [new file with mode: 0644]
IntelFsp2Pkg/Include/Guid/FspHeaderFile.h [new file with mode: 0644]
IntelFsp2Pkg/Include/Guid/GuidHobFspEas.h [new file with mode: 0644]
IntelFsp2Pkg/Include/Library/CacheAsRamLib.h [new file with mode: 0644]
IntelFsp2Pkg/Include/Library/CacheLib.h [new file with mode: 0644]
IntelFsp2Pkg/Include/Library/DebugDeviceLib.h [new file with mode: 0644]
IntelFsp2Pkg/Include/Library/FspCommonLib.h [new file with mode: 0644]
IntelFsp2Pkg/Include/Library/FspPlatformLib.h [new file with mode: 0644]
IntelFsp2Pkg/Include/Library/FspSecPlatformLib.h [new file with mode: 0644]
IntelFsp2Pkg/Include/Library/FspSwitchStackLib.h [new file with mode: 0644]
IntelFsp2Pkg/IntelFsp2Pkg.dec [new file with mode: 0644]
IntelFsp2Pkg/IntelFsp2Pkg.dsc [new file with mode: 0644]
IntelFsp2Pkg/Library/BaseCacheAsRamLibNull/BaseCacheAsRamLibNull.inf [new file with mode: 0644]
IntelFsp2Pkg/Library/BaseCacheAsRamLibNull/DisableCacheAsRamNull.c [new file with mode: 0644]
IntelFsp2Pkg/Library/BaseCacheLib/BaseCacheLib.inf [new file with mode: 0644]
IntelFsp2Pkg/Library/BaseCacheLib/CacheLib.c [new file with mode: 0644]
IntelFsp2Pkg/Library/BaseCacheLib/CacheLibInternal.h [new file with mode: 0644]
IntelFsp2Pkg/Library/BaseDebugDeviceLibNull/BaseDebugDeviceLibNull.inf [new file with mode: 0644]
IntelFsp2Pkg/Library/BaseDebugDeviceLibNull/DebugDeviceLibNull.c [new file with mode: 0644]
IntelFsp2Pkg/Library/BaseFspCommonLib/BaseFspCommonLib.inf [new file with mode: 0644]
IntelFsp2Pkg/Library/BaseFspCommonLib/FspCommonLib.c [new file with mode: 0644]
IntelFsp2Pkg/Library/BaseFspDebugLibSerialPort/BaseFspDebugLibSerialPort.inf [new file with mode: 0644]
IntelFsp2Pkg/Library/BaseFspDebugLibSerialPort/DebugLib.c [new file with mode: 0644]
IntelFsp2Pkg/Library/BaseFspDebugLibSerialPort/Ia32/FspDebug.asm [new file with mode: 0644]
IntelFsp2Pkg/Library/BaseFspDebugLibSerialPort/Ia32/FspDebug.s [new file with mode: 0644]
IntelFsp2Pkg/Library/BaseFspPlatformLib/BaseFspPlatformLib.inf [new file with mode: 0644]
IntelFsp2Pkg/Library/BaseFspPlatformLib/FspPlatformMemory.c [new file with mode: 0644]
IntelFsp2Pkg/Library/BaseFspPlatformLib/FspPlatformNotify.c [new file with mode: 0644]
IntelFsp2Pkg/Library/BaseFspSwitchStackLib/BaseFspSwitchStackLib.inf [new file with mode: 0644]
IntelFsp2Pkg/Library/BaseFspSwitchStackLib/FspSwitchStackLib.c [new file with mode: 0644]
IntelFsp2Pkg/Library/BaseFspSwitchStackLib/Ia32/Stack.asm [new file with mode: 0644]
IntelFsp2Pkg/Library/BaseFspSwitchStackLib/Ia32/Stack.s [new file with mode: 0644]
IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/Ia32/Flat32.asm [new file with mode: 0644]
IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/Ia32/Flat32.s [new file with mode: 0644]
IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/Ia32/SecCarInit.asm [new file with mode: 0644]
IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/Ia32/SecCarInit.s [new file with mode: 0644]
IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/PlatformSecLibNull.c [new file with mode: 0644]
IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/SecFspSecPlatformLibNull.inf [new file with mode: 0644]
IntelFsp2Pkg/Tools/GenCfgOpt.py [new file with mode: 0644]
IntelFsp2Pkg/Tools/PatchFv.py [new file with mode: 0644]
IntelFsp2Pkg/Tools/SplitFspBin.py [new file with mode: 0644]
IntelFsp2Pkg/Tools/UserManuals/GenCfgOptUserManual.docx [new file with mode: 0644]
IntelFsp2Pkg/Tools/UserManuals/PatchFvUserManual.docx [new file with mode: 0644]
IntelFsp2WrapperPkg/Contributions.txt [new file with mode: 0644]
IntelFsp2WrapperPkg/FspWrapperNotifyDxe/FspWrapperNotifyDxe.c [new file with mode: 0644]
IntelFsp2WrapperPkg/FspWrapperNotifyDxe/FspWrapperNotifyDxe.inf [new file with mode: 0644]
IntelFsp2WrapperPkg/FspWrapperNotifyDxe/LoadBelow4G.c [new file with mode: 0644]
IntelFsp2WrapperPkg/FspmWrapperPeim/FspmWrapperPeim.c [new file with mode: 0644]
IntelFsp2WrapperPkg/FspmWrapperPeim/FspmWrapperPeim.inf [new file with mode: 0644]
IntelFsp2WrapperPkg/FspsWrapperPeim/FspsWrapperPeim.c [new file with mode: 0644]
IntelFsp2WrapperPkg/FspsWrapperPeim/FspsWrapperPeim.inf [new file with mode: 0644]
IntelFsp2WrapperPkg/Include/Library/FspWrapperApiLib.h [new file with mode: 0644]
IntelFsp2WrapperPkg/Include/Library/FspWrapperApiTestLib.h [new file with mode: 0644]
IntelFsp2WrapperPkg/Include/Library/FspWrapperHobProcessLib.h [new file with mode: 0644]
IntelFsp2WrapperPkg/Include/Library/FspWrapperPlatformLib.h [new file with mode: 0644]
IntelFsp2WrapperPkg/Include/Ppi/FspSiliconInitDone.h [new file with mode: 0644]
IntelFsp2WrapperPkg/Include/Ppi/TopOfTemporaryRam.h [new file with mode: 0644]
IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec [new file with mode: 0644]
IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dsc [new file with mode: 0644]
IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/BaseFspWrapperApiLib.inf [new file with mode: 0644]
IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/FspWrapperApiLib.c [new file with mode: 0644]
IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/IA32/DispatchExecute.c [new file with mode: 0644]
IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/X64/DispatchExecute.c [new file with mode: 0644]
IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/X64/Thunk64To32.S [new file with mode: 0644]
IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/X64/Thunk64To32.asm [new file with mode: 0644]
IntelFsp2WrapperPkg/Library/BaseFspWrapperApiTestLibNull/BaseFspWrapperApiTestLibNull.inf [new file with mode: 0644]
IntelFsp2WrapperPkg/Library/BaseFspWrapperApiTestLibNull/FspWrapperApiTestNull.c [new file with mode: 0644]
IntelFsp2WrapperPkg/Library/BaseFspWrapperPlatformLibSample/BaseFspWrapperPlatformLibSample.inf [new file with mode: 0644]
IntelFsp2WrapperPkg/Library/BaseFspWrapperPlatformLibSample/FspWrapperPlatformLibSample.c [new file with mode: 0644]
IntelFsp2WrapperPkg/Library/PeiFspWrapperApiTestLib/FspWrapperApiTest.c [new file with mode: 0644]
IntelFsp2WrapperPkg/Library/PeiFspWrapperApiTestLib/PeiFspWrapperApiTestLib.inf [new file with mode: 0644]
IntelFsp2WrapperPkg/Library/PeiFspWrapperHobProcessLibSample/FspWrapperHobProcessLibSample.c [new file with mode: 0644]
IntelFsp2WrapperPkg/Library/PeiFspWrapperHobProcessLibSample/PeiFspWrapperHobProcessLibSample.inf [new file with mode: 0644]
IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/FspWrapperPlatformSecLibSample.c [new file with mode: 0644]
IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/Fsp.h [new file with mode: 0644]
IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/PeiCoreEntry.S [new file with mode: 0644]
IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/PeiCoreEntry.asm [new file with mode: 0644]
IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/SecEntry.S [new file with mode: 0644]
IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/SecEntry.asm [new file with mode: 0644]
IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/Stack.S [new file with mode: 0644]
IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/Stack.asm [new file with mode: 0644]
IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/PlatformInit.c [new file with mode: 0644]
IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/SecFspWrapperPlatformSecLibSample.inf [new file with mode: 0644]
IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/SecGetPerformance.c [new file with mode: 0644]
IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/SecPlatformInformation.c [new file with mode: 0644]
IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/SecRamInitData.c [new file with mode: 0644]
IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/SecTempRamDone.c [new file with mode: 0644]

diff --git a/IntelFsp2Pkg/Contributions.txt b/IntelFsp2Pkg/Contributions.txt
new file mode 100644 (file)
index 0000000..f87cbd7
--- /dev/null
@@ -0,0 +1,218 @@
+\r
+======================\r
+= Code Contributions =\r
+======================\r
+\r
+To make a contribution to a TianoCore project, follow these steps.\r
+1. Create a change description in the format specified below to\r
+   use in the source control commit log.\r
+2. Your commit message must include your "Signed-off-by" signature,\r
+   and "Contributed-under" message.\r
+3. Your "Contributed-under" message explicitly states that the\r
+   contribution is made under the terms of the specified\r
+   contribution agreement.  Your "Contributed-under" message\r
+   must include the name of contribution agreement and version.\r
+   For example: Contributed-under: TianoCore Contribution Agreement 1.0\r
+   The "TianoCore Contribution Agreement" is included below in\r
+   this document.\r
+4. Submit your code to the TianoCore project using the process\r
+   that the project documents on its web page.  If the process is\r
+   not documented, then submit the code on development email list\r
+   for the project.\r
+5. It is preferred that contributions are submitted using the same\r
+   copyright license as the base project. When that is not possible,\r
+   then contributions using the following licenses can be accepted:\r
+   * BSD (2-clause): http://opensource.org/licenses/BSD-2-Clause\r
+   * BSD (3-clause): http://opensource.org/licenses/BSD-3-Clause\r
+   * MIT: http://opensource.org/licenses/MIT\r
+   * Python-2.0: http://opensource.org/licenses/Python-2.0\r
+   * Zlib: http://opensource.org/licenses/Zlib\r
+\r
+   Contributions of code put into the public domain can also be\r
+   accepted.\r
+\r
+   Contributions using other licenses might be accepted, but further\r
+   review will be required.\r
+\r
+=====================================================\r
+= Change Description / Commit Message / Patch Email =\r
+=====================================================\r
+\r
+Your change description should use the standard format for a\r
+commit message, and must include your "Signed-off-by" signature\r
+and the "Contributed-under" message.\r
+\r
+== Sample Change Description / Commit Message =\r
+\r
+=== Start of sample patch email message ===\r
+\r
+From: Contributor Name <contributor@example.com>\r
+Subject: [PATCH] CodeModule: Brief-single-line-summary\r
+\r
+Full-commit-message\r
+\r
+Contributed-under: TianoCore Contribution Agreement 1.0\r
+Signed-off-by: Contributor Name <contributor@example.com>\r
+---\r
+\r
+An extra message for the patch email which will not be considered part\r
+of the commit message can be added here.\r
+\r
+Patch content inline or attached\r
+\r
+=== End of sample patch email message ===\r
+\r
+=== Notes for sample patch email ===\r
+\r
+* The first line of commit message is taken from the email's subject\r
+  line following [PATCH]. The remaining portion of the commit message\r
+  is the email's content until the '---' line.\r
+* git format-patch is one way to create this format\r
+\r
+=== Definitions for sample patch email ===\r
+\r
+* "CodeModule" is a short idenfier for the affected code.  For\r
+  example MdePkg, or MdeModulePkg UsbBusDxe.\r
+* "Brief-single-line-summary" is a short summary of the change.\r
+* The entire first line should be less than ~70 characters.\r
+* "Full-commit-message" a verbose multiple line comment describing\r
+  the change.  Each line should be less than ~70 characters.\r
+* "Contributed-under" explicitely states that the contribution is\r
+  made under the terms of the contribtion agreement.  This\r
+  agreement is included below in this document.\r
+* "Signed-off-by" is the contributor's signature identifying them\r
+  by their real/legal name and their email address.\r
+\r
+========================================\r
+= TianoCore Contribution Agreement 1.0 =\r
+========================================\r
+\r
+INTEL CORPORATION ("INTEL") MAKES AVAILABLE SOFTWARE, DOCUMENTATION,\r
+INFORMATION AND/OR OTHER MATERIALS FOR USE IN THE TIANOCORE OPEN SOURCE\r
+PROJECT (COLLECTIVELY "CONTENT"). USE OF THE CONTENT IS GOVERNED BY THE\r
+TERMS AND CONDITIONS OF THIS AGREEMENT BETWEEN YOU AND INTEL AND/OR THE\r
+TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR\r
+REFERENCED BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE OF THE\r
+CONTENT IS GOVERNED BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS\r
+OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\r
+BELOW. IF YOU DO NOT AGREE TO THE TERMS AND CONDITIONS OF THIS\r
+AGREEMENT AND THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE\r
+AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU MAY NOT\r
+USE THE CONTENT.\r
+\r
+Unless otherwise indicated, all Content made available on the TianoCore\r
+site is provided to you under the terms and conditions of the BSD\r
+License ("BSD"). A copy of the BSD License is available at\r
+http://opensource.org/licenses/bsd-license.php\r
+or when applicable, in the associated License.txt file.\r
+\r
+Certain other content may be made available under other licenses as\r
+indicated in or with such Content. (For example, in a License.txt file.)\r
+\r
+You accept and agree to the following terms and conditions for Your\r
+present and future Contributions submitted to TianoCore site. Except\r
+for the license granted to Intel hereunder, You reserve all right,\r
+title, and interest in and to Your Contributions.\r
+\r
+== SECTION 1: Definitions ==\r
+* "You" or "Contributor" shall mean the copyright owner or legal\r
+  entity authorized by the copyright owner that is making a\r
+  Contribution hereunder. All other entities that control, are\r
+  controlled by, or are under common control with that entity are\r
+  considered to be a single Contributor. For the purposes of this\r
+  definition, "control" means (i) the power, direct or indirect, to\r
+  cause the direction or management of such entity, whether by\r
+  contract or otherwise, or (ii) ownership of fifty percent (50%)\r
+  or more of the outstanding shares, or (iii) beneficial ownership\r
+  of such entity.\r
+* "Contribution" shall mean any original work of authorship,\r
+  including any modifications or additions to an existing work,\r
+  that is intentionally submitted by You to the TinaoCore site for\r
+  inclusion in, or documentation of, any of the Content. For the\r
+  purposes of this definition, "submitted" means any form of\r
+  electronic, verbal, or written communication sent to the\r
+  TianoCore site or its representatives, including but not limited\r
+  to communication on electronic mailing lists, source code\r
+  control systems, and issue tracking systems that are managed by,\r
+  or on behalf of, the TianoCore site for the purpose of\r
+  discussing and improving the Content, but excluding\r
+  communication that is conspicuously marked or otherwise\r
+  designated in writing by You as "Not a Contribution."\r
+\r
+== SECTION 2: License for Contributions ==\r
+* Contributor hereby agrees that redistribution and use of the\r
+  Contribution in source and binary forms, with or without\r
+  modification, are permitted provided that the following\r
+  conditions are met:\r
+** Redistributions of source code must retain the Contributor's\r
+   copyright notice, this list of conditions and the following\r
+   disclaimer.\r
+** Redistributions in binary form must reproduce the Contributor's\r
+   copyright notice, this list of conditions and the following\r
+   disclaimer in the documentation and/or other materials provided\r
+   with the distribution.\r
+* Disclaimer. None of the names of Contributor, Intel, or the names\r
+  of their respective contributors may be used to endorse or\r
+  promote products derived from this software without specific\r
+  prior written permission.\r
+* Contributor grants a license (with the right to sublicense) under\r
+  claims of Contributor's patents that Contributor can license that\r
+  are infringed by the Contribution (as delivered by Contributor) to\r
+  make, use, distribute, sell, offer for sale, and import the\r
+  Contribution and derivative works thereof solely to the minimum\r
+  extent necessary for licensee to exercise the granted copyright\r
+  license; this patent license applies solely to those portions of\r
+  the Contribution that are unmodified. No hardware per se is\r
+  licensed.\r
+* EXCEPT AS EXPRESSLY SET FORTH IN SECTION 3 BELOW, THE\r
+  CONTRIBUTION IS PROVIDED BY THE CONTRIBUTOR "AS IS" AND ANY\r
+  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,\r
+  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A\r
+  PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\r
+  CONTRIBUTOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r
+  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r
+  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
+  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR\r
+  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THE\r
+  CONTRIBUTION, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH\r
+  DAMAGE.\r
+\r
+== SECTION 3: Representations ==\r
+* You represent that You are legally entitled to grant the above\r
+  license. If your employer(s) has rights to intellectual property\r
+  that You create that includes Your Contributions, You represent\r
+  that You have received permission to make Contributions on behalf\r
+  of that employer, that Your employer has waived such rights for\r
+  Your Contributions.\r
+* You represent that each of Your Contributions is Your original\r
+  creation (see Section 4 for submissions on behalf of others).\r
+  You represent that Your Contribution submissions include complete\r
+  details of any third-party license or other restriction\r
+  (including, but not limited to, related patents and trademarks)\r
+  of which You are personally aware and which are associated with\r
+  any part of Your Contributions.\r
+\r
+== SECTION 4: Third Party Contributions ==\r
+* Should You wish to submit work that is not Your original creation,\r
+  You may submit it to TianoCore site separately from any\r
+  Contribution, identifying the complete details of its source\r
+  and of any license or other restriction (including, but not\r
+  limited to, related patents, trademarks, and license agreements)\r
+  of which You are personally aware, and conspicuously marking the\r
+  work as "Submitted on behalf of a third-party: [named here]".\r
+\r
+== SECTION 5: Miscellaneous ==\r
+* Applicable Laws. Any claims arising under or relating to this\r
+  Agreement shall be governed by the internal substantive laws of\r
+  the State of Delaware or federal courts located in Delaware,\r
+  without regard to principles of conflict of laws.\r
+* Language. This Agreement is in the English language only, which\r
+  language shall be controlling in all respects, and all versions\r
+  of this Agreement in any other language shall be for accommodation\r
+  only and shall not be binding. All communications and notices made\r
+  or given pursuant to this Agreement, and all documentation and\r
+  support to be provided, unless otherwise noted, shall be in the\r
+  English language.\r
+\r
diff --git a/IntelFsp2Pkg/FspNotifyPhase/FspNotifyPhasePeim.c b/IntelFsp2Pkg/FspNotifyPhase/FspNotifyPhasePeim.c
new file mode 100644 (file)
index 0000000..6acdeb3
--- /dev/null
@@ -0,0 +1,142 @@
+/** @file\r
+  Source file for FSP notify phase PEI module\r
+\r
+  Copyright (c) 2016, Intel Corporation. All rights reserved.\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
+#include "FspNotifyPhasePeim.h"\r
+\r
+/**\r
+\r
+   This function waits for FSP notify.\r
+    \r
+   @param This          Entry point for DXE IPL PPI.\r
+   @param PeiServices   General purpose services available to every PEIM.\r
+   @param HobList       Address to the Pei HOB list.\r
+   \r
+   @return EFI_SUCCESS              This function never returns.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+WaitForNotify (\r
+  IN CONST EFI_DXE_IPL_PPI *This,\r
+  IN EFI_PEI_SERVICES      **PeiServices,\r
+  IN EFI_PEI_HOB_POINTERS  HobList\r
+  );\r
+\r
+CONST EFI_DXE_IPL_PPI mDxeIplPpi = {\r
+  WaitForNotify\r
+};\r
+\r
+CONST EFI_PEI_PPI_DESCRIPTOR mInstallDxeIplPpi = {\r
+  EFI_PEI_PPI_DESCRIPTOR_PPI,\r
+  &gEfiDxeIplPpiGuid,\r
+  (VOID *) &mDxeIplPpi\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
+\r
+   This function waits for FSP notify.\r
+    \r
+   @param This          Entry point for DXE IPL PPI.\r
+   @param PeiServices   General purpose services available to every PEIM.\r
+   @param HobList       Address to the Pei HOB list.\r
+   \r
+   @return EFI_SUCCESS              This function never returns.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+WaitForNotify (\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
+  // End of PEI phase signal\r
+  //\r
+  Status = PeiServicesInstallPpi (&gEndOfPeiSignalPpi);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  //\r
+  // Give control back to BootLoader after FspSiliconInit\r
+  //\r
+  DEBUG ((DEBUG_INFO | DEBUG_INIT, "FSP is waiting for NOTIFY\n"));\r
+  FspSiliconInitDone ();\r
+\r
+  //\r
+  // BootLoader called FSP again through NotifyPhase\r
+  //\r
+  FspWaitForNotify ();\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
+\r
+/**\r
+  FSP notify phase PEI module entry point\r
+\r
+  @param[in]  FileHandle           Not used.\r
+  @param[in]  PeiServices          General purpose services available to every PEIM.\r
+\r
+  @retval     EFI_SUCCESS          The function completes successfully\r
+  @retval     EFI_OUT_OF_RESOURCES Insufficient resources to create database\r
+**/\r
+EFI_STATUS\r
+FspNotifyPhasePeimEntryPoint (\r
+  IN       EFI_PEI_FILE_HANDLE    FileHandle,\r
+  IN CONST EFI_PEI_SERVICES       **PeiServices\r
+  )\r
+{\r
+  EFI_STATUS                      Status;\r
+  VOID                            *OldDxeIplPpi;\r
+  EFI_PEI_PPI_DESCRIPTOR          *OldDescriptor;\r
+\r
+  DEBUG ((DEBUG_INFO | DEBUG_INIT, "The entry of FspNotificationPeim\n"));\r
+\r
+  //\r
+  // Locate old DXE IPL PPI\r
+  //\r
+  Status = PeiServicesLocatePpi (\r
+            &gEfiDxeIplPpiGuid,\r
+            0,\r
+            &OldDescriptor,\r
+            &OldDxeIplPpi\r
+            );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  //\r
+  // Re-install the DXE IPL PPI to wait for notify\r
+  //\r
+  Status = PeiServicesReInstallPpi (OldDescriptor, &mInstallDxeIplPpi);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
diff --git a/IntelFsp2Pkg/FspNotifyPhase/FspNotifyPhasePeim.h b/IntelFsp2Pkg/FspNotifyPhase/FspNotifyPhasePeim.h
new file mode 100644 (file)
index 0000000..6e2ae59
--- /dev/null
@@ -0,0 +1,23 @@
+/** @file\r
+  Header file for FSP notify phase PEI module\r
+\r
+  Copyright (c) 2016 Intel Corporation. All rights reserved.\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
+#ifndef _FSP_NOTIFY_PHASE_PEIM_H_\r
+#define _FSP_NOTIFY_PHASE_PEIM_H_\r
+\r
+#include <Library/PeiServicesLib.h>\r
+#include <Ppi/DxeIpl.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/FspPlatformLib.h>\r
+#include <Library/FspCommonLib.h>\r
+#include <Library/FspSwitchStackLib.h>\r
+#endif\r
diff --git a/IntelFsp2Pkg/FspNotifyPhase/FspNotifyPhasePeim.inf b/IntelFsp2Pkg/FspNotifyPhase/FspNotifyPhasePeim.inf
new file mode 100644 (file)
index 0000000..75f7ae5
--- /dev/null
@@ -0,0 +1,49 @@
+## @file\r
+# Component information file for the FSP notify phase PEI module.\r
+#\r
+#@copyright\r
+#  Copyright (c) 2016 Intel Corporation. All rights reserved.\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
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = FspNotifyPhasePeim\r
+  FILE_GUID                      = 29CBB005-C972-49F3-960F-292E2202CECD\r
+  MODULE_TYPE                    = PEIM\r
+  VERSION_STRING                 = 1.0\r
+  ENTRY_POINT                    = FspNotifyPhasePeimEntryPoint\r
+\r
+[Sources]\r
+  FspNotifyPhasePeim.h\r
+  FspNotifyPhasePeim.c\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  IntelFsp2Pkg/IntelFsp2Pkg.dec\r
+\r
+[LibraryClasses]\r
+  PeimEntryPoint\r
+  DebugLib\r
+  FspPlatformLib\r
+  FspCommonLib\r
+  FspSwitchStackLib\r
+\r
+[Ppis]\r
+  gEfiDxeIplPpiGuid                       ## PRODUCES\r
+  gEfiEndOfPeiSignalPpiGuid               ## PRODUCES\r
+\r
+[Protocols]\r
+  gEfiPciEnumerationCompleteProtocolGuid  ## PRODUCES\r
+\r
+[Guids]\r
+  gEfiEventReadyToBootGuid                ## PRODUCES ## Event\r
+\r
+[Depex]\r
+  gEfiDxeIplPpiGuid\r
diff --git a/IntelFsp2Pkg/FspSecCore/FspSecCoreM.inf b/IntelFsp2Pkg/FspSecCore/FspSecCoreM.inf
new file mode 100644 (file)
index 0000000..611fab2
--- /dev/null
@@ -0,0 +1,74 @@
+## @file\r
+#  Sec Core for FSP\r
+#\r
+#  Copyright (c) 2016, 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                      = FspSecCoreM\r
+  FILE_GUID                      = C2F9AE46-3437-4FEF-9CB1-9A568B282FEE\r
+  MODULE_TYPE                    = SEC\r
+  VERSION_STRING                 = 1.0\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
+  SecFspApiChk.c\r
+\r
+[Sources.IA32]\r
+  Ia32/Stack.nasm\r
+  Ia32/InitializeFpu.nasm\r
+  Ia32/FspApiEntryM.nasm\r
+  Ia32/FspApiEntryCommon.nasm\r
+  Ia32/FspHelper.nasm\r
+\r
+[Binaries.Ia32]\r
+  RAW|Vtf0/Bin/ResetVec.ia32.raw |GCC\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec  \r
+  IntelFsp2Pkg/IntelFsp2Pkg.dec\r
+\r
+[LibraryClasses]\r
+  BaseMemoryLib\r
+  DebugLib\r
+  BaseLib\r
+  PciCf8Lib\r
+  SerialPortLib\r
+  FspSwitchStackLib\r
+  FspCommonLib\r
+  FspSecPlatformLib\r
+\r
+[Pcd]\r
+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress           ## UNDEFINED\r
+  gIntelFsp2PkgTokenSpaceGuid.PcdGlobalDataPointerAddress      ## CONSUMES\r
+  gIntelFsp2PkgTokenSpaceGuid.PcdTemporaryRamBase              ## CONSUMES\r
+  gIntelFsp2PkgTokenSpaceGuid.PcdTemporaryRamSize              ## CONSUMES\r
+  gIntelFsp2PkgTokenSpaceGuid.PcdFspTemporaryRamSize           ## CONSUMES\r
+  gIntelFsp2PkgTokenSpaceGuid.PcdFspHeapSizePercentage         ## CONSUMES\r
+\r
+[FixedPcd]\r
+  gIntelFsp2PkgTokenSpaceGuid.PcdFspMaxPatchEntry              ## CONSUMES\r
+  gIntelFsp2PkgTokenSpaceGuid.PcdFspMaxPerfEntry               ## CONSUMES\r
+\r
+[Ppis]\r
+  gEfiTemporaryRamSupportPpiGuid                              ## PRODUCES\r
+\r
diff --git a/IntelFsp2Pkg/FspSecCore/FspSecCoreS.inf b/IntelFsp2Pkg/FspSecCore/FspSecCoreS.inf
new file mode 100644 (file)
index 0000000..8e1bb4a
--- /dev/null
@@ -0,0 +1,68 @@
+## @file\r
+#  Sec Core for FSP\r
+#\r
+#  Copyright (c) 2016, 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                      = FspSecCoreS\r
+  FILE_GUID                      = 53AB1ACD-EDB1-4E3A-A2C7-978D721D179D\r
+  MODULE_TYPE                    = SEC\r
+  VERSION_STRING                 = 1.0\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
+  SecFspApiChk.c\r
+\r
+[Sources.IA32]\r
+  Ia32/Stack.nasm\r
+  Ia32/FspApiEntryS.nasm\r
+  Ia32/FspApiEntryCommon.nasm\r
+  Ia32/FspHelper.nasm\r
+\r
+[Binaries.Ia32]\r
+  RAW|Vtf0/Bin/ResetVec.ia32.raw |GCC\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec  \r
+  IntelFsp2Pkg/IntelFsp2Pkg.dec\r
+\r
+[LibraryClasses]\r
+  BaseMemoryLib\r
+  DebugLib\r
+  BaseLib\r
+  PciCf8Lib\r
+  SerialPortLib\r
+  FspSwitchStackLib\r
+  FspCommonLib\r
+  FspSecPlatformLib\r
+\r
+[Pcd]\r
+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress           ## UNDEFINED\r
+  gIntelFsp2PkgTokenSpaceGuid.PcdGlobalDataPointerAddress      ## CONSUMES\r
+  gIntelFsp2PkgTokenSpaceGuid.PcdTemporaryRamBase              ## CONSUMES\r
+  gIntelFsp2PkgTokenSpaceGuid.PcdTemporaryRamSize              ## CONSUMES\r
+  gIntelFsp2PkgTokenSpaceGuid.PcdFspTemporaryRamSize           ## CONSUMES\r
+\r
+[FixedPcd]\r
+  gIntelFsp2PkgTokenSpaceGuid.PcdFspMaxPatchEntry              ## CONSUMES\r
+  gIntelFsp2PkgTokenSpaceGuid.PcdFspMaxPerfEntry               ## CONSUMES\r
+\r
+[Ppis]\r
+  gEfiTemporaryRamSupportPpiGuid                              ## PRODUCES\r
+\r
diff --git a/IntelFsp2Pkg/FspSecCore/FspSecCoreT.inf b/IntelFsp2Pkg/FspSecCore/FspSecCoreT.inf
new file mode 100644 (file)
index 0000000..cf6a191
--- /dev/null
@@ -0,0 +1,66 @@
+## @file\r
+#  Sec Core for FSP\r
+#\r
+#  Copyright (c) 2016, 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                      = FspSecCoreT\r
+  FILE_GUID                      = 5B94E419-C795-414D-A0D4-B80A877BE5FE\r
+  MODULE_TYPE                    = SEC\r
+  VERSION_STRING                 = 1.0\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
+\r
+\r
+[Sources.IA32]\r
+  Ia32/Stack.nasm\r
+  Ia32/InitializeFpu.nasm\r
+  Ia32/FspApiEntryT.nasm\r
+  Ia32/FspHelper.nasm\r
+\r
+[Binaries.Ia32]\r
+  RAW|Vtf0/Bin/ResetVec.ia32.raw |GCC\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec\r
+  IntelFsp2Pkg/IntelFsp2Pkg.dec\r
+\r
+[LibraryClasses]\r
+  BaseMemoryLib\r
+  DebugLib\r
+  BaseLib\r
+  PciCf8Lib\r
+  SerialPortLib\r
+  FspSwitchStackLib\r
+  FspCommonLib\r
+  FspSecPlatformLib\r
+\r
+[Pcd]\r
+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress           ## UNDEFINED\r
+  gIntelFsp2PkgTokenSpaceGuid.PcdTemporaryRamBase              ## CONSUMES\r
+  gIntelFsp2PkgTokenSpaceGuid.PcdTemporaryRamSize              ## CONSUMES\r
+  gIntelFsp2PkgTokenSpaceGuid.PcdFspReservedBufferSize         ## CONSUMES\r
+\r
+[FixedPcd]\r
+  gIntelFsp2PkgTokenSpaceGuid.PcdFspMaxPatchEntry              ## CONSUMES\r
+  gIntelFsp2PkgTokenSpaceGuid.PcdFspMaxPerfEntry               ## CONSUMES\r
+\r
+[Ppis]\r
+  gEfiTemporaryRamSupportPpiGuid                              ## PRODUCES\r
diff --git a/IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryCommon.nasm b/IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryCommon.nasm
new file mode 100644 (file)
index 0000000..c48a956
--- /dev/null
@@ -0,0 +1,76 @@
+;; @file\r
+;  Provide FSP API entry points.\r
+;\r
+; Copyright (c) 2016, 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
+    SECTION .text\r
+\r
+;\r
+; Following functions will be provided in C\r
+;\r
+extern ASM_PFX(Loader2PeiSwitchStack)\r
+extern ASM_PFX(FspApiCallingCheck)\r
+\r
+;\r
+; Following functions will be provided in ASM\r
+;\r
+extern ASM_PFX(FspApiCommonContinue)\r
+extern ASM_PFX(AsmGetFspInfoHeader)\r
+\r
+;----------------------------------------------------------------------------\r
+; FspApiCommon API\r
+;\r
+; This is the FSP API common entry point to resume the FSP execution\r
+;\r
+;----------------------------------------------------------------------------\r
+global ASM_PFX(FspApiCommon)\r
+ASM_PFX(FspApiCommon):\r
+  ;\r
+  ; EAX holds the API index\r
+  ;\r
+\r
+  ;\r
+  ; Stack must be ready\r
+  ;\r
+  push   eax\r
+  add    esp, 4\r
+  cmp    eax, dword  [esp - 4]\r
+  jz     FspApiCommon1\r
+  mov    eax, 080000003h\r
+  jmp    exit\r
+\r
+FspApiCommon1:\r
+  ;\r
+  ; Verify the calling condition\r
+  ;\r
+  pushad\r
+  push   DWORD [esp + (4 * 8 + 4)]  ; push ApiParam\r
+  push   eax                ; push ApiIdx\r
+  call   ASM_PFX(FspApiCallingCheck)\r
+  add    esp, 8\r
+  cmp    eax, 0\r
+  jz     FspApiCommon2\r
+  mov    dword  [esp + (4 * 7)], eax\r
+  popad\r
+exit:\r
+  ret\r
+\r
+FspApiCommon2:\r
+  popad\r
+  cmp    eax, 3   ; FspMemoryInit API\r
+  jz     FspApiCommon3\r
+\r
+  call   ASM_PFX(AsmGetFspInfoHeader)\r
+  jmp    ASM_PFX(Loader2PeiSwitchStack)\r
+\r
+FspApiCommon3:\r
+  jmp    ASM_PFX(FspApiCommonContinue)\r
+\r
diff --git a/IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryM.nasm b/IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryM.nasm
new file mode 100644 (file)
index 0000000..9744e16
--- /dev/null
@@ -0,0 +1,202 @@
+;; @file\r
+;  Provide FSP API entry points.\r
+;\r
+; Copyright (c) 2016, 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
+    SECTION .text\r
+\r
+;\r
+; Following are fixed PCDs\r
+;\r
+extern   ASM_PFX(PcdGet32(PcdTemporaryRamBase))\r
+extern   ASM_PFX(PcdGet32(PcdTemporaryRamSize))\r
+extern   ASM_PFX(PcdGet32(PcdFspTemporaryRamSize))\r
+\r
+struc FSPM_UPD_COMMON\r
+    ; FSP_UPD_HEADER {\r
+    .FspUpdHeader:            resd    8\r
+    ; }\r
+    ; FSPM_ARCH_UPD {\r
+    .Revision:                resb    1\r
+    .Reserved:                resb    3\r
+    .NvsBufferPtr:            resd    1\r
+    .StackBase:               resd    1\r
+    .StackSize:               resd    1\r
+    .BootLoaderTolumSize:     resd    1\r
+    .BootMode:                resd    1\r
+    .Reserved1:               resb    8\r
+    ; }\r
+    .size:\r
+endstruc\r
+\r
+;\r
+; Following functions will be provided in C\r
+;\r
+extern ASM_PFX(SecStartup)\r
+extern ASM_PFX(FspApiCommon)\r
+\r
+;\r
+; Following functions will be provided in PlatformSecLib\r
+;\r
+extern ASM_PFX(AsmGetFspBaseAddress)\r
+extern ASM_PFX(AsmGetFspInfoHeader)\r
+\r
+API_PARAM1_OFFSET            EQU   34h  ; ApiParam1 [ sub esp,8 + pushad + pushfd + push eax + call]\r
+FSP_HEADER_IMGBASE_OFFSET    EQU   1Ch\r
+FSP_HEADER_CFGREG_OFFSET     EQU   24h\r
+\r
+;----------------------------------------------------------------------------\r
+; FspMemoryInit API\r
+;\r
+; This FSP API is called after TempRamInit and initializes the memory.\r
+;\r
+;----------------------------------------------------------------------------\r
+global ASM_PFX(FspMemoryInitApi)\r
+ASM_PFX(FspMemoryInitApi):\r
+  mov    eax,  3 ; FSP_API_INDEX.FspMemoryInitApiIndex\r
+  jmp    ASM_PFX(FspApiCommon)\r
+\r
+;----------------------------------------------------------------------------\r
+; TempRamExitApi API\r
+;\r
+; This API tears down temporary RAM\r
+;\r
+;----------------------------------------------------------------------------\r
+global ASM_PFX(TempRamExitApi)\r
+ASM_PFX(TempRamExitApi):\r
+  mov    eax,  4 ; FSP_API_INDEX.TempRamExitApiIndex\r
+  jmp    ASM_PFX(FspApiCommon)\r
+\r
+;----------------------------------------------------------------------------\r
+; FspApiCommonContinue API\r
+;\r
+; This is the FSP API common entry point to resume the FSP execution\r
+;\r
+;----------------------------------------------------------------------------\r
+global ASM_PFX(FspApiCommonContinue)\r
+ASM_PFX(FspApiCommonContinue):\r
+  ;\r
+  ; EAX holds the API index\r
+  ;\r
+\r
+  ;\r
+  ; FspMemoryInit API setup the initial stack frame\r
+  ;\r
+\r
+  ;\r
+  ; Place holder to store the FspInfoHeader pointer\r
+  ;\r
+  push   eax\r
+\r
+  ;\r
+  ; Update the FspInfoHeader pointer\r
+  ;\r
+  push   eax\r
+  call   ASM_PFX(AsmGetFspInfoHeader)\r
+  mov    [esp + 4], eax\r
+  pop    eax\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    [esp]\r
+\r
+\r
+  ;  Get Stackbase and StackSize from FSPM_UPD Param \r
+  mov    edx, [esp + API_PARAM1_OFFSET] \r
+  cmp    edx, 0\r
+  jnz    FspStackSetup  \r
+\r
+  ; Get UPD default values if FspmUpdDataPtr (ApiParam1) is null\r
+  push   eax\r
+  call   ASM_PFX(AsmGetFspInfoHeader)\r
+  mov    edx, [eax + FSP_HEADER_IMGBASE_OFFSET]\r
+  add    edx, [eax + FSP_HEADER_CFGREG_OFFSET]\r
+  pop    eax\r
+  \r
+  FspStackSetup:\r
+  mov    edi, [edx + FSPM_UPD_COMMON.StackBase]\r
+  mov    ecx, [edx + FSPM_UPD_COMMON.StackSize]\r
+  add    edi, ecx\r
+  ;\r
+  ; Setup new FSP stack\r
+  ;\r
+  xchg    edi, esp                                ; Exchange edi and esp, edi will be assigned to the current esp pointer and esp will be Stack base + Stack size\r
+  mov     ebx, esp                                ; Put Stack base + Stack size in ebx\r
+\r
+  ;\r
+  ; Pass the API Idx to SecStartup\r
+  ;\r
+  push    eax\r
+\r
+  ;\r
+  ; Pass the BootLoader stack to SecStartup\r
+  ;\r
+  push    edi\r
+\r
+  ;\r
+  ; Pass entry point of the PEI core\r
+  ;\r
+  call    ASM_PFX(AsmGetFspBaseAddress)\r
+  mov     edi, eax\r
+  call    ASM_PFX(AsmGetPeiCoreOffset)\r
+  add     edi, eax\r
+  push    edi\r
+\r
+  ;\r
+  ; Pass BFV into the PEI Core\r
+  ; It uses relative address to calucate the actual boot FV base\r
+  ; For FSP implementation with single FV, PcdFspBootFirmwareVolumeBase 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(AsmGetFspBaseAddress)\r
+  push    eax\r
+\r
+  ;\r
+  ; Pass stack base and size into the PEI Core\r
+  ;\r
+  sub     ebx, ecx            ; Stack base + Stack size - Stack size\r
+  push    ebx\r
+  push    ecx\r
+\r
+  ;\r
+  ; Pass Control into the PEI Core\r
+  ;\r
+  call    ASM_PFX(SecStartup)\r
+  add     esp, 4\r
+exit:\r
+  ret\r
+\r
+global ASM_PFX(FspPeiCoreEntryOff)\r
+ASM_PFX(FspPeiCoreEntryOff):\r
+   ;\r
+   ; This value will be pached by the build script\r
+   ;\r
+   DD    0x12345678\r
+\r
+global ASM_PFX(AsmGetPeiCoreOffset)\r
+ASM_PFX(AsmGetPeiCoreOffset):\r
+   mov   eax, dword [ASM_PFX(FspPeiCoreEntryOff)]\r
+   ret\r
+\r
+;----------------------------------------------------------------------------\r
+; Module Entrypoint API\r
+;----------------------------------------------------------------------------\r
+global ASM_PFX(_ModuleEntryPoint)\r
+ASM_PFX(_ModuleEntryPoint):\r
+  jmp $\r
diff --git a/IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryS.nasm b/IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryS.nasm
new file mode 100644 (file)
index 0000000..cdc1149
--- /dev/null
@@ -0,0 +1,62 @@
+;; @file\r
+;  Provide FSP API entry points.\r
+;\r
+; Copyright (c) 2016, 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
+    SECTION .text\r
+\r
+;\r
+; Following functions will be provided in C\r
+;\r
+extern ASM_PFX(FspApiCommon)\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
+global ASM_PFX(NotifyPhaseApi)\r
+ASM_PFX(NotifyPhaseApi):\r
+  mov    eax,  2 ; FSP_API_INDEX.NotifyPhaseApiIndex\r
+  jmp    ASM_PFX(FspApiCommon)\r
+\r
+;----------------------------------------------------------------------------\r
+; FspSiliconInit API\r
+;\r
+; This FSP API initializes the CPU and the chipset including the IO\r
+; controllers in the chipset to enable normal operation of these devices.\r
+;\r
+;----------------------------------------------------------------------------\r
+global ASM_PFX(FspSiliconInitApi)\r
+ASM_PFX(FspSiliconInitApi):\r
+  mov    eax,  5 ; FSP_API_INDEX.FspSiliconInitApiIndex\r
+  jmp    ASM_PFX(FspApiCommon)\r
+\r
+;----------------------------------------------------------------------------\r
+; FspApiCommonContinue API\r
+;\r
+; This is the FSP API common entry point to resume the FSP execution\r
+;\r
+;----------------------------------------------------------------------------\r
+global ASM_PFX(FspApiCommonContinue)\r
+ASM_PFX(FspApiCommonContinue):\r
+  jmp    $\r
+  ret\r
+\r
+;----------------------------------------------------------------------------\r
+; Module Entrypoint API\r
+;----------------------------------------------------------------------------\r
+global ASM_PFX(_ModuleEntryPoint)\r
+ASM_PFX(_ModuleEntryPoint):\r
+  jmp $\r
+\r
diff --git a/IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryT.nasm b/IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryT.nasm
new file mode 100644 (file)
index 0000000..55ee85a
--- /dev/null
@@ -0,0 +1,469 @@
+;; @file\r
+;  Provide FSP API entry points.\r
+;\r
+; Copyright (c) 2016, 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
+    SECTION .text\r
+\r
+%include    "SaveRestoreSseNasm.inc"\r
+%include    "MicrocodeLoadNasm.inc"\r
+\r
+;\r
+; Following are fixed PCDs\r
+;\r
+extern   ASM_PFX(PcdGet32 (PcdTemporaryRamBase))\r
+extern   ASM_PFX(PcdGet32 (PcdTemporaryRamSize))\r
+extern   ASM_PFX(PcdGet32 (PcdFspReservedBufferSize))\r
+\r
+;\r
+; Following functions will be provided in PlatformSecLib\r
+;\r
+extern ASM_PFX(AsmGetFspBaseAddress)\r
+extern ASM_PFX(AsmGetFspInfoHeader)\r
+;extern ASM_PFX(LoadMicrocode)    ; @todo: needs a weak implementation\r
+extern ASM_PFX(SecPlatformInit)   ; @todo: needs a weak implementation\r
+extern ASM_PFX(SecCarInit)\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
+; @todo: These structures are moved from MicrocodeLoadNasm.inc to avoid\r
+;        build error. This needs to be fixed later on.\r
+;\r
+struc MicrocodeHdr\r
+    .MicrocodeHdrVersion:      resd    1\r
+    .MicrocodeHdrRevision:     resd    1\r
+    .MicrocodeHdrDate:         resd    1\r
+    .MicrocodeHdrProcessor:    resd    1\r
+    .MicrocodeHdrChecksum:     resd    1\r
+    .MicrocodeHdrLoader:       resd    1\r
+    .MicrocodeHdrFlags:        resd    1\r
+    .MicrocodeHdrDataSize:     resd    1\r
+    .MicrocodeHdrTotalSize:    resd    1\r
+    .MicrocodeHdrRsvd:         resd    3\r
+    .size:\r
+endstruc\r
+\r
+struc ExtSigHdr\r
+    .ExtSigHdrCount:          resd    1\r
+    .ExtSigHdrChecksum:       resd    1\r
+    .ExtSigHdrRsvd:           resd    3\r
+    .size:\r
+endstruc\r
+\r
+struc ExtSig\r
+    .ExtSigProcessor:         resd    1\r
+    .ExtSigFlags:             resd    1\r
+    .ExtSigChecksum:          resd    1\r
+    .size:\r
+endstruc\r
+\r
+struc LoadMicrocodeParams\r
+    ; FSP_UPD_HEADER {\r
+    .FspUpdHeader:            resd    8\r
+    ; }\r
+    ; FSPT_CORE_UPD {\r
+    .MicrocodeCodeAddr:       resd    1\r
+    .MicrocodeCodeSize:       resd    1\r
+    .CodeRegionBase:          resd    1\r
+    .CodeRegionSize:          resd    1\r
+    ; }\r
+    .size:\r
+endstruc\r
+\r
+\r
+;\r
+; Define SSE macros\r
+;\r
+;\r
+;args 1: ReturnAddress  2:MmxRegister\r
+;\r
+%macro LOAD_MMX_EXT 2\r
+  mov     esi, %1\r
+  movd    %2, esi              ; save ReturnAddress into MMX\r
+%endmacro\r
+\r
+;\r
+;args 1: RoutineLabel  2:MmxRegister\r
+;\r
+%macro CALL_MMX_EXT  2\r
+  mov     esi, %%ReturnAddress\r
+  movd    %2, esi              ; save ReturnAddress into MMX\r
+  jmp     %1\r
+%%ReturnAddress:\r
+%endmacro\r
+\r
+;\r
+;arg 1:MmxRegister\r
+;\r
+%macro RET_ESI_EXT   1\r
+  movd    esi, %1              ; move ReturnAddress from MMX to ESI\r
+  jmp     esi\r
+%endmacro\r
+\r
+;\r
+;arg 1:RoutineLabel\r
+;\r
+%macro CALL_MMX   1\r
+         CALL_MMX_EXT  %1, mm7\r
+%endmacro\r
+\r
+%macro RET_ESI 0\r
+         RET_ESI_EXT   mm7\r
+%endmacro\r
+\r
+;\r
+; @todo: The strong/weak implementation does not work.\r
+;        This needs to be reviewed later.\r
+;\r
+;------------------------------------------------------------------------------\r
+;\r
+;;global ASM_PFX(SecPlatformInitDefault)\r
+;ASM_PFX(SecPlatformInitDefault):\r
+;   ; Inputs:\r
+;   ;   mm7 -> 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
+;   movd  ebp, mm7\r
+;\r
+;   xor   eax, eax\r
+;Exit1:\r
+;   jmp   ebp\r
+\r
+;------------------------------------------------------------------------------\r
+global ASM_PFX(LoadMicrocodeDefault)\r
+ASM_PFX(LoadMicrocodeDefault):\r
+   ; Inputs:\r
+   ;   esp -> LoadMicrocodeParams 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
+   movd   ebp, mm7\r
+\r
+   cmp    esp, 0\r
+   jz     ParamError\r
+   mov    eax, dword [esp + 4]    ; Parameter pointer\r
+   cmp    eax, 0\r
+   jz     ParamError\r
+   mov    esp, eax\r
+   \r
+   mov    esi, dword [esp + LoadMicrocodeParams.MicrocodeCodeAddr]\r
+   cmp    esi, 0\r
+   jnz    CheckMainHeader\r
+\r
+ParamError:\r
+   mov    eax, 080000002h\r
+   jmp    Exit2\r
+\r
+CheckMainHeader:\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                          ; shift (50d-32d=18d=0x12) bits\r
+   and   ecx, 7h                             ; platform id at bit[52..50]\r
+   mov   edx, 1\r
+   shl   edx, cl\r
+\r
+   ; Current register usage\r
+   ; esp -> stack with parameters\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 1\r
+   cmp   dword [esi + MicrocodeHdr.MicrocodeHdrVersion], eax\r
+   jne   AdvanceFixedSize\r
+   cmp   dword [esi + MicrocodeHdr.MicrocodeHdrLoader], eax\r
+   jne   AdvanceFixedSize\r
+\r
+   ; Check if signature and plaform ID match\r
+   cmp   ebx, dword [esi + MicrocodeHdr.MicrocodeHdrProcessor]\r
+   jne   LoadMicrocodeDefault1\r
+   test  edx, dword [esi + MicrocodeHdr.MicrocodeHdrFlags ]\r
+   jnz   LoadCheck  ; Jif signature and platform ID match\r
+\r
+LoadMicrocodeDefault1:\r
+   ; Check if extended header exists\r
+   ; First check if MicrocodeHdrTotalSize and MicrocodeHdrDataSize are valid\r
+   xor   eax, eax\r
+   cmp   dword [esi + MicrocodeHdr.MicrocodeHdrTotalSize], eax\r
+   je    NextMicrocode\r
+   cmp   dword [esi + MicrocodeHdr.MicrocodeHdrDataSize], eax\r
+   je    NextMicrocode\r
+\r
+   ; Then verify total size - sizeof header > data size\r
+   mov   ecx, dword [esi + MicrocodeHdr.MicrocodeHdrTotalSize]\r
+   sub   ecx, MicrocodeHdr.size\r
+   cmp   ecx, dword [esi + MicrocodeHdr.MicrocodeHdrDataSize]\r
+   jng   NextMicrocode    ; Jif extended header does not exist\r
+\r
+   ; Set edi -> extended header\r
+   mov   edi, esi\r
+   add   edi, MicrocodeHdr.size\r
+   add   edi, dword [esi + MicrocodeHdr.MicrocodeHdrDataSize]\r
+\r
+   ; Get count of extended structures\r
+   mov   ecx, dword [edi + ExtSigHdr.ExtSigHdrCount]\r
+\r
+   ; Move pointer to first signature structure\r
+   add   edi, ExtSigHdr.size\r
+\r
+CheckExtSig:\r
+   ; Check if extended signature and platform ID match\r
+   cmp   dword [edi + ExtSig.ExtSigProcessor], ebx\r
+   jne   LoadMicrocodeDefault2\r
+   test  dword [edi + ExtSig.ExtSigFlags], edx\r
+   jnz   LoadCheck      ; Jif signature and platform ID match\r
+LoadMicrocodeDefault2:\r
+   ; Check if any more extended signatures exist\r
+   add   edi, ExtSig.size\r
+   loop  CheckExtSig\r
+\r
+NextMicrocode:\r
+   ; Advance just after end of this microcode\r
+   xor   eax, eax\r
+   cmp   dword [esi + MicrocodeHdr.MicrocodeHdrTotalSize], eax\r
+   je    LoadMicrocodeDefault3\r
+   add   esi, dword [esi + MicrocodeHdr.MicrocodeHdrTotalSize]\r
+   jmp   CheckAddress\r
+LoadMicrocodeDefault3:\r
+   add   esi, dword  2048\r
+   jmp   CheckAddress\r
+\r
+AdvanceFixedSize:\r
+   ; Advance by 4X dwords\r
+   add   esi, dword  1024\r
+\r
+CheckAddress:\r
+   ; Is valid Microcode start point ?\r
+   cmp   dword [esi + MicrocodeHdr.MicrocodeHdrVersion], 0ffffffffh\r
+   jz    Done\r
+\r
+   ; Is automatic size detection ?\r
+   mov   eax, dword [esp + LoadMicrocodeParams.MicrocodeCodeSize]\r
+   cmp   eax, 0ffffffffh\r
+   jz    LoadMicrocodeDefault4\r
+\r
+   ; Address >= microcode region address + microcode region size?\r
+   add   eax, dword [esp + LoadMicrocodeParams.MicrocodeCodeAddr]\r
+   cmp   esi, eax\r
+   jae   Done        ;Jif address is outside of microcode region\r
+   jmp   CheckMainHeader\r
+\r
+LoadMicrocodeDefault4:\r
+LoadCheck:\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   dword [esi + MicrocodeHdr.MicrocodeHdrRevision], edx\r
+   je    Continue\r
+\r
+LoadMicrocode:\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, MicrocodeHdr.size\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   NextMicrocode\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   Exit2\r
+   mov   eax, 08000000Eh\r
+\r
+Exit2:\r
+   jmp   ebp\r
+\r
+\r
+global ASM_PFX(EstablishStackFsp)\r
+ASM_PFX(EstablishStackFsp):\r
+  ;\r
+  ; Save parameter pointer in edx\r
+  ;\r
+  mov       edx, dword [esp + 4]\r
+\r
+  ;\r
+  ; Enable FSP STACK\r
+  ;\r
+  mov       esp, DWORD [ASM_PFX(PcdGet32 (PcdTemporaryRamBase))]\r
+  add       esp, DWORD [ASM_PFX(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 [edx + 2Ch]    ; Code size       sizeof(FSPT_UPD_COMMON) + 12\r
+  push      dword [edx + 28h]    ; Code base       sizeof(FSPT_UPD_COMMON) + 8\r
+  push      dword [edx + 24h]    ; Microcode size  sizeof(FSPT_UPD_COMMON) + 4\r
+  push      dword [edx + 20h]    ; Microcode base  sizeof(FSPT_UPD_COMMON) + 0\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_EDX\r
+  push      edx\r
+  LOAD_EAX\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,  [ASM_PFX(PcdGet32 (PcdTemporaryRamBase))]\r
+  mov       edx, ecx\r
+  add       edx,  [ASM_PFX(PcdGet32 (PcdTemporaryRamSize))]\r
+  sub       edx,  [ASM_PFX(PcdGet32 (PcdFspReservedBufferSize))]\r
+\r
+  cmp       ecx, edx        ;If PcdFspReservedBufferSize >= PcdTemporaryRamSize, then error.\r
+  jb        EstablishStackFspSuccess\r
+  mov       eax, 80000003h  ;EFI_UNSUPPORTED\r
+  jmp       EstablishStackFspExit\r
+EstablishStackFspSuccess:\r
+  xor       eax, eax\r
+\r
+EstablishStackFspExit:\r
+  RET_ESI\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
+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 XMM6\r
+  ;\r
+  rdtsc\r
+  SAVE_EAX\r
+  SAVE_EDX\r
+\r
+  ;\r
+  ; Check Parameter\r
+  ;\r
+  mov       eax, dword [esp + 4]\r
+  cmp       eax, 0\r
+  mov       eax, 80000002h\r
+  jz        TempRamInitExit\r
+\r
+  ;\r
+  ; Sec Platform Init\r
+  ;\r
+  CALL_MMX  ASM_PFX(SecPlatformInit)\r
+  cmp       eax, 0\r
+  jnz       TempRamInitExit\r
+\r
+  ; Load microcode\r
+  LOAD_ESP\r
+  CALL_MMX  ASM_PFX(LoadMicrocodeDefault)\r
+  SXMMN     xmm6, 3, eax            ;Save microcode return status in ECX-SLOT 3 in xmm6.\r
+  ;@note If return value eax is not 0, microcode did not load, but continue and attempt to boot.\r
+\r
+  ; Call Sec CAR Init\r
+  LOAD_ESP\r
+  CALL_MMX  ASM_PFX(SecCarInit)\r
+  cmp       eax, 0\r
+  jnz       TempRamInitExit\r
+\r
+  LOAD_ESP\r
+  CALL_MMX  ASM_PFX(EstablishStackFsp)\r
+  cmp       eax, 0\r
+  jnz       TempRamInitExit\r
+\r
+  LXMMN      xmm6, eax, 3  ;Restore microcode status if no CAR init error from ECX-SLOT 3 in xmm6.\r
+\r
+TempRamInitExit:\r
+   mov      bl, al                  ; save al data in bl\r
+   mov      al, 07Fh                ; API exit postcode 7f\r
+   out      080h, al\r
+   mov      al, bl                  ; restore al data from bl\r
+\r
+  ;\r
+  ; Load EBP, EBX, ESI, EDI & ESP from XMM7 & XMM6\r
+  ;\r
+  LOAD_REGS\r
+  ret\r
+\r
+;----------------------------------------------------------------------------\r
+; Module Entrypoint API\r
+;----------------------------------------------------------------------------\r
+global ASM_PFX(_ModuleEntryPoint)\r
+ASM_PFX(_ModuleEntryPoint):\r
+  jmp $\r
diff --git a/IntelFsp2Pkg/FspSecCore/Ia32/FspHelper.nasm b/IntelFsp2Pkg/FspSecCore/Ia32/FspHelper.nasm
new file mode 100644 (file)
index 0000000..00e953b
--- /dev/null
@@ -0,0 +1,35 @@
+;; @file\r
+;  Provide FSP helper function.\r
+;\r
+; Copyright (c) 2015 - 2016, 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
+    SECTION .text\r
+\r
+global ASM_PFX(FspInfoHeaderRelativeOff)\r
+ASM_PFX(FspInfoHeaderRelativeOff):\r
+   ;\r
+   ; This value will be pached by the build script\r
+   ;\r
+   DD    0x12345678\r
+\r
+global ASM_PFX(AsmGetFspBaseAddress)\r
+ASM_PFX(AsmGetFspBaseAddress):\r
+   mov   eax, ASM_PFX(AsmGetFspInfoHeader)\r
+   sub   eax, dword [ASM_PFX(FspInfoHeaderRelativeOff)]\r
+   add   eax, 0x1C\r
+   mov   eax, dword [eax]\r
+   ret\r
+\r
+global ASM_PFX(AsmGetFspInfoHeader)\r
+ASM_PFX(AsmGetFspInfoHeader):\r
+   mov   eax, ASM_PFX(AsmGetFspInfoHeader)\r
+   sub   eax, dword [ASM_PFX(FspInfoHeaderRelativeOff)]\r
+   ret\r
diff --git a/IntelFsp2Pkg/FspSecCore/Ia32/InitializeFpu.nasm b/IntelFsp2Pkg/FspSecCore/Ia32/InitializeFpu.nasm
new file mode 100644 (file)
index 0000000..cc87e89
--- /dev/null
@@ -0,0 +1,78 @@
+;------------------------------------------------------------------------------\r
+;\r
+; Copyright (c) 2015, 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
+SECTION .data\r
+;\r
+; Float control word initial value:\r
+; all exceptions masked, double-precision, round-to-nearest\r
+;\r
+ASM_PFX(mFpuControlWord):\r
+    dw    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):\r
+     dd     0x01F80\r
+\r
+SECTION .text\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
+global ASM_PFX(InitializeFloatingPointUnits)\r
+ASM_PFX(InitializeFloatingPointUnits):\r
+\r
+\r
+    push    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
+    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 [ASM_PFX(mMmxControlWord)]\r
+Done:\r
+    pop     ebx\r
+\r
+    ret\r
diff --git a/IntelFsp2Pkg/FspSecCore/Ia32/MicrocodeLoadNasm.inc b/IntelFsp2Pkg/FspSecCore/Ia32/MicrocodeLoadNasm.inc
new file mode 100644 (file)
index 0000000..1663a85
--- /dev/null
@@ -0,0 +1,16 @@
+;; @file\r
+;\r
+;@copyright\r
+; Copyright (c) 2015 - 2016, 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
+MSR_IA32_PLATFORM_ID        equ     000000017h\r
+MSR_IA32_BIOS_UPDT_TRIG     equ     000000079h\r
+MSR_IA32_BIOS_SIGN_ID       equ     00000008bh
\ No newline at end of file
diff --git a/IntelFsp2Pkg/FspSecCore/Ia32/SaveRestoreSseNasm.inc b/IntelFsp2Pkg/FspSecCore/Ia32/SaveRestoreSseNasm.inc
new file mode 100644 (file)
index 0000000..ae0a93d
--- /dev/null
@@ -0,0 +1,187 @@
+;------------------------------------------------------------------------------\r
+;\r
+; Copyright (c) 2015, 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
+; args 1:XMM, 2:IDX, 3:REG\r
+%macro SXMMN           3\r
+             pinsrd  %1, %3, (%2 & 3)\r
+             %endmacro\r
+\r
+;\r
+;args 1:XMM, 2:REG, 3:IDX\r
+;\r
+%macro LXMMN           3\r
+             pextrd  %2, %1, (%3 & 3)\r
+             %endmacro\r
+%else\r
+;\r
+; Define SSE macros using SSE 2 instructions\r
+; args 1:XMM, 2:IDX, 3:REG\r
+%macro SXMMN       3\r
+             pinsrw  %1, %3, (%2 & 3) * 2\r
+             ror     %3, 16\r
+             pinsrw  %1, %3, (%2 & 3) * 2 + 1\r
+             rol     %3, 16\r
+             %endmacro\r
+\r
+;\r
+;args 1:XMM, 2:REG,  3:IDX\r
+;\r
+%macro LXMMN    3\r
+             pshufd  %1, %1,  ((0E4E4E4h >> (%3 * 2))  & 0FFh)\r
+             movd    %2, %1\r
+             pshufd  %1, %1,  ((0E4E4E4h >> (%3 * 2 + (%3 & 1) * 4)) & 0FFh)\r
+             %endmacro\r
+%endif\r
+\r
+;\r
+; XMM7 to save/restore EBP, EBX, ESI, EDI\r
+;\r
+%macro SAVE_REGS   0\r
+  SXMMN      xmm7, 0, ebp\r
+  SXMMN      xmm7, 1, ebx\r
+  SXMMN      xmm7, 2, esi\r
+  SXMMN      xmm7, 3, edi\r
+  SAVE_ESP\r
+             %endmacro\r
+\r
+%macro LOAD_REGS    0\r
+  LXMMN      xmm7, ebp, 0\r
+  LXMMN      xmm7, ebx, 1\r
+  LXMMN      xmm7, esi, 2\r
+  LXMMN      xmm7, edi, 3\r
+  LOAD_ESP\r
+             %endmacro\r
+\r
+;\r
+; XMM6 to save/restore EAX, EDX, ECX, ESP\r
+;\r
+%macro LOAD_EAX     0\r
+  LXMMN      xmm6, eax, 1\r
+             %endmacro\r
+\r
+%macro SAVE_EAX     0\r
+  SXMMN      xmm6, 1, eax\r
+             %endmacro\r
+\r
+%macro LOAD_EDX     0\r
+  LXMMN      xmm6, edx, 2\r
+             %endmacro\r
+\r
+%macro SAVE_EDX     0\r
+  SXMMN      xmm6, 2, edx\r
+             %endmacro\r
+\r
+%macro SAVE_ECX     0\r
+  SXMMN      xmm6, 3, ecx\r
+             %endmacro\r
+\r
+%macro LOAD_ECX     0\r
+  LXMMN      xmm6, ecx, 3\r
+             %endmacro\r
+\r
+%macro SAVE_ESP     0\r
+  SXMMN      xmm6, 0, esp\r
+             %endmacro\r
+\r
+%macro LOAD_ESP     0\r
+  movd       esp,  xmm6\r
+             %endmacro\r
+;\r
+; XMM5 for calling stack\r
+; arg 1:Entry\r
+%macro CALL_XMM       1\r
+             mov     esi, %%ReturnAddress\r
+             pslldq  xmm5, 4\r
+%ifdef USE_SSE41_FLAG\r
+             pinsrd  xmm5, esi, 0\r
+%else\r
+             pinsrw  xmm5, esi, 0\r
+             ror     esi,  16\r
+             pinsrw  xmm5, esi, 1\r
+%endif\r
+             mov     esi,  %1\r
+             jmp     esi\r
+%%ReturnAddress:\r
+             %endmacro\r
+\r
+%macro RET_XMM       0\r
+             movd    esi, xmm5\r
+             psrldq  xmm5, 4\r
+             jmp     esi\r
+             %endmacro\r
+\r
+%macro ENABLE_SSE   0\r
+            ;\r
+            ; Initialize floating point units\r
+            ;\r
+            jmp     NextAddress\r
+align 4\r
+            ;\r
+            ; Float control word initial value:\r
+            ; all exceptions masked, double-precision, round-to-nearest\r
+            ;\r
+FpuControlWord       DW      027Fh\r
+            ;\r
+            ; Multimedia-extensions control word:\r
+            ; all exceptions masked, round-to-nearest, flush to zero for masked underflow\r
+            ;\r
+MmxControlWord       DD      01F80h\r
+SseError:\r
+            ;\r
+            ; Processor has to support SSE\r
+            ;\r
+            jmp     SseError\r
+NextAddress:\r
+            finit\r
+            fldcw   [FpuControlWord]\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     SseError\r
+\r
+%ifdef USE_SSE41_FLAG\r
+            ;\r
+            ; SSE 4.1 support\r
+            ;\r
+            bt      ecx, 19\r
+            jnc     SseError\r
+%endif\r
+\r
+            ;\r
+            ; Set OSFXSR bit (bit #9) & OSXMMEXCPT bit (bit #10)\r
+            ;\r
+            mov     eax, cr4\r
+            or      eax, 00000600h\r
+            mov     cr4, eax\r
+\r
+            ;\r
+            ; The processor should support SSE instruction and we can use\r
+            ; ldmxcsr instruction\r
+            ;\r
+            ldmxcsr [MmxControlWord]\r
+            %endmacro\r
diff --git a/IntelFsp2Pkg/FspSecCore/Ia32/Stack.nasm b/IntelFsp2Pkg/FspSecCore/Ia32/Stack.nasm
new file mode 100644 (file)
index 0000000..338e700
--- /dev/null
@@ -0,0 +1,78 @@
+;------------------------------------------------------------------------------\r
+;\r
+; Copyright (c) 2015, 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 permanent memory.\r
+;\r
+;------------------------------------------------------------------------------\r
+\r
+SECTION .text\r
+\r
+;------------------------------------------------------------------------------\r
+; VOID\r
+; EFIAPI\r
+; SecSwitchStack (\r
+;   UINT32   TemporaryMemoryBase,\r
+;   UINT32   PermenentMemoryBase\r
+;   );\r
+;------------------------------------------------------------------------------\r
+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 permanent\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 permanent memory at first.\r
+    ; Then, Fixup the esp point to permanent memory\r
+    ;\r
+    mov   eax, esp\r
+    sub   eax, ebx\r
+    add   eax, ecx\r
+    mov   edx, dword [esp]         ; copy pushed register's value to permanent memory\r
+    mov   dword [eax], edx\r
+    mov   edx, dword [esp + 4]\r
+    mov   dword [eax + 4], edx\r
+    mov   edx, dword [esp + 8]\r
+    mov   dword [eax + 8], edx\r
+    mov   edx, dword [esp + 12]\r
+    mov   dword [eax + 12], edx\r
+    mov   edx, dword [esp + 16]    ; Update this function's return address into permanent memory\r
+    mov   dword [eax + 16], edx\r
+    mov   esp, eax                     ; From now, esp is pointed to permanent 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 permanent memory\r
+\r
+    pop   edx\r
+    pop   ecx\r
+    pop   ebx\r
+    pop   eax\r
+    ret\r
diff --git a/IntelFsp2Pkg/FspSecCore/SecFsp.c b/IntelFsp2Pkg/FspSecCore/SecFsp.c
new file mode 100644 (file)
index 0000000..7259a55
--- /dev/null
@@ -0,0 +1,216 @@
+/** @file\r
+\r
+  Copyright (c) 2014 - 2016, 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
+/**\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 *)AsmGetFspInfoHeader();\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 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
+\r
+  FspPlatformData->DataPtr   = NULL;\r
+  FspPlatformData->MicrocodeRegionBase = 0;\r
+  FspPlatformData->MicrocodeRegionSize = 0;\r
+  FspPlatformData->CodeRegionBase      = 0;\r
+  FspPlatformData->CodeRegionSize      = 0;\r
+\r
+  //\r
+  // Pointer to the size field\r
+  //\r
+  TopOfCar = FspPlatformData->CarBase + FspPlatformData->CarSize;\r
+  StackPtr = (UINT32 *)(TopOfCar - sizeof (UINT32));\r
+\r
+  if (*(StackPtr - 1) == FSP_MCUD_SIGNATURE) {\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->MicrocodeRegionBase), 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
+\r
+        ((UINT8 *)(&FspData->PerfData[0]))[7] = FSP_PERF_ID_API_TEMP_RAM_INIT_ENTRY;\r
+        ((UINT8 *)(&FspData->PerfData[1]))[7] = FSP_PERF_ID_API_TEMP_RAM_INIT_EXIT;\r
+\r
+        StackPtr--;\r
+      } else {\r
+        StackPtr -= (*StackPtr);\r
+      }\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]     BootLoaderStack        BootLoader stack.\r
+  @param[in]     ApiIdx                 The index of the FSP API.\r
+\r
+**/\r
+VOID\r
+FspGlobalDataInit (\r
+  IN OUT  FSP_GLOBAL_DATA    *PeiFspData,\r
+  IN UINT32                   BootLoaderStack,\r
+  IN UINT8                    ApiIdx\r
+  )\r
+{\r
+  VOID              *FspmUpdDataPtr;\r
+  CHAR8              ImageId[9];\r
+  UINTN              Idx;\r
+\r
+  //\r
+  // Set FSP Global Data pointer\r
+  //\r
+  SetFspGlobalDataPointer    (PeiFspData);\r
+  ZeroMem  ((VOID *)PeiFspData, sizeof(FSP_GLOBAL_DATA));\r
+\r
+  PeiFspData->Signature            = FSP_GLOBAL_DATA_SIGNATURE;\r
+  PeiFspData->Version              = 0;\r
+  PeiFspData->CoreStack            = BootLoaderStack;\r
+  PeiFspData->PerfIdx              = 2;\r
+  PeiFspData->PerfSig              = FSP_PERFORMANCE_DATA_SIGNATURE;\r
+  PeiFspData->PlatformData.CarBase = AsmReadMsr32 (0x200) & ~(0x6);\r
+  PeiFspData->PlatformData.CarSize = ~(AsmReadMsr32(0x201) & ~(0x800)) + 1;\r
+\r
+  SetFspMeasurePoint (FSP_PERF_ID_API_FSP_MEMORY_INIT_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 *)AsmGetFspInfoHeader();\r
+  SecGetPlatformData (PeiFspData);\r
+\r
+  //\r
+  // Set API calling mode\r
+  //\r
+  SetFspApiCallingIndex (ApiIdx);\r
+  \r
+  //\r
+  // Set UPD pointer\r
+  //\r
+  FspmUpdDataPtr = (VOID *) GetFspApiParameter ();\r
+  if (FspmUpdDataPtr == NULL) {\r
+    FspmUpdDataPtr = (VOID *)(PeiFspData->FspInfoHeader->ImageBase + PeiFspData->FspInfoHeader->CfgRegionOffset);\r
+  }\r
+  SetFspUpdDataPointer (FspmUpdDataPtr);\r
+  SetFspMemoryInitUpdDataPointer (FspmUpdDataPtr);\r
+  SetFspSiliconInitUpdDataPointer (NULL);\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============= FSP Spec v%d.%d Header Revision v%x (%a v%x.%x.%x.%x) =============\n", \\r
+         (PeiFspData->FspInfoHeader->SpecVersion >> 4) & 0xF, \\r
+         PeiFspData->FspInfoHeader->SpecVersion & 0xF, \\r
+         PeiFspData->FspInfoHeader->HeaderRevision, \\r
+         ImageId, \\r
+         (PeiFspData->FspInfoHeader->ImageRevision >> 24) & 0xFF, \\r
+         (PeiFspData->FspInfoHeader->ImageRevision >> 16) & 0xFF, \\r
+         (PeiFspData->FspInfoHeader->ImageRevision >> 8) & 0xFF, \\r
+         PeiFspData->FspInfoHeader->ImageRevision & 0xFF));\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
diff --git a/IntelFsp2Pkg/FspSecCore/SecFsp.h b/IntelFsp2Pkg/FspSecCore/SecFsp.h
new file mode 100644 (file)
index 0000000..f199b12
--- /dev/null
@@ -0,0 +1,99 @@
+/** @file\r
+\r
+  Copyright (c) 2014 - 2016, 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_FSP_H_\r
+\r
+#include <PiPei.h>\r
+#include <FspEas.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
+#include <Library/FspSecPlatformLib.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]     BootLoaderStack        BootLoader stack.\r
+  @param[in]     ApiIdx                 The index of the FSP API.\r
+\r
+**/\r
+VOID\r
+FspGlobalDataInit (\r
+  IN OUT  FSP_GLOBAL_DATA    *PeiFspData,\r
+  IN UINT32                   BootLoaderStack,\r
+  IN UINT8                    ApiIdx\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
+AsmGetFspBaseAddress (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  This interface gets FspInfoHeader pointer\r
+\r
+  @return   FSP binary base address.\r
+\r
+**/\r
+UINT32\r
+EFIAPI\r
+AsmGetFspInfoHeader (\r
+  VOID\r
+  );\r
+\r
+#endif\r
diff --git a/IntelFsp2Pkg/FspSecCore/SecFspApiChk.c b/IntelFsp2Pkg/FspSecCore/SecFspApiChk.c
new file mode 100644 (file)
index 0000000..bace5ec
--- /dev/null
@@ -0,0 +1,97 @@
+/** @file\r
+\r
+  Copyright (c) 2016, 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
+\r
+/**\r
+  This function check the FSP API calling condition.\r
+\r
+  @param[in]  ApiIdx           Internal index of the FSP API.\r
+  @param[in]  ApiParam         Parameter of the FSP API.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FspApiCallingCheck (\r
+  IN UINT8     ApiIdx,\r
+  IN VOID     *ApiParam\r
+  )\r
+{\r
+  EFI_STATUS                Status;\r
+  FSP_GLOBAL_DATA           *FspData;\r
+\r
+  Status = EFI_SUCCESS;\r
+  FspData = GetFspGlobalDataPointer ();\r
+  \r
+  if (ApiIdx == NotifyPhaseApiIndex) {\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 if (ApiIdx == FspMemoryInitApiIndex) {\r
+    //\r
+    // FspMemoryInit check\r
+    //\r
+    if ((UINT32)FspData != 0xFFFFFFFF) {\r
+      Status = EFI_UNSUPPORTED;\r
+    } else if (EFI_ERROR (FspUpdSignatureCheck (ApiIdx, ApiParam))) {\r
+      Status = EFI_INVALID_PARAMETER;\r
+    }\r
+  } else if (ApiIdx == TempRamExitApiIndex) {\r
+    //\r
+    // TempRamExit 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 if (ApiIdx == FspSiliconInitApiIndex) {\r
+    //\r
+    // FspSiliconInit 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
+      } else if (EFI_ERROR (FspUpdSignatureCheck (ApiIdx, ApiParam))) {\r
+        Status = EFI_INVALID_PARAMETER;\r
+      }\r
+    }\r
+  } else {\r
+    Status = EFI_UNSUPPORTED;\r
+  }\r
+\r
+  if (!EFI_ERROR (Status)) {\r
+    if ((ApiIdx != FspMemoryInitApiIndex)) {\r
+      //\r
+      // For FspMemoryInit, the global data is not valid yet\r
+      // The API index will be updated by SecCore after the global data\r
+      // is initialized\r
+      //\r
+      SetFspApiCallingIndex (ApiIdx);\r
+    }\r
+  }\r
+  \r
+  return Status;\r
+}\r
diff --git a/IntelFsp2Pkg/FspSecCore/SecMain.c b/IntelFsp2Pkg/FspSecCore/SecMain.c
new file mode 100644 (file)
index 0000000..fa556bf
--- /dev/null
@@ -0,0 +1,227 @@
+/** @file\r
+\r
+  Copyright (c) 2014 - 2016, 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
+  @param[in] PeiCore            PeiCore entry point.\r
+  @param[in] BootLoaderStack    BootLoader stack.\r
+  @param[in] ApiIdx             the index of API.\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
+  IN PEI_CORE_ENTRY           PeiCore,\r
+  IN UINT32                   BootLoaderStack,\r
+  IN UINT32                   ApiIdx\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
+  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
+  // Initialize the global FSP data region\r
+  //\r
+  FspGlobalDataInit (&PeiFspData, BootLoaderStack, (UINT8)ApiIdx);\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
+\r
+  SecCoreData.TemporaryRamBase       = (VOID*)(UINTN) TempRamBase;\r
+  SecCoreData.TemporaryRamSize       = SizeOfRam;\r
+  SecCoreData.PeiTemporaryRamBase    = SecCoreData.TemporaryRamBase;\r
+  SecCoreData.PeiTemporaryRamSize    = SecCoreData.TemporaryRamSize * PcdGet8 (PcdFspHeapSizePercentage) / 100;\r
+  SecCoreData.StackBase              = (VOID*)(UINTN)((UINTN)SecCoreData.TemporaryRamBase + SecCoreData.PeiTemporaryRamSize);\r
+  SecCoreData.StackSize              = SecCoreData.TemporaryRamSize - SecCoreData.PeiTemporaryRamSize;\r
+\r
+  DEBUG ((DEBUG_INFO, "Fsp BootFirmwareVolumeBase - 0x%x\n", SecCoreData.BootFirmwareVolumeBase));\r
+  DEBUG ((DEBUG_INFO, "Fsp BootFirmwareVolumeSize - 0x%x\n", SecCoreData.BootFirmwareVolumeSize));\r
+  DEBUG ((DEBUG_INFO, "Fsp TemporaryRamBase       - 0x%x\n", SecCoreData.TemporaryRamBase));\r
+  DEBUG ((DEBUG_INFO, "Fsp TemporaryRamSize       - 0x%x\n", SecCoreData.TemporaryRamSize));\r
+  DEBUG ((DEBUG_INFO, "Fsp PeiTemporaryRamBase    - 0x%x\n", SecCoreData.PeiTemporaryRamBase));\r
+  DEBUG ((DEBUG_INFO, "Fsp PeiTemporaryRamSize    - 0x%x\n", SecCoreData.PeiTemporaryRamSize));\r
+  DEBUG ((DEBUG_INFO, "Fsp StackBase              - 0x%x\n", SecCoreData.StackBase));\r
+  DEBUG ((DEBUG_INFO, "Fsp StackSize              - 0x%x\n", SecCoreData.StackSize));\r
+\r
+  //\r
+  // Call PeiCore Entry\r
+  //  \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
+  UINTN             HeapSize;\r
+  UINTN             StackSize;\r
+\r
+  HeapSize   = CopySize * PcdGet8 (PcdFspHeapSizePercentage) / 100 ;\r
+  StackSize  = CopySize - HeapSize;\r
+    \r
+  OldHeap = (VOID*)(UINTN)TemporaryMemoryBase;\r
+  NewHeap = (VOID*)((UINTN)PermanentMemoryBase + StackSize);\r
+\r
+  OldStack = (VOID*)((UINTN)TemporaryMemoryBase + HeapSize);\r
+  NewStack = (VOID*)(UINTN)PermanentMemoryBase;\r
+\r
+  //\r
+  // Migrate Heap\r
+  //\r
+  CopyMem (NewHeap, OldHeap, HeapSize);\r
+\r
+  //\r
+  // Migrate Stack\r
+  //\r
+  CopyMem (NewStack, OldStack, StackSize);\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/IntelFsp2Pkg/FspSecCore/SecMain.h b/IntelFsp2Pkg/FspSecCore/SecMain.h
new file mode 100644 (file)
index 0000000..33f7362
--- /dev/null
@@ -0,0 +1,140 @@
+/** @file\r
+\r
+  Copyright (c) 2014 - 2016, 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 <FspEas.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
+  @param[in] PeiCore            PeiCore entry point.\r
+  @param[in] BootLoaderStack    BootLoader stack.\r
+  @param[in] ApiIdx             the index of API.\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
+  IN PEI_CORE_ENTRY           PeiCore,\r
+  IN UINT32                   BootLoaderStack,\r
+  IN UINT32                   ApiIdx\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/IntelFsp2Pkg/FspSecCore/Vtf0/Bin/ResetVec.ia32.raw b/IntelFsp2Pkg/FspSecCore/Vtf0/Bin/ResetVec.ia32.raw
new file mode 100644 (file)
index 0000000..2dc9f17
Binary files /dev/null and b/IntelFsp2Pkg/FspSecCore/Vtf0/Bin/ResetVec.ia32.raw differ
diff --git a/IntelFsp2Pkg/FspSecCore/Vtf0/Build.py b/IntelFsp2Pkg/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/IntelFsp2Pkg/FspSecCore/Vtf0/Ia16/ResetVec.asm16 b/IntelFsp2Pkg/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/IntelFsp2Pkg/FspSecCore/Vtf0/ResetVectorCode.asm b/IntelFsp2Pkg/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/IntelFsp2Pkg/FspSecCore/Vtf0/Tools/FixupForRawSection.py b/IntelFsp2Pkg/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/IntelFsp2Pkg/Include/FspDataTable.h b/IntelFsp2Pkg/Include/FspDataTable.h
new file mode 100644 (file)
index 0000000..3c79f34
--- /dev/null
@@ -0,0 +1,32 @@
+/** @file\r
+  The header file of FSP data table\r
+\r
+  Copyright (c) 2016, 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_DATA_TABLE_H_\r
+#define _FSP_DATA_TABLE_H_\r
+\r
+#pragma pack(1)\r
+\r
+#define FSP_DATA_SIGNATURE  SIGNATURE_32 ('F', 'S', 'P', 'D')\r
+\r
+typedef struct  {\r
+  UINT32  Signature;\r
+  UINT32  Length;\r
+  UINT32  FsptBase;\r
+  UINT32  FspmBase;\r
+  UINT32  FspsBase;\r
+} FSP_DATA_TABLE;\r
+\r
+#pragma pack()\r
+\r
+#endif\r
diff --git a/IntelFsp2Pkg/Include/FspEas.h b/IntelFsp2Pkg/Include/FspEas.h
new file mode 100644 (file)
index 0000000..79bb0b8
--- /dev/null
@@ -0,0 +1,24 @@
+/** @file\r
+  Intel FSP definition from Intel Firmware Support Package External\r
+  Architecture Specification v2.0.\r
+\r
+  Copyright (c) 2014 - 2016, 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_EAS_H_\r
+#define _FSP_EAS_H_\r
+\r
+#include <Uefi.h>\r
+#include <Guid/GuidHobFspEas.h>\r
+#include <Guid/FspHeaderFile.h>\r
+#include <FspEas/FspApi.h>\r
+\r
+#endif\r
diff --git a/IntelFsp2Pkg/Include/FspEas/FspApi.h b/IntelFsp2Pkg/Include/FspEas/FspApi.h
new file mode 100644 (file)
index 0000000..f7c7168
--- /dev/null
@@ -0,0 +1,241 @@
+/** @file\r
+  Intel FSP API definition from Intel Firmware Support Package External\r
+  Architecture Specification v2.0.\r
+\r
+  Copyright (c) 2014 - 2016, 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_API_H_\r
+#define _FSP_API_H_\r
+\r
+#pragma pack(1)\r
+typedef struct {\r
+  ///\r
+  /// UPD Region Signature. This signature will be\r
+  /// "XXXXXX_T" for FSP-T\r
+  /// "XXXXXX_M" for FSP-M\r
+  /// "XXXXXX_S" for FSP-S\r
+  /// Where XXXXXX is an unique signature\r
+  ///\r
+  UINT64                      Signature;\r
+  ///\r
+  /// Revision of the Data structure. For FSP v2.0 value is 1.\r
+  ///\r
+  UINT8                       Revision;\r
+  UINT8                       Reserved[23];\r
+} FSP_UPD_HEADER;\r
+\r
+typedef struct {\r
+  ///\r
+  /// Revision of the structure. For FSP v2.0 value is 1.\r
+  ///\r
+  UINT8                       Revision;\r
+  UINT8                       Reserved[3];\r
+  ///\r
+  /// Pointer to the non-volatile storage (NVS) data buffer.\r
+  /// If it is NULL it indicates the NVS data is not available.\r
+  ///\r
+  VOID                        *NvsBufferPtr;\r
+  ///\r
+  /// Pointer to the temporary stack base address to be\r
+  /// consumed inside FspMemoryInit() API.\r
+  ///\r
+  VOID                        *StackBase;\r
+  ///\r
+  /// Temporary stack size to be consumed inside\r
+  /// FspMemoryInit() API.\r
+  ///\r
+  UINT32                      StackSize;\r
+  ///\r
+  /// Size of memory to be reserved by FSP below "top\r
+  /// of low usable memory" for bootloader usage.\r
+  ///\r
+  UINT32                      BootLoaderTolumSize;\r
+  ///\r
+  /// Current boot mode.\r
+  ///\r
+  UINT32                      BootMode;\r
+  UINT8                       Reserved1[8];\r
+} FSPM_ARCH_UPD;\r
+\r
+typedef struct {\r
+  FSP_UPD_HEADER              FspUpdHeader;\r
+} FSPT_UPD_COMMON;\r
+\r
+typedef struct {\r
+  FSP_UPD_HEADER              FspUpdHeader;\r
+  FSPM_ARCH_UPD               FspmArchUpd;\r
+} FSPM_UPD_COMMON;\r
+\r
+typedef struct {\r
+  FSP_UPD_HEADER              FspUpdHeader;\r
+} FSPS_UPD_COMMON;\r
+\r
+typedef enum {\r
+  ///\r
+  /// This stage is notified when the bootloader completes the\r
+  /// PCI enumeration and the resource allocation for the\r
+  /// PCI devices is complete.\r
+  ///\r
+  EnumInitPhaseAfterPciEnumeration = 0x20,\r
+  ///\r
+  /// This stage is notified just before the bootloader hand-off\r
+  /// to the OS loader.\r
+  ///\r
+  EnumInitPhaseReadyToBoot         = 0x40,\r
+  ///\r
+  /// This stage is notified just before the firmware/Preboot\r
+  /// environment transfers management of all system resources\r
+  /// to the OS or next level execution environment.\r
+  ///\r
+  EnumInitPhaseEndOfFirmware       = 0xF0\r
+} FSP_INIT_PHASE;\r
+\r
+typedef struct {\r
+  ///\r
+  /// Notification phase used for NotifyPhase API\r
+  ///\r
+  FSP_INIT_PHASE     Phase;\r
+} NOTIFY_PHASE_PARAMS;\r
+\r
+#pragma pack()\r
+\r
+/**\r
+  This FSP API is called soon after coming out of reset and before memory and stack is\r
+  available. 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 used until\r
+  main memory is initialized.\r
+\r
+  A hardcoded stack can be set up with the following values, and the "esp" register\r
+  initialized to point to this hardcoded stack.\r
+  1. The return address where the FSP will return control after setting up a temporary\r
+     stack.\r
+  2. A pointer to the input parameter structure\r
+\r
+  However, since the stack is in ROM and not writeable, this FSP API cannot be called\r
+  using the "call" instruction, but needs to be jumped to.\r
+\r
+  @param[in] FsptUpdDataPtr     Pointer to the FSPT_UPD data structure.\r
+\r
+  @retval EFI_SUCCESS           Temporary RAM was initialized successfully.\r
+  @retval EFI_INVALID_PARAMETER Input parameters are invalid.\r
+  @retval EFI_UNSUPPORTED       The FSP calling conditions were not met.\r
+  @retval EFI_DEVICE_ERROR      Temp RAM initialization failed.\r
+\r
+  If this function is successful, the FSP initializes the ECX and EDX registers to point to\r
+  a temporary but writeable memory range available to the boot loader and returns with\r
+  FSP_SUCCESS in register EAX. Register ECX points to the start of this temporary\r
+  memory range and EDX points to the end of the range. Boot loader is free to use the\r
+  whole range described. Typically the boot loader can reload the ESP register to point\r
+  to the end of this returned range so that it can be used as a standard stack.\r
+**/\r
+typedef\r
+EFI_STATUS\r
+(EFIAPI *FSP_TEMP_RAM_INIT) (\r
+  IN  VOID    *FsptUpdDataPtr\r
+  );\r
+\r
+/**\r
+  This FSP API is used to notify the FSP about the different phases in the boot process.\r
+  This allows the FSP to take appropriate actions as needed during different initialization\r
+  phases. The phases will be platform dependent and will be documented with the FSP\r
+  release. The current FSP supports two notify phases:\r
+    Post PCI enumeration\r
+    Ready To Boot\r
+\r
+  @param[in] NotifyPhaseParamPtr Address pointer to the NOTIFY_PHASE_PRAMS\r
+\r
+  @retval EFI_SUCCESS           The notification was handled successfully.\r
+  @retval EFI_UNSUPPORTED       The notification was not called in the proper order.\r
+  @retval EFI_INVALID_PARAMETER The notification code is invalid.\r
+**/\r
+typedef\r
+EFI_STATUS\r
+(EFIAPI *FSP_NOTIFY_PHASE) (\r
+  IN NOTIFY_PHASE_PARAMS *NotifyPhaseParamPtr\r
+  );\r
+\r
+/**\r
+  This FSP API is called after TempRamInit and initializes the memory.\r
+  This FSP API accepts a pointer to a data structure that will be platform dependent\r
+  and defined for each FSP binary. This will be documented in Integration guide with\r
+  each FSP release.\r
+  After FspMemInit completes its execution, it passes the pointer to the HobList and\r
+  returns to the boot loader from where it was called. BootLoader is responsible to \r
+  migrate it's stack and data to Memory.\r
+  FspMemoryInit, TempRamExit and FspSiliconInit APIs provide an alternate method to\r
+  complete the silicon initialization and provides bootloader an opportunity to get\r
+  control after system memory is available and before the temporary RAM is torn down.\r
+\r
+  @param[in]  FspmUpdDataPtr          Pointer to the FSPM_UPD data sructure.\r
+  @param[out] HobListPtr              Pointer to receive the address of the HOB list.\r
+\r
+  @retval EFI_SUCCESS                 FSP execution environment was initialized successfully.\r
+  @retval EFI_INVALID_PARAMETER       Input parameters are invalid.\r
+  @retval EFI_UNSUPPORTED             The FSP calling conditions were not met.\r
+  @retval EFI_DEVICE_ERROR            FSP initialization failed.\r
+  @retval EFI_OUT_OF_RESOURCES        Stack range requested by FSP is not met.\r
+  @retval FSP_STATUS_RESET_REQUIREDx  A reset is reuired. These status codes will not be returned during S3.\r
+**/\r
+typedef\r
+EFI_STATUS\r
+(EFIAPI *FSP_MEMORY_INIT) (\r
+  IN  VOID    *FspmUpdDataPtr,\r
+  OUT VOID    **HobListPtr\r
+  );\r
+\r
+\r
+/**\r
+  This FSP API is called after FspMemoryInit API. This FSP API tears down the temporary\r
+  memory setup by TempRamInit API. This FSP API accepts a pointer to a data structure\r
+  that will be platform dependent and defined for each FSP binary. This will be\r
+  documented in Integration Guide.\r
+  FspMemoryInit, TempRamExit and FspSiliconInit APIs provide an alternate method to\r
+  complete the silicon initialization and provides bootloader an opportunity to get\r
+  control after system memory is available and before the temporary RAM is torn down.\r
+\r
+  @param[in] TempRamExitParamPtr Pointer to the Temp Ram Exit parameters structure.\r
+                                 This structure is normally defined in the Integration Guide.\r
+                                 And if it is not defined in the Integration Guide, pass NULL.\r
+\r
+  @retval EFI_SUCCESS            FSP execution environment was initialized successfully.\r
+  @retval EFI_INVALID_PARAMETER  Input parameters are invalid.\r
+  @retval EFI_UNSUPPORTED        The FSP calling conditions were not met.\r
+  @retval EFI_DEVICE_ERROR       FSP initialization failed.\r
+**/\r
+typedef\r
+EFI_STATUS\r
+(EFIAPI *FSP_TEMP_RAM_EXIT) (\r
+  IN  VOID    *TempRamExitParamPtr\r
+  );\r
+\r
+\r
+/**\r
+  This FSP API is called after TempRamExit API.\r
+  FspMemoryInit, TempRamExit and FspSiliconInit APIs provide an alternate method to complete the\r
+  silicon initialization.\r
+\r
+  @param[in] FspsUpdDataPtr     Pointer to the FSPS_UPD data structure.\r
+                                If NULL, FSP will use the default parameters.\r
+\r
+  @retval EFI_SUCCESS                 FSP execution environment was initialized successfully.\r
+  @retval EFI_INVALID_PARAMETER       Input parameters are invalid.\r
+  @retval EFI_UNSUPPORTED             The FSP calling conditions were not met.\r
+  @retval EFI_DEVICE_ERROR            FSP initialization failed.\r
+  @retval FSP_STATUS_RESET_REQUIREDx  A reset is reuired. These status codes will not be returned during S3.\r
+**/\r
+typedef\r
+EFI_STATUS\r
+(EFIAPI *FSP_SILICON_INIT) (\r
+  IN  VOID    *FspsUpdDataPtr\r
+  );\r
+\r
+#endif\r
diff --git a/IntelFsp2Pkg/Include/FspGlobalData.h b/IntelFsp2Pkg/Include/FspGlobalData.h
new file mode 100644 (file)
index 0000000..a484d16
--- /dev/null
@@ -0,0 +1,68 @@
+/** @file\r
+\r
+  Copyright (c) 2014 - 2016, 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 <FspEas.h>\r
+\r
+#pragma pack(1)\r
+\r
+typedef enum {\r
+  TempRamInitApiIndex,\r
+  FspInitApiIndex,\r
+  NotifyPhaseApiIndex,\r
+  FspMemoryInitApiIndex,\r
+  TempRamExitApiIndex,\r
+  FspSiliconInitApiIndex,\r
+  FspApiIndexMax\r
+} FSP_API_INDEX;\r
+\r
+typedef struct  {\r
+   VOID               *DataPtr;\r
+   UINT32             MicrocodeRegionBase;\r
+   UINT32             MicrocodeRegionSize;\r
+   UINT32             CodeRegionBase;\r
+   UINT32             CodeRegionSize;\r
+   UINT32             CarBase;\r
+   UINT32             CarSize;\r
+} FSP_PLAT_DATA;\r
+\r
+#define FSP_GLOBAL_DATA_SIGNATURE  SIGNATURE_32 ('F', 'S', 'P', 'D')\r
+#define FSP_PERFORMANCE_DATA_SIGNATURE  SIGNATURE_32 ('P', 'E', 'R', 'F')\r
+\r
+typedef struct  {\r
+   UINT32             Signature;\r
+   UINT8              Version;\r
+   UINT8              Reserved1[3];\r
+   UINT32             CoreStack;\r
+   UINT32             StatusCode;\r
+   UINT32             Reserved2[8];\r
+   FSP_PLAT_DATA      PlatformData;\r
+   FSP_INFO_HEADER    *FspInfoHeader;\r
+   VOID               *UpdDataPtr;\r
+   VOID               *TempRamInitUpdPtr;\r
+   VOID               *MemoryInitUpdPtr;\r
+   VOID               *SiliconInitUpdPtr;\r
+   UINT8              ApiIdx;\r
+   UINT8              Reserved3[31];\r
+   UINT32             PerfSig;\r
+   UINT16             PerfLen;\r
+   UINT16             Reserved4;\r
+   UINT32             PerfIdx;\r
+   UINT64             PerfData[32];\r
+} FSP_GLOBAL_DATA;\r
+\r
+#pragma pack()\r
+\r
+#endif\r
diff --git a/IntelFsp2Pkg/Include/FspMeasurePointId.h b/IntelFsp2Pkg/Include/FspMeasurePointId.h
new file mode 100644 (file)
index 0000000..ee103df
--- /dev/null
@@ -0,0 +1,62 @@
+/** @file\r
+\r
+  Copyright (c) 2014 - 2016, 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_MRC_INIT_ENTRY               0xD0\r
+#define  FSP_PERF_ID_MRC_INIT_EXIT                (FSP_PERF_ID_MRC_INIT_ENTRY +  1)\r
+\r
+#define  FSP_PERF_ID_SYSTEM_AGENT_INIT_ENTRY      0xD8\r
+#define  FSP_PERF_ID_SYSTEM_AGENT_INIT_EXIT       (FSP_PERF_ID_SYSTEM_AGENT_INIT_ENTRY +  1)\r
+\r
+#define  FSP_PERF_ID_PCH_INIT_ENTRY               0xDA\r
+#define  FSP_PERF_ID_PCH_INIT_EXIT                (FSP_PERF_ID_PCH_INIT_ENTRY +  1)\r
+\r
+#define  FSP_PERF_ID_CPU_INIT_ENTRY               0xE0\r
+#define  FSP_PERF_ID_CPU_INIT_EXIT                (FSP_PERF_ID_CPU_INIT_ENTRY +  1)\r
+\r
+#define  FSP_PERF_ID_GFX_INIT_ENTRY               0xE8\r
+#define  FSP_PERF_ID_GFX_INIT_EXIT                (FSP_PERF_ID_GFX_INIT_ENTRY +  1)\r
+\r
+#define  FSP_PERF_ID_ME_INIT_ENTRY                0xEA\r
+#define  FSP_PERF_ID_ME_INIT_EXIT                 (FSP_PERF_ID_ME_INIT_ENTRY +  1)\r
+\r
+//\r
+// 0xF0 - 0xFF are reserved for FSP API\r
+//\r
+#define  FSP_PERF_ID_API_TEMP_RAM_INIT_ENTRY           0xF0\r
+#define  FSP_PERF_ID_API_TEMP_RAM_INIT_EXIT            (FSP_PERF_ID_API_TEMP_RAM_INIT_ENTRY + 1)\r
+\r
+#define  FSP_PERF_ID_API_FSP_MEMORY_INIT_ENTRY         0xF2\r
+#define  FSP_PERF_ID_API_FSP_MEMORY_INIT_EXIT          (FSP_PERF_ID_API_FSP_MEMORY_INIT_ENTRY + 1)\r
+\r
+#define  FSP_PERF_ID_API_TEMP_RAM_EXIT_ENTRY           0xF4\r
+#define  FSP_PERF_ID_API_TEMP_RAM_EXIT_EXIT            (FSP_PERF_ID_API_TEMP_RAM_EXIT_ENTRY + 1)\r
+\r
+#define  FSP_PERF_ID_API_FSP_SILICON_INIT_ENTRY        0xF6\r
+#define  FSP_PERF_ID_API_FSP_SILICON_INIT_EXIT         (FSP_PERF_ID_API_FSP_SILICON_INIT_ENTRY + 1)\r
+\r
+#define  FSP_PERF_ID_API_NOTIFY_POST_PCI_ENTRY         0xF8\r
+#define  FSP_PERF_ID_API_NOTIFY_POST_PCI_EXIT          (FSP_PERF_ID_API_NOTIFY_POST_PCI_ENTRY + 1)\r
+\r
+#define  FSP_PERF_ID_API_NOTIFY_READY_TO_BOOT_ENTRY    0xFA\r
+#define  FSP_PERF_ID_API_NOTIFY_READY_TO_BOOT_EXIT     (FSP_PERF_ID_API_NOTIFY_READY_TO_BOOT_ENTRY + 1)\r
+\r
+#define  FSP_PERF_ID_API_NOTIFY_END_OF_FIRMWARE_ENTRY  0xFC\r
+#define  FSP_PERF_ID_API_NOTIFY_END_OF_FIRMWARE_EXIT   (FSP_PERF_ID_API_NOTIFY_END_OF_FIRMWARE_ENTRY + 1)\r
+\r
+#endif\r
diff --git a/IntelFsp2Pkg/Include/FspStatusCode.h b/IntelFsp2Pkg/Include/FspStatusCode.h
new file mode 100644 (file)
index 0000000..c9a316e
--- /dev/null
@@ -0,0 +1,46 @@
+/** @file\r
+  Intel FSP status code definition\r
+\r
+  Copyright (c) 2016, 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_STATUS_CODE_H_\r
+#define _FSP_STATUS_CODE_H_\r
+\r
+//\r
+// FSP API - 4 BITS\r
+//\r
+#define FSP_STATUS_CODE_TEMP_RAM_INIT                0xF000\r
+#define FSP_STATUS_CODE_MEMORY_INIT                  0xD000\r
+#define FSP_STATUS_CODE_TEMP_RAM_EXIT                0xB000\r
+#define FSP_STATUS_CODE_SILICON_INIT                 0x9000\r
+#define FSP_STATUS_CODE_POST_PCIE_ENUM_NOTIFICATION  0x6000\r
+#define FSP_STATUS_CODE_READY_TO_BOOT_NOTIFICATION   0x4000\r
+#define FSP_STATUS_CODE_END_OF_FIRMWARE_NOTIFICATION 0x2000\r
+\r
+//\r
+// MODULE - 4 BITS\r
+//\r
+#define FSP_STATUS_CODE_GFX_PEIM                     0x0700\r
+#define FSP_STATUS_CODE_COMMON_CODE                  0x0800\r
+#define FSP_STATUS_CODE_SILICON_COMMON_CODE          0x0900\r
+#define FSP_STATUS_CODE_SYSTEM_AGENT                 0x0A00\r
+#define FSP_STATUS_CODE_PCH                          0x0B00\r
+#define FSP_STATUS_CODE_CPU                          0x0C00\r
+#define FSP_STATUS_CODE_MRC                          0x0D00\r
+#define FSP_STATUS_CODE_ME_BIOS                      0x0E00\r
+//\r
+// Individual Codes - 1 BYTE\r
+//\r
+#define FSP_STATUS_CODE_API_ENTRY                    0x0000\r
+#define FSP_STATUS_CODE_API_EXIT                     0x007F\r
+\r
+#endif\r
diff --git a/IntelFsp2Pkg/Include/Guid/FspHeaderFile.h b/IntelFsp2Pkg/Include/Guid/FspHeaderFile.h
new file mode 100644 (file)
index 0000000..96cac00
--- /dev/null
@@ -0,0 +1,204 @@
+/** @file\r
+  Intel FSP Header File definition from Intel Firmware Support Package External\r
+  Architecture Specification v2.0.\r
+\r
+  Copyright (c) 2014 - 2016, 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_HEADER_FILE_H__\r
+#define __FSP_HEADER_FILE_H__\r
+\r
+#define FSP_HEADER_REVISION_3   3\r
+\r
+#define FSPE_HEADER_REVISION_1  1\r
+#define FSPP_HEADER_REVISION_1  1\r
+\r
+///\r
+/// Fixed FSP header offset in the FSP image\r
+///\r
+#define FSP_INFO_HEADER_OFF    0x94\r
+\r
+#define OFFSET_IN_FSP_INFO_HEADER(x)  (UINT32)&((FSP_INFO_HEADER *)(UINTN)0)->x\r
+\r
+#define FSP_INFO_HEADER_SIGNATURE  SIGNATURE_32 ('F', 'S', 'P', 'H')\r
+\r
+#pragma pack(1)\r
+\r
+///\r
+/// FSP Information Header as described in FSP v2.0 Spec section 5.1.1.\r
+///\r
+typedef struct {\r
+  ///\r
+  /// Byte 0x00: Signature ('FSPH') for the FSP Information Header.\r
+  ///\r
+  UINT32  Signature;\r
+  ///\r
+  /// Byte 0x04: Length of the FSP Information Header.\r
+  ///\r
+  UINT32  HeaderLength;\r
+  ///\r
+  /// Byte 0x08: Reserved.\r
+  ///\r
+  UINT8   Reserved1[2];\r
+  ///\r
+  /// Byte 0x0A: Indicates compliance with a revision of this specification in the BCD format.\r
+  ///\r
+  UINT8   SpecVersion;\r
+  ///\r
+  /// Byte 0x0B: Revision of the FSP Information Header.\r
+  ///\r
+  UINT8   HeaderRevision;\r
+  ///\r
+  /// Byte 0x0C: Revision of the FSP binary.\r
+  ///\r
+  UINT32  ImageRevision;\r
+  ///\r
+  /// Byte 0x10: Signature string that will help match the FSP Binary to a supported HW configuration.\r
+  ///\r
+  CHAR8   ImageId[8];\r
+  ///\r
+  /// Byte 0x18: Size of the entire FSP binary.\r
+  ///\r
+  UINT32  ImageSize;\r
+  ///\r
+  /// Byte 0x1C: FSP binary preferred base address.\r
+  ///\r
+  UINT32  ImageBase;\r
+  ///\r
+  /// Byte 0x20: Attribute for the FSP binary.\r
+  ///\r
+  UINT16  ImageAttribute;\r
+  ///\r
+  /// Byte 0x22: Attributes of the FSP Component.\r
+  ///\r
+  UINT16  ComponentAttribute;\r
+  ///\r
+  /// Byte 0x24: Offset of the FSP configuration region.\r
+  ///\r
+  UINT32  CfgRegionOffset;\r
+  ///\r
+  /// Byte 0x28: Size of the FSP configuration region.\r
+  ///\r
+  UINT32  CfgRegionSize;\r
+  ///\r
+  /// Byte 0x2C: Reserved2.\r
+  ///\r
+  UINT32  Reserved2;\r
+  ///\r
+  /// Byte 0x30: The offset for the API to setup a temporary stack till the memory is initialized.\r
+  ///\r
+  UINT32  TempRamInitEntryOffset;\r
+  ///\r
+  /// Byte 0x34: Reserved3.\r
+  ///\r
+  UINT32  Reserved3;\r
+  ///\r
+  /// Byte 0x38: The offset for the API to inform the FSP about the different stages in the boot process.\r
+  ///\r
+  UINT32  NotifyPhaseEntryOffset;\r
+  ///\r
+  /// Byte 0x3C: The offset for the API to initialize the memory.\r
+  ///\r
+  UINT32  FspMemoryInitEntryOffset;\r
+  ///\r
+  /// Byte 0x40: The offset for the API to tear down temporary RAM.\r
+  ///\r
+  UINT32  TempRamExitEntryOffset;\r
+  ///\r
+  /// Byte 0x44: The offset for the API to initialize the CPU and chipset.\r
+  ///\r
+  UINT32  FspSiliconInitEntryOffset;\r
+} FSP_INFO_HEADER;\r
+\r
+///\r
+/// Signature of the FSP Extended Header\r
+///\r
+#define FSP_INFO_EXTENDED_HEADER_SIGNATURE  SIGNATURE_32 ('F', 'S', 'P', 'E')\r
+\r
+///\r
+/// FSP Information Extended Header as described in FSP v2.0 Spec section 5.1.2.\r
+///\r
+typedef struct {\r
+  ///\r
+  /// Byte 0x00: Signature ('FSPE') for the FSP Extended Information Header.\r
+  ///\r
+  UINT32  Signature;\r
+  ///\r
+  /// Byte 0x04: Length of the table in bytes, including all additional FSP producer defined data.\r
+  ///\r
+  UINT32  Length;\r
+  ///\r
+  /// Byte 0x08: FSP producer defined revision of the table.\r
+  ///\r
+  UINT8   Revision;\r
+  ///\r
+  /// Byte 0x09: Reserved for future use.\r
+  ///\r
+  UINT8   Reserved;\r
+  ///\r
+  /// Byte 0x0A: FSP producer identification string \r
+  ///\r
+  CHAR8   FspProducerId[6];\r
+  ///\r
+  /// Byte 0x10: FSP producer implementation revision number. Larger numbers are assumed to be newer revisions.\r
+  ///\r
+  UINT32  FspProducerRevision;\r
+  ///\r
+  /// Byte 0x14: Size of the FSP producer defined data (n) in bytes.\r
+  ///\r
+  UINT32  FspProducerDataSize;\r
+  ///\r
+  /// Byte 0x18: FSP producer defined data of size (n) defined by FspProducerDataSize.\r
+  ///\r
+} FSP_INFO_EXTENDED_HEADER;\r
+\r
+//\r
+// A generic table search algorithm for additional tables can be implemented with a\r
+// signature search algorithm until a terminator signature 'FSPP' is found.\r
+//\r
+#define FSP_FSPP_SIGNATURE  SIGNATURE_32 ('F', 'S', 'P', 'P')\r
+#define FSP_PATCH_TABLE_SIGNATURE  FSP_FSPP_SIGNATURE\r
+\r
+///\r
+/// FSP Patch Table as described in FSP v2.0 Spec section 5.1.5.\r
+///\r
+typedef struct {\r
+  ///\r
+  /// Byte 0x00: FSP Patch Table Signature "FSPP".\r
+  ///\r
+  UINT32  Signature;\r
+  ///\r
+  /// Byte 0x04: Size including the PatchData.\r
+  ///\r
+  UINT16  HeaderLength;\r
+  ///\r
+  /// Byte 0x06: Revision is set to 0x01.\r
+  ///\r
+  UINT8   HeaderRevision;\r
+  ///\r
+  /// Byte 0x07: Reserved for future use.\r
+  ///\r
+  UINT8   Reserved;\r
+  ///\r
+  /// Byte 0x08: Number of entries to Patch.\r
+  ///\r
+  UINT32  PatchEntryNum;\r
+  ///\r
+  /// Byte 0x0C: Patch Data.\r
+  ///\r
+//UINT32  PatchData[];\r
+} FSP_PATCH_TABLE;\r
+\r
+#pragma pack()\r
+\r
+extern EFI_GUID gFspHeaderFileGuid;\r
+\r
+#endif\r
diff --git a/IntelFsp2Pkg/Include/Guid/GuidHobFspEas.h b/IntelFsp2Pkg/Include/Guid/GuidHobFspEas.h
new file mode 100644 (file)
index 0000000..83c7f00
--- /dev/null
@@ -0,0 +1,23 @@
+/** @file\r
+  Intel FSP Hob Guid definition from Intel Firmware Support Package External\r
+  Architecture Specification v2.0.\r
+\r
+  Copyright (c) 2014 - 2016, 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_EAS_GUID__\r
+#define __GUID_HOB_FSP_EAS_GUID__\r
+\r
+extern EFI_GUID gFspBootLoaderTolumHobGuid;\r
+extern EFI_GUID gFspReservedMemoryResourceHobGuid;\r
+extern EFI_GUID gFspNonVolatileStorageHobGuid;\r
+\r
+#endif\r
diff --git a/IntelFsp2Pkg/Include/Library/CacheAsRamLib.h b/IntelFsp2Pkg/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/IntelFsp2Pkg/Include/Library/CacheLib.h b/IntelFsp2Pkg/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/IntelFsp2Pkg/Include/Library/DebugDeviceLib.h b/IntelFsp2Pkg/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/IntelFsp2Pkg/Include/Library/FspCommonLib.h b/IntelFsp2Pkg/Include/Library/FspCommonLib.h
new file mode 100644 (file)
index 0000000..0bb0c53
--- /dev/null
@@ -0,0 +1,312 @@
+/** @file\r
+\r
+  Copyright (c) 2014 - 2016, 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 first parameter passed by the bootlaoder.\r
+\r
+  @retval ApiParameter FSP API first parameter passed by the bootlaoder.\r
+**/\r
+UINT32\r
+EFIAPI\r
+GetFspApiParameter (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  This function gets back the FSP API second parameter passed by the bootlaoder.\r
+\r
+  @retval ApiParameter FSP API second parameter passed by the bootlaoder.\r
+**/\r
+UINT32\r
+EFIAPI\r
+GetFspApiParameter2 (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  This function sets the FSP API parameter 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 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] UpdDataPtr   UPD data pointer.\r
+**/\r
+VOID\r
+EFIAPI\r
+SetFspUpdDataPointer (\r
+  IN VOID    *UpdDataPtr\r
+  );\r
+\r
+/**\r
+  This function gets the UPD data pointer.\r
+\r
+  @return UpdDataPtr   UPD data pointer.\r
+**/\r
+VOID *\r
+EFIAPI\r
+GetFspUpdDataPointer (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  This function sets the memory init UPD data pointer.\r
+\r
+  @param[in] MemoryInitUpdPtr   memory init UPD data pointer.\r
+**/\r
+VOID\r
+EFIAPI\r
+SetFspMemoryInitUpdDataPointer (\r
+  IN VOID    *MemoryInitUpdPtr\r
+  );\r
+\r
+/**\r
+  This function gets the memory init UPD data pointer.\r
+\r
+  @return memory init UPD data pointer.\r
+**/\r
+VOID *\r
+EFIAPI\r
+GetFspMemoryInitUpdDataPointer (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  This function sets the silicon init UPD data pointer.\r
+\r
+  @param[in] SiliconInitUpdPtr   silicon init UPD data pointer.\r
+**/\r
+VOID\r
+EFIAPI\r
+SetFspSiliconInitUpdDataPointer (\r
+  IN VOID    *SiliconInitUpdPtr\r
+  );\r
+\r
+/**\r
+  This function gets the silicon init UPD data pointer.\r
+\r
+  @return silicon init UPD data pointer.\r
+**/\r
+VOID *\r
+EFIAPI\r
+GetFspSiliconInitUpdDataPointer (\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
+/**\r
+  This function gets the FSP info header pointer.\r
+\r
+  @retval FspInfoHeader   FSP info header pointer\r
+**/\r
+FSP_INFO_HEADER *\r
+EFIAPI\r
+GetFspInfoHeader (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  This function sets the FSP info header pointer.\r
+\r
+  @param[in] FspInfoHeader   FSP info header pointer\r
+**/\r
+VOID\r
+EFIAPI\r
+SetFspInfoHeader (\r
+  FSP_INFO_HEADER *FspInfoHeader\r
+  );\r
+\r
+/**\r
+  This function gets the FSP info header pointer from the API context.\r
+\r
+  @retval FspInfoHeader   FSP info header pointer\r
+**/\r
+FSP_INFO_HEADER *\r
+EFIAPI\r
+GetFspInfoHeaderFromApiContext (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  This function gets the VPD data pointer.\r
+\r
+  @return VpdDataRgnPtr   VPD data pointer.\r
+**/\r
+VOID *\r
+EFIAPI\r
+GetFspVpdDataPointer (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  This function gets FSP API calling mode.\r
+\r
+  @retval API calling mode\r
+**/\r
+UINT8\r
+EFIAPI\r
+GetFspApiCallingIndex (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  This function sets FSP API calling mode.\r
+\r
+  @param[in] Index     API calling index\r
+**/\r
+VOID\r
+EFIAPI\r
+SetFspApiCallingIndex (\r
+  UINT8  Index\r
+  );\r
+\r
+/**\r
+  This function gets FSP Phase StatusCode.\r
+  \r
+  @retval StatusCode\r
+**/\r
+UINT32\r
+EFIAPI\r
+GetPhaseStatusCode (\r
+  VOID\r
+  );\r
+\r
+\r
+/**\r
+  This function sets FSP Phase StatusCode.\r
+\r
+  @param[in] Mode     Phase StatusCode\r
+**/\r
+VOID\r
+EFIAPI\r
+SetPhaseStatusCode (\r
+  UINT32  StatusCode\r
+  );\r
+\r
+/**\r
+  This function gets FSP CAR base.\r
+\r
+**/\r
+UINT32\r
+EFIAPI\r
+GetFspCarBase (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  This function gets FSP CAR size.\r
+\r
+**/\r
+UINT32\r
+EFIAPI\r
+GetFspCarSize (\r
+  VOID\r
+  );\r
+\r
+#endif\r
diff --git a/IntelFsp2Pkg/Include/Library/FspPlatformLib.h b/IntelFsp2Pkg/Include/Library/FspPlatformLib.h
new file mode 100644 (file)
index 0000000..9247bd5
--- /dev/null
@@ -0,0 +1,105 @@
+/** @file\r
+\r
+  Copyright (c) 2014 - 2016, 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 resource descriptor by owner.\r
+\r
+  @param[in] OwnerGuid   resource owner guid\r
+**/\r
+EFI_HOB_RESOURCE_DESCRIPTOR *\r
+EFIAPI\r
+FspGetResourceDescriptorByOwner (\r
+  IN EFI_GUID   *OwnerGuid\r
+  );\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
+  Set a new stack frame for the continuation function.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+FspSetNewStackFrame (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  This function transfer control back to BootLoader after FspSiliconInit.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+FspSiliconInitDone (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  This function returns control to BootLoader after MemoryInitApi.\r
+\r
+  @param[in,out] HobListPtr The address of HobList pointer.\r
+**/\r
+VOID\r
+EFIAPI\r
+FspMemoryInitDone (\r
+  IN OUT VOID   **HobListPtr\r
+  );\r
+\r
+/**\r
+  This function returns control to BootLoader after TempRamExitApi.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+FspTempRamExitDone (\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/IntelFsp2Pkg/Include/Library/FspSecPlatformLib.h b/IntelFsp2Pkg/Include/Library/FspSecPlatformLib.h
new file mode 100644 (file)
index 0000000..cf2b0ff
--- /dev/null
@@ -0,0 +1,88 @@
+/** @file\r
+\r
+  Copyright (c) 2015 - 2016, 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_SEC_PLATFORM_LIB_H_\r
+#define _FSP_SEC_PLATFORM_LIB_H_\r
+\r
+/**\r
+  This function performs platform level initialization.\r
+\r
+  This function must be in ASM file, because stack is not established yet.\r
+  This function is optional. If a library instance does not provide this function, the default empty one will be used.\r
+\r
+  The callee should not use XMM6/XMM7.\r
+  The return address is saved in MM7.\r
+\r
+  @retval in saved in EAX - 0 means platform initialization success.\r
+                            other means platform initialization fail.\r
+**/\r
+UINT32\r
+EFIAPI\r
+SecPlatformInit (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  This function loads Microcode.\r
+\r
+  This function must be in ASM file, because stack is not established yet.\r
+  This function is optional. If a library instance does not provide this function, the default one will be used.\r
+\r
+  The callee should not use XMM6/XMM7.\r
+  The return address is saved in MM7.\r
+\r
+  @param[in] FsptUpdDataPtr     Address pointer to the FSPT_UPD data structure. It is saved in ESP.\r
+\r
+  @retval in saved in EAX - 0 means Microcode is loaded successfully.\r
+                            other means Microcode is not loaded successfully.\r
+**/\r
+UINT32\r
+EFIAPI\r
+LoadMicrocode (\r
+  IN  VOID    *FsptUpdDataPtr\r
+  );\r
+\r
+/**\r
+  This function initializes the CAR.\r
+\r
+  This function must be in ASM file, because stack is not established yet.\r
+\r
+  The callee should not use XMM6/XMM7.\r
+  The return address is saved in MM7.\r
+\r
+  @param[in] FsptUpdDataPtr     Address pointer to the FSPT_UPD data structure. It is saved in ESP.\r
+\r
+  @retval in saved in EAX - 0 means CAR initialization success.\r
+                            other means CAR initialization fail.\r
+**/\r
+UINT32\r
+EFIAPI\r
+SecCarInit (\r
+  IN  VOID    *FsptUpdDataPtr\r
+  );\r
+\r
+/**\r
+  This function check the signture of UPD.\r
+\r
+  @param[in]  ApiIdx           Internal index of the FSP API.\r
+  @param[in]  ApiParam         Parameter of the FSP API.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FspUpdSignatureCheck (\r
+  IN UINT32   ApiIdx,\r
+  IN VOID     *ApiParam\r
+  );\r
+\r
+#endif\r
diff --git a/IntelFsp2Pkg/Include/Library/FspSwitchStackLib.h b/IntelFsp2Pkg/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/IntelFsp2Pkg/IntelFsp2Pkg.dec b/IntelFsp2Pkg/IntelFsp2Pkg.dec
new file mode 100644 (file)
index 0000000..52024af
--- /dev/null
@@ -0,0 +1,80 @@
+## @file\r
+# Provides driver and definitions to build fsp in EDKII bios.\r
+#\r
+# Copyright (c) 2014 - 2016, 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
+  DEC_SPECIFICATION              = 0x00010005\r
+  PACKAGE_NAME                   = IntelFsp2Pkg\r
+  PACKAGE_GUID                   = A8C53B5E-D556-4F3E-874D-0D6FA2CDC7BF\r
+  PACKAGE_VERSION                = 0.1\r
+\r
+[Includes]\r
+  Include\r
+  \r
+[LibraryClasses]\r
+  ##  @libraryclass  Provides cache-as-ram support.\r
+  CacheAsRamLib|Include/Library/CacheAsRamLib.h\r
+\r
+  ##  @libraryclass  Provides cache setting on MTRR.\r
+  CacheLib|Include/Library/CacheLib.h\r
+\r
+  ##  @libraryclass  Provides debug device abstraction.\r
+  DebugDeviceLib|Include/Library/DebugDeviceLib.h\r
+\r
+  ##  @libraryclass  Provides FSP related services.\r
+  FspCommonLib|Include/Library/FspCommonLib.h\r
+\r
+  ##  @libraryclass  Provides FSP platform related actions.\r
+  FspPlatformLib|Include/Library/FspPlatformLib.h\r
+\r
+  ##  @libraryclass  Provides FSP switch stack function.\r
+  FspSwitchStackLib|Include/Library/FspSwitchStackLib.h\r
+  \r
+  ##  @libraryclass  Provides FSP platform sec related actions.\r
+  FspSecPlatformLib|Include/Library/FspSecPlatformLib.h\r
+\r
+[Guids]\r
+  #\r
+  # GUID defined in package\r
+  #\r
+  gIntelFsp2PkgTokenSpaceGuid           = { 0xed6e0531, 0xf715, 0x4a3d, { 0x9b, 0x12, 0xc1, 0xca, 0x5e, 0xf6, 0x98, 0xa2 } }\r
+\r
+  # Guid define in FSP EAS\r
+  gFspHeaderFileGuid                    = { 0x912740BE, 0x2284, 0x4734, { 0xB9, 0x71, 0x84, 0xB0, 0x27, 0x35, 0x3F, 0x0C } }\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
+  gFspBootLoaderTolumHobGuid            = { 0x73ff4f56, 0xaa8e, 0x4451, { 0xb3, 0x16, 0x36, 0x35, 0x36, 0x67, 0xad, 0x44 } } # FSP EAS v1.1\r
+\r
+  gFspPerformanceDataGuid               = { 0x56ed21b6, 0xba23, 0x429e, { 0x89, 0x32, 0x37, 0x6d, 0x8e, 0x18, 0x2e, 0xe3 } }\r
+  gFspEventEndOfFirmwareGuid            = { 0xbd44f629, 0xeae7, 0x4198, { 0x87, 0xf1, 0x39, 0xfa, 0xb0, 0xfd, 0x71, 0x7e } }\r
+\r
+[PcdsFixedAtBuild]\r
+  gIntelFsp2PkgTokenSpaceGuid.PcdGlobalDataPointerAddress |0xFED00108|UINT32|0x00000001\r
+  gIntelFsp2PkgTokenSpaceGuid.PcdTemporaryRamBase         |0xFEF00000|UINT32|0x10001001\r
+  gIntelFsp2PkgTokenSpaceGuid.PcdTemporaryRamSize         |    0x2000|UINT32|0x10001002\r
+  gIntelFsp2PkgTokenSpaceGuid.PcdFspTemporaryRamSize      |    0x1000|UINT32|0x10001003\r
+  gIntelFsp2PkgTokenSpaceGuid.PcdFspReservedBufferSize    |     0x100|UINT32|0x10001004\r
+  gIntelFsp2PkgTokenSpaceGuid.PcdFspMaxPerfEntry          |        32|UINT32|0x00002001\r
+  gIntelFsp2PkgTokenSpaceGuid.PcdFspMaxPatchEntry         |         6|UINT32|0x00002002\r
+  gIntelFsp2PkgTokenSpaceGuid.PcdFspAreaBaseAddress       |0xFFF80000|UINT32|0x10000001\r
+  gIntelFsp2PkgTokenSpaceGuid.PcdFspAreaSize              |0x00040000|UINT32|0x10000002\r
+  gIntelFsp2PkgTokenSpaceGuid.PcdFspBootFirmwareVolumeBase|0xFFF80000|UINT32|0x10000003\r
+  gIntelFsp2PkgTokenSpaceGuid.PcdFspHeaderSpecVersion     |      0x20| UINT8|0x00000002\r
+\r
+  # x % of FSP temporary memory will be used for heap\r
+  # (100 - x) % of FSP temporary memory will be used for stack\r
+  gIntelFsp2PkgTokenSpaceGuid.PcdFspHeapSizePercentage    |        50| UINT8|0x10000004\r
+  \r
+[PcdsFixedAtBuild,PcdsDynamic,PcdsDynamicEx]\r
+  gIntelFsp2PkgTokenSpaceGuid.PcdFspReservedMemoryLength |0x00100000|UINT32|0x46530000\r
+  gIntelFsp2PkgTokenSpaceGuid.PcdBootLoaderEntry         |0xFFFFFFE4|UINT32|0x46530100\r
diff --git a/IntelFsp2Pkg/IntelFsp2Pkg.dsc b/IntelFsp2Pkg/IntelFsp2Pkg.dsc
new file mode 100644 (file)
index 0000000..3b50bbf
--- /dev/null
@@ -0,0 +1,77 @@
+## @file\r
+# Provides driver and definitions to build fsp.\r
+#\r
+# Copyright (c) 2014 - 2016, 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                  = IntelFsp2Pkg\r
+  PLATFORM_GUID                  = 55CA3D18-831B-469A-A1C3-7AE719EB6A97\r
+  PLATFORM_VERSION               = 0.1\r
+  DSC_SPECIFICATION              = 0x00010005\r
+  OUTPUT_DIRECTORY               = Build/IntelFsp2Pkg\r
+  SUPPORTED_ARCHITECTURES        = IA32\r
+  BUILD_TARGETS                  = DEBUG|RELEASE|NOOPT\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
+  ReportStatusCodeLib|MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.inf\r
+  PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf\r
+  SerialPortLib|MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.inf\r
+  ReportStatusCodeLib|MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.inf\r
+  DebugDeviceLib|IntelFsp2Pkg/Library/BaseDebugDeviceLibNull/BaseDebugDeviceLibNull.inf\r
+\r
+  # FSP override\r
+  DebugLib|IntelFsp2Pkg/Library/BaseFspDebugLibSerialPort/BaseFspDebugLibSerialPort.inf\r
+\r
+  # FSP specific lib\r
+  CacheAsRamLib|IntelFsp2Pkg/Library/BaseCacheAsRamLibNull/BaseCacheAsRamLibNull.inf\r
+  CacheLib|IntelFsp2Pkg/Library/BaseCacheLib/BaseCacheLib.inf\r
+  FspCommonLib|IntelFsp2Pkg/Library/BaseFspCommonLib/BaseFspCommonLib.inf\r
+  FspPlatformLib|IntelFsp2Pkg/Library/BaseFspPlatformLib/BaseFspPlatformLib.inf\r
+  FspSwitchStackLib|IntelFsp2Pkg/Library/BaseFspSwitchStackLib/BaseFspSwitchStackLib.inf\r
+  FspSecPlatformLib|IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/SecFspSecPlatformLibNull.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
+  IntelFsp2Pkg/Library/BaseCacheAsRamLibNull/BaseCacheAsRamLibNull.inf\r
+  IntelFsp2Pkg/Library/BaseCacheLib/BaseCacheLib.inf\r
+  IntelFsp2Pkg/Library/BaseFspCommonLib/BaseFspCommonLib.inf\r
+  IntelFsp2Pkg/Library/BaseFspDebugLibSerialPort/BaseFspDebugLibSerialPort.inf\r
+  IntelFsp2Pkg/Library/BaseFspPlatformLib/BaseFspPlatformLib.inf\r
+  IntelFsp2Pkg/Library/BaseFspSwitchStackLib/BaseFspSwitchStackLib.inf\r
+\r
+  IntelFsp2Pkg/FspSecCore/FspSecCoreT.inf\r
+  IntelFsp2Pkg/FspSecCore/FspSecCoreM.inf\r
+  IntelFsp2Pkg/FspSecCore/FspSecCoreS.inf\r
+  IntelFsp2Pkg/FspNotifyPhase/FspNotifyPhasePeim.inf\r
+\r
+[PcdsFixedAtBuild.common]\r
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x1f\r
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80080046\r
+  gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x07\r
diff --git a/IntelFsp2Pkg/Library/BaseCacheAsRamLibNull/BaseCacheAsRamLibNull.inf b/IntelFsp2Pkg/Library/BaseCacheAsRamLibNull/BaseCacheAsRamLibNull.inf
new file mode 100644 (file)
index 0000000..bdb6744
--- /dev/null
@@ -0,0 +1,31 @@
+## @file\r
+#  NULL instance of Base cache as RAM.\r
+#\r
+#  Copyright (c) 2014 - 2015, 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                      = 630AEB10-2106-4234-9DB3-836A3663F50D\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
+  IntelFsp2Pkg/IntelFsp2Pkg.dec\r
+\r
+[LibraryClasses]\r
+\r
diff --git a/IntelFsp2Pkg/Library/BaseCacheAsRamLibNull/DisableCacheAsRamNull.c b/IntelFsp2Pkg/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/IntelFsp2Pkg/Library/BaseCacheLib/BaseCacheLib.inf b/IntelFsp2Pkg/Library/BaseCacheLib/BaseCacheLib.inf
new file mode 100644 (file)
index 0000000..7b026b1
--- /dev/null
@@ -0,0 +1,34 @@
+## @file\r
+#  Instance of BaseCache.\r
+#\r
+#  Copyright (c) 2014 - 2015, 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                      = 8EF3A653-DA8B-4FFA-BB85-FF47406DB9F0\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
+  IntelFsp2Pkg/IntelFsp2Pkg.dec\r
+\r
+[LibraryClasses]\r
+  BaseMemoryLib\r
+  CacheAsRamLib\r
+\r
diff --git a/IntelFsp2Pkg/Library/BaseCacheLib/CacheLib.c b/IntelFsp2Pkg/Library/BaseCacheLib/CacheLib.c
new file mode 100644 (file)
index 0000000..b38dce3
--- /dev/null
@@ -0,0 +1,703 @@
+/** @file\r
+\r
+  Copyright (c) 2014 - 2015, 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
+  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 FALSE 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 |= (UINT64)(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
+  Result = GetPowerOfTwo64(MemoryLength);\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
+  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/IntelFsp2Pkg/Library/BaseCacheLib/CacheLibInternal.h b/IntelFsp2Pkg/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/IntelFsp2Pkg/Library/BaseDebugDeviceLibNull/BaseDebugDeviceLibNull.inf b/IntelFsp2Pkg/Library/BaseDebugDeviceLibNull/BaseDebugDeviceLibNull.inf
new file mode 100644 (file)
index 0000000..5e4c572
--- /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                      = 5E975522-176F-4E2D-BB25-64ADCC7792A4\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
+  IntelFsp2Pkg/IntelFsp2Pkg.dec\r
+\r
diff --git a/IntelFsp2Pkg/Library/BaseDebugDeviceLibNull/DebugDeviceLibNull.c b/IntelFsp2Pkg/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/IntelFsp2Pkg/Library/BaseFspCommonLib/BaseFspCommonLib.inf b/IntelFsp2Pkg/Library/BaseFspCommonLib/BaseFspCommonLib.inf
new file mode 100644 (file)
index 0000000..0b0741b
--- /dev/null
@@ -0,0 +1,39 @@
+## @file\r
+#  Instance of FspCommonLib \r
+#  Copyright (c) 2014 - 2016, 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                      = 38BE57E8-902C-485A-AB5E-D5AEC613194D\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
+  IntelFsp2Pkg/IntelFsp2Pkg.dec\r
+\r
+[LibraryClasses]\r
+  BaseMemoryLib\r
+\r
+[Pcd]\r
+  gIntelFsp2PkgTokenSpaceGuid.PcdGlobalDataPointerAddress      ## CONSUMES\r
+\r
+[FixedPcd]\r
+  gIntelFsp2PkgTokenSpaceGuid.PcdFspMaxPatchEntry              ## CONSUMES\r
+  gIntelFsp2PkgTokenSpaceGuid.PcdFspMaxPerfEntry               ## CONSUMES\r
+  gIntelFsp2PkgTokenSpaceGuid.PcdTemporaryRamBase              ## CONSUMES\r
+  gIntelFsp2PkgTokenSpaceGuid.PcdTemporaryRamSize              ## CONSUMES\r
diff --git a/IntelFsp2Pkg/Library/BaseFspCommonLib/FspCommonLib.c b/IntelFsp2Pkg/Library/BaseFspCommonLib/FspCommonLib.c
new file mode 100644 (file)
index 0000000..efd55f4
--- /dev/null
@@ -0,0 +1,546 @@
+/** @file\r
+\r
+  Copyright (c) 2014 - 2016, 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 <FspEas.h>\r
+#include <FspDataTable.h>\r
+\r
+#pragma pack(1)\r
+\r
+//\r
+//   API Parameter                +0x34\r
+//   API return address           +0x30\r
+//\r
+//   push    FspInfoHeader        +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    FspInfoHeader;\r
+  UINT32    ApiRet;\r
+  UINT32    ApiParam[2];\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 first parameter passed by the bootlaoder.\r
+\r
+  @retval ApiParameter FSP API first parameter 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[0]));\r
+}\r
+\r
+/**\r
+  This function gets back the FSP API second parameter passed by the bootlaoder.\r
+\r
+  @retval ApiParameter FSP API second parameter passed by the bootlaoder.\r
+**/\r
+UINT32\r
+EFIAPI\r
+GetFspApiParameter2 (\r
+  VOID\r
+  )\r
+{\r
+  FSP_GLOBAL_DATA  *FspData;\r
+\r
+  FspData  = GetFspGlobalDataPointer ();\r
+  return *(UINT32 *)(UINTN)(FspData->CoreStack + CONTEXT_STACK_OFFSET(ApiParam[1]));\r
+}\r
+\r
+/**\r
+  This function sets the FSP API parameter 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 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] UpdDataPtr   UPD data pointer.\r
+**/\r
+VOID\r
+EFIAPI\r
+SetFspUpdDataPointer (\r
+  IN VOID    *UpdDataPtr\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->UpdDataPtr = UpdDataPtr;\r
+}\r
+\r
+/**\r
+  This function gets the UPD data pointer.\r
+\r
+  @return UpdDataPtr   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->UpdDataPtr;\r
+}\r
+\r
+\r
+/**\r
+  This function sets the memory init UPD data pointer.\r
+\r
+  @param[in] MemoryInitUpdPtr   memory init UPD data pointer.\r
+**/\r
+VOID\r
+EFIAPI\r
+SetFspMemoryInitUpdDataPointer (\r
+  IN VOID    *MemoryInitUpdPtr\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 memory init UPD pointer.\r
+  //\r
+  FspData->MemoryInitUpdPtr = MemoryInitUpdPtr;\r
+}\r
+\r
+/**\r
+  This function gets the memory init UPD data pointer.\r
+\r
+  @return memory init UPD data pointer.\r
+**/\r
+VOID *\r
+EFIAPI\r
+GetFspMemoryInitUpdDataPointer (\r
+  VOID\r
+  )\r
+{\r
+  FSP_GLOBAL_DATA  *FspData;\r
+\r
+  FspData  = GetFspGlobalDataPointer ();\r
+  return FspData->MemoryInitUpdPtr;\r
+}\r
+\r
+\r
+/**\r
+  This function sets the silicon init UPD data pointer.\r
+\r
+  @param[in] SiliconInitUpdPtr   silicon init UPD data pointer.\r
+**/\r
+VOID\r
+EFIAPI\r
+SetFspSiliconInitUpdDataPointer (\r
+  IN VOID    *SiliconInitUpdPtr\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 silicon init UPD data pointer.\r
+  //\r
+  FspData->SiliconInitUpdPtr = SiliconInitUpdPtr;\r
+}\r
+\r
+/**\r
+  This function gets the silicon init UPD data pointer.\r
+\r
+  @return silicon init UPD data pointer.\r
+**/\r
+VOID *\r
+EFIAPI\r
+GetFspSiliconInitUpdDataPointer (\r
+  VOID\r
+  )\r
+{\r
+  FSP_GLOBAL_DATA  *FspData;\r
+\r
+  FspData  = GetFspGlobalDataPointer ();\r
+  return FspData->SiliconInitUpdPtr;\r
+}\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
+\r
+/**\r
+  This function gets the FSP info header pointer.\r
+\r
+  @retval FspInfoHeader   FSP info header pointer\r
+**/\r
+FSP_INFO_HEADER *\r
+EFIAPI\r
+GetFspInfoHeader (\r
+  VOID\r
+  )\r
+{\r
+  return  GetFspGlobalDataPointer()->FspInfoHeader;\r
+}\r
+\r
+/**\r
+  This function sets the FSP info header pointer.\r
+\r
+  @param[in] FspInfoHeader   FSP info header pointer\r
+**/\r
+VOID\r
+EFIAPI\r
+SetFspInfoHeader (\r
+  FSP_INFO_HEADER *FspInfoHeader\r
+  )\r
+{\r
+  GetFspGlobalDataPointer()->FspInfoHeader = FspInfoHeader;\r
+}\r
+\r
+/**\r
+  This function gets the FSP info header pointer using the API stack context.\r
+\r
+  @retval FspInfoHeader   FSP info header pointer using the API stack context\r
+**/\r
+FSP_INFO_HEADER *\r
+EFIAPI\r
+GetFspInfoHeaderFromApiContext (\r
+  VOID\r
+  )\r
+{\r
+  FSP_GLOBAL_DATA  *FspData;\r
+\r
+  FspData  = GetFspGlobalDataPointer ();\r
+  return  (FSP_INFO_HEADER *)(*(UINT32 *)(UINTN)(FspData->CoreStack + CONTEXT_STACK_OFFSET(FspInfoHeader)));\r
+}\r
+\r
+/**\r
+  This function gets the VPD data pointer.\r
+\r
+  @return VpdDataRgnPtr   VPD data pointer.\r
+**/\r
+VOID *\r
+EFIAPI\r
+GetFspVpdDataPointer (\r
+  VOID\r
+  )\r
+{\r
+  FSP_INFO_HEADER   *FspInfoHeader;\r
+\r
+  FspInfoHeader = GetFspInfoHeader ();\r
+  return (VOID *)(FspInfoHeader->ImageBase + FspInfoHeader->CfgRegionOffset);\r
+}\r
+\r
+/**\r
+  This function gets FSP API calling index.\r
+\r
+  @retval API calling index\r
+**/\r
+UINT8\r
+EFIAPI\r
+GetFspApiCallingIndex (\r
+  VOID\r
+  )\r
+{\r
+  return  GetFspGlobalDataPointer()->ApiIdx;\r
+}\r
+\r
+/**\r
+  This function sets FSP API calling mode.\r
+\r
+  @param[in] Index     API calling index\r
+**/\r
+VOID\r
+EFIAPI\r
+SetFspApiCallingIndex (\r
+  UINT8  Index\r
+  )\r
+{\r
+  FSP_GLOBAL_DATA  *FspData;\r
+\r
+  FspData  = GetFspGlobalDataPointer ();\r
+  FspData->ApiIdx = Index;\r
+}\r
+\r
+/**\r
+  This function gets FSP Phase StatusCode.\r
+\r
+  @retval StatusCode\r
+**/\r
+UINT32\r
+EFIAPI\r
+GetPhaseStatusCode (\r
+  VOID\r
+  )\r
+{\r
+  return  GetFspGlobalDataPointer()->StatusCode;\r
+}\r
+\r
+/**\r
+  This function sets FSP Phase StatusCode.\r
+\r
+  @param[in] Mode     Phase StatusCode\r
+**/\r
+VOID\r
+EFIAPI\r
+SetPhaseStatusCode (\r
+  UINT32  StatusCode\r
+  )\r
+{\r
+  FSP_GLOBAL_DATA  *FspData;\r
+\r
+  FspData  = GetFspGlobalDataPointer ();\r
+  FspData->StatusCode = StatusCode;\r
+}\r
+\r
+/**\r
+  This function gets FSP CAR base.\r
+\r
+**/\r
+UINT32\r
+EFIAPI\r
+GetFspCarBase (\r
+  VOID\r
+  )\r
+{\r
+  FSP_GLOBAL_DATA  *FspData;\r
+  UINT32           CarBase;\r
+\r
+  FspData  = GetFspGlobalDataPointer ();\r
+  CarBase = FspData->PlatformData.CarBase;\r
+  if (CarBase == 0) {\r
+    CarBase = PcdGet32(PcdTemporaryRamBase);\r
+  }\r
+  return CarBase;\r
+}\r
+\r
+/**\r
+  This function gets FSP CAR size.\r
+\r
+**/\r
+UINT32\r
+EFIAPI\r
+GetFspCarSize (\r
+  VOID\r
+  )\r
+{\r
+  FSP_GLOBAL_DATA  *FspData;\r
+  UINT32           CarSize;\r
+\r
+  FspData  = GetFspGlobalDataPointer ();\r
+  CarSize = FspData->PlatformData.CarSize;\r
+  if (FspData->PlatformData.CarBase == 0) {\r
+    CarSize = PcdGet32(PcdTemporaryRamSize);\r
+  }\r
+  return CarSize;\r
+}\r
diff --git a/IntelFsp2Pkg/Library/BaseFspDebugLibSerialPort/BaseFspDebugLibSerialPort.inf b/IntelFsp2Pkg/Library/BaseFspDebugLibSerialPort/BaseFspDebugLibSerialPort.inf
new file mode 100644 (file)
index 0000000..a7f10d4
--- /dev/null
@@ -0,0 +1,51 @@
+## @file\r
+#  Instance of BaseFspDebugLib\r
+#\r
+#  Copyright (c) 2014 - 2015, 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                      = CEA4FF9C-D7BC-4F07-96F1-03F41F2B17AE\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
+  IntelFsp2Pkg/IntelFsp2Pkg.dec\r
+\r
+[LibraryClasses]\r
+  SerialPortLib\r
+  BaseMemoryLib\r
+  PcdLib\r
+  PrintLib\r
+  BaseLib\r
+  DebugDeviceLib\r
+  DebugPrintErrorLevelLib\r
+\r
+[Pcd]\r
+  gEfiMdePkgTokenSpaceGuid.PcdDebugClearMemoryValue       ## CONSUMES\r
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask           ## CONSUMES\r
+  gEfiMdePkgTokenSpaceGuid.PcdFixedDebugPrintErrorLevel   ## CONSUMES\r
+\r
diff --git a/IntelFsp2Pkg/Library/BaseFspDebugLibSerialPort/DebugLib.c b/IntelFsp2Pkg/Library/BaseFspDebugLibSerialPort/DebugLib.c
new file mode 100644 (file)
index 0000000..73bb08e
--- /dev/null
@@ -0,0 +1,328 @@
+/** @file\r
+\r
+  Copyright (c) 2014 - 2015, 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
+  AsciiStrnCpyS (\r
+    Buffer,\r
+    sizeof(Buffer) / sizeof(CHAR8),\r
+    "-> EBP:0x00000000  EIP:0x00000000\n",\r
+    sizeof(Buffer) / sizeof(CHAR8) - 1\r
+    );\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
+\r
+/**\r
+  Returns TRUE if any one of the bit is set both in ErrorLevel and PcdFixedDebugPrintErrorLevel.\r
+\r
+  This function compares the bit mask of ErrorLevel and PcdFixedDebugPrintErrorLevel.\r
+\r
+  @retval  TRUE    Current ErrorLevel is supported.\r
+  @retval  FALSE   Current ErrorLevel is not supported.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+DebugPrintLevelEnabled (\r
+  IN  CONST UINTN        ErrorLevel\r
+  )\r
+{\r
+  return (BOOLEAN) ((ErrorLevel & PcdGet32(PcdFixedDebugPrintErrorLevel)) != 0);\r
+}\r
diff --git a/IntelFsp2Pkg/Library/BaseFspDebugLibSerialPort/Ia32/FspDebug.asm b/IntelFsp2Pkg/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/IntelFsp2Pkg/Library/BaseFspDebugLibSerialPort/Ia32/FspDebug.s b/IntelFsp2Pkg/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/IntelFsp2Pkg/Library/BaseFspPlatformLib/BaseFspPlatformLib.inf b/IntelFsp2Pkg/Library/BaseFspPlatformLib/BaseFspPlatformLib.inf
new file mode 100644 (file)
index 0000000..d04689e
--- /dev/null
@@ -0,0 +1,50 @@
+## @file\r
+# Instance of FspPlatformLib\r
+#\r
+#  Copyright (c) 2014 - 2016, 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                      = B6380BFB-7140-4C52-AC42-8C966C9A3F34\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
+  IntelFsp2Pkg/IntelFsp2Pkg.dec\r
+\r
+[LibraryClasses]\r
+  BaseMemoryLib\r
+  MemoryAllocationLib\r
+  FspCommonLib\r
+  PerformanceLib\r
+  ReportStatusCodeLib\r
+\r
+[Pcd]\r
+  gIntelFsp2PkgTokenSpaceGuid.PcdGlobalDataPointerAddress    ## CONSUMES\r
+  gIntelFsp2PkgTokenSpaceGuid.PcdTemporaryRamBase            ## CONSUMES\r
+  gIntelFsp2PkgTokenSpaceGuid.PcdTemporaryRamSize            ## CONSUMES\r
+  gIntelFsp2PkgTokenSpaceGuid.PcdFspTemporaryRamSize         ## CONSUMES\r
+\r
+[Guids]\r
+  gFspPerformanceDataGuid                                   ## CONSUMES ## GUID\r
+  gFspEventEndOfFirmwareGuid                                ## PRODUCES ## GUID\r
+\r
+[FixedPcd]\r
+  gIntelFsp2PkgTokenSpaceGuid.PcdFspMaxPatchEntry        ## CONSUMES\r
+  gIntelFsp2PkgTokenSpaceGuid.PcdFspMaxPerfEntry         ## CONSUMES\r
diff --git a/IntelFsp2Pkg/Library/BaseFspPlatformLib/FspPlatformMemory.c b/IntelFsp2Pkg/Library/BaseFspPlatformLib/FspPlatformMemory.c
new file mode 100644 (file)
index 0000000..d6684f3
--- /dev/null
@@ -0,0 +1,189 @@
+/** @file\r
+\r
+  Copyright (c) 2014 - 2016, 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/MemoryAllocationLib.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 <FspGlobalData.h>\r
+#include <FspEas.h>\r
+\r
+/**\r
+  Get system memory resource descriptor by owner.\r
+\r
+  @param[in] OwnerGuid   resource owner guid\r
+**/\r
+EFI_HOB_RESOURCE_DESCRIPTOR *\r
+EFIAPI\r
+FspGetResourceDescriptorByOwner (\r
+  IN EFI_GUID   *OwnerGuid\r
+  )\r
+{\r
+  EFI_PEI_HOB_POINTERS    Hob;\r
+\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_MEMORY_RESERVED) && \\r
+          (CompareGuid (&Hob.ResourceDescriptor->Owner, OwnerGuid))) {\r
+        return  Hob.ResourceDescriptor;                     \r
+      }\r
+    }\r
+    Hob.Raw = GET_NEXT_HOB (Hob);\r
+  }\r
+  \r
+  return NULL;\r
+}\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_STATUS                  Status;\r
+  EFI_BOOT_MODE               BootMode;\r
+  EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttribute;\r
+  EFI_PEI_HOB_POINTERS        Hob;\r
+\r
+  ResourceAttribute = (\r
+                       EFI_RESOURCE_ATTRIBUTE_PRESENT |\r
+                       EFI_RESOURCE_ATTRIBUTE_INITIALIZED |\r
+                       EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |\r
+                       EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |\r
+                       EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |\r
+                       EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE\r
+                       );\r
+\r
+  Status = PeiServicesGetBootMode (&BootMode);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  if (BootMode != BOOT_ON_S3_RESUME) {\r
+    ResourceAttribute |= EFI_RESOURCE_ATTRIBUTE_TESTED;\r
+  }\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
+          ((Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_MEMORY_RESERVED) &&\r
+           (Hob.ResourceDescriptor->ResourceAttribute == ResourceAttribute))) {\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
+  UINT32                    BootLoaderTempRamStart;\r
+  UINT32                    BootLoaderTempRamEnd;\r
+  UINT32                    BootLoaderTempRamSize;\r
+  UINT32                    OffsetGap;\r
+  UINT32                    FspParamPtr;\r
+  VOID                      *BootLoaderTempRamHob;\r
+  UINT32                    MemoryInitUpdPtr;\r
+  VOID                      *PlatformDataPtr;\r
+\r
+  //\r
+  // Get the temporary memory range used by the BootLoader\r
+  //\r
+  BootLoaderTempRamStart = GetFspCarBase ();\r
+  BootLoaderTempRamSize  = GetFspCarSize () - PcdGet32(PcdFspTemporaryRamSize);\r
+\r
+  BootLoaderTempRamEnd   = BootLoaderTempRamStart +  BootLoaderTempRamSize;\r
+\r
+  //\r
+  // Build a Boot Loader Temporary Memory GUID HOB\r
+  //\r
+  BootLoaderTempRamHob = (VOID *)AllocatePages (EFI_SIZE_TO_PAGES (BootLoaderTempRamSize));\r
+  ASSERT(BootLoaderTempRamHob != NULL);\r
+\r
+  DEBUG ((DEBUG_INFO, "FSP_BOOT_LOADER_TEMPORARY_MEMORY_HOB\n"));\r
+  DEBUG ((DEBUG_INFO, "FspBootLoaderTemporaryMemory Base : %x\n", BootLoaderTempRamStart));\r
+  DEBUG ((DEBUG_INFO, "FspBootLoaderTemporaryMemory Size : %x\n", BootLoaderTempRamSize));\r
+\r
+  CopyMem (BootLoaderTempRamHob, (VOID *)BootLoaderTempRamStart, BootLoaderTempRamSize);\r
+  OffsetGap = (UINT32)BootLoaderTempRamHob - BootLoaderTempRamStart;\r
+\r
+  //\r
+  // Fix the FspMemoryinit Parameter Pointers to the new location.\r
+  //\r
+  FspParamPtr = GetFspApiParameter ();\r
+  if ((VOID *)FspParamPtr != NULL && FspParamPtr >= BootLoaderTempRamStart && \r
+      FspParamPtr < BootLoaderTempRamEnd) {\r
+    SetFspApiParameter (FspParamPtr + OffsetGap);\r
+  }\r
+\r
+  //\r
+  // Update UPD pointer in FSP Global Data\r
+  //\r
+  MemoryInitUpdPtr = (UINT32)((UINT32 *)GetFspMemoryInitUpdDataPointer ());\r
+  if (MemoryInitUpdPtr >= BootLoaderTempRamStart && MemoryInitUpdPtr < BootLoaderTempRamEnd) {\r
+    SetFspMemoryInitUpdDataPointer ((VOID *)(MemoryInitUpdPtr + OffsetGap));\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
diff --git a/IntelFsp2Pkg/Library/BaseFspPlatformLib/FspPlatformNotify.c b/IntelFsp2Pkg/Library/BaseFspPlatformLib/FspPlatformNotify.c
new file mode 100644 (file)
index 0000000..66b6cdb
--- /dev/null
@@ -0,0 +1,279 @@
+/** @file\r
+\r
+  Copyright (c) 2014 - 2016, 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 <FspEas.h>\r
+#include <FspStatusCode.h>\r
+#include <Protocol/PciEnumerationComplete.h>\r
+#include <Library/ReportStatusCodeLib.h>\r
+#include <Library/PerformanceLib.h>\r
+extern EFI_GUID gFspPerformanceDataGuid;\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
+EFI_PEI_PPI_DESCRIPTOR      mPeiEndOfFirmwarePpi = {\r
+  (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
+  &gFspEventEndOfFirmwareGuid,\r
+  NULL\r
+};\r
+\r
+UINT32  mFspNotifySequence[] = {\r
+  EnumInitPhaseAfterPciEnumeration,\r
+  EnumInitPhaseReadyToBoot,\r
+  EnumInitPhaseEndOfFirmware\r
+};\r
+\r
+/**\r
+  Install FSP notification.\r
+\r
+  @param[in] NotificationCode  FSP notification code\r
+\r
+  @retval EFI_SUCCESS            Notify FSP successfully\r
+  @retval EFI_INVALID_PARAMETER  NotificationCode is invalid\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FspNotificationHandler (\r
+  IN  UINT32     NotificationCode\r
+  )\r
+{\r
+  EFI_STATUS                Status;\r
+\r
+  Status   = EFI_SUCCESS;\r
+\r
+  switch (NotificationCode) {\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
+  case EnumInitPhaseEndOfFirmware:\r
+    //\r
+    // End of Firmware\r
+    //\r
+    DEBUG ((DEBUG_INFO| DEBUG_INIT, "FSP End of Firmware ...\n"));\r
+    PeiServicesInstallPpi (&mPeiEndOfFirmwarePpi);\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 back to BootLoader after FspSiliconInit.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+FspSiliconInitDone (\r
+  VOID\r
+  )\r
+{\r
+  //\r
+  // This is the end of the FspSiliconInit API\r
+  // Give control back to the boot loader\r
+  //\r
+  SetFspMeasurePoint (FSP_PERF_ID_API_FSP_SILICON_INIT_EXIT);\r
+  DEBUG ((DEBUG_INFO | DEBUG_INIT, "FspSiliconInitApi() - End\n"));\r
+\r
+  PERF_END_EX (&gFspPerformanceDataGuid, "EventRec", NULL, 0, 0x907F);\r
+\r
+  REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);\r
+  SetFspApiReturnStatus (EFI_SUCCESS);\r
+\r
+  Pei2LoaderSwitchStack();\r
+\r
+  PERF_START_EX (&gFspPerformanceDataGuid, "EventRec", NULL, 0, 0x6000);\r
+}\r
+\r
+/**\r
+  This function returns control to BootLoader after MemoryInitApi.\r
+\r
+  @param[in,out] HobListPtr The address of HobList pointer.\r
+**/\r
+VOID\r
+EFIAPI\r
+FspMemoryInitDone (\r
+  IN OUT VOID   **HobListPtr\r
+  )\r
+{\r
+  //\r
+  // Calling use FspMemoryInit API\r
+  // Update HOB and return the control directly\r
+  //\r
+  if (HobListPtr != NULL) {\r
+    *HobListPtr = (VOID *) GetHobList ();\r
+  }\r
+\r
+  //\r
+  // This is the end of the FspMemoryInit API\r
+  // Give control back to the boot loader\r
+  //\r
+  SetFspMeasurePoint (FSP_PERF_ID_API_FSP_MEMORY_INIT_EXIT);\r
+  DEBUG ((DEBUG_INFO | DEBUG_INIT, "FspMemoryInitApi() - End\n"));\r
+  REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_MEMORY_INIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);\r
+  SetFspApiReturnStatus (EFI_SUCCESS);\r
+  Pei2LoaderSwitchStack ();\r
+\r
+  //\r
+  // The TempRamExitApi is called\r
+  //\r
+  if (GetFspApiCallingIndex () == TempRamExitApiIndex) {\r
+    SetPhaseStatusCode (FSP_STATUS_CODE_TEMP_RAM_EXIT);\r
+    REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_TEMP_RAM_EXIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);\r
+    SetFspMeasurePoint (FSP_PERF_ID_API_TEMP_RAM_EXIT_ENTRY);\r
+    DEBUG ((DEBUG_INFO | DEBUG_INIT, "TempRamExitApi() - Begin\n"));\r
+  } else {\r
+    SetFspMeasurePoint (FSP_PERF_ID_API_FSP_SILICON_INIT_ENTRY);\r
+    DEBUG ((DEBUG_INFO | DEBUG_INIT, "FspSiliconInitApi() - Begin\n"));\r
+    SetPhaseStatusCode (FSP_STATUS_CODE_SILICON_INIT);\r
+    REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_SILICON_INIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);\r
+  }\r
+}\r
+\r
+/**\r
+  This function returns control to BootLoader after TempRamExitApi.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+FspTempRamExitDone (\r
+  VOID\r
+  )\r
+{\r
+\r
+  //\r
+  // This is the end of the TempRamExit API\r
+  // Give control back to the boot loader\r
+  //\r
+  SetFspMeasurePoint (FSP_PERF_ID_API_TEMP_RAM_EXIT_EXIT);\r
+  DEBUG ((DEBUG_INFO | DEBUG_INIT, "TempRamExitApi() - End\n"));\r
+  REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_TEMP_RAM_EXIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);\r
+  SetFspApiReturnStatus (EFI_SUCCESS);\r
+  Pei2LoaderSwitchStack ();\r
+\r
+  SetPhaseStatusCode (FSP_STATUS_CODE_SILICON_INIT);\r
+  SetFspMeasurePoint (FSP_PERF_ID_API_FSP_SILICON_INIT_ENTRY);\r
+  DEBUG ((DEBUG_INFO | DEBUG_INIT, "SiliconInitApi() - Begin\n"));\r
+  REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_SILICON_INIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);\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                     NotificationValue;\r
+  UINT32                     NotificationCount;\r
+  UINT8                      Count;\r
+\r
+  NotificationCount = 0;\r
+  while (NotificationCount < sizeof(mFspNotifySequence) / sizeof(UINT32)) {\r
+\r
+    Count = (UINT8)((NotificationCount << 1) & 0x07);\r
+    SetFspMeasurePoint (FSP_PERF_ID_API_NOTIFY_POST_PCI_ENTRY + Count);\r
+\r
+    if (NotificationCount == 0) {\r
+      SetPhaseStatusCode (FSP_STATUS_CODE_POST_PCIE_ENUM_NOTIFICATION);\r
+      REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_POST_PCIE_ENUM_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);\r
+    } else if (NotificationCount == 1) {\r
+      SetPhaseStatusCode (FSP_STATUS_CODE_READY_TO_BOOT_NOTIFICATION);\r
+      REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_READY_TO_BOOT_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);\r
+    } else if (NotificationCount == 2) {\r
+      SetPhaseStatusCode (FSP_STATUS_CODE_END_OF_FIRMWARE_NOTIFICATION);\r
+      REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_END_OF_FIRMWARE_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);\r
+    }\r
+\r
+    NotificationValue = ((NOTIFY_PHASE_PARAMS *)(UINTN)GetFspApiParameter ())->Phase;\r
+    DEBUG ((DEBUG_INFO | DEBUG_INIT, "NotifyPhaseApi() - Begin  [Phase: %08X]\n", NotificationValue));\r
+    if (mFspNotifySequence[NotificationCount] != NotificationValue) {\r
+      //\r
+      // Notify code does not follow the predefined order\r
+      //\r
+      DEBUG ((DEBUG_INFO, "Unsupported FSP Notification Value\n"));\r
+      Status = EFI_UNSUPPORTED;\r
+    } else {\r
+      //\r
+      // Process Notification and Give control back to the boot loader framework caller\r
+      //\r
+      Status = FspNotificationHandler (NotificationValue);\r
+      if (!EFI_ERROR(Status)) {\r
+        NotificationCount++;\r
+      }\r
+    }\r
+\r
+    SetFspApiReturnStatus(Status);\r
+    DEBUG ((DEBUG_INFO | DEBUG_INIT, "NotifyPhaseApi() - End  [Status: 0x%08X]\n", Status));\r
+\r
+    SetFspMeasurePoint (FSP_PERF_ID_API_NOTIFY_POST_PCI_EXIT + Count);\r
+\r
+    if ((NotificationCount - 1) == 0) {\r
+      REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_POST_PCIE_ENUM_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);\r
+    } else if ((NotificationCount - 1) == 1) {\r
+      REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_READY_TO_BOOT_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);\r
+    } else if ((NotificationCount - 1) == 2) {\r
+      REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_END_OF_FIRMWARE_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);\r
+    }\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/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/BaseFspSwitchStackLib.inf b/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/BaseFspSwitchStackLib.inf
new file mode 100644 (file)
index 0000000..bbeeb74
--- /dev/null
@@ -0,0 +1,43 @@
+## @file\r
+#  Instance of BaseFspSwitchStackLib\r
+#\r
+#  Copyright (c) 2014 - 2015, 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                      = 68E79161-F7CE-4A61-8C72-F4DF6FF35CAA\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
+  IntelFsp2Pkg/IntelFsp2Pkg.dec\r
+\r
+[LibraryClasses]\r
+  BaseLib\r
+  IoLib\r
+\r
+[FixedPcd]\r
+  gIntelFsp2PkgTokenSpaceGuid.PcdFspMaxPatchEntry      ## CONSUMES\r
+  gIntelFsp2PkgTokenSpaceGuid.PcdFspMaxPerfEntry       ## CONSUMES\r
+\r
+\r
+\r
diff --git a/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/FspSwitchStackLib.c b/IntelFsp2Pkg/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/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/Ia32/Stack.asm b/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/Ia32/Stack.asm
new file mode 100644 (file)
index 0000000..1efab52
--- /dev/null
@@ -0,0 +1,77 @@
+;------------------------------------------------------------------------------\r
+;\r
+; Copyright (c) 2014 - 2015, 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
+    xor     eax, eax\r
+    jmp     FspSwitchStack\r
+Pei2LoaderSwitchStack   ENDP\r
+\r
+;------------------------------------------------------------------------------\r
+; UINT32\r
+; EFIAPI\r
+; Loader2PeiSwitchStack (\r
+;   VOID\r
+;   )\r
+;------------------------------------------------------------------------------\r
+Loader2PeiSwitchStack   PROC C PUBLIC\r
+    jmp     FspSwitchStack\r
+Loader2PeiSwitchStack   ENDP\r
+\r
+;------------------------------------------------------------------------------\r
+; UINT32\r
+; EFIAPI\r
+; FspSwitchStack (\r
+;   VOID\r
+;   )\r
+;------------------------------------------------------------------------------\r
+EXTERNDEF  C   SwapStack:PROC\r
+FspSwitchStack   PROC C PUBLIC\r
+    ; Save current contexts\r
+    push    eax\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
+    add     esp, 4\r
+    ret\r
+FspSwitchStack   ENDP\r
+\r
+    END\r
diff --git a/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/Ia32/Stack.s b/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/Ia32/Stack.s
new file mode 100644 (file)
index 0000000..a21a5b6
--- /dev/null
@@ -0,0 +1,78 @@
+#------------------------------------------------------------------------------\r
+#\r
+# Copyright (c) 2014 - 2015, 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
+\r
+#------------------------------------------------------------------------------\r
+# UINT32\r
+# EFIAPI\r
+# Pei2LoaderSwitchStack (\r
+#   VOID\r
+#   )\r
+#------------------------------------------------------------------------------\r
+ASM_GLOBAL ASM_PFX(Pei2LoaderSwitchStack)\r
+ASM_PFX(Pei2LoaderSwitchStack):\r
+    xorl    %eax, %eax\r
+    jmp     ASM_PFX(FspSwitchStack)\r
+\r
+#------------------------------------------------------------------------------\r
+# UINT32\r
+# EFIAPI\r
+# Loader2PeiSwitchStack (\r
+#   VOID\r
+#   )\r
+#------------------------------------------------------------------------------\r
+ASM_GLOBAL ASM_PFX(Loader2PeiSwitchStack)\r
+ASM_PFX(Loader2PeiSwitchStack):\r
+    jmp     ASM_PFX(FspSwitchStack)\r
+\r
+#------------------------------------------------------------------------------\r
+# UINT32\r
+# EFIAPI\r
+# FspSwitchStack (\r
+#   VOID\r
+#   )\r
+#------------------------------------------------------------------------------\r
+ASM_GLOBAL ASM_PFX(FspSwitchStack)\r
+ASM_PFX(FspSwitchStack):\r
+    #\r
+    #Save current contexts\r
+    #\r
+    push    %eax\r
+    pushf\r
+    cli\r
+    pusha\r
+    sub     $0x08, %esp\r
+    sidt    (%esp)\r
+\r
+    #\r
+    # Load new stack\r
+    #\r
+    push   %esp\r
+    call   ASM_PFX(SwapStack)\r
+    movl   %eax, %esp\r
+\r
+    #\r
+    # Restore previous contexts\r
+    #\r
+    lidt    (%esp)\r
+    add     $0x08,%esp\r
+    popa\r
+    popf\r
+    add     $0x04,%esp\r
+    ret\r
+\r
+\r
diff --git a/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/Ia32/Flat32.asm b/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/Ia32/Flat32.asm
new file mode 100644 (file)
index 0000000..9f144fc
--- /dev/null
@@ -0,0 +1,131 @@
+;; @file\r
+;  This is the code that goes from real-mode to protected mode.\r
+;  It consumes the reset vector, configures the stack.\r
+;\r
+; Copyright (c) 2015 - 2016, 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
+; Define assembler characteristics\r
+;\r
+.586p\r
+.xmm\r
+.model flat, c\r
+\r
+EXTRN   TempRamInitApi:NEAR\r
+\r
+.code \r
+\r
+RET_ESI  MACRO\r
+\r
+  movd    esi, mm7                      ; restore ESP from MM7\r
+  jmp     esi\r
+\r
+ENDM\r
+\r
+;\r
+; Perform early platform initialization\r
+;\r
+SecPlatformInit    PROC    NEAR    PUBLIC\r
+\r
+  RET_ESI\r
+\r
+SecPlatformInit    ENDP\r
+\r
+;\r
+; Protected mode portion initializes stack, configures cache, and calls C entry point\r
+;\r
+\r
+;----------------------------------------------------------------------------\r
+;\r
+; Procedure:    ProtectedModeEntryPoint\r
+;\r
+; Input:        Executing in 32 Bit Protected (flat) mode\r
+;               cs: 0-4GB\r
+;               ds: 0-4GB\r
+;               es: 0-4GB\r
+;               fs: 0-4GB\r
+;               gs: 0-4GB\r
+;               ss: 0-4GB\r
+;\r
+; Output:       This function never returns\r
+;\r
+; Destroys:\r
+;               ecx\r
+;               edi\r
+;               esi\r
+;               esp\r
+;\r
+; Description:\r
+;               Perform any essential early platform initilaisation\r
+;               Setup a stack\r
+;\r
+;----------------------------------------------------------------------------\r
+\r
+ProtectedModeEntryPoint PROC NEAR C PUBLIC\r
+  ;\r
+  ; Dummy function. Consume 2 API to make sure they can be linked.\r
+  ;\r
+  mov  eax, TempRamInitApi\r
+\r
+  ; Should never return\r
+  jmp  $\r
+\r
+ProtectedModeEntryPoint ENDP\r
+\r
+;\r
+; ROM-based Global-Descriptor Table for the PEI Phase\r
+;\r
+align 16\r
+PUBLIC  BootGdtTable\r
+\r
+;\r
+; GDT[0]: 0x00: Null entry, never used.\r
+;\r
+NULL_SEL        equ     $ - GDT_BASE        ; Selector [0]\r
+GDT_BASE:\r
+BootGdtTable    DD      0\r
+                DD      0\r
+;\r
+; Linear code segment descriptor\r
+;\r
+LINEAR_CODE_SEL equ     $ - GDT_BASE        ; Selector [0x8]\r
+        DW      0FFFFh                      ; limit 0xFFFF\r
+        DW      0                           ; base 0\r
+        DB      0\r
+        DB      09Bh                        ; present, ring 0, data, expand-up, not-writable\r
+        DB      0CFh                        ; page-granular, 32-bit\r
+        DB      0\r
+;\r
+; System data segment descriptor\r
+;\r
+SYS_DATA_SEL    equ     $ - GDT_BASE        ; Selector [0x10]\r
+        DW      0FFFFh                      ; limit 0xFFFF\r
+        DW      0                           ; base 0\r
+        DB      0\r
+        DB      093h                        ; present, ring 0, data, expand-up, not-writable\r
+        DB      0CFh                        ; page-granular, 32-bit\r
+        DB      0\r
+\r
+GDT_SIZE        EQU     $ - BootGDTtable    ; Size, in bytes\r
+\r
+;\r
+; GDT Descriptor\r
+;\r
+GdtDesc:                                    ; GDT descriptor\r
+        DW      GDT_SIZE - 1                ; GDT limit\r
+        DD      OFFSET BootGdtTable         ; GDT base address\r
+\r
+ProtectedModeEntryLinearAddress   LABEL   FWORD\r
+ProtectedModeEntryLinearOffset    LABEL   DWORD\r
+  DD      OFFSET ProtectedModeEntryPoint  ; Offset of our 32 bit code\r
+  DW      LINEAR_CODE_SEL\r
+  \r
+END\r
diff --git a/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/Ia32/Flat32.s b/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/Ia32/Flat32.s
new file mode 100644 (file)
index 0000000..d46d792
--- /dev/null
@@ -0,0 +1,110 @@
+#------------------------------------------------------------------------------\r
+#\r
+# Copyright (c) 2015 - 2016, 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
+#  This is the code that goes from real-mode to protected mode.\r
+#  It consumes the reset vector, configures the stack.\r
+#\r
+#------------------------------------------------------------------------------\r
+\r
+\r
+#\r
+# Contrary to the name, this file contains 16 bit code as well.\r
+#\r
+.text\r
+\r
+ASM_GLOBAL ASM_PFX(SecPlatformInit)\r
+ASM_PFX(SecPlatformInit):\r
+  movd    %mm7, %esi                      # restore ESP from MM7\r
+  jmp     *%esi\r
+\r
+#----------------------------------------------------------------------------\r
+#\r
+# Procedure:    ProtectedModeEntryPoint\r
+#\r
+# Input:        Executing in 32 Bit Protected (flat) mode\r
+#               cs: 0-4GB\r
+#               ds: 0-4GB\r
+#               es: 0-4GB\r
+#               fs: 0-4GB\r
+#               gs: 0-4GB\r
+#               ss: 0-4GB\r
+#\r
+# Output:       This function never returns\r
+#\r
+# Destroys:\r
+#               ecx\r
+#               edi\r
+#               esi\r
+#               esp\r
+#\r
+# Description:\r
+#               Perform any essential early platform initilaisation\r
+#               Setup a stack\r
+#\r
+#----------------------------------------------------------------------------\r
+ProtectedModeEntryPoint:\r
+  #\r
+  # Dummy function. Consume 2 API to make sure they can be linked.\r
+  #\r
+  movl   ASM_PFX(TempRamInitApi), %eax\r
+  #\r
+  # Should never return\r
+  #\r
+  jmp     . #'$'\r
+\r
+#\r
+# ROM-based Global-Descriptor Table for the PEI Phase\r
+#\r
+.align 16\r
+#\r
+# GDT[0]: 000h: Null entry, never used.\r
+#\r
+.equ   NULL_SEL, . - GDT_BASE         # Selector [0]\r
+GDT_BASE: \r
+BootGdtTable:   \r
+        .long   0\r
+        .long   0\r
+#\r
+# Linear code segment descriptor\r
+#\r
+.equ     LINEAR_CODE_SEL, . - GDT_BASE         # Selector [08h]\r
+        .word   0xFFFF                      # limit 0FFFFh\r
+        .word   0                           # base 0\r
+        .byte   0\r
+        .byte   0x9B                        # present, ring 0, data, expand-up, not-writable\r
+        .byte   0xCF                        # page-granular, 32-bit\r
+        .byte   0\r
+#\r
+# System data segment descriptor\r
+#\r
+.equ    SYS_DATA_SEL, . - GDT_BASE         # Selector [010h]\r
+        .word   0xFFFF                      # limit 0FFFFh\r
+        .word   0                           # base 0\r
+        .byte   0\r
+        .byte   0x93                        # present, ring 0, data, expand-up, not-writable\r
+        .byte   0xCF                        # page-granular, 32-bit\r
+        .byte   0\r
+\r
+.equ            GDT_SIZE, . - BootGdtTable  # Size, in bytes\r
+\r
+#\r
+# GDT Descriptor\r
+#\r
+GdtDesc:                                     # GDT descriptor\r
+       .word    GDT_SIZE - 1               \r
+       .long    BootGdtTable        \r
+\r
+ProtectedModeEntryLinearAddress:\r
+ProtectedModeEntryLinearOffset:\r
+       .long    ProtectedModeEntryPoint\r
+       .word    LINEAR_CODE_SEL\r
diff --git a/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/Ia32/SecCarInit.asm b/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/Ia32/SecCarInit.asm
new file mode 100644 (file)
index 0000000..31296e0
--- /dev/null
@@ -0,0 +1,51 @@
+;; @file\r
+;  SEC CAR function\r
+;\r
+; Copyright (c) 2015, 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
+; Define assembler characteristics\r
+;\r
+.586p\r
+.xmm\r
+.model flat, c\r
+\r
+RET_ESI  MACRO\r
+\r
+  movd    esi, mm7                      ; move ReturnAddress from MM7 to ESI\r
+  jmp     esi\r
+\r
+ENDM\r
+\r
+.code \r
+\r
+;-----------------------------------------------------------------------------\r
+;\r
+;  Section:     SecCarInit\r
+;\r
+;  Description: This function initializes the Cache for Data, Stack, and Code\r
+;\r
+;-----------------------------------------------------------------------------\r
+SecCarInit    PROC    NEAR    PUBLIC\r
+\r
+  ;\r
+  ; Set up CAR\r
+  ;\r
+\r
+  xor    eax, eax\r
+\r
+SecCarInitExit:\r
+\r
+  RET_ESI\r
+\r
+SecCarInit    ENDP\r
+\r
+END\r
diff --git a/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/Ia32/SecCarInit.s b/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/Ia32/SecCarInit.s
new file mode 100644 (file)
index 0000000..7bd40df
--- /dev/null
@@ -0,0 +1,37 @@
+#------------------------------------------------------------------------------\r
+#\r
+# Copyright (c) 2015, 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
+#  SEC CAR function\r
+#\r
+#------------------------------------------------------------------------------\r
+\r
+#-----------------------------------------------------------------------------\r
+#\r
+#  Section:     SecCarInit\r
+#\r
+#  Description: This function initializes the Cache for Data, Stack, and Code\r
+#\r
+#-----------------------------------------------------------------------------\r
+ASM_GLOBAL ASM_PFX(SecCarInit)\r
+ASM_PFX(SecCarInit):\r
+\r
+  #\r
+  # Set up CAR\r
+  #\r
+\r
+  xor     %eax, %eax\r
+\r
+SecCarInitExit:\r
+\r
+  movd       %mm7, %esi                      #RET_ESI\r
+  jmp        *%esi\r
diff --git a/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/PlatformSecLibNull.c b/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/PlatformSecLibNull.c
new file mode 100644 (file)
index 0000000..7bb95a9
--- /dev/null
@@ -0,0 +1,33 @@
+/** @file\r
+  Null instance of Platform Sec Lib.\r
+\r
+  Copyright (c) 2014 - 2016, 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/FspCommonLib.h>\r
+\r
+/**\r
+  This function check the signture of UPD.\r
+\r
+  @param[in]  ApiIdx           Internal index of the FSP API.\r
+  @param[in]  ApiParam         Parameter of the FSP API.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FspUpdSignatureCheck (\r
+  IN UINT32   ApiIdx,\r
+  IN VOID     *ApiParam\r
+  )\r
+{\r
+  return EFI_SUCCESS;\r
+}\r
diff --git a/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/SecFspSecPlatformLibNull.inf b/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/SecFspSecPlatformLibNull.inf
new file mode 100644 (file)
index 0000000..1c18a58
--- /dev/null
@@ -0,0 +1,58 @@
+## @file\r
+#  NULL instance of Platform Sec Lib.\r
+#\r
+#  Copyright (c) 2014 - 2015, 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                      = BaseFspSecPlatformLibNull\r
+  FILE_GUID                      = C128CADC-623E-4E41-97CB-A7138E627460\r
+  MODULE_TYPE                    = SEC\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = FspSecPlatformLib\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
+################################################################################\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
+[Sources.IA32]\r
+  Ia32/Flat32.asm\r
+  Ia32/Flat32.s\r
+  Ia32/SecCarInit.asm\r
+  Ia32/SecCarInit.s\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
+  IntelFsp2Pkg/IntelFsp2Pkg.dec\r
diff --git a/IntelFsp2Pkg/Tools/GenCfgOpt.py b/IntelFsp2Pkg/Tools/GenCfgOpt.py
new file mode 100644 (file)
index 0000000..4fd0562
--- /dev/null
@@ -0,0 +1,1465 @@
+## @ GenCfgOpt.py\r
+#\r
+# Copyright (c) 2014 - 2016, 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 CLogicalExpression:\r
+    def __init__(self):\r
+        self.index    = 0\r
+        self.string   = ''\r
+\r
+    def errExit(self, err = ''):\r
+        print "ERROR: Express parsing for:"\r
+        print "       %s" % self.string\r
+        print "       %s^" % (' ' * self.index)\r
+        if err:\r
+            print "INFO : %s" % err\r
+        raise SystemExit\r
+\r
+    def getNonNumber (self, n1, n2):\r
+        if not n1.isdigit():\r
+            return n1\r
+        if not n2.isdigit():\r
+            return n2\r
+        return None\r
+\r
+    def getCurr(self, lens = 1):\r
+        try:\r
+            if lens == -1:\r
+                return self.string[self.index :]\r
+            else:\r
+                if self.index + lens > len(self.string):\r
+                    lens = len(self.string) - self.index\r
+                return self.string[self.index : self.index + lens]\r
+        except Exception:\r
+            return ''\r
+\r
+    def isLast(self):\r
+        return self.index == len(self.string)\r
+\r
+    def moveNext(self, len = 1):\r
+        self.index += len\r
+\r
+    def skipSpace(self):\r
+        while not self.isLast():\r
+            if self.getCurr() in ' \t':\r
+                self.moveNext()\r
+            else:\r
+                return\r
+\r
+    def normNumber (self, val):\r
+        return True if val else False\r
+\r
+    def getNumber(self, var):\r
+        var = var.strip()\r
+        if   re.match('^0x[a-fA-F0-9]+$', var):\r
+            value = int(var, 16)\r
+        elif re.match('^[+-]?\d+$', var):\r
+            value = int(var, 10)\r
+        else:\r
+            value = None\r
+        return value\r
+\r
+    def parseValue(self):\r
+        self.skipSpace()\r
+        var = ''\r
+        while not self.isLast():\r
+            char = self.getCurr()\r
+            if re.match('^[\w.]', char):\r
+                var += char\r
+                self.moveNext()\r
+            else:\r
+                break\r
+        val = self.getNumber(var)\r
+        if val is None:\r
+            value = var\r
+        else:\r
+            value = "%d" % val\r
+        return value\r
+\r
+    def parseSingleOp(self):\r
+        self.skipSpace()\r
+        if re.match('^NOT\W', self.getCurr(-1)):\r
+            self.moveNext(3)\r
+            op  = self.parseBrace()\r
+            val = self.getNumber (op)\r
+            if val is None:\r
+                self.errExit ("'%s' is not a number" % op)\r
+            return "%d" % (not self.normNumber(int(op)))\r
+        else:\r
+            return self.parseValue()\r
+\r
+    def parseBrace(self):\r
+        self.skipSpace()\r
+        char = self.getCurr()\r
+        if char == '(':\r
+            self.moveNext()\r
+            value = self.parseExpr()\r
+            self.skipSpace()\r
+            if self.getCurr() != ')':\r
+                self.errExit ("Expecting closing brace or operator")\r
+            self.moveNext()\r
+            return value\r
+        else:\r
+            value = self.parseSingleOp()\r
+            return value\r
+\r
+    def parseCompare(self):\r
+        value = self.parseBrace()\r
+        while True:\r
+            self.skipSpace()\r
+            char = self.getCurr()\r
+            if char in ['<', '>']:\r
+                self.moveNext()\r
+                next = self.getCurr()\r
+                if next == '=':\r
+                    op = char + next\r
+                    self.moveNext()\r
+                else:\r
+                    op = char\r
+                result = self.parseBrace()\r
+                test = self.getNonNumber(result, value)\r
+                if test is None:\r
+                    value = "%d" % self.normNumber(eval (value + op + result))\r
+                else:\r
+                    self.errExit ("'%s' is not a valid number for comparision" % test)\r
+            elif char in ['=', '!']:\r
+                op = self.getCurr(2)\r
+                if op in ['==', '!=']:\r
+                    self.moveNext(2)\r
+                    result = self.parseBrace()\r
+                    test = self.getNonNumber(result, value)\r
+                    if test is None:\r
+                        value = "%d" % self.normNumber((eval (value + op + result)))\r
+                    else:\r
+                        value = "%d" % self.normNumber(eval ("'" + value + "'" + op + "'" + result + "'"))\r
+                else:\r
+                    break\r
+            else:\r
+                break\r
+        return value\r
+\r
+    def parseAnd(self):\r
+        value = self.parseCompare()\r
+        while True:\r
+            self.skipSpace()\r
+            if re.match('^AND\W', self.getCurr(-1)):\r
+                self.moveNext(3)\r
+                result = self.parseCompare()\r
+                test = self.getNonNumber(result, value)\r
+                if test is None:\r
+                    value = "%d" % self.normNumber(int(value) & int(result))\r
+                else:\r
+                    self.errExit ("'%s' is not a valid op number for AND" % test)\r
+            else:\r
+                break\r
+        return value\r
+\r
+    def parseOrXor(self):\r
+        value  = self.parseAnd()\r
+        op     = None\r
+        while True:\r
+            self.skipSpace()\r
+            op = None\r
+            if re.match('^XOR\W', self.getCurr(-1)):\r
+                self.moveNext(3)\r
+                op = '^'\r
+            elif re.match('^OR\W', self.getCurr(-1)):\r
+                self.moveNext(2)\r
+                op = '|'\r
+            else:\r
+                break\r
+            if op:\r
+                result = self.parseAnd()\r
+                test = self.getNonNumber(result, value)\r
+                if test is None:\r
+                    value = "%d" % self.normNumber(eval (value + op + result))\r
+                else:\r
+                    self.errExit ("'%s' is not a valid op number for XOR/OR" % test)\r
+        return value\r
+\r
+    def parseExpr(self):\r
+        return self.parseOrXor()\r
+\r
+    def getResult(self):\r
+        value = self.parseExpr()\r
+        self.skipSpace()\r
+        if not self.isLast():\r
+            self.errExit ("Unexpected character found '%s'" % self.getCurr())\r
+        test = self.getNumber(value)\r
+        if test is None:\r
+            self.errExit ("Result '%s' is not a number" % value)\r
+        return int(value)\r
+\r
+    def evaluateExpress (self, Expr):\r
+        self.index     = 0\r
+        self.string    = Expr\r
+        if self.getResult():\r
+            Result = True\r
+        else:\r
+            Result = False\r
+        return Result\r
+\r
+class CGenCfgOpt:\r
+    def __init__(self):\r
+        self.Debug          = False\r
+        self.Error          = ''\r
+        self.ReleaseMode    = True\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', 'EMBED', 'COMMENT']\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 ParseBuildMode (self, OutputStr):\r
+        if "RELEASE_" in OutputStr:\r
+            self.ReleaseMode = True\r
+        if "DEBUG_" in OutputStr:\r
+            self.ReleaseMode = False\r
+        return\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
+            Error = 1\r
+        else:\r
+            Error = 0\r
+            if self.Debug:\r
+                print "INFO : Macro dictionary:"\r
+                for Each in self._MacroDict:\r
+                    print "       $(%s) = [ %s ]" % (Each , self._MacroDict[Each])\r
+        return Error\r
+\r
+    def EvaulateIfdef   (self, Macro):\r
+        Result = Macro in self._MacroDict\r
+        if self.Debug:\r
+            print "INFO : Eval Ifdef [%s] : %s" % (Macro, Result)\r
+        return  Result\r
+\r
+    def ExpandMacros (self, Input):\r
+        Line = Input\r
+        Match = re.findall("\$\(\w+\)", Input)\r
+        if Match:\r
+            for Each in Match:\r
+              Variable = Each[2:-1]\r
+              if Variable in self._MacroDict:\r
+                  Line = Line.replace(Each, self._MacroDict[Variable])\r
+              else:\r
+                  if self.Debug:\r
+                      print "WARN : %s is not defined" % Each\r
+                  Line = Line.replace(Each, Each[2:-1])\r
+        return Line\r
+\r
+    def EvaluateExpress (self, Expr):\r
+        ExpExpr = self.ExpandMacros(Expr)\r
+        LogExpr = CLogicalExpression()\r
+        Result  = LogExpr.evaluateExpress (ExpExpr)\r
+        if self.Debug:\r
+            print "INFO : Eval Express [%s] : %s" % (Expr, Result)\r
+        return Result\r
+\r
+    def FormatListValue(self, ConfigDict):\r
+        Struct = ConfigDict['struct']\r
+        if Struct not in ['UINT8','UINT16','UINT32','UINT64']:\r
+            return\r
+\r
+        dataarray = []\r
+        binlist = ConfigDict['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
+            dataarray.append(value)\r
+\r
+        unit = int(Struct[4:]) / 8\r
+        if int(ConfigDict['length']) != unit * len(dataarray):\r
+            raise Exception("Array size is not proper for '%s' !" % ConfigDict['cname'])\r
+\r
+        bytearray = []\r
+        for each in dataarray:\r
+            value = each\r
+            for loop in xrange(unit):\r
+                bytearray.append("0x%02X" % (value & 0xFF))\r
+                value = value >> 8\r
+        newvalue  = '{'  + ','.join(bytearray) + '}'\r
+        ConfigDict['value'] = newvalue\r
+        return ""\r
+\r
+    def ParseDscFile (self, DscFile, FvDir, ConfigDscFile, ExtConfigDscFile):\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         = []\r
+        ElifStack       = []\r
+        Error           = 0\r
+        ConfigDict      = {}\r
+\r
+        DscFd        = open(DscFile, "r")\r
+        DscLines     = DscFd.readlines()\r
+        DscFd.close()\r
+\r
+        while len(DscLines):\r
+            DscLine  = DscLines.pop(0).strip()\r
+            Handle   = False\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.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['embed']   = ''\r
+                    ConfigDict['comment'] = ''\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 re.match("^!else($|\s+#.+)", DscLine):\r
+                        if IfStack:\r
+                            IfStack[-1] = not IfStack[-1]\r
+                        else:\r
+                            print("ERROR: No paired '!if' found for '!else' for line '%s'" % DscLine)\r
+                            raise SystemExit\r
+                    elif re.match("^!endif($|\s+#.+)", DscLine):\r
+                        if IfStack:\r
+                            IfStack.pop()\r
+                            Level = ElifStack.pop()\r
+                            if Level > 0:\r
+                                del IfStack[-Level:]\r
+                        else:\r
+                            print("ERROR: No paired '!if' found for '!endif' for line '%s'" % DscLine)\r
+                            raise SystemExit\r
+                    else:\r
+                        Result = False\r
+                        Match = re.match("!(ifdef|ifndef)\s+(.+)", DscLine)\r
+                        if Match:\r
+                            Result = self.EvaulateIfdef (Match.group(2))\r
+                            if Match.group(1) == 'ifndef':\r
+                                Result = not Result\r
+                            IfStack.append(Result)\r
+                            ElifStack.append(0)\r
+                        else:\r
+                            Match  = re.match("!(if|elseif)\s+(.+)", DscLine)\r
+                            if Match:\r
+                                IsFoundInFile = False\r
+                                MatchPcdFormat = re.match("^\s*(.+)\.(.+)\s*==\s*(.+)", Match.group(2))\r
+                                if MatchPcdFormat:\r
+                                       ExtConfigDsc = open(ExtConfigDscFile, "r")\r
+                                       ExtConfigDscLines = ExtConfigDsc.readlines()\r
+                                       ExtConfigDsc.close()\r
+                                       \r
+                                       while len(ExtConfigDscLines):\r
+                                           ExtConfigDscLine  = ExtConfigDscLines.pop(0).strip()\r
+                                           MatchExtConfigPcd = re.match("^\s*(.+)\s*\|\s*(.+)", ExtConfigDscLine)\r
+                                           if MatchExtConfigPcd and IsFoundInFile == False:\r
+                                                 PcdFormatStr = str(str(MatchPcdFormat.group(1)) + "." + str(MatchPcdFormat.group(2)))\r
+                                                 ExtConfigPcd = str(MatchExtConfigPcd.group(1))\r
+                                                 Result = False\r
+                                                 if PcdFormatStr.strip() == ExtConfigPcd.strip():\r
+                                                       Result = self.EvaluateExpress(str(str(MatchExtConfigPcd.group(2)) + " == " + str(MatchPcdFormat.group(3))))\r
+                                                       IsFoundInFile = True\r
+                                                       break\r
+                                       if IsFoundInFile == False:\r
+                                           ConfigDsc = open(ConfigDscFile, "r")\r
+                                           ConfigDscLines = ConfigDsc.readlines()\r
+                                           ConfigDsc.close()\r
+                                           while len(ConfigDscLines):\r
+                                               ConfigDscLine  = ConfigDscLines.pop(0).strip()\r
+                                               MatchConfigPcd = re.match("^\s*(.+)\s*\|\s*(.+)", ConfigDscLine)\r
+                                               if MatchConfigPcd:\r
+                                                     PcdFormatStr = str(str(MatchPcdFormat.group(1)) + "." + str(MatchPcdFormat.group(2)))\r
+                                                     ConfigPcd = str(MatchConfigPcd.group(1))\r
+                                                     Result = False\r
+                                                     if PcdFormatStr.strip() == ConfigPcd.strip():\r
+                                                           Result = self.EvaluateExpress(str(str(MatchConfigPcd.group(2)) + " == " + str(MatchPcdFormat.group(3))))\r
+                                                           IsFoundInFile = True\r
+                                                           break\r
+                                else:\r
+                                       Result = self.EvaluateExpress(Match.group(2))\r
+                                if Match.group(1) == "if":\r
+                                    ElifStack.append(0)\r
+                                    IfStack.append(Result)\r
+                                else:   #elseif\r
+                                    if IfStack:\r
+                                        IfStack[-1] = not IfStack[-1]\r
+                                        IfStack.append(Result)\r
+                                        ElifStack[-1] = ElifStack[-1] + 1\r
+                                    else:\r
+                                        print("ERROR: No paired '!if' found for '!elif' for line '%s'" % DscLine)\r
+                                        raise SystemExit\r
+                            else:\r
+                                if IfStack:\r
+                                    Handle = reduce(lambda x,y: x and y, IfStack)\r
+                                else:\r
+                                    Handle = True\r
+                                if Handle:\r
+                                    Match = re.match("!include\s+(.+)", DscLine)\r
+                                    if Match:\r
+                                        IncludeFilePath = Match.group(1)\r
+                                        IncludeFilePath = self.ExpandMacros(IncludeFilePath)\r
+                                        try:\r
+                                            IncludeDsc  = open(IncludeFilePath, "r")\r
+                                        except:\r
+                                            print("ERROR: Cannot open file '%s'" % IncludeFilePath)\r
+                                            raise SystemExit\r
+                                        NewDscLines = IncludeDsc.readlines()\r
+                                        IncludeDsc.close()\r
+                                        DscLines = NewDscLines + DscLines\r
+                                    else:\r
+                                        if DscLine.startswith('!'):\r
+                                            print("ERROR: Unrecoginized directive for line '%s'" % DscLine)\r
+                                            raise SystemExit\r
+            if not Handle:\r
+                continue\r
+\r
+            if IsDefSect:\r
+                #DEFINE UPD_TOOL_GUID       = 8C3D856A-9BE6-468E-850A-24F7A8D38E09\r
+                #DEFINE FSP_T_UPD_TOOL_GUID = 34686CA3-34F9-4901-B82A-BA630F0714C6\r
+                #DEFINE FSP_M_UPD_TOOL_GUID = 39A250DB-E465-4DD1-A2AC-E2BD3C0E2385\r
+                #DEFINE FSP_S_UPD_TOOL_GUID = CAE3605B-5B34-4C85-B3D7-27D54273C40F\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
+                    if self.Debug:\r
+                        print "INFO : DEFINE %s = [ %s ]" % (Match.group(1), Match.group(2))\r
+            else:\r
+                Match = re.match("^\s*#\s+(!BSF|@Bsf|!HDR)\s+(.+)", DscLine)\r
+                if Match:\r
+                    Remaining = Match.group(2)\r
+                    if Match.group(1) == '!BSF' or 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 ['NAME', '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
+                Match = re.match("^\s*#\s+@Prompt\s+(.+)", DscLine)\r
+                if Match:\r
+                    ConfigDict['name'] = Match.group(1)\r
+\r
+                Match = re.match("^\s*#\s*@ValidList\s*(.+)\s*\|\s*(.+)\s*\|\s*(.+)\s*", DscLine)\r
+                if Match:\r
+                    if Match.group(2).strip() in self._BuidinOption:\r
+                        ConfigDict['option'] = Match.group(2).strip()\r
+                    else:\r
+                        OptionValueList = Match.group(2).split(',')\r
+                        OptionStringList = Match.group(3).split(',')\r
+                        Index = 0\r
+                        for Option in OptionValueList:\r
+                             Option = Option.strip()\r
+                             ConfigDict['option'] = ConfigDict['option'] + str(Option) + ':' + OptionStringList[Index].strip()\r
+                             Index += 1\r
+                             if Index in range(len(OptionValueList)):\r
+                                 ConfigDict['option'] += ', '\r
+                    ConfigDict['type'] = "Combo"\r
+\r
+                Match = re.match("^\s*#\s*@ValidRange\s*(.+)\s*\|\s*(.+)\s*-\s*(.+)\s*", DscLine)\r
+                if Match:\r
+                    if "0x" in Match.group(2) or "0x" in Match.group(3):\r
+                       ConfigDict['type'] = "EditNum, HEX, (%s,%s)" % (Match.group(2), Match.group(3))\r
+                    else:\r
+                       ConfigDict['type'] = "EditNum, DEC, (%s,%s)" % (Match.group(2), Match.group(3))\r
+\r
+                Match = re.match("^\s*##\s+(.+)", DscLine)\r
+                if Match:\r
+                    ConfigDict['help'] = 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]+)\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
+\r
+                    ConfigDict['value']  = Value\r
+                    if (len(Value) > 0)  and (Value[0] == '{'):\r
+                        Value = self.FormatListValue(ConfigDict)\r
+\r
+                    if ConfigDict['name']  == '':\r
+                        # Clear BSF specific items\r
+                        ConfigDict['bsfname']   = ''\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['embed']  = ''\r
+                    ConfigDict['comment'] = ''\r
+                    ConfigDict['order']  = -1\r
+                    ConfigDict['subreg'] = []\r
+                    ConfigDict['option'] = ''\r
+                else:\r
+                    # It could be a virtual item as below\r
+                    # !BSF FIELD:{1:SerialDebugPortAddress0}\r
+                    # or\r
+                    # @Bsf FIELD:{1:SerialDebugPortAddress0}\r
+                    Match = re.match("^\s*#\s+(!BSF|@Bsf)\s+FIELD:{(.+):(\d+)}", DscLine)\r
+                    if Match:\r
+                        SubCfgDict = ConfigDict\r
+                        SubCfgDict['cname']  = Match.group(2)\r
+                        SubCfgDict['length'] = int (Match.group(3))\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 CreateSplitUpdTxt (self, UpdTxtFile):\r
+        GuidList = ['FSP_T_UPD_TOOL_GUID','FSP_M_UPD_TOOL_GUID','FSP_S_UPD_TOOL_GUID']\r
+        SignatureList = ['0x545F', '0x4D5F','0x535F']        #  _T, _M, and _S signature for FSPT, FSPM, FSPS\r
+        for Index in range(len(GuidList)):\r
+            UpdTxtFile = ''\r
+            FvDir = self._FvDir\r
+            if GuidList[Index] not in self._MacroDict:\r
+                self.Error = "%s definition is missing in DSC file" % (GuidList[Index])\r
+                return 1\r
+\r
+            if UpdTxtFile == '':\r
+                UpdTxtFile = os.path.join(FvDir, self._MacroDict[GuidList[Index]] + '.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
+            StartAddr  = 0\r
+            EndAddr    = 0\r
+            Default = 'DEFAULT|'\r
+            InRange = False\r
+            for Item in self._CfgItemList:\r
+                if Item['cname'] == 'Signature' and str(Item['value'])[0:6] == SignatureList[Index]:\r
+                    StartAddr = Item['offset']\r
+                    NextOffset = StartAddr\r
+                    InRange = True\r
+                if Item['cname'] == 'UpdTerminator' and InRange == True:\r
+                    EndAddr = Item['offset']\r
+                    InRange = False\r
+            InRange = False\r
+            for Item in self._CfgItemList:\r
+                if Item['cname'] == 'Signature' and str(Item['value'])[0:6] == SignatureList[Index]:\r
+                    InRange = True\r
+                if InRange != True:\r
+                    continue\r
+                if Item['cname'] == 'UpdTerminator':\r
+                    InRange = False\r
+                if Item['region'] != 'UPD':\r
+                    continue\r
+                Offset = Item['offset']\r
+                if StartAddr > Offset or EndAddr < Offset:\r
+                    continue\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 - StartAddr, Offset - NextOffset))\r
+                    SpaceIdx = SpaceIdx + 1\r
+                NextOffset = Offset + Item['length']\r
+                if Item['cname'] == 'PcdSerialIoUartDebugEnable':\r
+                    if self.ReleaseMode == False:\r
+                        Item['value'] = 0x01\r
+                TxtFd.write("%s.%s|%s0x%04X|%s|%s\n" % (Item['space'],Item['cname'],Default,Item['offset'] - StartAddr,Item['length'],Item['value']))\r
+            TxtFd.close()\r
+        return 0\r
+\r
+    def ProcessMultilines (self, String, MaxCharLength):\r
+            Multilines = ''\r
+            StringLength = len(String)\r
+            CurrentStringStart = 0\r
+            StringOffset = 0\r
+            BreakLineDict = []\r
+            if len(String) <= MaxCharLength:\r
+                while (StringOffset < StringLength):\r
+                    if StringOffset >= 1:\r
+                        if String[StringOffset - 1] == '\\' and String[StringOffset] == 'n':\r
+                            BreakLineDict.append (StringOffset + 1)\r
+                    StringOffset += 1\r
+                if BreakLineDict != []:\r
+                    for Each in BreakLineDict:\r
+                        Multilines += "  %s\n" % String[CurrentStringStart:Each].lstrip()\r
+                        CurrentStringStart = Each\r
+                    if StringLength - CurrentStringStart > 0:\r
+                        Multilines += "  %s\n" % String[CurrentStringStart:].lstrip()\r
+                else:\r
+                    Multilines = "  %s\n" % String\r
+            else:\r
+                NewLineStart = 0\r
+                NewLineCount = 0\r
+                FoundSpaceChar = False\r
+                while (StringOffset < StringLength):\r
+                    if StringOffset >= 1:\r
+                        if NewLineCount >= MaxCharLength - 1:\r
+                            if String[StringOffset] == ' ' and StringLength - StringOffset > 10:\r
+                                BreakLineDict.append (NewLineStart + NewLineCount)\r
+                                NewLineStart = NewLineStart + NewLineCount\r
+                                NewLineCount = 0\r
+                                FoundSpaceChar = True\r
+                            elif StringOffset == StringLength - 1 and FoundSpaceChar == False:\r
+                                BreakLineDict.append (0)\r
+                        if String[StringOffset - 1] == '\\' and String[StringOffset] == 'n':\r
+                            BreakLineDict.append (StringOffset + 1)\r
+                            NewLineStart = StringOffset + 1\r
+                            NewLineCount = 0\r
+                    StringOffset += 1\r
+                    NewLineCount += 1\r
+                if BreakLineDict != []:\r
+                    BreakLineDict.sort ()\r
+                    for Each in BreakLineDict:\r
+                        if Each > 0:\r
+                            Multilines += "  %s\n" % String[CurrentStringStart:Each].lstrip()\r
+                        CurrentStringStart = Each\r
+                    if StringLength - CurrentStringStart > 0:\r
+                        Multilines += "  %s\n" % String[CurrentStringStart:].lstrip()\r
+            return Multilines\r
+\r
+    def CreateField (self, Item, Name, Length, Offset, Struct, BsfName, Help, Option):\r
+        PosName    = 28\r
+        PosComment = 30\r
+        NameLine=''\r
+        HelpLine=''\r
+        OptionLine=''\r
+\r
+        IsArray = False\r
+        if Length in [1,2,4,8]:\r
+            Type = "UINT%d" % (Length * 8)\r
+        else:\r
+            IsArray = True\r
+            Type = "UINT8"\r
+\r
+        if Item and Item['value'].startswith('{'):\r
+            Type = "UINT8"\r
+            IsArray = True\r
+\r
+        if Struct != '':\r
+            Type = Struct\r
+            if Struct in ['UINT8','UINT16','UINT32','UINT64']:\r
+                IsArray = True\r
+                Unit = int(Type[4:]) / 8\r
+                Length = Length / Unit\r
+            else:\r
+                IsArray = False\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 BsfName != '':\r
+            NameLine=" - %s\n" % BsfName\r
+        else:\r
+            NameLine="\n"\r
+\r
+        if Help != '':\r
+            HelpLine = self.ProcessMultilines (Help, 80)\r
+\r
+        if Option != '':\r
+            OptionLine = self.ProcessMultilines (Option, 80)\r
+\r
+        if Offset is None:\r
+            OffsetStr = '????'\r
+        else:\r
+            OffsetStr = '0x%04X' % Offset\r
+\r
+        return "\n/** Offset %s%s%s%s**/\n  %s%s%s;\n" % (OffsetStr, NameLine, HelpLine, OptionLine, Type, ' ' * Space1, Name,)\r
+\r
+    def PostProcessBody (self, TextBody):\r
+        NewTextBody = []\r
+        OldTextBody = []\r
+        IncludeLine = False\r
+        StructName  = ''\r
+        VariableName = ''\r
+        IsUpdHdrDefined = False\r
+        IsUpdHeader = False\r
+        for Line in TextBody:\r
+           SplitToLines = Line.splitlines()\r
+           MatchComment = re.match("^/\*\sCOMMENT:(\w+):([\w|\W|\s]+)\s\*/\s([\s\S]*)", SplitToLines[0])\r
+           if MatchComment:\r
+              if MatchComment.group(1) == 'FSP_UPD_HEADER':\r
+                  IsUpdHeader = True\r
+              else:\r
+                  IsUpdHeader = False\r
+              if IsUpdHdrDefined != True or IsUpdHeader != True:\r
+                CommentLine = " " + MatchComment.group(2) + "\n"\r
+                NewTextBody.append("/**" + CommentLine + "**/\n")\r
+              Line = Line[(len(SplitToLines[0]) + 1):]\r
+\r
+           Match = re.match("^/\*\sEMBED_STRUCT:(\w+):(\w+):(START|END)\s\*/\s([\s\S]*)", Line)\r
+           if Match:\r
+               Line = Match.group(4)\r
+               if Match.group(1) == 'FSP_UPD_HEADER':\r
+                   IsUpdHeader = True\r
+               else:\r
+                   IsUpdHeader = False\r
+\r
+           if Match and Match.group(3) == 'START':\r
+               if IsUpdHdrDefined != True or IsUpdHeader != True:\r
+                   NewTextBody.append ('typedef struct {\n')\r
+               StructName   = Match.group(1)\r
+               VariableName = Match.group(2)\r
+               MatchOffset = re.search('/\*\*\sOffset\s0x([a-fA-F0-9]+)', Line)\r
+               if MatchOffset:\r
+                   Offset = int(MatchOffset.group(1), 16)\r
+               else:\r
+                   Offset = None\r
+               Line\r
+               IncludeLine = True\r
+               OldTextBody.append (self.CreateField (None, VariableName, 0, Offset, StructName, '', '', ''))\r
+           if IncludeLine:\r
+               if IsUpdHdrDefined != True or IsUpdHeader != True:\r
+                   NewTextBody.append (Line)\r
+           else:\r
+               OldTextBody.append (Line)\r
+\r
+           if Match and Match.group(3) == 'END':  \r
+               if (StructName != Match.group(1)) or (VariableName != Match.group(2)):\r
+                   print "Unmatched struct name '%s' and '%s' !"  % (StructName, Match.group(1))\r
+               else:\r
+                   if IsUpdHdrDefined != True or IsUpdHeader != True:\r
+                      NewTextBody.append ('} %s;\n\n' %  StructName)\r
+                      IsUpdHdrDefined = True\r
+               IncludeLine = False\r
+        NewTextBody.extend(OldTextBody)\r
+        return NewTextBody\r
+\r
+    def CreateHeaderFile (self, InputHeaderFile):\r
+        FvDir = self._FvDir\r
+\r
+        HeaderFileName = 'FspUpd.h'\r
+        HeaderFile = os.path.join(FvDir, HeaderFileName)\r
+\r
+        # Check if header needs to be recreated\r
+        ReCreate = False\r
+\r
+        TxtBody = []\r
+        for Item in self._CfgItemList:\r
+           if str(Item['cname']) == 'Signature' and Item['length'] == 8:\r
+               Value = int(Item['value'], 16)\r
+               Chars = []\r
+               while Value != 0x0:\r
+                   Chars.append(chr(Value & 0xFF))\r
+                   Value = Value >> 8\r
+               SignatureStr = ''.join(Chars)\r
+               # Signature will be _T / _M / _S for FSPT / FSPM / FSPS accordingly\r
+               if '_T' in SignatureStr[6:6+2]:\r
+                   TxtBody.append("#define FSPT_UPD_SIGNATURE               %s        /* '%s' */\n\n" % (Item['value'], SignatureStr))\r
+               elif '_M' in SignatureStr[6:6+2]:\r
+                   TxtBody.append("#define FSPM_UPD_SIGNATURE               %s        /* '%s' */\n\n" % (Item['value'], SignatureStr))\r
+               elif '_S' in SignatureStr[6:6+2]:\r
+                   TxtBody.append("#define FSPS_UPD_SIGNATURE               %s        /* '%s' */\n\n" % (Item['value'], SignatureStr))\r
+        TxtBody.append("\n")\r
+\r
+        for Region in ['UPD']:\r
+            UpdOffsetTable = []\r
+            UpdSignature = ['0x545F', '0x4D5F', '0x535F']   #['_T', '_M', '_S'] signature for FSPT, FSPM, FSPS\r
+            UpdStructure = ['FSPT_UPD', 'FSPM_UPD', 'FSPS_UPD']\r
+            for Item in self._CfgItemList:\r
+                if Item["cname"] == 'Signature' and Item["value"][0:6] in UpdSignature:\r
+                    UpdOffsetTable.append (Item["offset"])\r
+\r
+            for UpdIdx in range(len(UpdOffsetTable)):\r
+                CommentLine = ""\r
+                for Item in self._CfgItemList:\r
+                    if Item["comment"] != '' and Item["offset"] >= UpdOffsetTable[UpdIdx]:\r
+                        MatchComment = re.match("^(U|V)PD_DATA_REGION:([\w|\W|\s]+)", Item["comment"])\r
+                        if MatchComment and MatchComment.group(1) == Region[0]:\r
+                            CommentLine = " " + MatchComment.group(2) + "\n"\r
+                            TxtBody.append("/**" + CommentLine + "**/\n")\r
+                    elif Item["offset"] >= UpdOffsetTable[UpdIdx] and Item["comment"] == '':\r
+                        Match = re.match("^FSP([\w|\W|\s])_UPD", UpdStructure[UpdIdx])\r
+                        if Match:\r
+                            TxtBody.append("/** Fsp " + Match.group(1) + " UPD Configuration\n**/\n")\r
+                TxtBody.append("typedef struct {\n")\r
+                NextOffset  = 0\r
+                SpaceIdx    = 0\r
+                Offset      = 0\r
+\r
+                LastVisible = True\r
+                ResvOffset  = 0\r
+                ResvIdx     = 0\r
+                LineBuffer  = []\r
+                InRange = False\r
+                for Item in self._CfgItemList:\r
+                    if Item['cname'] == 'Signature' and str(Item['value'])[0:6] == UpdSignature[UpdIdx] or Region[0] == 'V':\r
+                        InRange = True\r
+                    if InRange != True:\r
+                        continue\r
+                    if Item['cname'] == 'UpdTerminator':\r
+                        InRange = False\r
+\r
+                    if Item['region'] != Region:\r
+                        continue\r
+\r
+                    if Item["offset"] < UpdOffsetTable[UpdIdx]:\r
+                        continue\r
+\r
+                    NextVisible = LastVisible\r
+\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
+                        TxtBody.append(self.CreateField (Item, Name, Item["offset"] - ResvOffset, ResvOffset, '', '', '', ''))\r
+\r
+                    if  Offset < Item["offset"]:\r
+                        if LastVisible:\r
+                            Name = "Unused" + Region[0] + "pdSpace%d" % SpaceIdx\r
+                            LineBuffer.append(self.CreateField (Item, Name, Item["offset"] - Offset, Offset, '', '', '', ''))\r
+                        SpaceIdx = SpaceIdx + 1\r
+                        Offset   = Item["offset"]\r
+\r
+                    LastVisible = NextVisible\r
+\r
+                    Offset = Offset + Item["length"]\r
+                    if LastVisible:\r
+                        for Each in LineBuffer:\r
+                            TxtBody.append (Each)\r
+                        LineBuffer = []\r
+                        Comment = Item["comment"]\r
+                        Embed = Item["embed"].upper()\r
+                        if Embed.endswith(':START') or Embed.endswith(':END'):\r
+                            if not Comment == '' and Embed.endswith(':START'):\r
+                               Marker = '/* COMMENT:%s */ \n' % Item["comment"]\r
+                               Marker = Marker + '/* EMBED_STRUCT:%s */ ' % Item["embed"]\r
+                            else:\r
+                               Marker = '/* EMBED_STRUCT:%s */ ' % Item["embed"]\r
+                        else:\r
+                            if Embed == '':\r
+                                Marker = '';\r
+                            else:\r
+                                self.Error = "Invalid embedded structure format '%s'!\n" % Item["embed"]\r
+                                return 4\r
+                        Line = Marker + self.CreateField (Item, Item["cname"], Item["length"], Item["offset"], Item['struct'], Item['name'], Item['help'], Item['option'])\r
+                        TxtBody.append(Line)\r
+                    if Item['cname'] == 'UpdTerminator':\r
+                        break\r
+                TxtBody.append("} " + UpdStructure[UpdIdx] + ";\n\n")\r
+        \r
+        # Handle the embedded data structure\r
+        TxtBody = self.PostProcessBody (TxtBody)\r
+\r
+        HeaderTFileName = 'FsptUpd.h'\r
+        HeaderMFileName = 'FspmUpd.h'\r
+        HeaderSFileName = 'FspsUpd.h'\r
+\r
+        UpdRegionCheck = ['FSPT', 'FSPM', 'FSPS']     # FSPX_UPD_REGION\r
+        UpdConfigCheck = ['FSP_T', 'FSP_M', 'FSP_S']  # FSP_X_CONFIG, FSP_X_TEST_CONFIG, FSP_X_RESTRICTED_CONFIG\r
+        UpdSignatureCheck = ['FSPT_UPD_SIGNATURE', 'FSPM_UPD_SIGNATURE', 'FSPS_UPD_SIGNATURE']\r
+        ExcludedSpecificUpd = 'FSPM_ARCH_UPD'\r
+\r
+        if InputHeaderFile != '':\r
+            if not os.path.exists(InputHeaderFile):\r
+                 self.Error = "Input header file '%s' does not exist" % InputHeaderFile\r
+                 return 6\r
+\r
+            InFd         = open(InputHeaderFile, "r")\r
+            IncLines     = InFd.readlines()\r
+            InFd.close()\r
+\r
+        for item in range(len(UpdRegionCheck)):\r
+            if UpdRegionCheck[item] == 'FSPT':\r
+                HeaderFd = open(os.path.join(FvDir, HeaderTFileName), "w")\r
+                FileBase = os.path.basename(os.path.join(FvDir, HeaderTFileName))\r
+            elif UpdRegionCheck[item] == 'FSPM':\r
+                HeaderFd = open(os.path.join(FvDir, HeaderMFileName), "w")\r
+                FileBase = os.path.basename(os.path.join(FvDir, HeaderMFileName))\r
+            elif UpdRegionCheck[item] == 'FSPS':\r
+                HeaderFd = open(os.path.join(FvDir, HeaderSFileName), "w")\r
+                FileBase = os.path.basename(os.path.join(FvDir, HeaderSFileName))\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("#include <%s>\n\n" % HeaderFileName)\r
+            HeaderFd.write("#pragma pack(push, 1)\n\n")\r
+\r
+            Export = False\r
+            for Line in IncLines:\r
+                Match = re.search ("!EXPORT\s+([A-Z]+)\s+EXTERNAL_BOOTLOADER_STRUCT_(BEGIN|END)\s+", Line)\r
+                if Match:\r
+                    if Match.group(2) == "BEGIN" and Match.group(1) == UpdRegionCheck[item]:\r
+                        Export = True\r
+                        continue\r
+                    else:\r
+                        Export = False\r
+                        continue\r
+                if Export:\r
+                    HeaderFd.write(Line)\r
+            HeaderFd.write("\n")\r
+\r
+            Index = 0\r
+            StartIndex = 0\r
+            EndIndex = 0\r
+            StructStart = []\r
+            StructStartWithComment = []\r
+            StructEnd = []\r
+            for Line in TxtBody:\r
+                Index += 1\r
+                Match = re.match("(typedef struct {)", Line)\r
+                if Match:\r
+                    StartIndex = Index - 1\r
+                Match = re.match("}\s([_A-Z0-9]+);", Line)\r
+                if Match and (UpdRegionCheck[item] in Match.group(1) or UpdConfigCheck[item] in Match.group(1)) and (ExcludedSpecificUpd not in Match.group(1)):\r
+                    EndIndex = Index\r
+                    StructStart.append(StartIndex)\r
+                    StructEnd.append(EndIndex)\r
+            Index = 0\r
+            for Line in TxtBody:\r
+                Index += 1\r
+                for Item in range(len(StructStart)):\r
+                    if Index == StructStart[Item]:\r
+                        Match = re.match("^(/\*\*\s*)", Line)\r
+                        if Match:\r
+                            StructStartWithComment.append(StructStart[Item])\r
+                        else:\r
+                            StructStartWithComment.append(StructStart[Item] + 1)\r
+            Index = 0\r
+            for Line in TxtBody:\r
+                Index += 1\r
+                for Item in range(len(StructStart)):\r
+                    if Index >= StructStartWithComment[Item] and Index <= StructEnd[Item]:\r
+                        HeaderFd.write (Line)\r
+            HeaderFd.write("#pragma pack(pop)\n\n")\r
+            HeaderFd.write("#endif\n")\r
+            HeaderFd.close()\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("#include <FspEas.h>\n\n")\r
+        HeaderFd.write("#pragma pack(push, 1)\n\n")\r
+\r
+        for item in range(len(UpdRegionCheck)):\r
+            Index = 0\r
+            StartIndex = 0\r
+            EndIndex = 0\r
+            StructStart = []\r
+            StructStartWithComment = []\r
+            StructEnd = []\r
+            for Line in TxtBody:\r
+                Index += 1\r
+                Match = re.match("(typedef struct {)", Line)\r
+                if Match:\r
+                    StartIndex = Index - 1\r
+                Match = re.match("#define\s([_A-Z0-9]+)\s*", Line)\r
+                if Match and (UpdSignatureCheck[item] in Match.group(1) or UpdSignatureCheck[item] in Match.group(1)):\r
+                    StructStart.append(Index - 1)\r
+                    StructEnd.append(Index)\r
+            Index = 0\r
+            for Line in TxtBody:\r
+                Index += 1\r
+                for Item in range(len(StructStart)):\r
+                    if Index == StructStart[Item]:\r
+                        Match = re.match("^(/\*\*\s*)", Line)\r
+                        if Match:\r
+                            StructStartWithComment.append(StructStart[Item])\r
+                        else:\r
+                            StructStartWithComment.append(StructStart[Item] + 1)\r
+            Index = 0\r
+            for Line in TxtBody:\r
+                Index += 1\r
+                for Item in range(len(StructStart)):\r
+                    if Index >= StructStartWithComment[Item] and Index <= StructEnd[Item]:\r
+                        HeaderFd.write (Line)\r
+        HeaderFd.write("#pragma pack(pop)\n\n")\r
+        HeaderFd.write("#endif\n")\r
+        HeaderFd.close()\r
+\r
+        return 0\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
+        elif Item['type'] == "Table":\r
+            Columns = Item['option'].split(',')\r
+            if len(Columns) != 0:\r
+                BsfFd.write('    %s $%s "%s",' % (Item['type'], PcdName, Item['name']));\r
+                for Col in Columns:\r
+                    Fmt = Col.split(':')\r
+                    if len(Fmt) != 3:\r
+                        raise Exception("Column format '%s' is invalid !" % Fmt)\r
+                    try:\r
+                        Dtype = int(Fmt[1].strip())\r
+                    except:\r
+                        raise Exception("Column size '%s' is invalid !" % Fmt[1])\r
+                    BsfFd.write('\n        Column "%s", %d bytes, %s' % (Fmt[0].strip(), Dtype, Fmt[2].strip()))\r
+                BsfFd.write(',\n')\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
+                    BsfFd.write('             "%s"\n' % (HelpLine));\r
+            if WriteHelp == 2:\r
+                    BsfFd.write('             "Valid range: %s ~ %s"\n' % (Match.group(2), Match.group(3)));\r
+\r
+    def GenerateBsfFile (self, BsfFile):\r
+\r
+        if BsfFile == '':\r
+            self.Error = "BSF output file '%s' is invalid" % BsfFile\r
+            return 1\r
+\r
+        Error = 0\r
+        OptionDict = {}\r
+        BsfFd      = open(BsfFile, "w")\r
+        BsfFd.write("%s\n" % (__copyright_bsf__ % date.today().year))\r
+        BsfFd.write("%s\n" % self._GlobalDataDef);\r
+        BsfFd.write("StructDef\n")\r
+        NextOffset = -1\r
+        for Item in self._CfgItemList:\r
+            if Item['find'] != '':\r
+                BsfFd.write('\n    Find "%s"\n' % Item['find'])\r
+                NextOffset = Item['offset'] + Item['length']\r
+            if Item['name'] != '':\r
+                if NextOffset != Item['offset']:\r
+                    BsfFd.write("        Skip %d bytes\n" % (Item['offset'] - NextOffset))\r
+                if len(Item['subreg']) > 0:\r
+                    NextOffset =  Item['offset']\r
+                    for SubItem in Item['subreg']:\r
+                        NextOffset += SubItem['length']\r
+                        if SubItem['name'] == '':\r
+                            BsfFd.write("        Skip %d bytes\n" % (SubItem['length']))\r
+                        else:\r
+                            Options = self.WriteBsfStruct(BsfFd, SubItem)\r
+                            if len(Options) > 0:\r
+                                OptionDict[SubItem['space']+'_'+SubItem['cname']] = Options\r
+                    if (Item['offset'] + Item['length']) <  NextOffset:\r
+                        self.Error = "BSF sub region '%s' length does not match" % (Item['space']+'.'+Item['cname'])\r
+                        return 2\r
+                else:\r
+                    NextOffset = Item['offset'] + Item['length']\r
+                    Options = self.WriteBsfStruct(BsfFd, Item)\r
+                    if len(Options) > 0:\r
+                        OptionDict[Item['space']+'_'+Item['cname']] = Options\r
+        BsfFd.write("\nEndStruct\n\n")\r
+\r
+        BsfFd.write("%s" % self._BuidinOptionTxt);\r
+\r
+        for Each in OptionDict:\r
+            BsfFd.write("List &%s\n" % Each);\r
+            for Item in OptionDict[Each]:\r
+                BsfFd.write('    Selection %s , "%s"\n' % (Item[0], Item[1]));\r
+            BsfFd.write("EndList\n\n");\r
+\r
+        BsfFd.write("BeginInfoBlock\n");\r
+        BsfFd.write('    PPVer       "%s"\n' % (self._CfgBlkDict['ver']));\r
+        BsfFd.write('    Description "%s"\n' % (self._CfgBlkDict['name']));\r
+        BsfFd.write("EndInfoBlock\n\n");\r
+\r
+        for Each in self._CfgPageDict:\r
+            BsfFd.write('Page "%s"\n' % self._CfgPageDict[Each]);\r
+            BsfItems = []\r
+            for Item in self._CfgItemList:\r
+                if Item['name'] != '':\r
+                    if Item['page'] != Each:\r
+                        continue\r
+                    if len(Item['subreg']) > 0:\r
+                        for SubItem in Item['subreg']:\r
+                            if SubItem['name'] != '':\r
+                                BsfItems.append(SubItem)\r
+                    else:\r
+                        BsfItems.append(Item)\r
+\r
+            BsfItems.sort(key=lambda x: x['order'])\r
+\r
+            for Item in BsfItems:\r
+                self.WriteBsfOption (BsfFd, Item)\r
+            BsfFd.write("EndPage\n\n");\r
+\r
+        BsfFd.close()\r
+        return  Error\r
+\r
+\r
+def Usage():\r
+    print "GenCfgOpt Version 0.51"\r
+    print "Usage:"\r
+    print " GenCfgOpt  UPDTXT  PlatformDscFile BuildFvDir  ConfigDscFile  ExtConfigDscFile"\r
+    print "                        [-D Macros]"\r
+    print " GenCfgOpt  HEADER  PlatformDscFile BuildFvDir  ConfigDscFile  ExtConfigDscFile"\r
+    print "            InputHFile  [-D Macros]"\r
+    print " GenCfgOpt  GENBSF  PlatformDscFile BuildFvDir  ConfigDscFile  ExtConfigDscFile"\r
+    print "            BsfOutFile  [-D Macros]"\r
+\r
+def Main():\r
+    #\r
+    # Parse the options and args\r
+    #\r
+    GenCfgOpt = CGenCfgOpt()\r
+    argc = len(sys.argv)\r
+    if argc < 4:\r
+        Usage()\r
+        return 1\r
+    else:\r
+        DscFile = sys.argv[2]\r
+        if not os.path.exists(DscFile):\r
+            print "ERROR: Cannot open DSC file '%s' !" % DscFile\r
+            return 2\r
+        ConfigDscFile = sys.argv[4]\r
+        if not os.path.exists(ConfigDscFile):\r
+            print "ERROR: Cannot open Config DSC file '%s' !" % ConfigDscFile\r
+            return 2\r
+        ExtConfigDscFile = sys.argv[5]\r
+        if not os.path.exists(ExtConfigDscFile):\r
+            print "ERROR: Cannot open Ext Config DSC file '%s' !" % ExtConfigDscFile\r
+            return 2\r
+\r
+        OutFile = ''\r
+        if argc > 4:\r
+            if sys.argv[6][0] == '-':\r
+                Start = 4\r
+            else:\r
+                OutFile = sys.argv[6]\r
+                Start = 5\r
+            GenCfgOpt.ParseBuildMode(sys.argv[3])\r
+            if GenCfgOpt.ParseMacros(sys.argv[Start:]) != 0:\r
+                print "ERROR: Macro parsing failed !"\r
+                return 3\r
+\r
+        FvDir = sys.argv[3]\r
+        if not os.path.exists(FvDir):\r
+            os.makedirs(FvDir)\r
+\r
+        if GenCfgOpt.ParseDscFile(DscFile, FvDir, ConfigDscFile, ExtConfigDscFile) != 0:\r
+            print "ERROR: %s !" % GenCfgOpt.Error\r
+            return 5\r
+\r
+        if GenCfgOpt.UpdateSubRegionDefaultValue() != 0:\r
+            print "ERROR: %s !" % GenCfgOpt.Error\r
+            return 7\r
+\r
+        if sys.argv[1] == "UPDTXT":\r
+            Ret = GenCfgOpt.CreateSplitUpdTxt(OutFile)\r
+            if Ret != 0:\r
+                # No change is detected\r
+                if Ret == 256:\r
+                    print "INFO: %s !" % (GenCfgOpt.Error)\r
+                else :\r
+                    print "ERROR: %s !" % (GenCfgOpt.Error)\r
+            return Ret\r
+        elif sys.argv[1] == "HEADER":\r
+            if GenCfgOpt.CreateHeaderFile(OutFile) != 0:\r
+                print "ERROR: %s !" % GenCfgOpt.Error\r
+                return 8\r
+        elif sys.argv[1] == "GENBSF":\r
+            if GenCfgOpt.GenerateBsfFile(OutFile) != 0:\r
+                print "ERROR: %s !" % GenCfgOpt.Error\r
+                return 9\r
+        else:\r
+            if argc < 5:\r
+                Usage()\r
+                return 1\r
+            print "ERROR: Unknown command '%s' !" % sys.argv[1]\r
+            Usage()\r
+            return 1\r
+        return 0\r
+    return 0\r
+\r
+\r
+if __name__ == '__main__':\r
+    sys.exit(Main())\r
diff --git a/IntelFsp2Pkg/Tools/PatchFv.py b/IntelFsp2Pkg/Tools/PatchFv.py
new file mode 100644 (file)
index 0000000..fc2ee19
--- /dev/null
@@ -0,0 +1,947 @@
+## @ PatchFv.py\r
+#\r
+# Copyright (c) 2014 - 2016, 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
+\r
+#\r
+#  Read data from file\r
+#\r
+#  param [in]  binfile     Binary file\r
+#  param [in]  offset      Offset\r
+#  param [in]  len         Length\r
+#\r
+#  retval      value       Value\r
+#\r
+def readDataFromFile (binfile, offset, len=1):\r
+    fd     = open(binfile, "r+b")\r
+    fsize  = os.path.getsize(binfile)\r
+    offval = offset & 0xFFFFFFFF\r
+    if (offval & 0x80000000):\r
+        offval = fsize - (0xFFFFFFFF - offval + 1)\r
+    fd.seek(offval)\r
+    bytearray = [ord(b) for b in fd.read(len)]\r
+    value = 0\r
+    idx   = len - 1\r
+    while  idx >= 0:\r
+        value = value << 8 | bytearray[idx]\r
+        idx = idx - 1\r
+    fd.close()\r
+    return value\r
+\r
+#\r
+#  Check FSP header is valid or not\r
+#\r
+#  param [in]  binfile     Binary file\r
+#\r
+#  retval      boolean     True: valid; False: invalid\r
+#\r
+def IsFspHeaderValid (binfile):\r
+    fd     = open (binfile, "rb")\r
+    bindat = fd.read(0x200) # only read first 0x200 bytes\r
+    fd.close()\r
+    HeaderList = ['FSPH' , 'FSPP' , 'FSPE']       # Check 'FSPH', 'FSPP', and 'FSPE' in the FSP header\r
+    OffsetList = []\r
+    for each in HeaderList:\r
+        if each in bindat:\r
+            idx = bindat.index(each)\r
+        else:\r
+            idx = 0\r
+        OffsetList.append(idx)\r
+    if not OffsetList[0] or not OffsetList[1]:    # If 'FSPH' or 'FSPP' is missing, it will return false\r
+        return False\r
+    Revision = ord(bindat[OffsetList[0] + 0x0B])\r
+    #\r
+    # if revision is bigger than 1, it means it is FSP v1.1 or greater revision, which must contain 'FSPE'.\r
+    #\r
+    if Revision > 1 and not OffsetList[2]:\r
+        return False                              # If FSP v1.1 or greater without 'FSPE', then return false\r
+    return True\r
+\r
+#\r
+#  Patch data in file\r
+#\r
+#  param [in]  binfile     Binary file\r
+#  param [in]  offset      Offset\r
+#  param [in]  value       Patch value\r
+#  param [in]  len         Length\r
+#\r
+#  retval      len         Length\r
+#\r
+def patchDataInFile (binfile, offset, value, len=1):\r
+    fd     = open(binfile, "r+b")\r
+    fsize  = os.path.getsize(binfile)\r
+    offval = offset & 0xFFFFFFFF\r
+    if (offval & 0x80000000):\r
+        offval = fsize - (0xFFFFFFFF - offval + 1)\r
+    bytearray = []\r
+    idx = 0\r
+    while  idx < len:\r
+        bytearray.append(value & 0xFF)\r
+        value          = value >> 8\r
+        idx            = idx + 1\r
+    fd.seek(offval)\r
+    fd.write("".join(chr(b) for b in bytearray))\r
+    fd.close()\r
+    return len\r
+\r
+\r
+class Symbols:\r
+    def __init__(self):\r
+        self.dictSymbolAddress = {}\r
+        self.dictGuidNameXref  = {}\r
+        self.dictFfsOffset     = {}\r
+        self.dictVariable      = {}\r
+        self.dictModBase       = {}\r
+        self.fdFile            = None\r
+        self.string            = ""\r
+        self.fdBase            = 0xFFFFFFFF\r
+        self.fdSize            = 0\r
+        self.index             = 0\r
+        self.fvList            = []\r
+        self.parenthesisOpenSet   =  '([{<'\r
+        self.parenthesisCloseSet  =  ')]}>'\r
+\r
+    #\r
+    #  Get FD file\r
+    #\r
+    #  retval      self.fdFile Retrieve FD file\r
+    #\r
+    def getFdFile (self):\r
+        return self.fdFile\r
+\r
+    #\r
+    #  Get FD size\r
+    #\r
+    #  retval      self.fdSize Retrieve the size of FD file\r
+    #\r
+    def getFdSize (self):\r
+        return self.fdSize\r
+\r
+    def parseFvInfFile (self, infFile):\r
+        fvInfo = {}\r
+        fvFile            = infFile[0:-4] + ".Fv"\r
+        fvInfo['Name']    = os.path.splitext(os.path.basename(infFile))[0]\r
+        fvInfo['Offset']  = self.getFvOffsetInFd(fvFile)\r
+        fvInfo['Size']    = readDataFromFile (fvFile, 0x20, 4)\r
+        fdIn        = open(infFile, "r")\r
+        rptLines    = fdIn.readlines() \r
+        fdIn.close()       \r
+        fvInfo['Base'] = 0\r
+        for rptLine in rptLines:\r
+            match = re.match("^EFI_BASE_ADDRESS\s*=\s*(0x[a-fA-F0-9]+)", rptLine)\r
+            if match:\r
+                fvInfo['Base'] = int(match.group(1), 16)\r
+                break\r
+        self.fvList.append(dict(fvInfo))\r
+        return 0\r
+\r
+    #\r
+    #  Create dictionaries\r
+    #\r
+    #  param [in]  fvDir       FV's directory\r
+    #  param [in]  fvNames     All FV's names\r
+    #\r
+    #  retval      0           Created dictionaries successfully\r
+    #\r
+    def createDicts (self, fvDir, fvNames):\r
+        #\r
+        # If the fvDir is not a dirctory, then raise an exception\r
+        #\r
+        if not os.path.isdir(fvDir):\r
+            raise Exception ("'%s' is not a valid directory!" % FvDir)\r
+\r
+        #\r
+        # If the Guid.xref is not existing in fvDir, then raise an exception\r
+        #\r
+        xrefFile = os.path.join(fvDir, "Guid.xref")\r
+        if not os.path.exists(xrefFile):\r
+            raise Exception("Cannot open GUID Xref file '%s'!" % xrefFile)\r
+\r
+        #\r
+        # Add GUID reference to dictionary\r
+        #\r
+        self.dictGuidNameXref  = {}\r
+        self.parseGuidXrefFile(xrefFile)\r
+\r
+        #\r
+        # Split up each FV from fvNames and get the fdBase\r
+        #\r
+        fvList = fvNames.split(":")\r
+        fdBase = fvList.pop()\r
+        if len(fvList) == 0:\r
+            fvList.append(fdBase)\r
+\r
+        #\r
+        # If the FD file is not existing, then raise an exception\r
+        #\r
+        fdFile =  os.path.join(fvDir, fdBase.strip() + ".fd")\r
+        if not os.path.exists(fdFile):\r
+            raise Exception("Cannot open FD file '%s'!" % fdFile)\r
+\r
+        #\r
+        # Get the size of the FD file\r
+        #\r
+        self.fdFile = fdFile\r
+        self.fdSize = os.path.getsize(fdFile)\r
+\r
+        #\r
+        # If the INF file, which is the first element of fvList, is not existing, then raise an exception\r
+        #\r
+        infFile = os.path.join(fvDir, fvList[0].strip()) + ".inf"\r
+        if not os.path.exists(infFile):\r
+            raise Exception("Cannot open INF file '%s'!" % infFile)\r
+\r
+        #\r
+        # Parse INF file in order to get fdBase and then assign those values to dictVariable\r
+        #\r
+        self.parseInfFile(infFile)\r
+        self.dictVariable = {}\r
+        self.dictVariable["FDSIZE"] =  self.fdSize\r
+        self.dictVariable["FDBASE"] =  self.fdBase\r
+\r
+        #\r
+        # Collect information from FV MAP file and FV TXT file then\r
+        # put them into dictionaries\r
+        #\r
+        self.fvList = []\r
+        self.dictSymbolAddress = {}\r
+        self.dictFfsOffset     = {}\r
+        for file in fvList:\r
+\r
+            #\r
+            # If the .Fv.map file is not existing, then raise an exception.\r
+            # Otherwise, parse FV MAP file\r
+            #\r
+            fvFile  = os.path.join(fvDir, file.strip()) + ".Fv"\r
+            mapFile = fvFile + ".map"\r
+            if not os.path.exists(mapFile):\r
+                raise Exception("Cannot open MAP file '%s'!" % mapFile)\r
+\r
+            infFile  = fvFile[0:-3] + ".inf"\r
+            self.parseFvInfFile(infFile)\r
+            self.parseFvMapFile(mapFile)\r
+\r
+            #\r
+            # If the .Fv.txt file is not existing, then raise an exception.\r
+            # Otherwise, parse FV TXT file\r
+            #\r
+            fvTxtFile  = fvFile + ".txt"\r
+            if not os.path.exists(fvTxtFile):\r
+                raise Exception("Cannot open FV TXT file '%s'!" % fvTxtFile)\r
+\r
+            self.parseFvTxtFile(fvTxtFile)\r
+\r
+        for fv in self.fvList:\r
+            self.dictVariable['_BASE_%s_' % fv['Name']] = fv['Base']\r
+        #\r
+        # Search all MAP files in FFS directory if it exists then parse MOD MAP file\r
+        #\r
+        ffsDir = os.path.join(fvDir, "Ffs")\r
+        if (os.path.isdir(ffsDir)):\r
+            for item in os.listdir(ffsDir):\r
+                if len(item) <= 0x24:\r
+                    continue\r
+                mapFile =os.path.join(ffsDir, item, "%s.map" % item[0:0x24])\r
+                if not os.path.exists(mapFile):\r
+                    continue\r
+                self.parseModMapFile(item[0x24:], mapFile)\r
+\r
+        return 0\r
+\r
+    #\r
+    #  Get FV offset in FD file\r
+    #\r
+    #  param [in]  fvFile      FV file\r
+    #\r
+    #  retval      offset      Got FV offset successfully\r
+    #\r
+    def getFvOffsetInFd(self, fvFile):\r
+        #\r
+        # Check if the first 0x70 bytes of fvFile can be found in fdFile\r
+        #\r
+        fvHandle = open(fvFile, "r+b")\r
+        fdHandle = open(self.fdFile, "r+b")\r
+        offset = fdHandle.read().find(fvHandle.read(0x70))\r
+        fvHandle.close()\r
+        fdHandle.close()\r
+        if offset == -1:\r
+            raise Exception("Could not locate FV file %s in FD!" % fvFile)\r
+        return offset\r
+\r
+    #\r
+    #  Parse INF file\r
+    #\r
+    #  param [in]  infFile     INF file\r
+    #\r
+    #  retval      0           Parsed INF file successfully\r
+    #\r
+    def parseInfFile(self, infFile):\r
+        #\r
+        # Get FV offset and search EFI_BASE_ADDRESS in the FD file \r
+        # then assign the value of EFI_BASE_ADDRESS to fdBase\r
+        #\r
+        fvOffset    = self.getFvOffsetInFd(infFile[0:-4] + ".Fv")\r
+        fdIn        = open(infFile, "r")\r
+        rptLine     = fdIn.readline()\r
+        self.fdBase = 0xFFFFFFFF\r
+        while (rptLine != "" ):\r
+            #EFI_BASE_ADDRESS = 0xFFFDF400\r
+            match = re.match("^EFI_BASE_ADDRESS\s*=\s*(0x[a-fA-F0-9]+)", rptLine)\r
+            if match is not None:\r
+                self.fdBase = int(match.group(1), 16) - fvOffset\r
+            rptLine  = fdIn.readline()\r
+        fdIn.close()\r
+        if self.fdBase == 0xFFFFFFFF:\r
+            raise Exception("Could not find EFI_BASE_ADDRESS in INF file!" % fvFile)\r
+        return 0\r
+\r
+    #\r
+    #  Parse FV TXT file\r
+    #\r
+    #  param [in]  fvTxtFile   .Fv.txt file\r
+    #\r
+    #  retval      0           Parsed FV TXT file successfully\r
+    #\r
+    def parseFvTxtFile(self, fvTxtFile):\r
+        fvName   = os.path.basename(fvTxtFile)[0:-7].upper()\r
+        #\r
+        # Get information from .Fv.txt in order to create a dictionary\r
+        # For example,\r
+        # self.dictFfsOffset[912740BE-2284-4734-B971-84B027353F0C] = 0x000D4078\r
+        #\r
+        fvOffset = self.getFvOffsetInFd(fvTxtFile[0:-4])\r
+        fdIn     = open(fvTxtFile, "r")\r
+        rptLine  = fdIn.readline()\r
+        while (rptLine != "" ):\r
+            match = re.match("(0x[a-fA-F0-9]+)\s([0-9a-fA-F\-]+)", rptLine)\r
+            if match is not None:\r
+                if match.group(2) in self.dictFfsOffset:\r
+                    self.dictFfsOffset[fvName + ':' + match.group(2)] = "0x%08X" % (int(match.group(1), 16) + fvOffset)\r
+                else:\r
+                    self.dictFfsOffset[match.group(2)] = "0x%08X" % (int(match.group(1), 16) + fvOffset)\r
+            rptLine  = fdIn.readline()\r
+        fdIn.close()\r
+        return 0\r
+\r
+    #\r
+    #  Parse FV MAP file\r
+    #\r
+    #  param [in]  mapFile     .Fv.map file\r
+    #\r
+    #  retval      0           Parsed FV MAP file successfully\r
+    #\r
+    def parseFvMapFile(self, mapFile):\r
+        #\r
+        # Get information from .Fv.map in order to create dictionaries\r
+        # For example,\r
+        # self.dictModBase[FspSecCore:BASE]  = 4294592776 (0xfffa4908)\r
+        # self.dictModBase[FspSecCore:ENTRY] = 4294606552 (0xfffa7ed8)\r
+        # self.dictModBase[FspSecCore:TEXT]  = 4294593080 (0xfffa4a38)\r
+        # self.dictModBase[FspSecCore:DATA]  = 4294612280 (0xfffa9538)\r
+        # self.dictSymbolAddress[FspSecCore:_SecStartup] = 0x00fffa4a38\r
+        #\r
+        fdIn     = open(mapFile, "r")\r
+        rptLine  = fdIn.readline()\r
+        modName  = ""\r
+        foundModHdr = False\r
+        while (rptLine != "" ):\r
+            if rptLine[0] != ' ':\r
+                #DxeIpl (Fixed Flash Address, BaseAddress=0x00fffb4310, EntryPoint=0x00fffb4958)\r
+                #(GUID=86D70125-BAA3-4296-A62F-602BEBBB9081 .textbaseaddress=0x00fffb4398 .databaseaddress=0x00fffb4178)\r
+                match = re.match("([_a-zA-Z0-9\-]+)\s\(.+BaseAddress=(0x[0-9a-fA-F]+),\s+EntryPoint=(0x[0-9a-fA-F]+)\)", rptLine)\r
+                if match is not None:\r
+                    foundModHdr = True\r
+                    modName = match.group(1)\r
+                    if len(modName) == 36:\r
+                       modName = self.dictGuidNameXref[modName.upper()]\r
+                    self.dictModBase['%s:BASE'  % modName] = int (match.group(2), 16)\r
+                    self.dictModBase['%s:ENTRY' % modName] = int (match.group(3), 16)\r
+                match = re.match("\(GUID=([A-Z0-9\-]+)\s+\.textbaseaddress=(0x[0-9a-fA-F]+)\s+\.databaseaddress=(0x[0-9a-fA-F]+)\)", rptLine)\r
+                if match is not None:\r
+                    if foundModHdr:\r
+                        foundModHdr = False\r
+                    else:\r
+                        modName = match.group(1)\r
+                        if len(modName) == 36:\r
+                            modName = self.dictGuidNameXref[modName.upper()]\r
+                    self.dictModBase['%s:TEXT' % modName] = int (match.group(2), 16)\r
+                    self.dictModBase['%s:DATA' % modName] = int (match.group(3), 16)\r
+            else:\r
+                #   0x00fff8016c    __ModuleEntryPoint\r
+                foundModHdr = False\r
+                match = re.match("^\s+(0x[a-z0-9]+)\s+([_a-zA-Z0-9]+)", rptLine)\r
+                if match is not None:\r
+                    self.dictSymbolAddress["%s:%s"%(modName, match.group(2))] = match.group(1)\r
+            rptLine  = fdIn.readline()\r
+        fdIn.close()\r
+        return 0\r
+\r
+    #\r
+    #  Parse MOD MAP file\r
+    #\r
+    #  param [in]  moduleName  Module name\r
+    #  param [in]  mapFile     .Fv.map file\r
+    #\r
+    #  retval      0           Parsed MOD MAP file successfully\r
+    #  retval      1           There is no moduleEntryPoint in modSymbols\r
+    #\r
+    def parseModMapFile(self, moduleName, mapFile):\r
+        #\r
+        # Get information from mapFile by moduleName in order to create a dictionary\r
+        # For example,\r
+        # self.dictSymbolAddress[FspSecCore:___guard_fids_count] = 0x00fffa4778\r
+        #\r
+        modSymbols  = {}\r
+        fdIn        = open(mapFile, "r")\r
+        reportLines = fdIn.readlines()\r
+        fdIn.close()\r
+\r
+        moduleEntryPoint = "__ModuleEntryPoint"\r
+        reportLine = reportLines[0]\r
+        if reportLine.strip().find("Archive member included") != -1:\r
+            #GCC\r
+            #                0x0000000000001d55                IoRead8\r
+            patchMapFileMatchString = "\s+(0x[0-9a-fA-F]{16})\s+([^\s][^0x][_a-zA-Z0-9\-]+)\s"\r
+            matchKeyGroupIndex = 2\r
+            matchSymbolGroupIndex  = 1\r
+            prefix = '_'\r
+        else:\r
+            #MSFT\r
+            #0003:00000190       _gComBase                  00007a50     SerialPo\r
+            patchMapFileMatchString =  "^\s[0-9a-fA-F]{4}:[0-9a-fA-F]{8}\s+(\w+)\s+([0-9a-fA-F]{8}\s+)"\r
+            matchKeyGroupIndex = 1\r
+            matchSymbolGroupIndex  = 2\r
+            prefix = ''\r
+\r
+        for reportLine in reportLines:\r
+            match = re.match(patchMapFileMatchString, reportLine)\r
+            if match is not None:\r
+                modSymbols[prefix + match.group(matchKeyGroupIndex)] = match.group(matchSymbolGroupIndex)\r
+\r
+        # Handle extra module patchable PCD variable in Linux map since it might have different format\r
+        # .data._gPcd_BinaryPatch_PcdVpdBaseAddress\r
+        #        0x0000000000003714        0x4 /tmp/ccmytayk.ltrans1.ltrans.o\r
+        handleNext = False\r
+        if matchSymbolGroupIndex == 1:\r
+            for reportLine in reportLines:\r
+                if handleNext:\r
+                    handleNext = False\r
+                    pcdName = match.group(1)\r
+                    match   = re.match("\s+(0x[0-9a-fA-F]{16})\s+", reportLine)\r
+                    if match is not None:\r
+                        modSymbols[prefix + pcdName] = match.group(1)\r
+                else:\r
+                    match = re.match("^\s\.data\.(_gPcd_BinaryPatch[_a-zA-Z0-9\-]+)", reportLine)\r
+                    if match is not None:\r
+                        handleNext = True\r
+                        continue\r
+\r
+        if not moduleEntryPoint in modSymbols:\r
+            return 1\r
+\r
+        modEntry = '%s:%s' % (moduleName,moduleEntryPoint)\r
+        if not modEntry in self.dictSymbolAddress:\r
+            modKey = '%s:ENTRY' % moduleName\r
+            if modKey in self.dictModBase:\r
+                baseOffset = self.dictModBase['%s:ENTRY' % moduleName] - int(modSymbols[moduleEntryPoint], 16)\r
+            else:\r
+               return 2\r
+        else:\r
+            baseOffset = int(self.dictSymbolAddress[modEntry], 16) - int(modSymbols[moduleEntryPoint], 16)\r
+        for symbol in modSymbols:\r
+            fullSym = "%s:%s" % (moduleName, symbol)\r
+            if not fullSym in self.dictSymbolAddress:\r
+                self.dictSymbolAddress[fullSym] = "0x00%08x" % (baseOffset+ int(modSymbols[symbol], 16))\r
+        return 0\r
+\r
+    #\r
+    #  Parse Guid.xref file\r
+    #\r
+    #  param [in]  xrefFile    the full directory of Guid.xref file\r
+    #\r
+    #  retval      0           Parsed Guid.xref file successfully\r
+    #\r
+    def parseGuidXrefFile(self, xrefFile):\r
+        #\r
+        # Get information from Guid.xref in order to create a GuidNameXref dictionary\r
+        # The dictGuidNameXref, for example, will be like\r
+        # dictGuidNameXref [1BA0062E-C779-4582-8566-336AE8F78F09] = FspSecCore\r
+        #\r
+        fdIn     = open(xrefFile, "r")\r
+        rptLine  = fdIn.readline()\r
+        while (rptLine != "" ):\r
+            match = re.match("([0-9a-fA-F\-]+)\s([_a-zA-Z0-9]+)", rptLine)\r
+            if match is not None:\r
+                self.dictGuidNameXref[match.group(1).upper()] = match.group(2)\r
+            rptLine  = fdIn.readline()\r
+        fdIn.close()\r
+        return 0\r
+\r
+    #\r
+    #  Get current character\r
+    #\r
+    #  retval      elf.string[self.index]\r
+    #  retval      ''                       Exception\r
+    #\r
+    def getCurr(self):\r
+        try:\r
+            return self.string[self.index]\r
+        except Exception:\r
+            return ''\r
+\r
+    #\r
+    #  Check to see if it is last index\r
+    #\r
+    #  retval      self.index\r
+    #\r
+    def isLast(self):\r
+        return self.index == len(self.string)\r
+\r
+    #\r
+    #  Move to next index\r
+    #\r
+    def moveNext(self):\r
+        self.index += 1\r
+\r
+    #\r
+    #  Skip space\r
+    #\r
+    def skipSpace(self):\r
+        while not self.isLast():\r
+            if self.getCurr() in ' \t':\r
+                self.moveNext()\r
+            else:\r
+                return\r
+\r
+    #\r
+    #  Parse value\r
+    #\r
+    #  retval      value\r
+    #\r
+    def parseValue(self):\r
+        self.skipSpace()\r
+        var = ''\r
+        while not self.isLast():\r
+            char = self.getCurr()\r
+            if char.lower() in '_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789:-':\r
+                var += char\r
+                self.moveNext()\r
+            else:\r
+                break\r
+\r
+        if ':' in var:\r
+            partList = var.split(':')\r
+            lenList  = len(partList)\r
+            if lenList != 2 and lenList != 3:\r
+                raise Exception("Unrecognized expression %s" % var)\r
+            modName = partList[lenList-2]\r
+            modOff  = partList[lenList-1]\r
+            if ('-' not in  modName) and (modOff[0] in '0123456789'):\r
+                # MOD: OFFSET\r
+                var = self.getModGuid(modName) + ":" + modOff\r
+            if '-' in var:  # GUID:OFFSET\r
+                value = self.getGuidOff(var)\r
+            else:\r
+                value = self.getSymbols(var)\r
+                self.synUsed   = True\r
+        else:\r
+            if var[0] in '0123456789':\r
+                value = self.getNumber(var)\r
+            else:\r
+                value = self.getVariable(var)\r
+        return int(value)\r
+\r
+    #\r
+    #  Parse single operation\r
+    #\r
+    #  retval      ~self.parseBrace() or self.parseValue()\r
+    #\r
+    def parseSingleOp(self):\r
+        self.skipSpace()\r
+        char = self.getCurr()\r
+        if char == '~':\r
+            self.moveNext()\r
+            return ~self.parseBrace()\r
+        else:\r
+            return self.parseValue()\r
+\r
+    #\r
+    #  Parse symbol of Brace([, {, <)\r
+    #\r
+    #  retval      value or self.parseSingleOp()\r
+    #\r
+    def parseBrace(self):\r
+        self.skipSpace()\r
+        char = self.getCurr()\r
+        parenthesisType = self.parenthesisOpenSet.find(char)\r
+        if parenthesisType >= 0:\r
+            self.moveNext()\r
+            value = self.parseExpr()\r
+            self.skipSpace()\r
+            if self.getCurr() != self.parenthesisCloseSet[parenthesisType]:\r
+                raise Exception("No closing brace")\r
+            self.moveNext()\r
+            if parenthesisType   == 1:  # [ : Get content\r
+                value = self.getContent(value)\r
+            elif parenthesisType == 2:  # { : To  address\r
+                value = self.toAddress(value)\r
+            elif parenthesisType == 3:  # < : To  offset\r
+                value = self.toOffset(value)\r
+            return value\r
+        else:\r
+            return self.parseSingleOp()\r
+\r
+    #\r
+    #  Parse symbol of Multiplier(*)\r
+    #\r
+    #  retval      value or self.parseSingleOp()\r
+    #\r
+    def parseMul(self):\r
+        values = [self.parseBrace()]\r
+        while True:\r
+            self.skipSpace()\r
+            char = self.getCurr()\r
+            if char == '*':\r
+                self.moveNext()\r
+                values.append(self.parseBrace())\r
+            else:\r
+                break\r
+        value  = 1\r
+        for each in values:\r
+            value *= each\r
+        return value\r
+\r
+    #\r
+    #  Parse symbol of And(&) and Or(|)\r
+    #\r
+    #  retval      value\r
+    #\r
+    def parseAndOr(self):\r
+        value  = self.parseMul()\r
+        op     = None\r
+        while True:\r
+            self.skipSpace()\r
+            char = self.getCurr()\r
+            if char == '&':\r
+                self.moveNext()\r
+                value &= self.parseMul()\r
+            elif char == '|':\r
+                div_index = self.index\r
+                self.moveNext()\r
+                value |= self.parseMul()\r
+            else:\r
+                break\r
+\r
+        return value\r
+\r
+    #\r
+    #  Parse symbol of Add(+) and Minus(-)\r
+    #\r
+    #  retval      sum(values)\r
+    #\r
+    def parseAddMinus(self):\r
+        values = [self.parseAndOr()]\r
+        while True:\r
+            self.skipSpace()\r
+            char = self.getCurr()\r
+            if char == '+':\r
+                self.moveNext()\r
+                values.append(self.parseAndOr())\r
+            elif char == '-':\r
+                self.moveNext()\r
+                values.append(-1 * self.parseAndOr())\r
+            else:\r
+                break\r
+        return sum(values)\r
+\r
+    #\r
+    #  Parse expression\r
+    #\r
+    #  retval      self.parseAddMinus()\r
+    #\r
+    def parseExpr(self):\r
+        return self.parseAddMinus()\r
+\r
+    #\r
+    #  Get result\r
+    #\r
+    #  retval      value\r
+    #\r
+    def getResult(self):\r
+        value = self.parseExpr()\r
+        self.skipSpace()\r
+        if not self.isLast():\r
+            raise Exception("Unexpected character found '%s'" % self.getCurr())\r
+        return value\r
+\r
+    #\r
+    #  Get module GUID\r
+    #\r
+    #  retval      value\r
+    #\r
+    def getModGuid(self, var):\r
+        guid = (guid for guid,name in self.dictGuidNameXref.items() if name==var)\r
+        try:\r
+            value = guid.next()\r
+        except Exception:\r
+            raise Exception("Unknown module name %s !" % var)\r
+        return value\r
+\r
+    #\r
+    #  Get variable\r
+    #\r
+    #  retval      value\r
+    #\r
+    def getVariable(self, var):\r
+        value = self.dictVariable.get(var, None)\r
+        if value == None:\r
+            raise Exception("Unrecognized variable '%s'" % var)\r
+        return value\r
+\r
+    #\r
+    #  Get number\r
+    #\r
+    #  retval      value\r
+    #\r
+    def getNumber(self, var):\r
+        var = var.strip()\r
+        if var.startswith('0x'):  # HEX\r
+            value = int(var, 16)\r
+        else:\r
+            value = int(var, 10)\r
+        return value\r
+\r
+    #\r
+    #  Get content\r
+    #\r
+    #  param [in]  value\r
+    #\r
+    #  retval      value\r
+    #\r
+    def getContent(self, value):\r
+        return readDataFromFile (self.fdFile, self.toOffset(value), 4)\r
+\r
+    #\r
+    #  Change value to address\r
+    #\r
+    #  param [in]  value\r
+    #\r
+    #  retval      value\r
+    #\r
+    def toAddress(self, value):\r
+        if value < self.fdSize:\r
+            value = value + self.fdBase\r
+        return value\r
+\r
+    #\r
+    #  Change value to offset\r
+    #\r
+    #  param [in]  value\r
+    #\r
+    #  retval      value\r
+    #\r
+    def toOffset(self, value):\r
+        offset = None\r
+        for fvInfo in self.fvList:\r
+            if (value >= fvInfo['Base']) and (value < fvInfo['Base'] + fvInfo['Size']):\r
+                offset = value - fvInfo['Base'] + fvInfo['Offset']\r
+        if not offset:\r
+            if (value >= self.fdBase) and (value < self.fdBase + self.fdSize):\r
+                offset = value - self.fdBase\r
+            else:\r
+                offset = value\r
+        if offset >= self.fdSize:\r
+            raise Exception("Invalid file offset 0x%08x !" % value)\r
+        return offset\r
+\r
+    #\r
+    #  Get GUID offset\r
+    #\r
+    #  param [in]  value\r
+    #\r
+    #  retval      value\r
+    #\r
+    def getGuidOff(self, value):\r
+        # GUID:Offset\r
+        symbolName = value.split(':')\r
+        if len(symbolName) == 3:\r
+            fvName  = symbolName[0].upper()\r
+            keyName = '%s:%s' % (fvName, symbolName[1])\r
+            offStr  = symbolName[2]\r
+        elif len(symbolName) == 2:\r
+            keyName = symbolName[0]\r
+            offStr  = symbolName[1]\r
+        if keyName in self.dictFfsOffset:\r
+            value = (int(self.dictFfsOffset[keyName], 16) + int(offStr, 16)) & 0xFFFFFFFF\r
+        else:\r
+            raise Exception("Unknown GUID %s !" % value)\r
+        return value\r
+\r
+    #\r
+    #  Get symbols\r
+    #\r
+    #  param [in]  value\r
+    #\r
+    #  retval      ret\r
+    #\r
+    def getSymbols(self, value):\r
+        if self.dictSymbolAddress.has_key(value):\r
+            # Module:Function\r
+            ret = int (self.dictSymbolAddress[value], 16)\r
+        else:\r
+            raise Exception("Unknown symbol %s !" % value)\r
+        return ret\r
+\r
+    #\r
+    #  Evaluate symbols\r
+    #\r
+    #  param [in]  expression\r
+    #  param [in]  isOffset\r
+    #\r
+    #  retval      value & 0xFFFFFFFF\r
+    #\r
+    def evaluate(self, expression, isOffset):\r
+        self.index     = 0\r
+        self.synUsed   = False\r
+        self.string    = expression\r
+        value = self.getResult()\r
+        if isOffset:\r
+            if self.synUsed:\r
+                # Consider it as an address first\r
+                value = self.toOffset(value)\r
+            if value & 0x80000000:\r
+                # Consider it as a negative offset next\r
+                offset = (~value & 0xFFFFFFFF) + 1\r
+                if offset < self.fdSize:\r
+                    value = self.fdSize - offset\r
+            if value >= self.fdSize:\r
+                raise Exception("Invalid offset expression !")\r
+        return value & 0xFFFFFFFF\r
+\r
+#\r
+#  Print out the usage\r
+#\r
+def usage():\r
+    print "Usage: \n\tPatchFv FvBuildDir [FvFileBaseNames:]FdFileBaseNameToPatch \"Offset, Value\""\r
+\r
+def main():\r
+    #\r
+    # Parse the options and args\r
+    #\r
+    symTables = Symbols()\r
+\r
+    #\r
+    # If the arguments are less than 4, then return an error.\r
+    #\r
+    if len(sys.argv) < 4:\r
+        Usage()\r
+        return 1\r
+\r
+    #\r
+    # If it fails to create dictionaries, then return an error.\r
+    #\r
+    if symTables.createDicts(sys.argv[1], sys.argv[2]) != 0:\r
+        print "ERROR: Failed to create symbol dictionary!!"\r
+        return 2\r
+\r
+    #\r
+    # Get FD file and size\r
+    #\r
+    fdFile = symTables.getFdFile()\r
+    fdSize = symTables.getFdSize()\r
+\r
+    try:\r
+        #\r
+        # Check to see if FSP header is valid\r
+        #\r
+        ret = IsFspHeaderValid(fdFile)\r
+        if ret == False:\r
+          raise Exception ("The FSP header is not valid. Stop patching FD.")\r
+        comment = ""\r
+        for fvFile in  sys.argv[3:]:\r
+            #\r
+            # Check to see if it has enough arguments\r
+            #\r
+            items = fvFile.split(",")\r
+            if len (items) < 2:\r
+                raise Exception("Expect more arguments for '%s'!" % fvFile)\r
+\r
+            comment = ""\r
+            command = ""\r
+            params  = []\r
+            for item in items:\r
+                item = item.strip()\r
+                if item.startswith("@"):\r
+                    comment = item[1:]\r
+                elif item.startswith("$"):\r
+                    command = item[1:]\r
+                else:\r
+                    if len(params) == 0:\r
+                        isOffset = True\r
+                    else :\r
+                        isOffset = False\r
+                    #\r
+                    # Parse symbols then append it to params\r
+                    #\r
+                    params.append (symTables.evaluate(item, isOffset))\r
+\r
+            #\r
+            # Patch a new value into FD file if it is not a command\r
+            #\r
+            if command == "":\r
+                # Patch a DWORD\r
+                if len (params) == 2:\r
+                    offset   = params[0]\r
+                    value    = params[1]\r
+                    oldvalue = readDataFromFile(fdFile, offset, 4)\r
+                    ret = patchDataInFile (fdFile, offset, value, 4) - 4\r
+                else:\r
+                    raise Exception ("Patch command needs 2 parameters !")\r
+\r
+                if ret:\r
+                    raise Exception ("Patch failed for offset 0x%08X" % offset)\r
+                else:\r
+                    print  "Patched offset 0x%08X:[%08X] with value 0x%08X  # %s" % (offset, oldvalue, value, comment)\r
+\r
+            elif command == "COPY":\r
+                #\r
+                # Copy binary block from source to destination\r
+                #\r
+                if len (params) == 3:\r
+                    src  = symTables.toOffset(params[0])\r
+                    dest = symTables.toOffset(params[1])\r
+                    clen = symTables.toOffset(params[2])\r
+                    if (dest + clen <= fdSize) and (src + clen <= fdSize):\r
+                        oldvalue = readDataFromFile(fdFile, src, clen)\r
+                        ret = patchDataInFile (fdFile, dest, oldvalue, clen) - clen\r
+                    else:\r
+                        raise Exception ("Copy command OFFSET or LENGTH parameter is invalid !")\r
+                else:\r
+                    raise Exception ("Copy command needs 3 parameters !")\r
+\r
+                if ret:\r
+                    raise Exception ("Copy failed from offset 0x%08X to offset 0x%08X!" % (src, dest))\r
+                else :\r
+                    print  "Copied %d bytes from offset 0x%08X ~ offset 0x%08X  # %s" % (clen, src, dest, comment)\r
+            else:\r
+                raise Exception ("Unknown command %s!" % command)\r
+        return 0\r
+\r
+    except Exception as (ex):\r
+        print "ERROR: %s" % ex\r
+        return 1\r
+\r
+if __name__ == '__main__':\r
+    sys.exit(main())\r
diff --git a/IntelFsp2Pkg/Tools/SplitFspBin.py b/IntelFsp2Pkg/Tools/SplitFspBin.py
new file mode 100644 (file)
index 0000000..cc2b87e
--- /dev/null
@@ -0,0 +1,363 @@
+## @ FspTool.py\r
+#\r
+# Copyright (c) 2015 - 2016, 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 sys\r
+import uuid\r
+import copy\r
+import struct\r
+import argparse\r
+from   ctypes import *\r
+\r
+"""\r
+This utility supports some operations for Intel FSP image.\r
+It supports:\r
+    - Split a FSP 2.0 compatibale image into individual FSP-T/M/S/C\r
+        and generate the mapping header file.\r
+"""\r
+\r
+class c_uint24(Structure):\r
+    """Little-Endian 24-bit Unsigned Integer"""\r
+    _pack_   = 1\r
+    _fields_ = [\r
+        ('Data', (c_uint8 * 3))\r
+        ]\r
+\r
+    def __init__(self, val=0):\r
+        self.set_value(val)\r
+\r
+    def __str__(self, indent=0):\r
+        return '0x%.6x' % self.value\r
+\r
+    def get_value(self):\r
+        return (\r
+            (self.Data[0]      ) +\r
+            (self.Data[1] <<  8) +\r
+            (self.Data[2] << 16)\r
+            )\r
+\r
+    def set_value(self, val):\r
+        self.Data[0] = (val      ) & 0xff\r
+        self.Data[1] = (val >>  8) & 0xff\r
+        self.Data[2] = (val >> 16) & 0xff\r
+\r
+    value = property(get_value, set_value)\r
+\r
+class EFI_FIRMWARE_VOLUME_HEADER(Structure):\r
+    _fields_ = [\r
+        ('ZeroVector',                 ARRAY(c_uint8, 16)),\r
+        ('FileSystemGuid',             ARRAY(c_char, 16)),\r
+        ('FvLength',                   c_uint64),\r
+        ('Signature',                  c_uint32),\r
+        ('Attributes',                 c_uint32),\r
+        ('HeaderLength',               c_uint16),\r
+        ('Checksum',                   c_uint16),\r
+        ('ExtHeaderOffset',            c_uint16),\r
+        ('Reserved',                   c_uint8),\r
+        ('Revision',                   c_uint8)\r
+        ]\r
+\r
+class EFI_FIRMWARE_VOLUME_EXT_HEADER(Structure):\r
+    _fields_ = [\r
+        ('FvName',                     ARRAY(c_char, 16)),\r
+        ('ExtHeaderSize',              c_uint32)\r
+        ]\r
+\r
+class EFI_FFS_INTEGRITY_CHECK(Structure):\r
+    _fields_ = [\r
+        ('Header',                     c_uint8),\r
+        ('File',                       c_uint8)\r
+        ]\r
+\r
+class EFI_FFS_FILE_HEADER(Structure):\r
+    _fields_ = [\r
+        ('Name',                       ARRAY(c_char, 16)),\r
+        ('IntegrityCheck',             EFI_FFS_INTEGRITY_CHECK),\r
+        ('Type',                       c_uint8),\r
+        ('Attributes',                 c_uint8),\r
+        ('Size',                       c_uint24),\r
+        ('State',                      c_uint8)\r
+        ]\r
+\r
+class EFI_COMMON_SECTION_HEADER(Structure):\r
+    _fields_ = [\r
+        ('Size',                       c_uint24),\r
+        ('Type',                       c_uint8)\r
+        ]\r
+\r
+class FSP_INFORMATION_HEADER(Structure):\r
+     _fields_ = [\r
+        ('Signature',                   c_uint32),\r
+        ('HeaderLength',                c_uint32),\r
+        ('Reserved1',                   ARRAY(c_uint8, 3)),\r
+        ('HeaderRevision',              c_uint8),\r
+        ('ImageRevision',               c_uint32),\r
+        ('ImageId',                     c_uint64),\r
+        ('ImageSize',                   c_uint32),\r
+        ('ImageBase',                   c_uint32),\r
+        ('ImageAttribute',              c_uint32),\r
+        ('CfgRegionOffset',             c_uint32),\r
+        ('CfgRegionSize',               c_uint32),\r
+        ('ApiEntryNum',                 c_uint32),\r
+        ('NemInitEntry',                c_uint32),\r
+        ('FspInitEntry',                c_uint32),\r
+        ('NotifyPhaseEntry',            c_uint32),\r
+        ('FspMemoryInitEntry',          c_uint32),\r
+        ('TempRamExitEntry',            c_uint32),\r
+        ('FspSiliconInitEntry',         c_uint32)\r
+    ]\r
+\r
+class FspFv:\r
+    HeaderFile = """/*\r
+ *\r
+ * Automatically generated file; DO NOT EDIT.\r
+ * FSP mapping file\r
+ *\r
+ */\r
+"""\r
+    FspNameDict = {\r
+        "0" : "-C.Fv",\r
+        "1" : "-T.Fv",\r
+        "2" : "-M.Fv",\r
+        "3" : "-S.Fv",\r
+    }\r
+\r
+    def __init__(self, FvBin):\r
+        self.FspFv  = {}\r
+        self.FvList = []\r
+        self.FspBin = FvBin\r
+        hfsp = open (self.FspBin, 'r+b')\r
+        self.FspDat = bytearray(hfsp.read())\r
+        hfsp.close()\r
+\r
+    def OutputStruct (self, obj, indent = 0):\r
+        max_key_len = 20\r
+        pstr = ('  ' * indent + '{0:<%d} = {1}\n') % max_key_len\r
+        if indent:\r
+            s = ''\r
+        else:\r
+            s = ('  ' * indent + '<%s>:\n') % obj.__class__.__name__\r
+        for field in obj._fields_:\r
+            key = field[0]\r
+            val = getattr(obj, key)\r
+            rep = ''\r
+            \r
+            if not isinstance(val, c_uint24) and isinstance(val, Structure):                \r
+                s += pstr.format(key, val.__class__.__name__)\r
+                s += self.OutputStruct (val, indent + 1)                \r
+            else:\r
+                if type(val) in (int, long):\r
+                    rep = hex(val)\r
+                elif isinstance(val, str) and (len(val) == 16):\r
+                    rep = str(uuid.UUID(bytes = val))\r
+                elif isinstance(val, c_uint24):                    \r
+                    rep = hex(val.get_value())\r
+                elif 'c_ubyte_Array' in str(type(val)):                \r
+                    rep = str(list(bytearray(val)))\r
+                else:\r
+                    rep = str(val)\r
+                s += pstr.format(key, rep)\r
+        return s\r
+    \r
+    def PrintFv (self):\r
+        print ("FV LIST:")\r
+        idx = 0\r
+        for (fvh, fvhe, offset) in self.FvList:            \r
+            guid = uuid.UUID(bytes = fvhe.FvName)\r
+            print ("FV%d FV GUID:%s  Offset:0x%08X  Length:0x%08X" % (idx, str(guid), offset, fvh.FvLength))\r
+            idx = idx + 1\r
+        print ("\nFSP LIST:")\r
+        for fsp in self.FspFv:\r
+            print "FSP%s contains FV%s" % (fsp, str(self.FspFv[fsp][1]))\r
+            print "\nFSP%s Info Header:" % fsp\r
+            fih = self.FspFv[fsp][0]            \r
+\r
+    def AlaignPtr (self, offset, alignment = 8):\r
+        return (offset + alignment - 1) & ~(alignment - 1)\r
+\r
+    def GetFspInfoHdr (self, fvh, fvhe, fvoffset):\r
+        if fvhe:\r
+            offset = fvh.ExtHeaderOffset + fvhe.ExtHeaderSize\r
+        else:\r
+            offset = fvh.HeaderLength\r
+        offset = self.AlaignPtr(offset)\r
+\r
+        # Now it should be 1st FFS\r
+        ffs = EFI_FFS_FILE_HEADER.from_buffer (self.FspDat, offset)        \r
+        offset += sizeof(ffs)\r
+        offset = self.AlaignPtr(offset)\r
+\r
+        # Now it should be 1st Section\r
+        sec = EFI_COMMON_SECTION_HEADER.from_buffer (self.FspDat, offset)\r
+        offset += sizeof(sec)\r
+\r
+        # Now it should be FSP_INFO_HEADER\r
+        offset += fvoffset\r
+        fih = FSP_INFORMATION_HEADER.from_buffer (self.FspDat, offset)\r
+        if 'FSPH' != bytearray.fromhex('%08X' % fih.Signature)[::-1]:\r
+            return None\r
+\r
+        return fih\r
+\r
+    def GetFvHdr (self, offset):\r
+        fvh = EFI_FIRMWARE_VOLUME_HEADER.from_buffer (self.FspDat, offset)\r
+        if '_FVH' != bytearray.fromhex('%08X' % fvh.Signature)[::-1]:\r
+            return None, None\r
+        if fvh.ExtHeaderOffset > 0:\r
+            offset += fvh.ExtHeaderOffset\r
+            fvhe = EFI_FIRMWARE_VOLUME_EXT_HEADER.from_buffer (self.FspDat, offset)\r
+        else:\r
+            fvhe = None\r
+        return fvh, fvhe\r
+\r
+    def GetFvData(self, idx):\r
+        (fvh, fvhe, offset) = self.FvList[idx]\r
+        return self.FspDat[offset:offset+fvh.FvLength]\r
+\r
+    def CheckFsp (self):\r
+        if len(self.FspFv) == 0:\r
+            return\r
+\r
+        fih = None\r
+        for fv in self.FspFv:\r
+            if not fih:\r
+                fih = self.FspFv[fv][0]\r
+            else:\r
+                newfih = self.FspFv[fv][0]\r
+                if (newfih.ImageId != fih.ImageId) or (newfih.ImageRevision != fih.ImageRevision):\r
+                    raise Exception("Inconsistent FSP ImageId or ImageRevision detected !")\r
+        return\r
+\r
+    def WriteFsp(self, dir, name):\r
+        if not name:\r
+            name = self.FspBin\r
+        fspname, ext = os.path.splitext(os.path.basename(name))\r
+        for fv in self.FspFv:\r
+            filename = os.path.join(dir, fspname + fv + ext)\r
+            hfsp = open(filename, 'w+b')\r
+            for fvidx in self.FspFv[fv][1]:\r
+                hfsp.write (self.GetFvData(fvidx))\r
+            hfsp.close()\r
+\r
+    def WriteMap(self, dir, hfile):\r
+        if not hfile:\r
+            hfile = os.path.splitext(os.path.basename(self.FspBin))[0] + '.h'\r
+        fspname, ext = os.path.splitext(os.path.basename(hfile))\r
+        filename = os.path.join(dir, fspname + ext)\r
+        hfsp   = open(filename, 'w')\r
+        hfsp.write ('%s\n\n' % self.HeaderFile)\r
+\r
+        firstfv = True\r
+        for fsp in self.FspFv:\r
+            fih = self.FspFv[fsp][0]\r
+            fvs = self.FspFv[fsp][1]\r
+            if firstfv:\r
+                IdStr = str(bytearray.fromhex('%016X' % fih.ImageId)[::-1])\r
+                hfsp.write("#define  FSP_IMAGE_ID    0x%016X        /* '%s' */\n" % (fih.ImageId, IdStr))\r
+                hfsp.write("#define  FSP_IMAGE_REV   0x%08X \n\n" % fih.ImageRevision)\r
+                firstfv = False\r
+            hfsp.write ('#define  FSP%s_BASE      0x%08X\n'   % (fsp, fih.ImageBase))\r
+            hfsp.write ('#define  FSP%s_OFFSET    0x%08X\n'   % (fsp, self.FvList[fvs[0]][-1]))\r
+            hfsp.write ('#define  FSP%s_LENGTH    0x%08X\n\n' % (fsp, fih.ImageSize))\r
+        hfsp.close()\r
+\r
+    def ParseFsp (self):\r
+        self.FspFv  = {}\r
+        flen = 0\r
+        for (fvh, fvhe, offset) in self.FvList:\r
+            fih = self.GetFspInfoHdr (fvh, fvhe, offset)\r
+            if fih:\r
+                if flen != 0:\r
+                    raise Exception("Incorrect FV size in image !")\r
+                ftype = str((fih.ImageAttribute >> 28) & 0xF)\r
+                if ftype not in self.FspNameDict:\r
+                    raise Exception("Unknown Attribute in image !")\r
+                fname = self.FspNameDict[str(ftype)]\r
+                if fname in self.FspFv:\r
+                    raise Exception("Multiple '%s' in image !" % fname)\r
+                self.FspFv[fname] = (copy.deepcopy(fih), [])\r
+                flen = fih.ImageSize\r
+            if flen > 0:\r
+                flen = flen - fvh.FvLength\r
+                if flen < 0:\r
+                    raise Exception("Incorrect FV size in image !")\r
+                self.FspFv[fname][1].append(self.FvList.index((fvh, fvhe, offset)))\r
+\r
+    def AddFv(self, offset):\r
+        fvh, fvhe = self.GetFvHdr (offset)\r
+        if fvh is None:\r
+            raise Exception('FV signature is not valid !')\r
+        fvitem = (copy.deepcopy(fvh), copy.deepcopy(fvhe), offset)\r
+        self.FvList.append(fvitem)\r
+        return fvh.FvLength\r
+\r
+    def ParseFv(self):\r
+        offset = 0\r
+        while (offset < len(self.FspDat)):\r
+            fv_len  = self.AddFv (offset)\r
+            offset += fv_len\r
+\r
+def GenFspHdr (fspfile, outdir, hfile, show):\r
+    fsp_fv = FspFv(fspfile)\r
+    fsp_fv.ParseFv()\r
+    fsp_fv.ParseFsp()\r
+    fsp_fv.CheckFsp()\r
+    if show:\r
+        fsp_fv.PrintFv()\r
+    fsp_fv.WriteMap(outdir, hfile)\r
+\r
+def SplitFspBin (fspfile, outdir, nametemplate, show):\r
+    fsp_fv = FspFv(fspfile)\r
+    fsp_fv.ParseFv()\r
+    fsp_fv.ParseFsp()\r
+    if show:\r
+        fsp_fv.PrintFv()\r
+    fsp_fv.WriteFsp(outdir, nametemplate)\r
+\r
+def main ():\r
+    parser = argparse.ArgumentParser()\r
+    subparsers    = parser.add_subparsers(title='commands')\r
+\r
+    parser_split  = subparsers.add_parser('split',  help='split a FSP into multiple components')\r
+    parser_split.set_defaults(which='split')\r
+    parser_split.add_argument('-f',  '--fspbin' , dest='FspBinary', type=str, help='FSP binary file path', required = True)\r
+    parser_split.add_argument('-o',  '--outdir' , dest='OutputDir', type=str, help='Output directory path',   default = '.')\r
+    parser_split.add_argument('-n',  '--nametpl', dest='NameTemplate', type=str, help='Output name template', default = '')\r
+    parser_split.add_argument('-p', action='store_true', help='Print FSP FV information', default = False)\r
+\r
+    parser_genhdr = subparsers.add_parser('genhdr',  help='generate a header file for FSP binary')\r
+    parser_genhdr.set_defaults(which='genhdr')\r
+    parser_genhdr.add_argument('-f',  '--fspbin' , dest='FspBinary', type=str, help='FSP binary file path', required = True)\r
+    parser_genhdr.add_argument('-o',  '--outdir' , dest='OutputDir', type=str, help='Output directory path',   default = '.')\r
+    parser_genhdr.add_argument('-n',  '--hfile',   dest='HFileName', type=str, help='Output header file name', default = '')\r
+    parser_genhdr.add_argument('-p', action='store_true', help='Print FSP FV information', default = False)\r
+\r
+    args = parser.parse_args()\r
+    if args.which in ['split', 'genhdr']:\r
+        if not os.path.exists(args.FspBinary):\r
+            raise Exception ("Could not locate FSP binary file '%s' !" % args.FspBinary)\r
+        if not os.path.exists(args.OutputDir):\r
+            raise Exception ("Invalid output directory '%s' !" % args.OutputDir)\r
+\r
+    if args.which == 'split':\r
+        SplitFspBin (args.FspBinary, args.OutputDir, args.NameTemplate, args.p)\r
+    elif args.which == 'genhdr':\r
+        GenFspHdr   (args.FspBinary, args.OutputDir, args.HFileName, args.p)\r
+    else:\r
+        pass\r
+\r
+    print 'Done!'\r
+    return 0\r
+\r
+if __name__ == '__main__':\r
+    sys.exit(main())\r
diff --git a/IntelFsp2Pkg/Tools/UserManuals/GenCfgOptUserManual.docx b/IntelFsp2Pkg/Tools/UserManuals/GenCfgOptUserManual.docx
new file mode 100644 (file)
index 0000000..c8766d5
Binary files /dev/null and b/IntelFsp2Pkg/Tools/UserManuals/GenCfgOptUserManual.docx differ
diff --git a/IntelFsp2Pkg/Tools/UserManuals/PatchFvUserManual.docx b/IntelFsp2Pkg/Tools/UserManuals/PatchFvUserManual.docx
new file mode 100644 (file)
index 0000000..ab1eda9
Binary files /dev/null and b/IntelFsp2Pkg/Tools/UserManuals/PatchFvUserManual.docx differ
diff --git a/IntelFsp2WrapperPkg/Contributions.txt b/IntelFsp2WrapperPkg/Contributions.txt
new file mode 100644 (file)
index 0000000..f87cbd7
--- /dev/null
@@ -0,0 +1,218 @@
+\r
+======================\r
+= Code Contributions =\r
+======================\r
+\r
+To make a contribution to a TianoCore project, follow these steps.\r
+1. Create a change description in the format specified below to\r
+   use in the source control commit log.\r
+2. Your commit message must include your "Signed-off-by" signature,\r
+   and "Contributed-under" message.\r
+3. Your "Contributed-under" message explicitly states that the\r
+   contribution is made under the terms of the specified\r
+   contribution agreement.  Your "Contributed-under" message\r
+   must include the name of contribution agreement and version.\r
+   For example: Contributed-under: TianoCore Contribution Agreement 1.0\r
+   The "TianoCore Contribution Agreement" is included below in\r
+   this document.\r
+4. Submit your code to the TianoCore project using the process\r
+   that the project documents on its web page.  If the process is\r
+   not documented, then submit the code on development email list\r
+   for the project.\r
+5. It is preferred that contributions are submitted using the same\r
+   copyright license as the base project. When that is not possible,\r
+   then contributions using the following licenses can be accepted:\r
+   * BSD (2-clause): http://opensource.org/licenses/BSD-2-Clause\r
+   * BSD (3-clause): http://opensource.org/licenses/BSD-3-Clause\r
+   * MIT: http://opensource.org/licenses/MIT\r
+   * Python-2.0: http://opensource.org/licenses/Python-2.0\r
+   * Zlib: http://opensource.org/licenses/Zlib\r
+\r
+   Contributions of code put into the public domain can also be\r
+   accepted.\r
+\r
+   Contributions using other licenses might be accepted, but further\r
+   review will be required.\r
+\r
+=====================================================\r
+= Change Description / Commit Message / Patch Email =\r
+=====================================================\r
+\r
+Your change description should use the standard format for a\r
+commit message, and must include your "Signed-off-by" signature\r
+and the "Contributed-under" message.\r
+\r
+== Sample Change Description / Commit Message =\r
+\r
+=== Start of sample patch email message ===\r
+\r
+From: Contributor Name <contributor@example.com>\r
+Subject: [PATCH] CodeModule: Brief-single-line-summary\r
+\r
+Full-commit-message\r
+\r
+Contributed-under: TianoCore Contribution Agreement 1.0\r
+Signed-off-by: Contributor Name <contributor@example.com>\r
+---\r
+\r
+An extra message for the patch email which will not be considered part\r
+of the commit message can be added here.\r
+\r
+Patch content inline or attached\r
+\r
+=== End of sample patch email message ===\r
+\r
+=== Notes for sample patch email ===\r
+\r
+* The first line of commit message is taken from the email's subject\r
+  line following [PATCH]. The remaining portion of the commit message\r
+  is the email's content until the '---' line.\r
+* git format-patch is one way to create this format\r
+\r
+=== Definitions for sample patch email ===\r
+\r
+* "CodeModule" is a short idenfier for the affected code.  For\r
+  example MdePkg, or MdeModulePkg UsbBusDxe.\r
+* "Brief-single-line-summary" is a short summary of the change.\r
+* The entire first line should be less than ~70 characters.\r
+* "Full-commit-message" a verbose multiple line comment describing\r
+  the change.  Each line should be less than ~70 characters.\r
+* "Contributed-under" explicitely states that the contribution is\r
+  made under the terms of the contribtion agreement.  This\r
+  agreement is included below in this document.\r
+* "Signed-off-by" is the contributor's signature identifying them\r
+  by their real/legal name and their email address.\r
+\r
+========================================\r
+= TianoCore Contribution Agreement 1.0 =\r
+========================================\r
+\r
+INTEL CORPORATION ("INTEL") MAKES AVAILABLE SOFTWARE, DOCUMENTATION,\r
+INFORMATION AND/OR OTHER MATERIALS FOR USE IN THE TIANOCORE OPEN SOURCE\r
+PROJECT (COLLECTIVELY "CONTENT"). USE OF THE CONTENT IS GOVERNED BY THE\r
+TERMS AND CONDITIONS OF THIS AGREEMENT BETWEEN YOU AND INTEL AND/OR THE\r
+TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR\r
+REFERENCED BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE OF THE\r
+CONTENT IS GOVERNED BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS\r
+OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\r
+BELOW. IF YOU DO NOT AGREE TO THE TERMS AND CONDITIONS OF THIS\r
+AGREEMENT AND THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE\r
+AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU MAY NOT\r
+USE THE CONTENT.\r
+\r
+Unless otherwise indicated, all Content made available on the TianoCore\r
+site is provided to you under the terms and conditions of the BSD\r
+License ("BSD"). A copy of the BSD License is available at\r
+http://opensource.org/licenses/bsd-license.php\r
+or when applicable, in the associated License.txt file.\r
+\r
+Certain other content may be made available under other licenses as\r
+indicated in or with such Content. (For example, in a License.txt file.)\r
+\r
+You accept and agree to the following terms and conditions for Your\r
+present and future Contributions submitted to TianoCore site. Except\r
+for the license granted to Intel hereunder, You reserve all right,\r
+title, and interest in and to Your Contributions.\r
+\r
+== SECTION 1: Definitions ==\r
+* "You" or "Contributor" shall mean the copyright owner or legal\r
+  entity authorized by the copyright owner that is making a\r
+  Contribution hereunder. All other entities that control, are\r
+  controlled by, or are under common control with that entity are\r
+  considered to be a single Contributor. For the purposes of this\r
+  definition, "control" means (i) the power, direct or indirect, to\r
+  cause the direction or management of such entity, whether by\r
+  contract or otherwise, or (ii) ownership of fifty percent (50%)\r
+  or more of the outstanding shares, or (iii) beneficial ownership\r
+  of such entity.\r
+* "Contribution" shall mean any original work of authorship,\r
+  including any modifications or additions to an existing work,\r
+  that is intentionally submitted by You to the TinaoCore site for\r
+  inclusion in, or documentation of, any of the Content. For the\r
+  purposes of this definition, "submitted" means any form of\r
+  electronic, verbal, or written communication sent to the\r
+  TianoCore site or its representatives, including but not limited\r
+  to communication on electronic mailing lists, source code\r
+  control systems, and issue tracking systems that are managed by,\r
+  or on behalf of, the TianoCore site for the purpose of\r
+  discussing and improving the Content, but excluding\r
+  communication that is conspicuously marked or otherwise\r
+  designated in writing by You as "Not a Contribution."\r
+\r
+== SECTION 2: License for Contributions ==\r
+* Contributor hereby agrees that redistribution and use of the\r
+  Contribution in source and binary forms, with or without\r
+  modification, are permitted provided that the following\r
+  conditions are met:\r
+** Redistributions of source code must retain the Contributor's\r
+   copyright notice, this list of conditions and the following\r
+   disclaimer.\r
+** Redistributions in binary form must reproduce the Contributor's\r
+   copyright notice, this list of conditions and the following\r
+   disclaimer in the documentation and/or other materials provided\r
+   with the distribution.\r
+* Disclaimer. None of the names of Contributor, Intel, or the names\r
+  of their respective contributors may be used to endorse or\r
+  promote products derived from this software without specific\r
+  prior written permission.\r
+* Contributor grants a license (with the right to sublicense) under\r
+  claims of Contributor's patents that Contributor can license that\r
+  are infringed by the Contribution (as delivered by Contributor) to\r
+  make, use, distribute, sell, offer for sale, and import the\r
+  Contribution and derivative works thereof solely to the minimum\r
+  extent necessary for licensee to exercise the granted copyright\r
+  license; this patent license applies solely to those portions of\r
+  the Contribution that are unmodified. No hardware per se is\r
+  licensed.\r
+* EXCEPT AS EXPRESSLY SET FORTH IN SECTION 3 BELOW, THE\r
+  CONTRIBUTION IS PROVIDED BY THE CONTRIBUTOR "AS IS" AND ANY\r
+  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,\r
+  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A\r
+  PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\r
+  CONTRIBUTOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r
+  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r
+  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
+  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR\r
+  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THE\r
+  CONTRIBUTION, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH\r
+  DAMAGE.\r
+\r
+== SECTION 3: Representations ==\r
+* You represent that You are legally entitled to grant the above\r
+  license. If your employer(s) has rights to intellectual property\r
+  that You create that includes Your Contributions, You represent\r
+  that You have received permission to make Contributions on behalf\r
+  of that employer, that Your employer has waived such rights for\r
+  Your Contributions.\r
+* You represent that each of Your Contributions is Your original\r
+  creation (see Section 4 for submissions on behalf of others).\r
+  You represent that Your Contribution submissions include complete\r
+  details of any third-party license or other restriction\r
+  (including, but not limited to, related patents and trademarks)\r
+  of which You are personally aware and which are associated with\r
+  any part of Your Contributions.\r
+\r
+== SECTION 4: Third Party Contributions ==\r
+* Should You wish to submit work that is not Your original creation,\r
+  You may submit it to TianoCore site separately from any\r
+  Contribution, identifying the complete details of its source\r
+  and of any license or other restriction (including, but not\r
+  limited to, related patents, trademarks, and license agreements)\r
+  of which You are personally aware, and conspicuously marking the\r
+  work as "Submitted on behalf of a third-party: [named here]".\r
+\r
+== SECTION 5: Miscellaneous ==\r
+* Applicable Laws. Any claims arising under or relating to this\r
+  Agreement shall be governed by the internal substantive laws of\r
+  the State of Delaware or federal courts located in Delaware,\r
+  without regard to principles of conflict of laws.\r
+* Language. This Agreement is in the English language only, which\r
+  language shall be controlling in all respects, and all versions\r
+  of this Agreement in any other language shall be for accommodation\r
+  only and shall not be binding. All communications and notices made\r
+  or given pursuant to this Agreement, and all documentation and\r
+  support to be provided, unless otherwise noted, shall be in the\r
+  English language.\r
+\r
diff --git a/IntelFsp2WrapperPkg/FspWrapperNotifyDxe/FspWrapperNotifyDxe.c b/IntelFsp2WrapperPkg/FspWrapperNotifyDxe/FspWrapperNotifyDxe.c
new file mode 100644 (file)
index 0000000..30c06b8
--- /dev/null
@@ -0,0 +1,250 @@
+/** @file\r
+  This driver will register two callbacks to call fsp's notifies.\r
+\r
+  Copyright (c) 2014 - 2016, 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 <PiDxe.h>\r
+\r
+#include <Protocol/PciEnumerationComplete.h>\r
+\r
+#include <Library/UefiDriverEntryPoint.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/UefiLib.h>\r
+#include <Library/FspWrapperApiLib.h>\r
+#include <Library/PerformanceLib.h>\r
+#include <Library/HobLib.h>\r
+\r
+typedef\r
+EFI_STATUS\r
+(EFIAPI * ADD_PERFORMANCE_RECORDS)(\r
+  IN CONST VOID *HobStart\r
+  );\r
+\r
+struct _ADD_PERFORMANCE_RECORD_PROTOCOL {\r
+  ADD_PERFORMANCE_RECORDS          AddPerformanceRecords;\r
+};\r
+\r
+typedef struct _ADD_PERFORMANCE_RECORD_PROTOCOL ADD_PERFORMANCE_RECORD_PROTOCOL;\r
+\r
+extern EFI_GUID gAddPerfRecordProtocolGuid;\r
+extern EFI_GUID gFspHobGuid;\r
+extern EFI_GUID gFspApiPerformanceGuid;\r
+\r
+EFI_EVENT mExitBootServicesEvent     = NULL;\r
+\r
+/**\r
+  Relocate this image under 4G memory.\r
+\r
+  @param  ImageHandle  Handle of driver image.\r
+  @param  SystemTable  Pointer to system table.\r
+\r
+  @retval EFI_SUCCESS  Image successfully relocated.\r
+  @retval EFI_ABORTED  Failed to relocate image.\r
+\r
+**/\r
+EFI_STATUS\r
+RelocateImageUnder4GIfNeeded (\r
+  IN EFI_HANDLE           ImageHandle,\r
+  IN EFI_SYSTEM_TABLE     *SystemTable\r
+  );\r
+\r
+/**\r
+  PciEnumerationComplete Protocol notification event handler.\r
+\r
+  @param[in] Event    Event whose notification function is being invoked.\r
+  @param[in] Context  Pointer to the notification function's context.\r
+**/\r
+VOID\r
+EFIAPI\r
+OnPciEnumerationComplete (\r
+  IN EFI_EVENT  Event,\r
+  IN VOID       *Context\r
+  )\r
+{\r
+  NOTIFY_PHASE_PARAMS NotifyPhaseParams;\r
+  EFI_STATUS          Status;\r
+  VOID                *Interface;\r
+\r
+  //\r
+  // Try to locate it because gEfiPciEnumerationCompleteProtocolGuid will trigger it once when registration.\r
+  // Just return if it is not found.\r
+  //\r
+  Status = gBS->LocateProtocol (\r
+                  &gEfiPciEnumerationCompleteProtocolGuid,\r
+                  NULL,\r
+                  &Interface\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return ;\r
+  }\r
+\r
+  NotifyPhaseParams.Phase = EnumInitPhaseAfterPciEnumeration;\r
+  PERF_START_EX(&gFspApiPerformanceGuid, "EventRec", NULL, 0, 0x6000);\r
+  Status = CallFspNotifyPhase (&NotifyPhaseParams);\r
+  PERF_END_EX(&gFspApiPerformanceGuid, "EventRec", NULL, 0, 0x607F);\r
+  if (Status != EFI_SUCCESS) {\r
+    DEBUG((DEBUG_ERROR, "FSP NotifyPhase AfterPciEnumeration failed, status: 0x%x\n", Status));\r
+  } else {\r
+    DEBUG((DEBUG_INFO, "FSP NotifyPhase AfterPciEnumeration Success.\n"));\r
+  }\r
+}\r
+\r
+/**\r
+  Notification function of EVT_GROUP_READY_TO_BOOT event group.\r
+\r
+  This is a notification function registered on EVT_GROUP_READY_TO_BOOT event group.\r
+  When the Boot Manager is about to load and execute a boot option, it reclaims variable\r
+  storage if free size is below the threshold.\r
+\r
+  @param[in] Event        Event whose notification function is being invoked.\r
+  @param[in] Context      Pointer to the notification function's context.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+OnReadyToBoot (\r
+  IN EFI_EVENT  Event,\r
+  IN VOID       *Context\r
+  )\r
+{\r
+  NOTIFY_PHASE_PARAMS               NotifyPhaseParams;\r
+  EFI_STATUS                        Status;\r
+  ADD_PERFORMANCE_RECORD_PROTOCOL   *AddPerfRecordInterface;\r
+  EFI_PEI_HOB_POINTERS              Hob;\r
+  VOID                              **FspHobListPtr;\r
+\r
+  gBS->CloseEvent (Event);\r
+\r
+  NotifyPhaseParams.Phase = EnumInitPhaseReadyToBoot;\r
+  PERF_START_EX(&gFspApiPerformanceGuid, "EventRec", NULL, 0, 0x4000);\r
+  Status = CallFspNotifyPhase (&NotifyPhaseParams);\r
+  PERF_END_EX(&gFspApiPerformanceGuid, "EventRec", NULL, 0, 0x407F);\r
+  if (Status != EFI_SUCCESS) {\r
+    DEBUG((DEBUG_ERROR, "FSP NotifyPhase ReadyToBoot failed, status: 0x%x\n", Status));\r
+  } else {\r
+    DEBUG((DEBUG_INFO, "FSP NotifyPhase ReadyToBoot Success.\n"));\r
+  }\r
+\r
+  Status = gBS->LocateProtocol (\r
+                  &gAddPerfRecordProtocolGuid,\r
+                  NULL,\r
+                  (VOID**) &AddPerfRecordInterface\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG((DEBUG_INFO, "gAddPerfRecordProtocolGuid - Locate protocol failed\n"));\r
+    return;\r
+  } else {\r
+    Hob.Raw = GetHobList ();\r
+    if (Hob.Raw != NULL) {\r
+      Hob.Raw = GetNextGuidHob (&gFspHobGuid, Hob.Raw);\r
+      FspHobListPtr = GET_GUID_HOB_DATA(Hob.Raw);\r
+      AddPerfRecordInterface->AddPerformanceRecords((VOID *)(UINTN)(((UINT32)(UINTN)*FspHobListPtr) & 0xFFFFFFFF));\r
+    }\r
+  }\r
+}\r
+\r
+/**\r
+  This stage is notified just before the firmware/Preboot environment transfers\r
+  management of all system resources to the OS or next level execution environment.\r
+\r
+  @param  Event         Event whose notification function is being invoked.\r
+  @param  Context       Pointer to the notification function's context, which is\r
+                        always zero in current implementation.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+OnEndOfFirmware (\r
+  IN EFI_EVENT  Event,\r
+  IN VOID       *Context\r
+  )\r
+{\r
+  NOTIFY_PHASE_PARAMS NotifyPhaseParams;\r
+  EFI_STATUS          Status;\r
+\r
+  gBS->CloseEvent (Event);\r
+\r
+  NotifyPhaseParams.Phase = EnumInitPhaseEndOfFirmware;\r
+  PERF_START_EX(&gFspApiPerformanceGuid, "EventRec", NULL, 0, 0x2000);\r
+  Status = CallFspNotifyPhase (&NotifyPhaseParams);\r
+  PERF_END_EX(&gFspApiPerformanceGuid, "EventRec", NULL, 0, 0x207F);\r
+  if (Status != EFI_SUCCESS) {\r
+    DEBUG((DEBUG_ERROR, "FSP NotifyPhase EndOfFirmware failed, status: 0x%x\n", Status));\r
+  } else {\r
+    DEBUG((DEBUG_INFO, "FSP NotifyPhase EndOfFirmware Success.\n"));\r
+  }\r
+}\r
+\r
+/**\r
+  Main entry for the FSP DXE module.\r
+\r
+  This routine registers two callbacks to call fsp's notifies.\r
+\r
+  @param[in] ImageHandle    The firmware allocated handle for the EFI image.\r
+  @param[in] SystemTable    A pointer to the EFI System Table.\r
+\r
+  @retval EFI_SUCCESS       The entry point is executed successfully.\r
+  @retval other             Some error occurs when executing this entry point.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FspWrapperNotifyDxeEntryPoint (\r
+  IN EFI_HANDLE         ImageHandle,\r
+  IN EFI_SYSTEM_TABLE   *SystemTable\r
+  )\r
+{\r
+  EFI_STATUS Status;\r
+  EFI_EVENT  ReadyToBootEvent;\r
+  VOID       *Registration;\r
+  EFI_EVENT  ProtocolNotifyEvent;\r
+\r
+  //\r
+  // Load this driver's image to memory\r
+  //\r
+  Status = RelocateImageUnder4GIfNeeded (ImageHandle, SystemTable);\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  ProtocolNotifyEvent = EfiCreateProtocolNotifyEvent (\r
+                          &gEfiPciEnumerationCompleteProtocolGuid,\r
+                          TPL_CALLBACK,\r
+                          OnPciEnumerationComplete,\r
+                          NULL,\r
+                          &Registration\r
+                          );\r
+  ASSERT (ProtocolNotifyEvent != NULL);\r
+\r
+  Status = EfiCreateEventReadyToBootEx (\r
+             TPL_CALLBACK,\r
+             OnReadyToBoot,\r
+             NULL,\r
+             &ReadyToBootEvent\r
+             );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  Status = gBS->CreateEventEx (\r
+                  EVT_NOTIFY_SIGNAL,\r
+                  TPL_NOTIFY,\r
+                  OnEndOfFirmware,\r
+                  NULL,\r
+                  &gEfiEventExitBootServicesGuid,\r
+                  &mExitBootServicesEvent\r
+                  );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
diff --git a/IntelFsp2WrapperPkg/FspWrapperNotifyDxe/FspWrapperNotifyDxe.inf b/IntelFsp2WrapperPkg/FspWrapperNotifyDxe/FspWrapperNotifyDxe.inf
new file mode 100644 (file)
index 0000000..9d50922
--- /dev/null
@@ -0,0 +1,66 @@
+## @file\r
+# FSP DXE Module\r
+#\r
+# This driver will register two callbacks to call fsp's notifies.\r
+#\r
+#  Copyright (c) 2014 - 2016, 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                      = FspWrapperNotifyDxe\r
+  FILE_GUID                      = AD61999A-507E-47E6-BA28-79CC609FA1A4\r
+  MODULE_TYPE                    = DXE_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+  ENTRY_POINT                    = FspWrapperNotifyDxeEntryPoint\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
+[Sources]\r
+  FspWrapperNotifyDxe.c\r
+  LoadBelow4G.c\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  IntelFsp2Pkg/IntelFsp2Pkg.dec\r
+  IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec\r
+\r
+[LibraryClasses]\r
+  UefiDriverEntryPoint\r
+  UefiBootServicesTableLib\r
+  DebugLib\r
+  BaseMemoryLib\r
+  UefiLib\r
+  FspWrapperApiLib\r
+  PeCoffLib\r
+  CacheMaintenanceLib\r
+  DxeServicesLib\r
+  PerformanceLib\r
+  HobLib\r
+\r
+[Protocols]\r
+  gEfiPciEnumerationCompleteProtocolGuid            ## CONSUMES\r
+  gAddPerfRecordProtocolGuid                        ## CONSUMES\r
+\r
+[Guids]\r
+  gFspApiPerformanceGuid                            ## CONSUMES ## GUID\r
+  gEfiEventExitBootServicesGuid                     ## CONSUMES ## Event\r
+  gFspHobGuid                                       ## CONSUMES ## HOB\r
+\r
+[Pcd]\r
+  gFspWrapperTokenSpaceGuid.PcdFspsBaseAddress              ## CONSUMES\r
+\r
+[Depex]\r
+  TRUE\r
diff --git a/IntelFsp2WrapperPkg/FspWrapperNotifyDxe/LoadBelow4G.c b/IntelFsp2WrapperPkg/FspWrapperNotifyDxe/LoadBelow4G.c
new file mode 100644 (file)
index 0000000..c073703
--- /dev/null
@@ -0,0 +1,152 @@
+/** @file\r
+\r
+Copyright (c) 2015 - 2016, 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\r
+of the BSD License which accompanies this distribution.  The\r
+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/UefiDriverEntryPoint.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/PeCoffLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/DxeServicesLib.h>\r
+#include <Library/CacheMaintenanceLib.h>\r
+#include <Library/UefiLib.h>\r
+\r
+/**\r
+  Relocate this image under 4G memory.\r
+\r
+  @param  ImageHandle  Handle of driver image.\r
+  @param  SystemTable  Pointer to system table.\r
+\r
+  @retval EFI_SUCCESS  Image successfully relocated.\r
+  @retval EFI_ABORTED  Failed to relocate image.\r
+\r
+**/\r
+EFI_STATUS\r
+RelocateImageUnder4GIfNeeded (\r
+  IN EFI_HANDLE           ImageHandle,\r
+  IN EFI_SYSTEM_TABLE     *SystemTable\r
+  )\r
+{\r
+  EFI_STATUS                                    Status;\r
+  UINT8                                         *Buffer;\r
+  UINTN                                         BufferSize;\r
+  EFI_HANDLE                                    NewImageHandle;\r
+  UINTN                                         Pages;\r
+  EFI_PHYSICAL_ADDRESS                          FfsBuffer;\r
+  PE_COFF_LOADER_IMAGE_CONTEXT                  ImageContext;\r
+  VOID                                          *Interface;\r
+\r
+  //\r
+  // If it is already <4G, no need do relocate\r
+  //\r
+  if ((UINTN)RelocateImageUnder4GIfNeeded < 0xFFFFFFFF) {\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  //\r
+  // If locate gEfiCallerIdGuid success, it means 2nd entry.\r
+  //\r
+  Status = gBS->LocateProtocol (&gEfiCallerIdGuid, NULL, &Interface);\r
+  if (!EFI_ERROR (Status)) {\r
+    DEBUG ((DEBUG_INFO, "FspNotifyDxe - 2nd entry\n"));\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  DEBUG ((DEBUG_INFO, "FspNotifyDxe - 1st entry\n"));\r
+\r
+  //\r
+  // Here we install a dummy handle\r
+  //\r
+  NewImageHandle = NULL;\r
+  Status = gBS->InstallProtocolInterface (\r
+                  &NewImageHandle,\r
+                  &gEfiCallerIdGuid,\r
+                  EFI_NATIVE_INTERFACE,\r
+                  NULL\r
+                  );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  //\r
+  // Reload image itself to <4G mem\r
+  //\r
+  Status = GetSectionFromAnyFv  (\r
+             &gEfiCallerIdGuid,\r
+             EFI_SECTION_PE32,\r
+             0,\r
+             (VOID **) &Buffer,\r
+             &BufferSize\r
+             );\r
+  ASSERT_EFI_ERROR (Status);\r
+  ImageContext.Handle    = Buffer;\r
+  ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory;\r
+  //\r
+  // Get information about the image being loaded\r
+  //\r
+  Status = PeCoffLoaderGetImageInfo (&ImageContext);\r
+  ASSERT_EFI_ERROR (Status);\r
+  if (ImageContext.SectionAlignment > EFI_PAGE_SIZE) {\r
+    Pages = EFI_SIZE_TO_PAGES ((UINTN) (ImageContext.ImageSize + ImageContext.SectionAlignment));\r
+  } else {\r
+    Pages = EFI_SIZE_TO_PAGES ((UINTN) ImageContext.ImageSize);\r
+  }\r
+  FfsBuffer = 0xFFFFFFFF;\r
+  Status = gBS->AllocatePages (\r
+                  AllocateMaxAddress,\r
+                  EfiBootServicesCode,\r
+                  Pages,\r
+                  &FfsBuffer\r
+                  );\r
+  ASSERT_EFI_ERROR (Status);\r
+  ImageContext.ImageAddress = (PHYSICAL_ADDRESS)(UINTN)FfsBuffer;\r
+  //\r
+  // Align buffer on section boundry\r
+  //\r
+  ImageContext.ImageAddress += ImageContext.SectionAlignment - 1;\r
+  ImageContext.ImageAddress &= ~((EFI_PHYSICAL_ADDRESS)(ImageContext.SectionAlignment - 1));\r
+  //\r
+  // Load the image to our new buffer\r
+  //\r
+  Status = PeCoffLoaderLoadImage (&ImageContext);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  //\r
+  // Relocate the image in our new buffer\r
+  //\r
+  Status = PeCoffLoaderRelocateImage (&ImageContext);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  //\r
+  // Free the buffer allocated by ReadSection since the image has been relocated in the new buffer\r
+  //\r
+  gBS->FreePool (Buffer);\r
+\r
+  //\r
+  // Flush the instruction cache so the image data is written before we execute it\r
+  //\r
+  InvalidateInstructionCacheRange ((VOID *)(UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.ImageSize);\r
+\r
+  DEBUG ((DEBUG_INFO, "Loading driver at 0x%08x EntryPoint=0x%08x\n", (UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.EntryPoint));\r
+  Status = ((EFI_IMAGE_ENTRY_POINT)(UINTN)(ImageContext.EntryPoint)) (NewImageHandle, gST);\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((DEBUG_ERROR, "Error: Image at 0x%08x start failed: %r\n", ImageContext.ImageAddress, Status));\r
+    gBS->FreePages (FfsBuffer, Pages);\r
+  }\r
+\r
+  //\r
+  // return error to unload >4G copy, if we already relocate itself to <4G.\r
+  //\r
+  return EFI_ALREADY_STARTED;\r
+}\r
diff --git a/IntelFsp2WrapperPkg/FspmWrapperPeim/FspmWrapperPeim.c b/IntelFsp2WrapperPkg/FspmWrapperPeim/FspmWrapperPeim.c
new file mode 100644 (file)
index 0000000..b1c605c
--- /dev/null
@@ -0,0 +1,161 @@
+/** @file\r
+  This will be invoked only once. It will call FspMemoryInit API,\r
+  register TemporaryRamDonePpi to call TempRamExit API, and register MemoryDiscoveredPpi\r
+  notify to call FspSiliconInit API.\r
+\r
+  Copyright (c) 2014 - 2016, 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 <PiPei.h>\r
+\r
+#include <Library/PeimEntryPoint.h>\r
+#include <Library/PeiServicesLib.h>\r
+#include <Library/PeiServicesTablePointerLib.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/HobLib.h>\r
+#include <Library/PcdLib.h>\r
+#include <Library/TimerLib.h>\r
+#include <Library/PerformanceLib.h>\r
+#include <Library/FspWrapperPlatformLib.h>\r
+#include <Library/FspWrapperHobProcessLib.h>\r
+#include <Library/FspWrapperApiLib.h>\r
+\r
+#include <Ppi/FspSiliconInitDone.h>\r
+#include <Ppi/EndOfPeiPhase.h>\r
+#include <Ppi/MemoryDiscovered.h>\r
+#include <Ppi/SecPlatformInformation.h>\r
+#include <Library/PlatformSecLib.h>\r
+#include <Library/FspWrapperApiTestLib.h>\r
+#include <FspEas.h>\r
+\r
+extern EFI_GUID gFspHobGuid;\r
+\r
+/**\r
+  Call FspMemoryInit API.\r
+\r
+  @return Status returned by FspMemoryInit API.\r
+**/\r
+EFI_STATUS\r
+PeiFspMemoryInit (\r
+  VOID\r
+  )\r
+{\r
+  FSP_INFO_HEADER           *FspmHeaderPtr;\r
+  EFI_STATUS                Status;\r
+  UINT64                    TimeStampCounterStart;\r
+  VOID                      *FspHobListPtr;\r
+  VOID                      *HobData;\r
+  FSPM_UPD_COMMON           *FspmUpdDataPtr;\r
+  UINTN                     *SourceData;\r
+\r
+  DEBUG ((DEBUG_INFO, "PeiFspMemoryInit enter\n"));\r
+\r
+  FspHobListPtr = NULL;\r
+\r
+  //\r
+  // Copy default FSP-M UPD data from Flash\r
+  //\r
+  FspmHeaderPtr = (FSP_INFO_HEADER *)FspFindFspHeader (PcdGet32 (PcdFspmBaseAddress));\r
+  FspmUpdDataPtr = (FSPM_UPD_COMMON *)AllocateZeroPool ((UINTN)FspmHeaderPtr->CfgRegionSize);\r
+  ASSERT (FspmUpdDataPtr != NULL);\r
+  SourceData = (UINTN *)((UINTN)FspmHeaderPtr->ImageBase + (UINTN)FspmHeaderPtr->CfgRegionOffset);\r
+  CopyMem (FspmUpdDataPtr, SourceData, (UINTN)FspmHeaderPtr->CfgRegionSize);\r
+\r
+  DEBUG ((DEBUG_INFO, "FspWrapperPlatformInitPreMem enter\n"));\r
+  UpdateFspmUpdData ((VOID *)FspmUpdDataPtr);\r
+  DEBUG ((DEBUG_INFO, "  NvsBufferPtr        - 0x%x\n", FspmUpdDataPtr->FspmArchUpd.NvsBufferPtr));\r
+  DEBUG ((DEBUG_INFO, "  StackBase           - 0x%x\n", FspmUpdDataPtr->FspmArchUpd.StackBase));\r
+  DEBUG ((DEBUG_INFO, "  StackSize           - 0x%x\n", FspmUpdDataPtr->FspmArchUpd.StackSize));\r
+  DEBUG ((DEBUG_INFO, "  BootLoaderTolumSize - 0x%x\n", FspmUpdDataPtr->FspmArchUpd.BootLoaderTolumSize));\r
+  DEBUG ((DEBUG_INFO, "  BootMode            - 0x%x\n", FspmUpdDataPtr->FspmArchUpd.BootMode));\r
+  DEBUG ((DEBUG_INFO, "  HobListPtr          - 0x%x\n", &FspHobListPtr));\r
+\r
+  TimeStampCounterStart = AsmReadTsc ();\r
+  Status = CallFspMemoryInit (FspmUpdDataPtr, &FspHobListPtr);\r
+  // Create hobs after memory initialization and not in temp RAM. Hence passing the recorded timestamp here\r
+  PERF_START_EX(&gFspApiPerformanceGuid, "EventRec", NULL, TimeStampCounterStart, 0xD000);\r
+  PERF_END_EX(&gFspApiPerformanceGuid, "EventRec", NULL, 0, 0xD07F);\r
+  DEBUG ((DEBUG_INFO, "Total time spent executing FspMemoryInitApi: %d millisecond\n", DivU64x32 (GetTimeInNanoSecond (AsmReadTsc () - TimeStampCounterStart), 1000000)));\r
+  if (EFI_ERROR(Status)) {\r
+    DEBUG ((DEBUG_ERROR, "ERROR - Failed to execute FspMemoryInitApi(), Status = %r\n", Status));\r
+  }\r
+  DEBUG((DEBUG_INFO, "FspMemoryInit status: 0x%x\n", Status));\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+\r
+  Status = TestFspMemoryInitApiOutput (FspmUpdDataPtr, &FspHobListPtr);\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((DEBUG_ERROR, "ERROR - TestFspMemoryInitApiOutput () fail, Status = %r\n", Status));\r
+  }\r
+\r
+  DEBUG ((DEBUG_INFO, "  FspHobListPtr (returned) - 0x%x\n", FspHobListPtr));\r
+  ASSERT (FspHobListPtr != NULL);\r
+\r
+  PostFspmHobProcess (FspHobListPtr);\r
+\r
+  //\r
+  // FspHobList is not complete at this moment.\r
+  // Save FspHobList pointer to hob, so that it can be got later\r
+  //\r
+  HobData = BuildGuidHob (\r
+             &gFspHobGuid,\r
+             sizeof (VOID *)\r
+             );\r
+  ASSERT (HobData != NULL);\r
+  CopyMem (HobData, &FspHobListPtr, sizeof (FspHobListPtr));\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Do FSP initialization.\r
+\r
+  @return FSP initialization status.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FspmWrapperInit (\r
+  VOID\r
+  )\r
+{\r
+  EFI_STATUS           Status;\r
+\r
+  Status = PeiFspMemoryInit ();\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  This is the entrypoint of PEIM\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_SUCCESS if it completed successfully.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FspmWrapperPeimEntryPoint (\r
+  IN       EFI_PEI_FILE_HANDLE  FileHandle,\r
+  IN CONST EFI_PEI_SERVICES     **PeiServices\r
+  )\r
+{\r
+  DEBUG((DEBUG_INFO, "FspmWrapperPeimEntryPoint\n"));\r
+\r
+  FspmWrapperInit ();\r
+\r
+  return EFI_SUCCESS;\r
+}\r
diff --git a/IntelFsp2WrapperPkg/FspmWrapperPeim/FspmWrapperPeim.inf b/IntelFsp2WrapperPkg/FspmWrapperPeim/FspmWrapperPeim.inf
new file mode 100644 (file)
index 0000000..df735e1
--- /dev/null
@@ -0,0 +1,77 @@
+## @file\r
+# FSP-M wrapper PEI Module\r
+#\r
+# This PEIM initialize FSP.\r
+# This will be invoked only once. It will call FspMemoryInit API,\r
+# register TemporaryRamDonePpi to call TempRamExit API, and register MemoryDiscoveredPpi\r
+# notify to call FspSiliconInit API.\r
+#\r
+#  Copyright (c) 2014 - 2016, 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                    = 0x00010017\r
+  BASE_NAME                      = FspmWrapperPeim\r
+  FILE_GUID                      = 9FAAD0FF-0E0C-4885-A738-BAB4E4FA1E66\r
+  VERSION_STRING                 = 1.0\r
+  MODULE_TYPE                    = PEIM\r
+  ENTRY_POINT                    = FspmWrapperPeimEntryPoint\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
+[LibraryClasses]\r
+  PeimEntryPoint\r
+  PeiServicesLib\r
+  PeiServicesTablePointerLib\r
+  BaseLib\r
+  BaseMemoryLib\r
+  MemoryAllocationLib\r
+  DebugLib\r
+  HobLib\r
+  FspWrapperPlatformLib\r
+  FspWrapperHobProcessLib\r
+  DebugAgentLib\r
+  UefiCpuLib\r
+  PeCoffGetEntryPointLib\r
+  PeCoffExtraActionLib\r
+  PerformanceLib\r
+  TimerLib\r
+  FspWrapperApiLib\r
+  FspWrapperApiTestLib\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec\r
+  UefiCpuPkg/UefiCpuPkg.dec\r
+  IntelFsp2Pkg/IntelFsp2Pkg.dec\r
+  IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec\r
+\r
+[Pcd]\r
+  gFspWrapperTokenSpaceGuid.PcdFspmBaseAddress                ## CONSUMES\r
+\r
+[Sources]\r
+  FspmWrapperPeim.c\r
+\r
+[Ppis]\r
+  gTopOfTemporaryRamPpiGuid             ## PRODUCES\r
+  gEfiEndOfPeiSignalPpiGuid             ## PRODUCES\r
+  gEfiPeiMemoryDiscoveredPpiGuid        ## PRODUCES\r
+\r
+[Guids]\r
+  gFspHobGuid                           ## PRODUCES ## HOB\r
+  gFspApiPerformanceGuid                ## CONSUMES ## GUID\r
+\r
+[Depex]\r
+  gEfiPeiMasterBootModePpiGuid\r
diff --git a/IntelFsp2WrapperPkg/FspsWrapperPeim/FspsWrapperPeim.c b/IntelFsp2WrapperPkg/FspsWrapperPeim/FspsWrapperPeim.c
new file mode 100644 (file)
index 0000000..9bc720f
--- /dev/null
@@ -0,0 +1,313 @@
+/** @file\r
+  This will be invoked only once. It will call FspMemoryInit API,\r
+  register TemporaryRamDonePpi to call TempRamExit API, and register MemoryDiscoveredPpi\r
+  notify to call FspSiliconInit API.\r
+\r
+  Copyright (c) 2014 - 2016, 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
+#include <Library/PeimEntryPoint.h>\r
+#include <Library/PeiServicesLib.h>\r
+#include <Library/PeiServicesTablePointerLib.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/HobLib.h>\r
+#include <Library/PcdLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/FspWrapperPlatformLib.h>\r
+#include <Library/FspWrapperHobProcessLib.h>\r
+#include <Library/TimerLib.h>\r
+#include <Library/PerformanceLib.h>\r
+#include <Library/FspWrapperApiLib.h>\r
+\r
+#include <Ppi/FspSiliconInitDone.h>\r
+#include <Ppi/EndOfPeiPhase.h>\r
+#include <Ppi/MemoryDiscovered.h>\r
+#include <Ppi/TemporaryRamDone.h>\r
+#include <Ppi/SecPlatformInformation.h>\r
+#include <Library/PlatformSecLib.h>\r
+#include <Library/FspWrapperApiTestLib.h>\r
+#include <FspEas.h>\r
+\r
+extern EFI_PEI_NOTIFY_DESCRIPTOR mS3EndOfPeiNotifyDesc;\r
+extern EFI_GUID                  gFspHobGuid;\r
+\r
+/**\r
+This function handles S3 resume task at the end of PEI\r
+\r
+@param[in] PeiServices    Pointer to PEI Services Table.\r
+@param[in] NotifyDesc     Pointer to the descriptor for the Notification event that\r
+caused this function to execute.\r
+@param[in] Ppi            Pointer to the PPI data associated with this function.\r
+\r
+@retval EFI_STATUS        Always return EFI_SUCCESS\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+S3EndOfPeiNotify(\r
+  IN EFI_PEI_SERVICES          **PeiServices,\r
+  IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc,\r
+  IN VOID                      *Ppi\r
+  );\r
+\r
+EFI_PEI_NOTIFY_DESCRIPTOR mS3EndOfPeiNotifyDesc = {\r
+  (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
+  &gEfiEndOfPeiSignalPpiGuid,\r
+  S3EndOfPeiNotify\r
+};\r
+\r
+/**\r
+This function handles S3 resume task at the end of PEI\r
+\r
+@param[in] PeiServices    Pointer to PEI Services Table.\r
+@param[in] NotifyDesc     Pointer to the descriptor for the Notification event that\r
+caused this function to execute.\r
+@param[in] Ppi            Pointer to the PPI data associated with this function.\r
+\r
+@retval EFI_STATUS        Always return EFI_SUCCESS\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+S3EndOfPeiNotify(\r
+  IN EFI_PEI_SERVICES          **PeiServices,\r
+  IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc,\r
+  IN VOID                      *Ppi\r
+  )\r
+{\r
+  NOTIFY_PHASE_PARAMS NotifyPhaseParams;\r
+  EFI_STATUS          Status;\r
+\r
+  DEBUG((DEBUG_INFO, "S3EndOfPeiNotify enter\n"));\r
+\r
+  NotifyPhaseParams.Phase = EnumInitPhaseAfterPciEnumeration;\r
+  Status = CallFspNotifyPhase (&NotifyPhaseParams);\r
+  DEBUG((DEBUG_INFO, "FSP S3NotifyPhase AfterPciEnumeration status: 0x%x\n", Status));\r
+\r
+  NotifyPhaseParams.Phase = EnumInitPhaseReadyToBoot;\r
+  Status = CallFspNotifyPhase (&NotifyPhaseParams);\r
+  DEBUG((DEBUG_INFO, "FSP S3NotifyPhase ReadyToBoot status: 0x%x\n", Status));\r
+\r
+  NotifyPhaseParams.Phase = EnumInitPhaseEndOfFirmware;\r
+  Status = CallFspNotifyPhase (&NotifyPhaseParams);\r
+  DEBUG((DEBUG_INFO, "FSP S3NotifyPhase EndOfFirmware status: 0x%x\n", Status));\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+Return Hob list produced by FSP.\r
+\r
+@param[in]  PeiServices  The pointer to the PEI Services Table.\r
+@param[in]  This         The pointer to this instance of this PPI.\r
+@param[out] FspHobList   The pointer to Hob list produced by FSP.\r
+\r
+@return EFI_SUCCESS FReturn Hob list produced by FSP successfully.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FspSiliconInitDoneGetFspHobList (\r
+  IN  CONST EFI_PEI_SERVICES         **PeiServices,\r
+  IN  FSP_SILICON_INIT_DONE_PPI      *This,\r
+  OUT VOID                           **FspHobList\r
+  );\r
+\r
+FSP_SILICON_INIT_DONE_PPI mFspSiliconInitDonePpi = {\r
+  FspSiliconInitDoneGetFspHobList\r
+};\r
+\r
+EFI_PEI_PPI_DESCRIPTOR            mPeiFspSiliconInitDonePpi = {\r
+  EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,\r
+  &gFspSiliconInitDonePpiGuid,\r
+  &mFspSiliconInitDonePpi\r
+};\r
+\r
+/**\r
+Return Hob list produced by FSP.\r
+\r
+@param[in]  PeiServices  The pointer to the PEI Services Table.\r
+@param[in]  This         The pointer to this instance of this PPI.\r
+@param[out] FspHobList   The pointer to Hob list produced by FSP.\r
+\r
+@return EFI_SUCCESS FReturn Hob list produced by FSP successfully.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FspSiliconInitDoneGetFspHobList (\r
+  IN  CONST EFI_PEI_SERVICES         **PeiServices,\r
+  IN  FSP_SILICON_INIT_DONE_PPI      *This,\r
+  OUT VOID                           **FspHobList\r
+  )\r
+{\r
+  EFI_HOB_GUID_TYPE                  *GuidHob;\r
+\r
+  GuidHob = GetFirstGuidHob (&gFspHobGuid);\r
+  if (GuidHob != NULL) {\r
+    *FspHobList = *(VOID **)GET_GUID_HOB_DATA(GuidHob);\r
+    return EFI_SUCCESS;\r
+  } else {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+}\r
+\r
+/**\r
+  This function is called after PEI core discover memory and finish migration.\r
+\r
+  @param[in] PeiServices    Pointer to PEI Services Table.\r
+  @param[in] NotifyDesc     Pointer to the descriptor for the Notification event that\r
+                            caused this function to execute.\r
+  @param[in] Ppi            Pointer to the PPI data associated with this function.\r
+\r
+  @retval EFI_STATUS        Always return EFI_SUCCESS\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+PeiMemoryDiscoveredNotify (\r
+  IN EFI_PEI_SERVICES          **PeiServices,\r
+  IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc,\r
+  IN VOID                      *Ppi\r
+  );\r
+\r
+EFI_PEI_NOTIFY_DESCRIPTOR mPeiMemoryDiscoveredNotifyDesc = {\r
+  (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
+  &gEfiPeiMemoryDiscoveredPpiGuid,\r
+  PeiMemoryDiscoveredNotify\r
+};\r
+\r
+/**\r
+This function is called after PEI core discover memory and finish migration.\r
+\r
+@param[in] PeiServices    Pointer to PEI Services Table.\r
+@param[in] NotifyDesc     Pointer to the descriptor for the Notification event that\r
+caused this function to execute.\r
+@param[in] Ppi            Pointer to the PPI data associated with this function.\r
+\r
+@retval EFI_STATUS        Always return EFI_SUCCESS\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+PeiMemoryDiscoveredNotify (\r
+  IN EFI_PEI_SERVICES          **PeiServices,\r
+  IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc,\r
+  IN VOID                      *Ppi\r
+  )\r
+{\r
+  FSP_INFO_HEADER           *FspsHeaderPtr;\r
+  UINT64                    TimeStampCounterStart;\r
+  EFI_STATUS                Status;\r
+  VOID                      *FspHobListPtr;\r
+  EFI_HOB_GUID_TYPE         *GuidHob;\r
+  FSPS_UPD_COMMON           *FspsUpdDataPtr;\r
+  UINTN                     *SourceData;\r
+\r
+  \r
+  DEBUG ((DEBUG_INFO, "PeiMemoryDiscoveredNotify enter\n"));\r
+  \r
+  //\r
+  // Copy default FSP-S UPD data from Flash\r
+  //\r
+  FspsHeaderPtr = (FSP_INFO_HEADER *)FspFindFspHeader (PcdGet32 (PcdFspsBaseAddress));\r
+  FspsUpdDataPtr = (FSPS_UPD_COMMON *)AllocateZeroPool ((UINTN)FspsHeaderPtr->CfgRegionSize);\r
+  ASSERT (FspsUpdDataPtr != NULL);\r
+  SourceData = (UINTN *)((UINTN)FspsHeaderPtr->ImageBase + (UINTN)FspsHeaderPtr->CfgRegionOffset);\r
+  CopyMem (FspsUpdDataPtr, SourceData, (UINTN)FspsHeaderPtr->CfgRegionSize);\r
+\r
+  UpdateFspsUpdData ((VOID *)FspsUpdDataPtr);\r
+\r
+  TimeStampCounterStart = AsmReadTsc ();\r
+  PERF_START_EX(&gFspApiPerformanceGuid, "EventRec", NULL, 0, 0x9000);\r
+  Status = CallFspSiliconInit ((VOID *)FspsUpdDataPtr);\r
+  PERF_END_EX(&gFspApiPerformanceGuid, "EventRec", NULL, 0, 0x907F);\r
+  DEBUG ((DEBUG_INFO, "Total time spent executing FspSiliconInitApi: %d millisecond\n", DivU64x32 (GetTimeInNanoSecond (AsmReadTsc () - TimeStampCounterStart), 1000000)));\r
+  if (EFI_ERROR(Status)) {\r
+    DEBUG ((DEBUG_ERROR, "ERROR - Failed to execute FspSiliconInitApi(), Status = %r\n", Status));\r
+  }\r
+  DEBUG((DEBUG_INFO, "FspSiliconInit status: 0x%x\n", Status));\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  Status = TestFspSiliconInitApiOutput ((VOID *)NULL);\r
+  if (RETURN_ERROR (Status)) {\r
+    DEBUG ((DEBUG_ERROR, "ERROR - TestFspSiliconInitApiOutput () fail, Status = %r\n", Status));\r
+  }\r
+\r
+  //\r
+  // Now FspHobList complete, process it\r
+  //\r
+  GuidHob = GetFirstGuidHob (&gFspHobGuid);\r
+  ASSERT (GuidHob != NULL);\r
+  FspHobListPtr = *(VOID **)GET_GUID_HOB_DATA (GuidHob);\r
+  DEBUG ((DEBUG_INFO, "FspHobListPtr - 0x%x\n", FspHobListPtr));\r
+  PostFspsHobProcess (FspHobListPtr);\r
+\r
+  //\r
+  // Install FspSiliconInitDonePpi so that any other driver can consume this info.\r
+  //\r
+  Status = PeiServicesInstallPpi (&mPeiFspSiliconInitDonePpi);\r
+  ASSERT_EFI_ERROR(Status);\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Do FSP initialization.\r
+\r
+  @return FSP initialization status.\r
+**/\r
+EFI_STATUS\r
+FspsWrapperInit (\r
+  VOID\r
+  )\r
+{\r
+  EFI_STATUS           Status;\r
+  EFI_BOOT_MODE        BootMode;\r
+\r
+  //\r
+  // Register MemoryDiscovered Nofity to run FspSiliconInit\r
+  //\r
+  Status = PeiServicesNotifyPpi (&mPeiMemoryDiscoveredNotifyDesc);\r
+  ASSERT_EFI_ERROR (Status);\r
+      \r
+  //\r
+  // Register EndOfPei Notify for S3 to run FSP NotifyPhase\r
+  //\r
+  PeiServicesGetBootMode (&BootMode);\r
+  if (BootMode == BOOT_ON_S3_RESUME) {\r
+    Status = PeiServicesNotifyPpi (&mS3EndOfPeiNotifyDesc);\r
+    ASSERT_EFI_ERROR (Status);\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  This is the entrypoint of PEIM\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_SUCCESS if it completed successfully.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FspsWrapperPeimEntryPoint (\r
+  IN       EFI_PEI_FILE_HANDLE  FileHandle,\r
+  IN CONST EFI_PEI_SERVICES     **PeiServices\r
+  )\r
+{\r
+\r
+  DEBUG ((DEBUG_INFO, "FspsWrapperPeimEntryPoint\n"));\r
+\r
+  FspsWrapperInit ();\r
+\r
+  return EFI_SUCCESS;\r
+}\r
diff --git a/IntelFsp2WrapperPkg/FspsWrapperPeim/FspsWrapperPeim.inf b/IntelFsp2WrapperPkg/FspsWrapperPeim/FspsWrapperPeim.inf
new file mode 100644 (file)
index 0000000..05914f3
--- /dev/null
@@ -0,0 +1,79 @@
+## @file\r
+# FSP-S wrapper PEI Module\r
+#\r
+# This PEIM initialize FSP.\r
+# This will be invoked only once. It will call FspMemoryInit API,\r
+# register TemporaryRamDonePpi to call TempRamExit API, and register MemoryDiscoveredPpi\r
+# notify to call FspSiliconInit API.\r
+#\r
+#  Copyright (c) 2014 - 2016, 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                    = 0x00010017\r
+  BASE_NAME                      = FspsWrapperPeim\r
+  FILE_GUID                      = 0D244DF9-6CE3-4133-A1CF-53200AB663AC\r
+  VERSION_STRING                 = 1.0\r
+  MODULE_TYPE                    = PEIM\r
+  ENTRY_POINT                    = FspsWrapperPeimEntryPoint\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
+[LibraryClasses]\r
+  PeimEntryPoint\r
+  PeiServicesLib\r
+  PeiServicesTablePointerLib\r
+  BaseLib\r
+  BaseMemoryLib\r
+  TimerLib\r
+  DebugLib\r
+  HobLib\r
+  MemoryAllocationLib\r
+  FspWrapperPlatformLib\r
+  FspWrapperHobProcessLib\r
+  DebugAgentLib\r
+  UefiCpuLib\r
+  PeCoffGetEntryPointLib\r
+  PeCoffExtraActionLib\r
+  PerformanceLib\r
+  FspWrapperApiLib\r
+  FspWrapperApiTestLib\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec\r
+  UefiCpuPkg/UefiCpuPkg.dec\r
+  IntelFsp2Pkg/IntelFsp2Pkg.dec\r
+  IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec\r
+\r
+[Ppis]\r
+  gTopOfTemporaryRamPpiGuid             ## PRODUCES\r
+  gFspSiliconInitDonePpiGuid            ## PRODUCES\r
+  gEfiEndOfPeiSignalPpiGuid             ## PRODUCES\r
+  gEfiTemporaryRamDonePpiGuid           ## PRODUCES\r
+  gEfiPeiMemoryDiscoveredPpiGuid        ## PRODUCES\r
+\r
+[Pcd]\r
+  gFspWrapperTokenSpaceGuid.PcdFspsBaseAddress                ## CONSUMES\r
+\r
+[Guids]\r
+  gFspHobGuid                           ## CONSUMES ## HOB\r
+  gFspApiPerformanceGuid                ## CONSUMES ## GUID\r
+\r
+[Sources]\r
+  FspsWrapperPeim.c\r
+\r
+[Depex]\r
+  gEfiPeiMemoryDiscoveredPpiGuid\r
diff --git a/IntelFsp2WrapperPkg/Include/Library/FspWrapperApiLib.h b/IntelFsp2WrapperPkg/Include/Library/FspWrapperApiLib.h
new file mode 100644 (file)
index 0000000..807fb03
--- /dev/null
@@ -0,0 +1,87 @@
+/** @file\r
+  Provide FSP wrapper API related function.\r
+\r
+  Copyright (c) 2014 - 2016, 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_WRAPPER_API_LIB_H__\r
+#define __FSP_WRAPPER_API_LIB_H__\r
+\r
+#include <FspEas.h>\r
+\r
+/**\r
+  Find FSP header pointer.\r
+\r
+  @param[in] FlashFvFspBase Flash address of FSP FV.\r
+\r
+  @return FSP header pointer.\r
+**/\r
+FSP_INFO_HEADER *\r
+EFIAPI\r
+FspFindFspHeader (\r
+  IN EFI_PHYSICAL_ADDRESS  FlashFvFspBase\r
+  );\r
+\r
+/**\r
+  Call FSP API - FspNotifyPhase.\r
+\r
+  @param[in] NotifyPhaseParams Address pointer to the NOTIFY_PHASE_PARAMS structure.\r
+\r
+  @return EFI status returned by FspNotifyPhase API.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+CallFspNotifyPhase (\r
+  IN NOTIFY_PHASE_PARAMS *NotifyPhaseParams\r
+  );\r
+\r
+/**\r
+  Call FSP API - FspMemoryInit.\r
+\r
+  @param[in]  FspmUpdDataPtr          Pointer to the FSPM_UPD data sructure.\r
+  @param[out] HobListPtr              Pointer to receive the address of the HOB list.\r
+\r
+  @return EFI status returned by FspMemoryInit API.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+CallFspMemoryInit (\r
+  IN VOID                       *FspmUpdDataPtr,\r
+  OUT VOID                      **HobListPtr\r
+  );\r
+\r
+/**\r
+  Call FSP API - TempRamExit.\r
+\r
+  @param[in] TempRamExitParam    Address pointer to the TempRamExit parameters structure.\r
+\r
+  @return EFI status returned by TempRamExit API.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+CallTempRamExit (\r
+  IN VOID                       *TempRamExitParam\r
+  );\r
+\r
+/**\r
+  Call FSP API - FspSiliconInit.\r
+\r
+  @param[in] FspsUpdDataPtr     Pointer to the FSPS_UPD data structure.\r
+\r
+  @return EFI status returned by FspSiliconInit API.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+CallFspSiliconInit (\r
+  IN VOID                       *FspsUpdDataPtr\r
+  );\r
+\r
+#endif\r
diff --git a/IntelFsp2WrapperPkg/Include/Library/FspWrapperApiTestLib.h b/IntelFsp2WrapperPkg/Include/Library/FspWrapperApiTestLib.h
new file mode 100644 (file)
index 0000000..a8f54af
--- /dev/null
@@ -0,0 +1,61 @@
+/** @file\r
+  Provide FSP wrapper API test related function.\r
+\r
+  Copyright (c) 2016, 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_WRAPPER_API_TEST_LIB_H__\r
+#define __FSP_WRAPPER_API_TEST_LIB_H__\r
+\r
+#include <PiPei.h>\r
+\r
+/**\r
+  Test the output of FSP API - FspMemoryInit.\r
+\r
+  @param[in]  FspmUpdDataPtr Address pointer to the FSP_MEMORY_INIT_PARAMS structure.\r
+  @param[in]  HobListPtr     Address of the HobList pointer.\r
+\r
+  @return test result on output of FspMemoryInit API.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+TestFspMemoryInitApiOutput (\r
+  IN  VOID        *FspmUpdDataPtr,\r
+  IN  VOID        **HobListPtr\r
+  );\r
+\r
+/**\r
+  Test the output of FSP API - TempRamExit.\r
+\r
+  @param[in] TempRamExitParam    Address pointer to the TempRamExit parameters structure.\r
+\r
+  @return test result on output of TempRamExit API.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+TestFspTempRamExitApiOutput (\r
+  IN VOID        *TempRamExitParam\r
+  );\r
+\r
+/**\r
+  Test the output of FSP API - FspSiliconInit.\r
+\r
+  @param[in] FspsUpdDataPtr Address pointer to the Silicon Init parameters structure.\r
+\r
+  @return test result on output of FspSiliconInit API.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+TestFspSiliconInitApiOutput (\r
+  IN  VOID        *FspsUpdDataPtr\r
+  );\r
+\r
+#endif\r
diff --git a/IntelFsp2WrapperPkg/Include/Library/FspWrapperHobProcessLib.h b/IntelFsp2WrapperPkg/Include/Library/FspWrapperHobProcessLib.h
new file mode 100644 (file)
index 0000000..8b1e7ef
--- /dev/null
@@ -0,0 +1,44 @@
+/** @file\r
+  Provide FSP wrapper hob process related function.\r
+\r
+  Copyright (c) 2014 - 2016, 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_WRAPPER_HOB_PROCESS_LIB_H__\r
+#define __FSP_WRAPPER_HOB_PROCESS_LIB_H__\r
+\r
+/**\r
+  Post FSP-M HOB process for Memory Resource Descriptor.\r
+\r
+  @param[in] FspHobList  Pointer to the HOB data structure produced by FSP.\r
+\r
+  @return If platform process the FSP hob list successfully.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+PostFspmHobProcess (\r
+  IN VOID                 *FspHobList\r
+  );\r
+\r
+/**\r
+  Post FSP-S HOB process (not Memory Resource Descriptor).\r
+\r
+  @param[in] FspHobList  Pointer to the HOB data structure produced by FSP.\r
+\r
+  @return If platform process the FSP hob list successfully.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+PostFspsHobProcess (\r
+  IN VOID                 *FspHobList\r
+  );\r
+\r
+#endif\r
diff --git a/IntelFsp2WrapperPkg/Include/Library/FspWrapperPlatformLib.h b/IntelFsp2WrapperPkg/Include/Library/FspWrapperPlatformLib.h
new file mode 100644 (file)
index 0000000..30dc8df
--- /dev/null
@@ -0,0 +1,73 @@
+/** @file\r
+  Provide FSP wrapper platform related function.\r
+\r
+  Copyright (c) 2014 - 2016, 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_WRAPPER_PLATFORM_LIB_H__\r
+#define __FSP_WRAPPER_PLATFORM_LIB_H__\r
+\r
+/**\r
+  This function overrides the default configurations in the FSP-M UPD data region.\r
+\r
+  @param[in,out] FspUpdRgnPtr   A pointer to the UPD data region data strcture.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+UpdateFspmUpdData (\r
+  IN OUT VOID        *FspUpdRgnPtr\r
+  );\r
+\r
+/**\r
+  This function overrides the default configurations in the FSP-S UPD data region.\r
+\r
+  @param[in,out] FspUpdRgnPtr   A pointer to the UPD data region data strcture.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+UpdateFspsUpdData (\r
+  IN OUT VOID        *FspUpdRgnPtr\r
+  );\r
+\r
+/**\r
+  Update TempRamExit parameter.\r
+\r
+  @note At this point, memory is ready, PeiServices are available to use.\r
+\r
+  @return TempRamExit parameter.\r
+**/\r
+VOID *\r
+EFIAPI\r
+UpdateTempRamExitParam (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Get S3 PEI memory information.\r
+\r
+  @note At this point, memory is ready, and PeiServices are available to use.\r
+  Platform can get some data from SMRAM directly.\r
+\r
+  @param[out] S3PeiMemSize  PEI memory size to be installed in S3 phase.\r
+  @param[out] S3PeiMemBase  PEI memory base to be installed in S3 phase.\r
+\r
+  @return If S3 PEI memory information is got successfully.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+GetS3MemoryInfo (\r
+  OUT UINT64               *S3PeiMemSize,\r
+  OUT EFI_PHYSICAL_ADDRESS *S3PeiMemBase\r
+  );\r
+\r
+#endif\r
diff --git a/IntelFsp2WrapperPkg/Include/Ppi/FspSiliconInitDone.h b/IntelFsp2WrapperPkg/Include/Ppi/FspSiliconInitDone.h
new file mode 100644 (file)
index 0000000..4f3d8ad
--- /dev/null
@@ -0,0 +1,43 @@
+/** @file\r
+  Provides the services to return FSP hob list.\r
+\r
+  Copyright (c) 2014 - 2016, 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_SILICON_INIT_DONE_H_\r
+#define _FSP_SILICON_INIT_DONE_H_\r
+\r
+typedef struct _FSP_SILICON_INIT_DONE_PPI  FSP_SILICON_INIT_DONE_PPI;\r
+\r
+/**\r
+  Return Hob list produced by FSP.\r
+\r
+  @param[in]  PeiServices  The pointer to the PEI Services Table.\r
+  @param[in]  This         The pointer to this instance of this PPI.\r
+  @param[out] FspHobList   The pointer to Hob list produced by FSP.\r
+\r
+  @return EFI_SUCCESS FReturn Hob list produced by FSP successfully.\r
+**/\r
+typedef\r
+EFI_STATUS\r
+(EFIAPI *FSP_SILICON_INIT_DONE_GET_FSP_HOB_LIST)(\r
+  IN  CONST EFI_PEI_SERVICES         **PeiServices,\r
+  IN  FSP_SILICON_INIT_DONE_PPI      *This,\r
+  OUT VOID                           **FspHobList\r
+  );\r
+\r
+struct _FSP_SILICON_INIT_DONE_PPI {\r
+  FSP_SILICON_INIT_DONE_GET_FSP_HOB_LIST      GetFspHobList;\r
+};\r
+\r
+extern EFI_GUID gFspSiliconInitDonePpiGuid;\r
+\r
+#endif\r
diff --git a/IntelFsp2WrapperPkg/Include/Ppi/TopOfTemporaryRam.h b/IntelFsp2WrapperPkg/Include/Ppi/TopOfTemporaryRam.h
new file mode 100644 (file)
index 0000000..c25c4fa
--- /dev/null
@@ -0,0 +1,20 @@
+/** @file\r
+  Provides the pointer to top of temporary ram.\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 _TOP_OF_TEMPORARY_RAM_H_\r
+#define _TOP_OF_TEMPORARY_RAM_H_\r
+\r
+extern EFI_GUID gTopOfTemporaryRamPpiGuid;\r
+\r
+#endif\r
diff --git a/IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec b/IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec
new file mode 100644 (file)
index 0000000..b76e611
--- /dev/null
@@ -0,0 +1,77 @@
+## @file\r
+# Provides drivers and definitions to support fsp in EDKII bios.\r
+#\r
+# Copyright (c) 2014 - 2016, 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
+  DEC_SPECIFICATION              = 0x00010005\r
+  PACKAGE_NAME                   = IntelFsp2WrapperPkg\r
+  PACKAGE_GUID                   = FAFE06D4-7245-42D7-9FD2-E5D5E36AB0A0\r
+  PACKAGE_VERSION                = 0.1\r
+\r
+[Includes]\r
+  Include\r
+\r
+[LibraryClasses]\r
+  ##  @libraryclass  Provide FSP API related function.\r
+  FspWrapperApiLib|Include/Library/FspWrapperApiLib.h\r
+  FspWrapperApiTestLib|Include/Library/FspWrapperApiTestLib.h\r
+\r
+  ##  @libraryclass  Provide FSP hob process related function.\r
+  FspWrapperHobProcessLib|Include/Library/FspWrapperHobProcessLib.h\r
+\r
+  ##  @libraryclass  Provide FSP platform related function.\r
+  FspWrapperPlatformLib|Include/Library/FspWrapperPlatformLib.h\r
+\r
+[Guids]\r
+  #\r
+  # GUID defined in package\r
+  #\r
+  gFspWrapperTokenSpaceGuid             = { 0xa34cf082, 0xf50, 0x4f0d,  { 0x89, 0x8a, 0x3d, 0x39, 0x30, 0x2b, 0xc5, 0x1e } }\r
+  gFspApiPerformanceGuid                = { 0xc9122295, 0x56ed, 0x4d4e, { 0x06, 0xa6, 0x50, 0x8d, 0x89, 0x4d, 0x3e, 0x40 } }\r
+  gFspHobGuid                           = { 0x6d86fb36, 0xba90, 0x472c, { 0xb5, 0x83, 0x3f, 0xbe, 0xd3, 0xfb, 0x20, 0x9a } }\r
+\r
+[Ppis]\r
+  gFspSiliconInitDonePpiGuid            = { 0x4eb6e09c, 0xd256, 0x4e1e, { 0xb5, 0x0a, 0x87, 0x4b, 0xd2, 0x84, 0xb3, 0xde } }\r
+  gTopOfTemporaryRamPpiGuid             = { 0x2f3962b2, 0x57c5, 0x44ec, { 0x9e, 0xfc, 0xa6, 0x9f, 0xd3, 0x02, 0x03, 0x2b } }\r
+\r
+[Protocols]\r
+  gAddPerfRecordProtocolGuid            = { 0xc4a58d6d, 0x3677, 0x49cb, { 0xa0, 0x0a, 0x94, 0x70, 0x76, 0x5f, 0xb5, 0x5e } }\r
+\r
+################################################################################\r
+#\r
+# PCD Declarations section - list of all PCDs Declared by this Package\r
+#                            Only this package should be providing the\r
+#                            declaration, other packages should not.\r
+#\r
+################################################################################\r
+[PcdsFixedAtBuild, PcdsPatchableInModule]\r
+  ## Provides the memory mapped base address of the BIOS CodeCache Flash Device.\r
+  gFspWrapperTokenSpaceGuid.PcdFlashCodeCacheAddress|0xFFE00000|UINT32|0x10000001\r
+  ## Provides the size of the BIOS Flash Device.\r
+  gFspWrapperTokenSpaceGuid.PcdFlashCodeCacheSize|0x00200000|UINT32|0x10000002\r
+\r
+  ## Indicates the base address of the first Microcode Patch in the Microcode Region\r
+  gFspWrapperTokenSpaceGuid.PcdCpuMicrocodePatchAddress|0x0|UINT64|0x10000005\r
+  gFspWrapperTokenSpaceGuid.PcdCpuMicrocodePatchRegionSize|0x0|UINT64|0x10000006\r
+  ## Indicates the offset of the Cpu Microcode.\r
+  gFspWrapperTokenSpaceGuid.PcdFlashMicrocodeOffset|0x90|UINT32|0x10000007\r
+\r
+  ## Indicate the PEI memory size platform want to report\r
+  gFspWrapperTokenSpaceGuid.PcdPeiMinMemSize|0x1800000|UINT32|0x40000004\r
+  ## Indicate the PEI memory size platform want to report\r
+  gFspWrapperTokenSpaceGuid.PcdPeiRecoveryMinMemSize|0x3000000|UINT32|0x40000005\r
+\r
+  ## This is the base address of FSP-T/M/S\r
+  gFspWrapperTokenSpaceGuid.PcdFsptBaseAddress|0x00000000|UINT32|0x00000300\r
+  gFspWrapperTokenSpaceGuid.PcdFspmBaseAddress|0x00000000|UINT32|0x00000301\r
+  gFspWrapperTokenSpaceGuid.PcdFspsBaseAddress|0x00000000|UINT32|0x00000302\r
diff --git a/IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dsc b/IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dsc
new file mode 100644 (file)
index 0000000..70541c8
--- /dev/null
@@ -0,0 +1,87 @@
+## @file\r
+# Provides drivers and definitions to support fsp in EDKII bios.\r
+#\r
+# Copyright (c) 2014 - 2016, 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                  = IntelFsp2WrapperPkg\r
+  PLATFORM_GUID                  = 34813E26-C930-427D-8993-80530549EADA\r
+  PLATFORM_VERSION               = 0.1\r
+  DSC_SPECIFICATION              = 0x00010005\r
+  OUTPUT_DIRECTORY               = Build/IntelFsp2WrapperPkg\r
+  SUPPORTED_ARCHITECTURES        = IA32|X64\r
+  BUILD_TARGETS                  = DEBUG|RELEASE|NOOPT\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
+  DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf\r
+  DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf\r
+  PciCf8Lib|MdePkg/Library/BasePciCf8Lib/BasePciCf8Lib.inf\r
+  IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf\r
+  PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf\r
+  PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf\r
+  PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf\r
+  CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf\r
+\r
+  PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf\r
+  SerialPortLib|MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.inf\r
+  ReportStatusCodeLib|MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.inf\r
+  TimerLib|MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplate.inf\r
+\r
+  # MdeModulePkg\r
+  DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf\r
+\r
+  # UefiCpuPkg\r
+  UefiCpuLib|UefiCpuPkg/Library/BaseUefiCpuLib/BaseUefiCpuLib.inf\r
+  LocalApicLib|UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.inf\r
+\r
+  # FSP Wrapper Lib\r
+  FspWrapperApiLib|IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/BaseFspWrapperApiLib.inf\r
+  FspWrapperApiTestLib|IntelFsp2WrapperPkg/Library/BaseFspWrapperApiTestLibNull/BaseFspWrapperApiTestLibNull.inf\r
+\r
+  # FSP platform sample\r
+  FspWrapperPlatformLib|IntelFsp2WrapperPkg/Library/BaseFspWrapperPlatformLibSample/BaseFspWrapperPlatformLibSample.inf\r
+  PlatformSecLib|IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/SecFspWrapperPlatformSecLibSample.inf\r
+  FspWrapperHobProcessLib|IntelFsp2WrapperPkg/Library/PeiFspWrapperHobProcessLibSample/PeiFspWrapperHobProcessLibSample.inf\r
+\r
+[LibraryClasses.common.PEIM,LibraryClasses.common.PEI_CORE]\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
+  HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf\r
+\r
+[LibraryClasses.common.DXE_DRIVER]\r
+  UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf\r
+  UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf\r
+  UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf\r
+  DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf\r
+  UefiLib|MdePkg/Library/UefiLib/UefiLib.inf\r
+  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf\r
+  DevicePathLib|MdePkg/Library/UefiDevicePathLibDevicePathProtocol/UefiDevicePathLibDevicePathProtocol.inf\r
+  HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf\r
+\r
+[Components.Ia32]\r
+  IntelFsp2WrapperPkg/FspmWrapperPeim/FspmWrapperPeim.inf\r
+  IntelFsp2WrapperPkg/FspsWrapperPeim/FspsWrapperPeim.inf\r
+\r
+[Components.IA32, Components.X64]\r
+  IntelFsp2WrapperPkg/FspWrapperNotifyDxe/FspWrapperNotifyDxe.inf\r
+\r
+[PcdsFixedAtBuild.common]\r
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x1f\r
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80080046\r
+  gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x07\r
diff --git a/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/BaseFspWrapperApiLib.inf b/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/BaseFspWrapperApiLib.inf
new file mode 100644 (file)
index 0000000..b1a9f38
--- /dev/null
@@ -0,0 +1,71 @@
+## @file\r
+#  Provide FSP API related function.\r
+#\r
+#  Copyright (c) 2014 - 2016, 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                      = BaseFspWrapperApiLib\r
+  FILE_GUID                      = F42C789F-4D66-49AF-8C73-1AADC00437AC\r
+  MODULE_TYPE                    = BASE\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = FspWrapperApiLib\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
+  FspWrapperApiLib.c\r
+\r
+[Sources.IA32]\r
+  IA32/DispatchExecute.c\r
+\r
+[Sources.X64]\r
+  X64/DispatchExecute.c\r
+  X64/Thunk64To32.asm\r
+  X64/Thunk64To32.S\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
+  IntelFsp2Pkg/IntelFsp2Pkg.dec\r
+  IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec\r
+\r
+[LibraryClasses]\r
+  BaseLib\r
+\r
+[Guids]\r
+  gFspHeaderFileGuid            ## CONSUMES ## GUID\r
+\r
+[Pcd]\r
+  gFspWrapperTokenSpaceGuid.PcdFspmBaseAddress          ## CONSUMES\r
+  gFspWrapperTokenSpaceGuid.PcdFspsBaseAddress          ## CONSUMES\r
diff --git a/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/FspWrapperApiLib.c b/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/FspWrapperApiLib.c
new file mode 100644 (file)
index 0000000..8cf136f
--- /dev/null
@@ -0,0 +1,203 @@
+/** @file\r
+  Provide FSP API related function.\r
+\r
+  Copyright (c) 2014 - 2016, 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
+#include <Library/FspWrapperApiLib.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+\r
+/**\r
+  Wrapper for a thunk  to transition from long mode to compatibility mode to execute 32-bit code and then transit back to\r
+  long mode.\r
+\r
+  @param[in] Function     The 32bit code entry to be executed.\r
+  @param[in] Param1       The first parameter to pass to 32bit code.\r
+  @param[in] Param2       The second parameter to pass to 32bit code.\r
+\r
+  @return EFI_STATUS.\r
+**/\r
+EFI_STATUS\r
+Execute32BitCode (\r
+  IN UINT64      Function,\r
+  IN UINT64      Param1,\r
+  IN UINT64      Param2\r
+  );\r
+\r
+/**\r
+  Find FSP header pointer.\r
+\r
+  @param[in] FlashFvFspBase Flash address of FSP FV.\r
+\r
+  @return FSP header pointer.\r
+**/\r
+FSP_INFO_HEADER *\r
+EFIAPI\r
+FspFindFspHeader (\r
+  IN EFI_PHYSICAL_ADDRESS  FlashFvFspBase\r
+  )\r
+{\r
+  UINT8 *CheckPointer;\r
+\r
+  CheckPointer = (UINT8 *) (UINTN) FlashFvFspBase;\r
+\r
+  if (((EFI_FIRMWARE_VOLUME_HEADER *)CheckPointer)->Signature != EFI_FVH_SIGNATURE) {\r
+    return NULL;\r
+  }\r
+\r
+  if (((EFI_FIRMWARE_VOLUME_HEADER *)CheckPointer)->ExtHeaderOffset != 0) {\r
+    CheckPointer = CheckPointer + ((EFI_FIRMWARE_VOLUME_HEADER *)CheckPointer)->ExtHeaderOffset;\r
+    CheckPointer = CheckPointer + ((EFI_FIRMWARE_VOLUME_EXT_HEADER *)CheckPointer)->ExtHeaderSize;\r
+    CheckPointer = (UINT8 *) ALIGN_POINTER (CheckPointer, 8);\r
+  } else {\r
+    CheckPointer = CheckPointer + ((EFI_FIRMWARE_VOLUME_HEADER *)CheckPointer)->HeaderLength;\r
+  }\r
+\r
+\r
+  CheckPointer = CheckPointer + sizeof (EFI_FFS_FILE_HEADER);\r
+\r
+  if (((EFI_RAW_SECTION *)CheckPointer)->Type != EFI_SECTION_RAW) {\r
+    return NULL;\r
+  }\r
+\r
+  CheckPointer = CheckPointer + sizeof (EFI_RAW_SECTION);\r
+\r
+  return (FSP_INFO_HEADER *)CheckPointer;\r
+}\r
+\r
+/**\r
+  Call FSP API - FspNotifyPhase.\r
+\r
+  @param[in] NotifyPhaseParams Address pointer to the NOTIFY_PHASE_PARAMS structure.\r
+\r
+  @return EFI status returned by FspNotifyPhase API.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+CallFspNotifyPhase (\r
+  IN NOTIFY_PHASE_PARAMS *NotifyPhaseParams\r
+  )\r
+{\r
+  FSP_INFO_HEADER     *FspHeader;\r
+  FSP_NOTIFY_PHASE    NotifyPhaseApi;\r
+  EFI_STATUS          Status;\r
+  BOOLEAN             InterruptState;\r
+\r
+  FspHeader = (FSP_INFO_HEADER *)FspFindFspHeader (PcdGet32 (PcdFspsBaseAddress));\r
+  if (FspHeader == NULL) {\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+\r
+  NotifyPhaseApi = (FSP_NOTIFY_PHASE)(UINTN)(FspHeader->ImageBase + FspHeader->NotifyPhaseEntryOffset);\r
+  InterruptState = SaveAndDisableInterrupts ();\r
+  Status = Execute32BitCode ((UINTN)NotifyPhaseApi, (UINTN)NotifyPhaseParams, (UINTN)NULL);\r
+  SetInterruptState (InterruptState);\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Call FSP API - FspMemoryInit.\r
+\r
+  @param[in]  FspmUpdDataPtr Address pointer to the FSP_MEMORY_INIT_PARAMS structure.\r
+  @param[out] HobListPtr     Address of the HobList pointer.\r
+\r
+  @return EFI status returned by FspMemoryInit API.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+CallFspMemoryInit (\r
+  IN VOID                       *FspmUpdDataPtr,\r
+  OUT VOID                      **HobListPtr\r
+  )\r
+{\r
+  FSP_INFO_HEADER     *FspHeader;\r
+  FSP_MEMORY_INIT     FspMemoryInitApi;\r
+  EFI_STATUS          Status;\r
+  BOOLEAN             InterruptState;\r
+\r
+  FspHeader = (FSP_INFO_HEADER *)FspFindFspHeader (PcdGet32 (PcdFspmBaseAddress));\r
+  if (FspHeader == NULL) {\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+\r
+  FspMemoryInitApi = (FSP_MEMORY_INIT)(UINTN)(FspHeader->ImageBase + FspHeader->FspMemoryInitEntryOffset);\r
+  InterruptState = SaveAndDisableInterrupts ();\r
+  Status = Execute32BitCode ((UINTN)FspMemoryInitApi, (UINTN)FspmUpdDataPtr, (UINTN)HobListPtr);\r
+  SetInterruptState (InterruptState);\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Call FSP API - TempRamExit.\r
+\r
+  @param[in] TempRamExitParam    Address pointer to the TempRamExit parameters structure.\r
+\r
+  @return EFI status returned by TempRamExit API.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+CallTempRamExit (\r
+  IN VOID                       *TempRamExitParam\r
+  )\r
+{\r
+  FSP_INFO_HEADER     *FspHeader;\r
+  FSP_TEMP_RAM_EXIT   TempRamExitApi;\r
+  EFI_STATUS          Status;\r
+  BOOLEAN             InterruptState;\r
+\r
+  FspHeader = (FSP_INFO_HEADER *)FspFindFspHeader (PcdGet32 (PcdFspmBaseAddress));\r
+  if (FspHeader == NULL) {\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+\r
+  TempRamExitApi = (FSP_TEMP_RAM_EXIT)(UINTN)(FspHeader->ImageBase + FspHeader->TempRamExitEntryOffset);\r
+  InterruptState = SaveAndDisableInterrupts ();\r
+  Status = Execute32BitCode ((UINTN)TempRamExitApi, (UINTN)TempRamExitParam, (UINTN)NULL);\r
+  SetInterruptState (InterruptState);\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Call FSP API - FspSiliconInit.\r
+\r
+  @param[in] FspsUpdDataPtr Address pointer to the Silicon Init parameters structure.\r
+\r
+  @return EFI status returned by FspSiliconInit API.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+CallFspSiliconInit (\r
+  IN VOID                       *FspsUpdDataPtr\r
+  )\r
+{\r
+  FSP_INFO_HEADER     *FspHeader;\r
+  FSP_SILICON_INIT    FspSiliconInitApi;\r
+  EFI_STATUS          Status;\r
+  BOOLEAN             InterruptState;\r
+\r
+  FspHeader = (FSP_INFO_HEADER *)FspFindFspHeader (PcdGet32 (PcdFspsBaseAddress));\r
+  if (FspHeader == NULL) {\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+\r
+  FspSiliconInitApi = (FSP_SILICON_INIT)(UINTN)(FspHeader->ImageBase + FspHeader->FspSiliconInitEntryOffset);\r
+  InterruptState = SaveAndDisableInterrupts ();\r
+  Status = Execute32BitCode ((UINTN)FspSiliconInitApi, (UINTN)FspsUpdDataPtr, (UINTN)NULL);\r
+  SetInterruptState (InterruptState);\r
+\r
+  return Status;\r
+}\r
diff --git a/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/IA32/DispatchExecute.c b/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/IA32/DispatchExecute.c
new file mode 100644 (file)
index 0000000..72b1762
--- /dev/null
@@ -0,0 +1,58 @@
+/** @file\r
+  Execute 32-bit code in Protected Mode.\r
+\r
+  Copyright (c) 2014 - 2016, 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 <FspEas.h>\r
+\r
+/**\r
+  FSP API functions.\r
+\r
+  @param[in] Param1       The first parameter to pass to 32bit code.\r
+  @param[in] Param2       The second parameter to pass to 32bit code.\r
+\r
+  @return EFI_STATUS.\r
+**/\r
+typedef\r
+EFI_STATUS\r
+(EFIAPI *FSP_FUNCTION) (\r
+  IN VOID *Param1,\r
+  IN VOID *Param2\r
+  );\r
+\r
+/**\r
+  Wrapper for a thunk to transition from long mode to compatibility mode to execute 32-bit code and then transit back to\r
+  long mode.\r
+\r
+  @param[in] Function     The 32bit code entry to be executed.\r
+  @param[in] Param1       The first parameter to pass to 32bit code.\r
+  @param[in] Param2       The second parameter to pass to 32bit code.\r
+\r
+  @return EFI_STATUS.\r
+**/\r
+EFI_STATUS\r
+Execute32BitCode (\r
+  IN UINT64      Function,\r
+  IN UINT64      Param1,\r
+  IN UINT64      Param2\r
+  )\r
+{\r
+  FSP_FUNCTION               EntryFunc;\r
+  EFI_STATUS                 Status;\r
+\r
+  EntryFunc = (FSP_FUNCTION) (UINTN) (Function);\r
+  Status    = EntryFunc ((VOID *)(UINTN)Param1, (VOID *)(UINTN)Param2);\r
+\r
+  return Status;\r
+}\r
+\r
diff --git a/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/X64/DispatchExecute.c b/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/X64/DispatchExecute.c
new file mode 100644 (file)
index 0000000..061d381
--- /dev/null
@@ -0,0 +1,108 @@
+/** @file\r
+  Execute 32-bit code in Long Mode.\r
+  Provide a thunk function to transition from long mode to compatibility mode to execute 32-bit code and then transit\r
+  back to long mode.\r
+\r
+  Copyright (c) 2014 - 2016, 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 <FspEas.h>\r
+\r
+#pragma pack(1)\r
+typedef union {\r
+  struct {\r
+    UINT32  LimitLow    : 16;\r
+    UINT32  BaseLow     : 16;\r
+    UINT32  BaseMid     : 8;\r
+    UINT32  Type        : 4;\r
+    UINT32  System      : 1;\r
+    UINT32  Dpl         : 2;\r
+    UINT32  Present     : 1;\r
+    UINT32  LimitHigh   : 4;\r
+    UINT32  Software    : 1;\r
+    UINT32  Reserved    : 1;\r
+    UINT32  DefaultSize : 1;\r
+    UINT32  Granularity : 1;\r
+    UINT32  BaseHigh    : 8;\r
+  } Bits;\r
+  UINT64  Uint64;\r
+} IA32_GDT;\r
+#pragma pack()\r
+\r
+GLOBAL_REMOVE_IF_UNREFERENCED IA32_GDT mGdtEntries[] = {\r
+  {{0,      0,  0,  0,    0,  0,  0,  0,    0,  0, 0,  0,  0}}, /* 0x0:  reserve */\r
+  {{0xFFFF, 0,  0,  0xB,  1,  0,  1,  0xF,  0,  0, 1,  1,  0}}, /* 0x8:  compatibility mode */\r
+  {{0xFFFF, 0,  0,  0xB,  1,  0,  1,  0xF,  0,  1, 0,  1,  0}}, /* 0x10: for long mode */\r
+  {{0xFFFF, 0,  0,  0x3,  1,  0,  1,  0xF,  0,  0, 1,  1,  0}}, /* 0x18: data */\r
+  {{0,      0,  0,  0,    0,  0,  0,  0,    0,  0, 0,  0,  0}}, /* 0x20: reserve */\r
+};\r
+\r
+//\r
+// IA32 Gdt register\r
+//\r
+GLOBAL_REMOVE_IF_UNREFERENCED IA32_DESCRIPTOR mGdt = {\r
+  sizeof (mGdtEntries) - 1,\r
+  (UINTN) mGdtEntries\r
+  };\r
+\r
+/**\r
+  Assembly function to transition from long mode to compatibility mode to execute 32-bit code and then transit back to\r
+  long mode.\r
+\r
+  @param[in] Function     The 32bit code entry to be executed.\r
+  @param[in] Param1       The first parameter to pass to 32bit code\r
+  @param[in] Param2       The second parameter to pass to 32bit code\r
+  @param[in] InternalGdtr The GDT and GDT descriptor used by this library\r
+\r
+  @return status.\r
+**/\r
+UINT32\r
+AsmExecute32BitCode (\r
+  IN UINT64           Function,\r
+  IN UINT64           Param1,\r
+  IN UINT64           Param2,\r
+  IN IA32_DESCRIPTOR  *InternalGdtr\r
+  );\r
+\r
+/**\r
+  Wrapper for a thunk  to transition from long mode to compatibility mode to execute 32-bit code and then transit back to\r
+  long mode.\r
+\r
+  @param[in] Function     The 32bit code entry to be executed.\r
+  @param[in] Param1       The first parameter to pass to 32bit code.\r
+  @param[in] Param2       The second parameter to pass to 32bit code.\r
+\r
+  @return EFI_STATUS.\r
+**/\r
+EFI_STATUS\r
+Execute32BitCode (\r
+  IN UINT64      Function,\r
+  IN UINT64      Param1,\r
+  IN UINT64      Param2\r
+  )\r
+{\r
+  EFI_STATUS       Status;\r
+  IA32_DESCRIPTOR  Idtr;\r
+\r
+  //\r
+  // Idtr might be changed inside of FSP. 32bit FSP only knows the <4G address.\r
+  // If IDTR.Base is >4G, FSP can not handle. So we need save/restore IDTR here for X64 only.\r
+  // Interrupt is already disabled here, so it is safety to update IDTR.\r
+  //\r
+  AsmReadIdtr (&Idtr);\r
+  Status = AsmExecute32BitCode (Function, Param1, Param2, &mGdt);\r
+  AsmWriteIdtr (&Idtr);\r
+\r
+  return Status;\r
+}\r
+\r
diff --git a/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/X64/Thunk64To32.S b/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/X64/Thunk64To32.S
new file mode 100644 (file)
index 0000000..b6b5c1a
--- /dev/null
@@ -0,0 +1,230 @@
+#\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
+# Module Name:\r
+#\r
+#    Thunk64To32.asm\r
+#\r
+# Abstract:\r
+#\r
+#   This is the assembly code to transition from long mode to compatibility mode to execute 32-bit code and then\r
+#   transit back to long mode.\r
+#\r
+#-------------------------------------------------------------------------------\r
+\r
+#----------------------------------------------------------------------------\r
+# Procedure:    AsmExecute32BitCode\r
+#\r
+# Input:        None\r
+#\r
+# Output:       None\r
+#\r
+# Prototype:    UINT32\r
+#               AsmExecute32BitCode (\r
+#                 IN UINT64           Function,\r
+#                 IN UINT64           Param1,\r
+#                 IN UINT64           Param2,\r
+#                 IN IA32_DESCRIPTOR  *InternalGdtr\r
+#                 );\r
+#\r
+#\r
+# Description:  A thunk function to execute 32-bit code in long mode.\r
+#\r
+#----------------------------------------------------------------------------\r
+\r
+ASM_GLOBAL ASM_PFX(AsmExecute32BitCode)\r
+ASM_PFX(AsmExecute32BitCode):\r
+    #\r
+    # save IFLAG and disable it\r
+    #\r
+    pushfq\r
+    cli\r
+\r
+    #\r
+    # save orignal GDTR and CS\r
+    #\r
+    movl    %ds, %eax\r
+    push    %rax\r
+    movl    %cs, %eax\r
+    push    %rax\r
+    subq    $0x10, %rsp\r
+    sgdt    (%rsp)\r
+    #\r
+    # load internal GDT\r
+    #\r
+    lgdt    (%r9)\r
+    #\r
+    # Save general purpose register and rflag register\r
+    #\r
+    pushfq\r
+    push    %rdi\r
+    push    %rsi\r
+    push    %rbp\r
+    push    %rbx\r
+\r
+    #\r
+    # save CR3\r
+    #\r
+    movq    %cr3, %rax\r
+    movq    %rax, %rbp\r
+\r
+    #\r
+    # Prepare the CS and return address for the transition from 32-bit to 64-bit mode\r
+    #\r
+    movq    $0x10, %rax              # load long mode selector\r
+    shl     $32, %rax\r
+    lea     ReloadCS(%rip), %r9   #Assume the ReloadCS is under 4G\r
+    orq     %r9, %rax\r
+    push    %rax\r
+    #\r
+    # Save parameters for 32-bit function call\r
+    #\r
+    movq    %r8, %rax\r
+    shl     $32, %rax\r
+    orq     %rdx, %rax\r
+    push    %rax\r
+    #\r
+    # save the 32-bit function entry and the return address into stack which will be\r
+    # retrieve in compatibility mode.\r
+    #\r
+    lea     ReturnBack(%rip), %rax   #Assume the ReloadCS is under 4G\r
+    shl     $32, %rax\r
+    orq     %rcx, %rax\r
+    push    %rax\r
+\r
+    #\r
+    # let rax save DS\r
+    #\r
+    movq    $0x18, %rax\r
+\r
+    #\r
+    # Change to Compatible Segment\r
+    #\r
+    movq    $8, %rcx               # load compatible mode selector\r
+    shl     $32, %rcx\r
+    lea     Compatible(%rip), %rdx # assume address < 4G\r
+    orq     %rdx, %rcx\r
+    push    %rcx\r
+    .byte   0xcb                # retf\r
+\r
+Compatible:\r
+    # reload DS/ES/SS to make sure they are correct referred to current GDT\r
+    movw    %ax, %ds\r
+    movw    %ax, %es\r
+    movw    %ax, %ss\r
+\r
+    #\r
+    # Disable paging\r
+    #\r
+    movq    %cr0, %rcx\r
+    btc     $31, %ecx\r
+    movq    %rcx, %cr0\r
+    #\r
+    # Clear EFER.LME\r
+    #\r
+    movl    $0xC0000080, %ecx\r
+    rdmsr\r
+    btc     $8, %eax\r
+    wrmsr\r
+\r
+# Now we are in protected mode\r
+    #\r
+    # Call 32-bit function. Assume the function entry address and parameter value is less than 4G\r
+    #\r
+    pop    %rax                 # Here is the function entry\r
+    #\r
+    # Now the parameter is at the bottom of the stack,  then call in to IA32 function.\r
+    #\r
+    jmp   *%rax\r
+ReturnBack:\r
+    movl  %eax, %ebx            # save return status\r
+    pop   %rcx                  # drop param1\r
+    pop   %rcx                  # drop param2\r
+\r
+    #\r
+    # restore CR4\r
+    #\r
+    movq    %cr4, %rax\r
+    bts     $5, %eax\r
+    movq    %rax, %cr4\r
+\r
+    #\r
+    # restore CR3\r
+    #\r
+    movl    %ebp, %eax\r
+    movq    %rax, %cr3\r
+\r
+    #\r
+    # Set EFER.LME to re-enable ia32-e\r
+    #\r
+    movl    $0xC0000080, %ecx\r
+    rdmsr\r
+    bts     $8, %eax\r
+    wrmsr\r
+    #\r
+    # Enable paging\r
+    #\r
+    movq    %cr0, %rax\r
+    bts     $31, %eax\r
+    mov     %rax, %cr0\r
+# Now we are in compatible mode\r
+\r
+    #\r
+    # Reload cs register\r
+    #\r
+    .byte   0xcb                # retf\r
+ReloadCS:\r
+    #\r
+    # Now we're in Long Mode\r
+    #\r
+    #\r
+    # Restore C register and eax hold the return status from 32-bit function.\r
+    # Note: Do not touch rax from now which hold the return value from IA32 function\r
+    #\r
+    movl    %ebx, %eax # put return status to EAX\r
+    pop     %rbx\r
+    pop     %rbp\r
+    pop     %rsi\r
+    pop     %rdi\r
+    popfq\r
+    #\r
+    # Switch to orignal GDT and CS. here rsp is pointer to the orignal GDT descriptor.\r
+    #\r
+    lgdt    (%rsp)\r
+    #\r
+    # drop GDT descriptor in stack\r
+    #\r
+    addq    $0x10, %rsp\r
+    #\r
+    # switch to orignal CS and GDTR\r
+    #\r
+    pop     %r9                 # get  CS\r
+    shl     $32, %r9            # rcx[32..47] <- Cs\r
+    lea     ReturnToLongMode(%rip), %rcx\r
+    orq     %r9, %rcx\r
+    push    %rcx\r
+    .byte   0xcb                # retf\r
+ReturnToLongMode:\r
+    #\r
+    # Reload original DS/ES/SS\r
+    #\r
+    pop     %rcx\r
+    movl    %ecx, %ds\r
+    movl    %ecx, %es\r
+    movl    %ecx, %ss\r
+\r
+    #\r
+    # Restore IFLAG\r
+    #\r
+    popfq\r
+\r
+    ret\r
+\r
diff --git a/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/X64/Thunk64To32.asm b/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/X64/Thunk64To32.asm
new file mode 100644 (file)
index 0000000..70e7b5f
--- /dev/null
@@ -0,0 +1,230 @@
+;\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
+; Module Name:\r
+;\r
+;    Thunk64To32.asm\r
+;\r
+; Abstract:\r
+;\r
+;   This is the assembly code to transition from long mode to compatibility mode to execute 32-bit code and then\r
+;   transit back to long mode.\r
+;\r
+;-------------------------------------------------------------------------------\r
+    .code\r
+;----------------------------------------------------------------------------\r
+; Procedure:    AsmExecute32BitCode\r
+;\r
+; Input:        None\r
+;\r
+; Output:       None\r
+;\r
+; Prototype:    UINT32\r
+;               AsmExecute32BitCode (\r
+;                 IN UINT64           Function,\r
+;                 IN UINT64           Param1,\r
+;                 IN UINT64           Param2,\r
+;                 IN IA32_DESCRIPTOR  *InternalGdtr\r
+;                 );\r
+;\r
+;\r
+; Description:  A thunk function to execute 32-bit code in long mode.\r
+;\r
+;----------------------------------------------------------------------------\r
+AsmExecute32BitCode    PROC\r
+    ;\r
+    ; save IFLAG and disable it\r
+    ;\r
+    pushfq\r
+    cli\r
+\r
+    ;\r
+    ; save orignal GDTR and CS\r
+    ;\r
+    mov     rax, ds\r
+    push    rax\r
+    mov     rax, cs\r
+    push    rax\r
+    sub     rsp, 10h\r
+    sgdt    fword ptr [rsp]\r
+    ;\r
+    ; load internal GDT\r
+    ;\r
+    lgdt    fword ptr [r9]\r
+    ;\r
+    ; Save general purpose register and rflag register\r
+    ;\r
+    pushfq\r
+    push    rdi\r
+    push    rsi\r
+    push    rbp\r
+    push    rbx\r
+\r
+    ;\r
+    ; save CR3\r
+    ;\r
+    mov     rax, cr3\r
+    mov     rbp, rax\r
+\r
+    ;\r
+    ; Prepare the CS and return address for the transition from 32-bit to 64-bit mode\r
+    ;\r
+    mov     rax, 10h              ; load long mode selector\r
+    shl     rax, 32\r
+    mov     r9, OFFSET ReloadCS   ;Assume the ReloadCS is under 4G\r
+    or      rax, r9\r
+    push    rax\r
+    ;\r
+    ; Save parameters for 32-bit function call\r
+    ;\r
+    mov     rax, r8\r
+    shl     rax, 32\r
+    or      rax, rdx\r
+    push    rax\r
+    ;\r
+    ; save the 32-bit function entry and the return address into stack which will be\r
+    ; retrieve in compatibility mode.\r
+    ;\r
+    mov     rax, OFFSET ReturnBack   ;Assume the ReloadCS is under 4G\r
+    shl     rax, 32\r
+    or      rax, rcx\r
+    push    rax\r
+\r
+    ;\r
+    ; let rax save DS\r
+    ;\r
+    mov     rax, 018h\r
+\r
+    ;\r
+    ; Change to Compatible Segment\r
+    ;\r
+    mov     rcx, 08h               ; load compatible mode selector\r
+    shl     rcx, 32\r
+    mov     rdx, OFFSET Compatible ; assume address < 4G\r
+    or      rcx, rdx\r
+    push    rcx\r
+    retf\r
+\r
+Compatible:\r
+    ; reload DS/ES/SS to make sure they are correct referred to current GDT\r
+    mov     ds, ax\r
+    mov     es, ax\r
+    mov     ss, ax\r
+\r
+    ;\r
+    ; Disable paging\r
+    ;\r
+    mov     rcx, cr0\r
+    btc     ecx, 31\r
+    mov     cr0, rcx\r
+    ;\r
+    ; Clear EFER.LME\r
+    ;\r
+    mov     ecx, 0C0000080h\r
+    rdmsr\r
+    btc     eax, 8\r
+    wrmsr\r
+\r
+; Now we are in protected mode\r
+    ;\r
+    ; Call 32-bit function. Assume the function entry address and parameter value is less than 4G\r
+    ;\r
+    pop    rax                 ; Here is the function entry\r
+    ;\r
+    ; Now the parameter is at the bottom of the stack,  then call in to IA32 function.\r
+    ;\r
+    jmp   rax\r
+ReturnBack:\r
+    mov   ebx, eax             ; save return status\r
+    pop   rcx                  ; drop param1\r
+    pop   rcx                  ; drop param2\r
+\r
+    ;\r
+    ; restore CR4\r
+    ;\r
+    mov     rax, cr4\r
+    bts     eax, 5\r
+    mov     cr4, rax\r
+\r
+    ;\r
+    ; restore CR3\r
+    ;\r
+    mov     eax, ebp\r
+    mov     cr3, rax\r
+\r
+    ;\r
+    ; Set EFER.LME to re-enable ia32-e\r
+    ;\r
+    mov     ecx, 0C0000080h\r
+    rdmsr\r
+    bts     eax, 8\r
+    wrmsr\r
+    ;\r
+    ; Enable paging\r
+    ;\r
+    mov     rax, cr0\r
+    bts     eax, 31\r
+    mov     cr0, rax\r
+; Now we are in compatible mode\r
+\r
+    ;\r
+    ; Reload cs register\r
+    ;\r
+    retf\r
+ReloadCS:\r
+    ;\r
+    ; Now we're in Long Mode\r
+    ;\r
+    ;\r
+    ; Restore C register and eax hold the return status from 32-bit function.\r
+    ; Note: Do not touch rax from now which hold the return value from IA32 function\r
+    ;\r
+    mov     eax, ebx ; put return status to EAX\r
+    pop     rbx\r
+    pop     rbp\r
+    pop     rsi\r
+    pop     rdi\r
+    popfq\r
+    ;\r
+    ; Switch to orignal GDT and CS. here rsp is pointer to the orignal GDT descriptor.\r
+    ;\r
+    lgdt    fword ptr[rsp]\r
+    ;\r
+    ; drop GDT descriptor in stack\r
+    ;\r
+    add     rsp, 10h\r
+    ;\r
+    ; switch to orignal CS and GDTR\r
+    ;\r
+    pop     r9                 ; get  CS\r
+    shl     r9,  32            ; rcx[32..47] <- Cs\r
+    mov     rcx, OFFSET @F\r
+    or      rcx, r9\r
+    push    rcx\r
+    retf\r
+@@:\r
+    ;\r
+    ; Reload original DS/ES/SS\r
+    ;\r
+    pop     rcx\r
+    mov     ds, rcx\r
+    mov     es, rcx\r
+    mov     ss, rcx\r
+\r
+    ;\r
+    ; Restore IFLAG\r
+    ;\r
+    popfq\r
+\r
+    ret\r
+AsmExecute32BitCode   ENDP\r
+\r
+    END\r
diff --git a/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiTestLibNull/BaseFspWrapperApiTestLibNull.inf b/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiTestLibNull/BaseFspWrapperApiTestLibNull.inf
new file mode 100644 (file)
index 0000000..6e82863
--- /dev/null
@@ -0,0 +1,53 @@
+### @file\r
+#  Provide FSP wrapper API test related function.\r
+#\r
+#  Copyright (C) 2016, 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                    = 0x00010017\r
+  BASE_NAME                      = BaseFspWrapperApiTestLibNull\r
+  FILE_GUID                      = E7E96F88-017B-417C-8DC8-B84C2B877020\r
+  VERSION_STRING                 = 1.0\r
+  MODULE_TYPE                    = PEIM\r
+  LIBRARY_CLASS                  = FspWrapperApiTestLib\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
+################################################################################\r
+#\r
+# Sources Section - list of files that are required for the build to succeed.\r
+#\r
+################################################################################\r
+\r
+[Sources]\r
+  FspWrapperApiTestNull.c\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
+  IntelFsp2Pkg/IntelFsp2Pkg.dec\r
+  IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec\r
+\r
+[LibraryClasses]\r
+  DebugLib\r
+\r
+[Guids]
\ No newline at end of file
diff --git a/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiTestLibNull/FspWrapperApiTestNull.c b/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiTestLibNull/FspWrapperApiTestNull.c
new file mode 100644 (file)
index 0000000..6e40cd0
--- /dev/null
@@ -0,0 +1,65 @@
+/** @file\r
+  Provide FSP wrapper API test related function.\r
+\r
+  Copyright (c) 2016, 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
+  Test the output of FSP API - FspMemoryInit.\r
+\r
+  @param[in]  FspmUpdDataPtr Address pointer to the FSP_MEMORY_INIT_PARAMS structure.\r
+  @param[in]  HobListPtr     Address of the HobList pointer.\r
+\r
+  @return test result on output of FspMemoryInit API.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+TestFspMemoryInitApiOutput (\r
+  IN  VOID        *FspmUpdDataPtr,\r
+  IN  VOID        **HobListPtr\r
+  )\r
+{\r
+  return RETURN_UNSUPPORTED;\r
+}\r
+\r
+/**\r
+  Test the output of FSP API - TempRamExit.\r
+\r
+  @param[in] TempRamExitParam    Address pointer to the TempRamExit parameters structure.\r
+\r
+  @return test result on output of TempRamExit API.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+TestFspTempRamExitApiOutput (\r
+  IN VOID         *TempRamExitParam\r
+  )\r
+{\r
+  return RETURN_UNSUPPORTED;\r
+}\r
+\r
+/**\r
+  Test the output of FSP API - FspSiliconInit.\r
+\r
+  @param[in] FspsUpdDataPtr Address pointer to the Silicon Init parameters structure.\r
+\r
+  @return test result on output of FspSiliconInit API.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+TestFspSiliconInitApiOutput (\r
+  IN  VOID        *FspsUpdDataPtr\r
+  )\r
+{\r
+  return RETURN_UNSUPPORTED;\r
+}\r
diff --git a/IntelFsp2WrapperPkg/Library/BaseFspWrapperPlatformLibSample/BaseFspWrapperPlatformLibSample.inf b/IntelFsp2WrapperPkg/Library/BaseFspWrapperPlatformLibSample/BaseFspWrapperPlatformLibSample.inf
new file mode 100644 (file)
index 0000000..f9581e8
--- /dev/null
@@ -0,0 +1,60 @@
+## @file\r
+#  Sample to provide FSP wrapper platform related function.\r
+#\r
+#  Copyright (c) 2014 - 2016, 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                      = BaseFspWrapperPlatformLibSample\r
+  FILE_GUID                      = 12F38E73-B34D-4559-99E5-AE2DCD002156\r
+  MODULE_TYPE                    = BASE\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = FspWrapperPlatformLib\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
+  FspWrapperPlatformLibSample.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
+  IntelFsp2Pkg/IntelFsp2Pkg.dec\r
+  IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec\r
+\r
+[LibraryClasses]\r
+\r
+[Pcd]\r
+  gIntelFsp2PkgTokenSpaceGuid.PcdTemporaryRamBase  ## CONSUMES\r
+  gIntelFsp2PkgTokenSpaceGuid.PcdTemporaryRamSize  ## CONSUMES\r
diff --git a/IntelFsp2WrapperPkg/Library/BaseFspWrapperPlatformLibSample/FspWrapperPlatformLibSample.c b/IntelFsp2WrapperPkg/Library/BaseFspWrapperPlatformLibSample/FspWrapperPlatformLibSample.c
new file mode 100644 (file)
index 0000000..9c1a84f
--- /dev/null
@@ -0,0 +1,83 @@
+/** @file\r
+  Sample to provide FSP wrapper related function.\r
+\r
+  Copyright (c) 2014 - 2016, 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/PcdLib.h>\r
+\r
+/**\r
+  This function overrides the default configurations in the FSP-M UPD data region.\r
+\r
+  @note At this point, memory is NOT ready, PeiServices are available to use.\r
+\r
+  @param[in,out] FspUpdRgnPtr   A pointer to the UPD data region data strcture.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+UpdateFspmUpdData (\r
+  IN OUT VOID        *FspUpdRgnPtr\r
+  )\r
+{\r
+}\r
+\r
+/**\r
+  This function overrides the default configurations in the FSP-S UPD data region.\r
+\r
+  @param[in,out] FspUpdRgnPtr   A pointer to the UPD data region data strcture.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+UpdateFspsUpdData (\r
+  IN OUT VOID        *FspUpdRgnPtr\r
+  )\r
+{\r
+}\r
+\r
+/**\r
+  Update TempRamExit parameter.\r
+\r
+  @note At this point, memory is ready, PeiServices are available to use.\r
+\r
+  @return TempRamExit parameter.\r
+**/\r
+VOID *\r
+EFIAPI\r
+UpdateTempRamExitParam (\r
+  VOID\r
+  )\r
+{\r
+  return NULL;\r
+}\r
+\r
+/**\r
+  Get S3 PEI memory information.\r
+\r
+  @note At this point, memory is ready, and PeiServices are available to use.\r
+  Platform can get some data from SMRAM directly.\r
+\r
+  @param[out] S3PeiMemSize  PEI memory size to be installed in S3 phase.\r
+  @param[out] S3PeiMemBase  PEI memory base to be installed in S3 phase.\r
+\r
+  @return If S3 PEI memory information is got successfully.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+GetS3MemoryInfo (\r
+  OUT UINT64               *S3PeiMemSize,\r
+  OUT EFI_PHYSICAL_ADDRESS *S3PeiMemBase\r
+  )\r
+{\r
+  return EFI_UNSUPPORTED;\r
+}
\ No newline at end of file
diff --git a/IntelFsp2WrapperPkg/Library/PeiFspWrapperApiTestLib/FspWrapperApiTest.c b/IntelFsp2WrapperPkg/Library/PeiFspWrapperApiTestLib/FspWrapperApiTest.c
new file mode 100644 (file)
index 0000000..b128061
--- /dev/null
@@ -0,0 +1,88 @@
+/** @file\r
+  Provide FSP wrapper API test related function.\r
+\r
+  Copyright (c) 2016, 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/BaseMemoryLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/HobLib.h>\r
+#include <Guid/GuidHobFspEas.h>\r
+\r
+/**\r
+  Test the output of FSP API - FspMemoryInit.\r
+\r
+  @param[in]  FspmUpdDataPtr Address pointer to the FSP_MEMORY_INIT_PARAMS structure.\r
+  @param[in]  HobListPtr     Address of the HobList pointer.\r
+\r
+  @return test result on output of FspMemoryInit API.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+TestFspMemoryInitApiOutput (\r
+  IN  VOID        *FspmUpdDataPtr,\r
+  IN  VOID        **HobListPtr\r
+  )\r
+{\r
+  DEBUG_CODE_BEGIN ();\r
+  EFI_PEI_HOB_POINTERS        Hob;\r
+\r
+  Hob.Raw = (UINT8 *)(*(HobListPtr));\r
+  while (TRUE) {\r
+    if (END_OF_HOB_LIST(Hob) == TRUE) {\r
+      DEBUG((DEBUG_INFO, "gFspBootLoaderTolumHobGuid not Found\n"));\r
+      break;\r
+    }\r
+    if ((CompareGuid (&Hob.ResourceDescriptor->Owner, &gFspBootLoaderTolumHobGuid))) {\r
+      DEBUG ((DEBUG_INFO, "gFspBootLoaderTolumHobGuid Found\n"));\r
+      DEBUG ((DEBUG_INFO, "Fill Boot Loader reserved memory range with 0x5A for testing purpose\n"));\r
+      SetMem ((VOID *)(UINTN)Hob.ResourceDescriptor->PhysicalStart, (UINTN)Hob.ResourceDescriptor->ResourceLength, 0x5A);\r
+      break;\r
+    }\r
+    Hob.Raw = GET_NEXT_HOB (Hob);\r
+  }\r
+  DEBUG_CODE_END ();\r
+\r
+  return RETURN_SUCCESS;\r
+}\r
+\r
+/**\r
+  Test the output of FSP API - TempRamExit.\r
+\r
+  @param[in] TempRamExitParam    Address pointer to the TempRamExit parameters structure.\r
+\r
+  @return test result on output of TempRamExit API.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+TestFspTempRamExitApiOutput (\r
+  IN VOID         *TempRamExitParam\r
+  )\r
+{\r
+  return RETURN_SUCCESS;\r
+}\r
+\r
+/**\r
+  Test the output of FSP API - FspSiliconInit.\r
+\r
+  @param[in] FspsUpdDataPtr Address pointer to the Silicon Init parameters structure.\r
+\r
+  @return test result on output of FspSiliconInit API.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+TestFspSiliconInitApiOutput (\r
+  IN  VOID        *FspsUpdDataPtr\r
+  )\r
+{\r
+  return RETURN_SUCCESS;\r
+}\r
diff --git a/IntelFsp2WrapperPkg/Library/PeiFspWrapperApiTestLib/PeiFspWrapperApiTestLib.inf b/IntelFsp2WrapperPkg/Library/PeiFspWrapperApiTestLib/PeiFspWrapperApiTestLib.inf
new file mode 100644 (file)
index 0000000..fbbcf30
--- /dev/null
@@ -0,0 +1,56 @@
+### @file\r
+#  Provide FSP-M wrapper API test related function.\r
+#\r
+#  Copyright (C) 2016, 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                    = 0x00010017\r
+  BASE_NAME                      = PeiFspWrapperApiTestLib\r
+  FILE_GUID                      = 87DC266A-C8F7-4A66-A0CB-018A6F5305B4\r
+  VERSION_STRING                 = 1.0\r
+  MODULE_TYPE                    = PEIM\r
+  LIBRARY_CLASS                  = FspWrapperApiTestLib\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
+################################################################################\r
+#\r
+# Sources Section - list of files that are required for the build to succeed.\r
+#\r
+################################################################################\r
+\r
+[Sources]\r
+  FspWrapperApiTest.c\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
+  IntelFsp2Pkg/IntelFsp2Pkg.dec\r
+  IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec\r
+\r
+[LibraryClasses]\r
+  BaseMemoryLib\r
+  DebugLib\r
+  HobLib\r
+\r
+[Guids]\r
+  gFspBootLoaderTolumHobGuid            ## CONSUMES ## GUID
\ No newline at end of file
diff --git a/IntelFsp2WrapperPkg/Library/PeiFspWrapperHobProcessLibSample/FspWrapperHobProcessLibSample.c b/IntelFsp2WrapperPkg/Library/PeiFspWrapperHobProcessLibSample/FspWrapperHobProcessLibSample.c
new file mode 100644 (file)
index 0000000..8765bba
--- /dev/null
@@ -0,0 +1,390 @@
+/** @file\r
+  Sample to provide FSP wrapper hob process related function.\r
+\r
+  Copyright (c) 2014 - 2016, 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
+#include <Library/PeiServicesLib.h>\r
+#include <Library/PeiServicesTablePointerLib.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/HobLib.h>\r
+#include <Library/PcdLib.h>\r
+#include <Library/FspWrapperPlatformLib.h>\r
+\r
+#include <Guid/GuidHobFspEas.h>\r
+#include <Guid/MemoryTypeInformation.h>\r
+#include <Guid/PcdDataBaseHobGuid.h>\r
+#include <Ppi/Capsule.h>\r
+\r
+//\r
+// Additional pages are used by DXE memory manager.\r
+// It should be consistent between RetrieveRequiredMemorySize() and GetPeiMemSize()\r
+//\r
+#define PEI_ADDITIONAL_MEMORY_SIZE    (16 * EFI_PAGE_SIZE)\r
+\r
+/**\r
+  Get the mem size in memory type infromation table.\r
+\r
+  @param[in] PeiServices  PEI Services table.\r
+\r
+  @return the mem size in memory type infromation table.\r
+**/\r
+UINT64\r
+GetMemorySizeInMemoryTypeInformation (\r
+  IN EFI_PEI_SERVICES **PeiServices\r
+  )\r
+{\r
+  EFI_STATUS                  Status;\r
+  EFI_PEI_HOB_POINTERS        Hob;\r
+  EFI_MEMORY_TYPE_INFORMATION *MemoryData;\r
+  UINT8                       Index;\r
+  UINTN                       TempPageNum;\r
+\r
+  MemoryData = NULL;\r
+  Status     = (*PeiServices)->GetHobList ((CONST EFI_PEI_SERVICES**)PeiServices, (VOID **) &Hob.Raw);\r
+  ASSERT_EFI_ERROR (Status);\r
+  while (!END_OF_HOB_LIST (Hob)) {\r
+    if (Hob.Header->HobType == EFI_HOB_TYPE_GUID_EXTENSION &&\r
+      CompareGuid (&Hob.Guid->Name, &gEfiMemoryTypeInformationGuid)) {\r
+      MemoryData = (EFI_MEMORY_TYPE_INFORMATION *) (Hob.Raw + sizeof (EFI_HOB_GENERIC_HEADER) + sizeof (EFI_GUID));\r
+      break;\r
+    }\r
+\r
+    Hob.Raw = GET_NEXT_HOB (Hob);\r
+  }\r
+\r
+  if (MemoryData == NULL) {\r
+    return 0;\r
+  }\r
+\r
+  TempPageNum = 0;\r
+  for (Index = 0; MemoryData[Index].Type != EfiMaxMemoryType; Index++) {\r
+    //\r
+    // Accumulate default memory size requirements\r
+    //\r
+    TempPageNum += MemoryData[Index].NumberOfPages;\r
+  }\r
+\r
+  return TempPageNum * EFI_PAGE_SIZE;\r
+}\r
+\r
+/**\r
+  Get the mem size need to be reserved in PEI phase.\r
+\r
+  @param[in] PeiServices  PEI Services table.\r
+\r
+  @return the mem size need to be reserved in PEI phase.\r
+**/\r
+UINT64\r
+RetrieveRequiredMemorySize (\r
+  IN EFI_PEI_SERVICES **PeiServices\r
+  )\r
+{\r
+  UINT64                      Size;\r
+\r
+  Size = GetMemorySizeInMemoryTypeInformation (PeiServices);\r
+  return Size + PEI_ADDITIONAL_MEMORY_SIZE;\r
+}\r
+\r
+/**\r
+  Get the mem size need to be consumed and reserved in PEI phase.\r
+\r
+  @param[in] PeiServices  PEI Services table.\r
+  @param[in] BootMode     Current boot mode.\r
+\r
+  @return the mem size need to be consumed and reserved in PEI phase.\r
+**/\r
+UINT64\r
+GetPeiMemSize (\r
+  IN EFI_PEI_SERVICES **PeiServices,\r
+  IN UINT32           BootMode\r
+  )\r
+{\r
+  UINT64                      Size;\r
+  UINT64                      MinSize;\r
+\r
+  if (BootMode == BOOT_IN_RECOVERY_MODE) {\r
+    return PcdGet32 (PcdPeiRecoveryMinMemSize);\r
+  }\r
+\r
+  Size = GetMemorySizeInMemoryTypeInformation (PeiServices);\r
+\r
+  if (BootMode == BOOT_ON_FLASH_UPDATE) {\r
+    //\r
+    // Maybe more size when in CapsuleUpdate phase ?\r
+    //\r
+    MinSize = PcdGet32 (PcdPeiMinMemSize);\r
+  } else {\r
+    MinSize = PcdGet32 (PcdPeiMinMemSize);\r
+  }\r
+\r
+  return MinSize + Size + PEI_ADDITIONAL_MEMORY_SIZE;\r
+}\r
+\r
+/**\r
+  Post FSP-M HOB process for Memory Resource Descriptor.\r
+\r
+  @param[in] FspHobList  Pointer to the HOB data structure produced by FSP.\r
+\r
+  @return If platform process the FSP hob list successfully.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+PostFspmHobProcess (\r
+  IN VOID                 *FspHobList\r
+  )\r
+{\r
+  EFI_PEI_HOB_POINTERS Hob;\r
+  UINT64               LowMemorySize;\r
+  UINT64               FspMemorySize;\r
+  EFI_PHYSICAL_ADDRESS FspMemoryBase;\r
+  UINT64               PeiMemSize;\r
+  EFI_PHYSICAL_ADDRESS PeiMemBase;\r
+  UINT64               S3PeiMemSize;\r
+  EFI_PHYSICAL_ADDRESS S3PeiMemBase;\r
+  BOOLEAN              FoundFspMemHob;\r
+  EFI_STATUS           Status;\r
+  EFI_BOOT_MODE        BootMode;\r
+  EFI_PEI_CAPSULE_PPI  *Capsule;\r
+  VOID                 *CapsuleBuffer;\r
+  UINTN                CapsuleBufferLength;\r
+  UINT64               RequiredMemSize;\r
+  EFI_PEI_SERVICES     **PeiServices;\r
+\r
+  PeiServices = (EFI_PEI_SERVICES **)GetPeiServicesTablePointer ();\r
+\r
+  PeiServicesGetBootMode (&BootMode);\r
+\r
+  PeiMemBase = 0;\r
+  LowMemorySize = 0;\r
+  FspMemorySize = 0;\r
+  FspMemoryBase = 0;\r
+  FoundFspMemHob = FALSE;\r
+\r
+  //\r
+  // Parse the hob list from fsp\r
+  // Report all the resource hob except the memory between 1M and 4G\r
+  //\r
+  Hob.Raw = (UINT8 *)(UINTN)FspHobList;\r
+  DEBUG((DEBUG_INFO, "FspHobList - 0x%x\n", FspHobList));\r
+\r
+  while ((Hob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, Hob.Raw)) != NULL) {\r
+    DEBUG((DEBUG_INFO, "\nResourceType: 0x%x\n", Hob.ResourceDescriptor->ResourceType));\r
+    if ((Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) ||\r
+        (Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_MEMORY_RESERVED)) {\r
+      DEBUG((DEBUG_INFO, "ResourceAttribute: 0x%x\n", Hob.ResourceDescriptor->ResourceAttribute));\r
+      DEBUG((DEBUG_INFO, "PhysicalStart: 0x%x\n", Hob.ResourceDescriptor->PhysicalStart));\r
+      DEBUG((DEBUG_INFO, "ResourceLength: 0x%x\n", Hob.ResourceDescriptor->ResourceLength));\r
+      DEBUG((DEBUG_INFO, "Owner: %g\n\n", &Hob.ResourceDescriptor->Owner));\r
+    }\r
+\r
+    if ((Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY)  // Found the low memory length below 4G\r
+        && (Hob.ResourceDescriptor->PhysicalStart >= BASE_1MB)\r
+        && (Hob.ResourceDescriptor->PhysicalStart + Hob.ResourceDescriptor->ResourceLength <= BASE_4GB)) {\r
+        LowMemorySize += Hob.ResourceDescriptor->ResourceLength;\r
+      Hob.Raw = GET_NEXT_HOB (Hob);\r
+      continue;\r
+    }\r
+\r
+    if ((Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_MEMORY_RESERVED)  // Found the low memory length below 4G\r
+        && (Hob.ResourceDescriptor->PhysicalStart >= BASE_1MB)\r
+        && (Hob.ResourceDescriptor->PhysicalStart + Hob.ResourceDescriptor->ResourceLength <= BASE_4GB)\r
+        && (CompareGuid (&Hob.ResourceDescriptor->Owner, &gFspReservedMemoryResourceHobGuid))) {\r
+      FoundFspMemHob = TRUE;\r
+      FspMemoryBase = Hob.ResourceDescriptor->PhysicalStart;\r
+      FspMemorySize = Hob.ResourceDescriptor->ResourceLength;\r
+      DEBUG((DEBUG_INFO, "Find fsp mem hob, base 0x%x, len 0x%x\n", FspMemoryBase, FspMemorySize));\r
+    }\r
+\r
+    //\r
+    // Report the resource hob\r
+    //\r
+    BuildResourceDescriptorHob (\r
+      Hob.ResourceDescriptor->ResourceType,\r
+      Hob.ResourceDescriptor->ResourceAttribute,\r
+      Hob.ResourceDescriptor->PhysicalStart,\r
+      Hob.ResourceDescriptor->ResourceLength\r
+      );\r
+\r
+    Hob.Raw = GET_NEXT_HOB (Hob);\r
+  }\r
+\r
+  if (!FoundFspMemHob) {\r
+    DEBUG((DEBUG_INFO, "Didn't find the fsp used memory information.\n"));\r
+    //ASSERT(FALSE);\r
+  }\r
+\r
+  DEBUG((DEBUG_INFO, "LowMemorySize: 0x%x.\n", LowMemorySize));\r
+  DEBUG((DEBUG_INFO, "FspMemoryBase: 0x%x.\n", FspMemoryBase));\r
+  DEBUG((DEBUG_INFO, "FspMemorySize: 0x%x.\n", FspMemorySize));\r
+\r
+  if (BootMode == BOOT_ON_S3_RESUME) {\r
+    BuildResourceDescriptorHob (\r
+      EFI_RESOURCE_SYSTEM_MEMORY,\r
+      (\r
+         EFI_RESOURCE_ATTRIBUTE_PRESENT |\r
+         EFI_RESOURCE_ATTRIBUTE_INITIALIZED |\r
+         // EFI_RESOURCE_ATTRIBUTE_TESTED |\r
+         EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |\r
+         EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |\r
+         EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |\r
+         EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE\r
+      ),\r
+      BASE_1MB,\r
+      LowMemorySize\r
+      );\r
+\r
+    S3PeiMemBase = 0;\r
+    S3PeiMemSize = 0;\r
+    Status = GetS3MemoryInfo (&S3PeiMemSize, &S3PeiMemBase);\r
+    ASSERT_EFI_ERROR (Status);\r
+    DEBUG((DEBUG_INFO, "S3 memory %Xh - %Xh bytes\n", S3PeiMemBase, S3PeiMemSize));\r
+\r
+    //\r
+    // Make sure Stack and PeiMemory are not overlap\r
+    //\r
+\r
+    Status = PeiServicesInstallPeiMemory (\r
+               S3PeiMemBase,\r
+               S3PeiMemSize\r
+               );\r
+    ASSERT_EFI_ERROR (Status);\r
+  } else {\r
+    PeiMemSize = GetPeiMemSize (PeiServices, BootMode);\r
+    DEBUG((DEBUG_INFO, "PEI memory size = %Xh bytes\n", PeiMemSize));\r
+\r
+    //\r
+    // Capsule mode\r
+    //\r
+    Capsule = NULL;\r
+    CapsuleBuffer = NULL;\r
+    CapsuleBufferLength = 0;\r
+    if (BootMode == BOOT_ON_FLASH_UPDATE) {\r
+      Status = PeiServicesLocatePpi (\r
+                 &gEfiPeiCapsulePpiGuid,\r
+                 0,\r
+                 NULL,\r
+                 (VOID **) &Capsule\r
+                 );\r
+      ASSERT_EFI_ERROR (Status);\r
+\r
+      if (Status == EFI_SUCCESS) {\r
+        //\r
+        // Make sure Stack and CapsuleBuffer are not overlap\r
+        //\r
+        CapsuleBuffer = (VOID *)(UINTN)BASE_1MB;\r
+        CapsuleBufferLength = (UINTN)(LowMemorySize - PeiMemSize);\r
+        //\r
+        // Call the Capsule PPI Coalesce function to coalesce the capsule data.\r
+        //\r
+        Status = Capsule->Coalesce (PeiServices, &CapsuleBuffer, &CapsuleBufferLength);\r
+      }\r
+    }\r
+\r
+    RequiredMemSize = RetrieveRequiredMemorySize (PeiServices);\r
+    DEBUG((DEBUG_INFO, "Required memory size = %Xh bytes\n", RequiredMemSize));\r
+\r
+    //\r
+    // Report the main memory\r
+    //\r
+    BuildResourceDescriptorHob (\r
+      EFI_RESOURCE_SYSTEM_MEMORY,\r
+      (\r
+         EFI_RESOURCE_ATTRIBUTE_PRESENT |\r
+         EFI_RESOURCE_ATTRIBUTE_INITIALIZED |\r
+         EFI_RESOURCE_ATTRIBUTE_TESTED |\r
+         EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |\r
+         EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |\r
+         EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |\r
+         EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE\r
+      ),\r
+      BASE_1MB,\r
+      LowMemorySize\r
+      );\r
+\r
+    //\r
+    // Make sure Stack and CapsuleBuffer are not overlap\r
+    //\r
+\r
+    //\r
+    // Install efi memory\r
+    //\r
+    PeiMemBase = BASE_1MB + LowMemorySize - PeiMemSize;\r
+    Status = PeiServicesInstallPeiMemory (\r
+               PeiMemBase,\r
+               PeiMemSize - RequiredMemSize\r
+               );\r
+    ASSERT_EFI_ERROR (Status);\r
+\r
+    if (Capsule != NULL) {\r
+      Status = Capsule->CreateState (PeiServices, CapsuleBuffer, CapsuleBufferLength);\r
+    }\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Process FSP HOB list\r
+\r
+  @param[in] FspHobList  Pointer to the HOB data structure produced by FSP.\r
+\r
+**/\r
+VOID\r
+ProcessFspHobList (\r
+  IN VOID                 *FspHobList\r
+  )\r
+{\r
+  EFI_PEI_HOB_POINTERS  FspHob;\r
+\r
+  FspHob.Raw = FspHobList;\r
+\r
+  //\r
+  // Add all the HOBs from FSP binary to FSP wrapper\r
+  //\r
+  while (!END_OF_HOB_LIST (FspHob)) {\r
+    if (FspHob.Header->HobType == EFI_HOB_TYPE_GUID_EXTENSION) {\r
+      //\r
+      // Skip FSP binary creates PcdDataBaseHobGuid\r
+      //\r
+      if (!CompareGuid(&FspHob.Guid->Name, &gPcdDataBaseHobGuid)) { \r
+        BuildGuidDataHob (\r
+          &FspHob.Guid->Name,\r
+          GET_GUID_HOB_DATA(FspHob),\r
+          GET_GUID_HOB_DATA_SIZE(FspHob)\r
+        );\r
+      }\r
+    }\r
+    FspHob.Raw = GET_NEXT_HOB (FspHob);\r
+  }\r
+}\r
+\r
+/**\r
+  Post FSP-S HOB process (not Memory Resource Descriptor).\r
+\r
+  @param[in] FspHobList  Pointer to the HOB data structure produced by FSP.\r
+\r
+  @return If platform process the FSP hob list successfully.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+PostFspsHobProcess (\r
+  IN VOID                 *FspHobList\r
+  )\r
+{\r
+  ProcessFspHobList (FspHobList);\r
+\r
+  return EFI_SUCCESS;\r
+}
\ No newline at end of file
diff --git a/IntelFsp2WrapperPkg/Library/PeiFspWrapperHobProcessLibSample/PeiFspWrapperHobProcessLibSample.inf b/IntelFsp2WrapperPkg/Library/PeiFspWrapperHobProcessLibSample/PeiFspWrapperHobProcessLibSample.inf
new file mode 100644 (file)
index 0000000..6fa91b6
--- /dev/null
@@ -0,0 +1,76 @@
+## @file\r
+#  Sample to provide FSP wrapper hob process related function.\r
+#\r
+#  Copyright (c) 2014 - 2016, 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                      = PeiFspWrapperHobProcessLibSample\r
+  FILE_GUID                      = 864693E2-EDE8-4DF8-8871-38C0BAA157EB\r
+  MODULE_TYPE                    = SEC\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = FspWrapperHobProcessLib\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
+  FspWrapperHobProcessLibSample.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
+  MdeModulePkg/MdeModulePkg.dec\r
+  IntelFsp2Pkg/IntelFsp2Pkg.dec\r
+  IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec\r
+\r
+[LibraryClasses]\r
+  BaseLib\r
+  BaseMemoryLib\r
+  HobLib\r
+  DebugLib\r
+  FspWrapperPlatformLib\r
+  PeiServicesLib\r
+  PeiServicesTablePointerLib\r
+\r
+[Pcd]\r
+  gFspWrapperTokenSpaceGuid.PcdPeiMinMemSize              ## CONSUMES\r
+  gFspWrapperTokenSpaceGuid.PcdPeiRecoveryMinMemSize      ## CONSUMES\r
+\r
+[Guids]\r
+  gFspReservedMemoryResourceHobGuid                       ## CONSUMES ## HOB\r
+  gEfiMemoryTypeInformationGuid                           ## CONSUMES ## GUID\r
+  gPcdDataBaseHobGuid                                     ## CONSUMES ## HOB\r
+\r
+[Ppis]\r
+  gEfiPeiCapsulePpiGuid                                   ## CONSUMES\r
diff --git a/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/FspWrapperPlatformSecLibSample.c b/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/FspWrapperPlatformSecLibSample.c
new file mode 100644 (file)
index 0000000..19379c2
--- /dev/null
@@ -0,0 +1,133 @@
+/** @file\r
+  Sample to provide FSP wrapper platform sec related function.\r
+\r
+  Copyright (c) 2014 - 2016, 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
+#include <Ppi/SecPlatformInformation.h>\r
+#include <Ppi/SecPerformance.h>\r
+\r
+#include <Library/LocalApicLib.h>\r
+\r
+/**\r
+  This interface conveys state information out of the Security (SEC) phase into PEI.\r
+\r
+  @param[in]     PeiServices               Pointer to the PEI Services Table.\r
+  @param[in,out] StructureSize             Pointer to the variable describing size of the input buffer.\r
+  @param[out]    PlatformInformationRecord Pointer to the EFI_SEC_PLATFORM_INFORMATION_RECORD.\r
+\r
+  @retval EFI_SUCCESS           The data was successfully returned.\r
+  @retval EFI_BUFFER_TOO_SMALL  The buffer was too small.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+SecPlatformInformation (\r
+  IN CONST EFI_PEI_SERVICES                     **PeiServices,\r
+  IN OUT   UINT64                               *StructureSize,\r
+     OUT   EFI_SEC_PLATFORM_INFORMATION_RECORD  *PlatformInformationRecord\r
+  );\r
+\r
+/**\r
+  This interface conveys performance information out of the Security (SEC) phase into PEI.\r
+\r
+  This service is published by the SEC phase. The SEC phase handoff has an optional\r
+  EFI_PEI_PPI_DESCRIPTOR list as its final argument when control is passed from SEC into the\r
+  PEI Foundation. As such, if the platform supports collecting performance data in SEC,\r
+  this information is encapsulated into the data structure abstracted by this service.\r
+  This information is collected for the boot-strap processor (BSP) on IA-32.\r
+\r
+  @param[in]  PeiServices  The pointer to the PEI Services Table.\r
+  @param[in]  This         The pointer to this instance of the PEI_SEC_PERFORMANCE_PPI.\r
+  @param[out] Performance  The pointer to performance data collected in SEC phase.\r
+\r
+  @retval EFI_SUCCESS  The data was successfully returned.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+SecGetPerformance (\r
+  IN CONST EFI_PEI_SERVICES          **PeiServices,\r
+  IN       PEI_SEC_PERFORMANCE_PPI   *This,\r
+  OUT      FIRMWARE_SEC_PERFORMANCE  *Performance\r
+  );\r
+\r
+PEI_SEC_PERFORMANCE_PPI  mSecPerformancePpi = {\r
+  SecGetPerformance\r
+};\r
+\r
+EFI_PEI_PPI_DESCRIPTOR  mPeiSecPlatformPpi[] = {\r
+  {\r
+    EFI_PEI_PPI_DESCRIPTOR_PPI,\r
+    &gTopOfTemporaryRamPpiGuid,\r
+    NULL // To be patched later.\r
+  },\r
+  {\r
+    EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,\r
+    &gPeiSecPerformancePpiGuid,\r
+    &mSecPerformancePpi\r
+  },\r
+};\r
+\r
+/**\r
+  A developer supplied function to perform platform specific operations.\r
+\r
+  It's a developer supplied function to perform any operations appropriate to a\r
+  given platform. It's invoked just before passing control to PEI core by SEC\r
+  core. Platform developer may modify the SecCoreData passed to PEI Core.\r
+  It returns a platform specific PPI list that platform wishes to pass to PEI core.\r
+  The Generic SEC core module will merge this list to join the final list passed to\r
+  PEI core.\r
+\r
+  @param[in,out] SecCoreData           The same parameter as passing to PEI core. It\r
+                                       could be overridden by this function.\r
+\r
+  @return The platform specific PPI list to be passed to PEI core or\r
+          NULL if there is no need of such platform specific PPI list.\r
+\r
+**/\r
+EFI_PEI_PPI_DESCRIPTOR *\r
+EFIAPI\r
+SecPlatformMain (\r
+  IN OUT   EFI_SEC_PEI_HAND_OFF        *SecCoreData\r
+  )\r
+{\r
+  EFI_PEI_PPI_DESCRIPTOR      *PpiList;\r
+\r
+  DEBUG((DEBUG_INFO, "SecPlatformMain\n"));\r
+\r
+  DEBUG((DEBUG_INFO, "BootFirmwareVolumeBase - 0x%x\n", SecCoreData->BootFirmwareVolumeBase));\r
+  DEBUG((DEBUG_INFO, "BootFirmwareVolumeSize - 0x%x\n", SecCoreData->BootFirmwareVolumeSize));\r
+  DEBUG((DEBUG_INFO, "TemporaryRamBase       - 0x%x\n", SecCoreData->TemporaryRamBase));\r
+  DEBUG((DEBUG_INFO, "TemporaryRamSize       - 0x%x\n", SecCoreData->TemporaryRamSize));\r
+  DEBUG((DEBUG_INFO, "PeiTemporaryRamBase    - 0x%x\n", SecCoreData->PeiTemporaryRamBase));\r
+  DEBUG((DEBUG_INFO, "PeiTemporaryRamSize    - 0x%x\n", SecCoreData->PeiTemporaryRamSize));\r
+  DEBUG((DEBUG_INFO, "StackBase              - 0x%x\n", SecCoreData->StackBase));\r
+  DEBUG((DEBUG_INFO, "StackSize              - 0x%x\n", SecCoreData->StackSize));\r
+\r
+  InitializeApicTimer (0, (UINT32) -1, TRUE, 5);\r
+\r
+  //\r
+  // Use middle of Heap as temp buffer, it will be copied by caller.\r
+  // Do not use Stack, because it will cause wrong calculation on stack by PeiCore\r
+  //\r
+  PpiList = (VOID *)((UINTN)SecCoreData->PeiTemporaryRamBase + (UINTN)SecCoreData->PeiTemporaryRamSize/2);\r
+  CopyMem (PpiList, mPeiSecPlatformPpi, sizeof(mPeiSecPlatformPpi));\r
+\r
+  //\r
+  // Patch TopOfTemporaryRamPpi\r
+  //\r
+  PpiList[0].Ppi = (VOID *)((UINTN)SecCoreData->TemporaryRamBase + SecCoreData->TemporaryRamSize);\r
+\r
+  return PpiList;\r
+}\r
diff --git a/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/Fsp.h b/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/Fsp.h
new file mode 100644 (file)
index 0000000..c625a88
--- /dev/null
@@ -0,0 +1,51 @@
+/** @file\r
+  Fsp related definitions\r
+\r
+  Copyright (c) 2014 - 2016, 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_H__\r
+#define __FSP_H__\r
+\r
+//\r
+// Fv Header\r
+//\r
+#define FVH_FV_LENGTH_OFFSET          0x20\r
+#define FVH_SIGINATURE_OFFSET         0x28\r
+#define FVH_SIGINATURE_VALID_VALUE    0x4856465F  // valid signature:_FVH\r
+#define FVH_HEADER_LENGTH_OFFSET      0x30\r
+#define FVH_EXTHEADER_OFFSET_OFFSET   0x34\r
+#define FVH_EXTHEADER_SIZE_OFFSET     0x10\r
+\r
+//\r
+// Ffs Header\r
+//\r
+#define FSP_HEADER_SIGNATURE_OFFSET   0x1C\r
+#define FSP_HEADER_SIGNATURE          0x48505346    ; valid signature:FSPH\r
+#define FSP_HEADER_GUID_DWORD1        0x912740BE\r
+#define FSP_HEADER_GUID_DWORD2        0x47342284\r
+#define FSP_HEADER_GUID_DWORD3        0xB08471B9\r
+#define FSP_HEADER_GUID_DWORD4        0x0C3F3527\r
+#define FFS_HEADER_SIZE_VALUE         0x18\r
+\r
+//\r
+// Section Header\r
+//\r
+#define SECTION_HEADER_TYPE_OFFSET    0x03\r
+#define RAW_SECTION_HEADER_SIZE_VALUE 0x04\r
+\r
+//\r
+// Fsp Header\r
+//\r
+#define FSP_HEADER_IMAGEBASE_OFFSET     0x1C\r
+#define FSP_HEADER_TEMPRAMINIT_OFFSET   0x30\r
+\r
+#endif\r
diff --git a/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/PeiCoreEntry.S b/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/PeiCoreEntry.S
new file mode 100644 (file)
index 0000000..c35f02b
--- /dev/null
@@ -0,0 +1,130 @@
+#------------------------------------------------------------------------------\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
+# Module Name:\r
+#\r
+#  PeiCoreEntry.S\r
+#\r
+# Abstract:\r
+#\r
+#   Find and call SecStartup\r
+#\r
+#------------------------------------------------------------------------------\r
+\r
+ASM_GLOBAL ASM_PFX(CallPeiCoreEntryPoint)\r
+ASM_PFX(CallPeiCoreEntryPoint):\r
+  #\r
+  # Obtain the hob list pointer\r
+  #\r
+  movl    0x4(%esp), %eax\r
+  #\r
+  # Obtain the stack information\r
+  #   ECX: start of range\r
+  #   EDX: end of range\r
+  #\r
+  movl    0x8(%esp), %ecx\r
+  movl    0xC(%esp), %edx\r
+\r
+  #\r
+  # Platform init\r
+  #\r
+  pushal\r
+  pushl %edx\r
+  pushl %ecx\r
+  pushl %eax\r
+  call  ASM_PFX(PlatformInit)\r
+  popl  %eax\r
+  popl  %eax\r
+  popl  %eax\r
+  popal\r
+\r
+  #\r
+  # Set stack top pointer\r
+  #\r
+  movl    %edx, %esp\r
+\r
+  #\r
+  # Push the hob list pointer\r
+  #\r
+  pushl   %eax\r
+\r
+  #\r
+  # Save the value\r
+  #   ECX: start of range\r
+  #   EDX: end of range\r
+  #\r
+  movl    %esp, %ebp\r
+  pushl   %ecx\r
+  pushl   %edx\r
+\r
+  #\r
+  # Push processor count to stack first, then BIST status (AP then BSP)\r
+  #\r
+  movl    $1, %eax\r
+  cpuid\r
+  shr     $16, %ebx\r
+  andl    $0x000000FF, %ebx\r
+  cmp     $1, %bl\r
+  jae     PushProcessorCount\r
+\r
+  #\r
+  # Some processors report 0 logical processors.  Effectively 0 = 1.\r
+  # So we fix up the processor count\r
+  #\r
+  inc     %ebx\r
+\r
+PushProcessorCount:\r
+  pushl   %ebx\r
+\r
+  #\r
+  # We need to implement a long-term solution for BIST capture.  For now, we just copy BSP BIST\r
+  # for all processor threads\r
+  #\r
+  xorl    %ecx, %ecx\r
+  movb    %bl, %cl\r
+PushBist:\r
+  movd    %mm0, %eax\r
+  pushl   %eax\r
+  loop    PushBist\r
+\r
+  # Save Time-Stamp Counter\r
+  movd  %mm5, %eax\r
+  pushl %eax\r
+\r
+  movd  %mm6, %eax\r
+  pushl %eax\r
+\r
+  #\r
+  # Pass entry point of the PEI core\r
+  #\r
+  movl    $0xFFFFFFE0, %edi\r
+  pushl   %ds:(%edi)\r
+\r
+  #\r
+  # Pass BFV into the PEI Core\r
+  #\r
+  movl    $0xFFFFFFFC, %edi\r
+  pushl   %ds:(%edi)\r
+\r
+  #\r
+  # Pass stack size into the PEI Core\r
+  #\r
+  movl    -4(%ebp), %ecx\r
+  movl    -8(%ebp), %edx\r
+  pushl   %ecx       # RamBase\r
+\r
+  subl    %ecx, %edx\r
+  pushl   %edx       # RamSize\r
+\r
+  #\r
+  # Pass Control into the PEI Core\r
+  #\r
+  call ASM_PFX(SecStartup)\r
diff --git a/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/PeiCoreEntry.asm b/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/PeiCoreEntry.asm
new file mode 100644 (file)
index 0000000..cd1c7b8
--- /dev/null
@@ -0,0 +1,140 @@
+;------------------------------------------------------------------------------\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
+; Module Name:\r
+;\r
+;  PeiCoreEntry.asm\r
+;\r
+; Abstract:\r
+;\r
+;   Find and call SecStartup\r
+;\r
+;------------------------------------------------------------------------------\r
+\r
+.686p\r
+.xmm\r
+.model flat, c\r
+.code\r
+\r
+EXTRN   SecStartup:NEAR\r
+EXTRN   PlatformInit:NEAR\r
+\r
+CallPeiCoreEntryPoint   PROC PUBLIC\r
+  ;\r
+  ; Obtain the hob list pointer\r
+  ;\r
+  mov     eax, [esp+4]\r
+  ;\r
+  ; Obtain the stack information\r
+  ;   ECX: start of range\r
+  ;   EDX: end of range\r
+  ;\r
+  mov     ecx, [esp+8]\r
+  mov     edx, [esp+0Ch]\r
+\r
+  ;\r
+  ; Platform init\r
+  ;\r
+  pushad\r
+  push edx\r
+  push ecx\r
+  push eax\r
+  call PlatformInit\r
+  pop  eax\r
+  pop  eax\r
+  pop  eax\r
+  popad\r
+\r
+  ;\r
+  ; Set stack top pointer\r
+  ;\r
+  mov     esp, edx\r
+\r
+  ;\r
+  ; Push the hob list pointer\r
+  ;\r
+  push    eax\r
+\r
+  ;\r
+  ; Save the value\r
+  ;   ECX: start of range\r
+  ;   EDX: end of range\r
+  ;\r
+  mov     ebp, esp\r
+  push    ecx\r
+  push    edx\r
+\r
+  ;\r
+  ; Push processor count to stack first, then BIST status (AP then BSP)\r
+  ;\r
+  mov     eax, 1\r
+  cpuid\r
+  shr     ebx, 16\r
+  and     ebx, 0000000FFh\r
+  cmp     bl, 1\r
+  jae     PushProcessorCount\r
+\r
+  ;\r
+  ; Some processors report 0 logical processors.  Effectively 0 = 1.\r
+  ; So we fix up the processor count\r
+  ;\r
+  inc     ebx\r
+\r
+PushProcessorCount:\r
+  push    ebx\r
+\r
+  ;\r
+  ; We need to implement a long-term solution for BIST capture.  For now, we just copy BSP BIST\r
+  ; for all processor threads\r
+  ;\r
+  xor     ecx, ecx\r
+  mov     cl, bl\r
+PushBist:\r
+  movd    eax, mm0\r
+  push    eax\r
+  loop    PushBist\r
+\r
+  ; Save Time-Stamp Counter\r
+  movd eax, mm5\r
+  push eax\r
+\r
+  movd eax, mm6\r
+  push eax\r
+\r
+  ;\r
+  ; Pass entry point of the PEI core\r
+  ;\r
+  mov     edi, 0FFFFFFE0h\r
+  push    DWORD PTR ds:[edi]\r
+\r
+  ;\r
+  ; Pass BFV into the PEI Core\r
+  ;\r
+  mov     edi, 0FFFFFFFCh\r
+  push    DWORD PTR ds:[edi]\r
+\r
+  ;\r
+  ; Pass stack size into the PEI Core\r
+  ;\r
+  mov     ecx, [ebp - 4]\r
+  mov     edx, [ebp - 8]\r
+  push    ecx       ; RamBase\r
+\r
+  sub     edx, ecx\r
+  push    edx       ; RamSize\r
+\r
+  ;\r
+  ; Pass Control into the PEI Core\r
+  ;\r
+  call SecStartup\r
+CallPeiCoreEntryPoint   ENDP\r
+\r
+END\r
diff --git a/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/SecEntry.S b/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/SecEntry.S
new file mode 100644 (file)
index 0000000..aff77f6
--- /dev/null
@@ -0,0 +1,336 @@
+#------------------------------------------------------------------------------\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
+# Module Name:\r
+#\r
+#  SecEntry.S\r
+#\r
+# Abstract:\r
+#\r
+#  This is the code that goes from real-mode to protected mode.\r
+#  It consumes the reset vector, calls TempRamInit API from FSP binary.\r
+#\r
+#------------------------------------------------------------------------------\r
+\r
+#include "Fsp.h"\r
+\r
+ASM_GLOBAL    ASM_PFX(_gPcd_FixedAtBuild_PcdFsptBaseAddress)\r
+\r
+ASM_GLOBAL ASM_PFX(_TEXT_REALMODE)\r
+ASM_PFX(_TEXT_REALMODE):\r
+#----------------------------------------------------------------------------\r
+#\r
+# Procedure:    _ModuleEntryPoint\r
+#\r
+# Input:        None\r
+#\r
+# Output:       None\r
+#\r
+# Destroys:     Assume all registers\r
+#\r
+# Description:\r
+#\r
+#   Transition to non-paged flat-model protected mode from a\r
+#   hard-coded GDT that provides exactly two descriptors.\r
+#   This is a bare bones transition to protected mode only\r
+#   used for a while in PEI and possibly DXE.\r
+#\r
+#   After enabling protected mode, a far jump is executed to\r
+#   transfer to PEI using the newly loaded GDT.\r
+#\r
+# Return:       None\r
+#\r
+#  MMX Usage:\r
+#              MM0 = BIST State\r
+#              MM5 = Save time-stamp counter value high32bit\r
+#              MM6 = Save time-stamp counter value low32bit.\r
+#\r
+#----------------------------------------------------------------------------\r
+\r
+.align 4\r
+ASM_GLOBAL ASM_PFX(_ModuleEntryPoint)\r
+ASM_PFX(_ModuleEntryPoint):\r
+  fninit                                # clear any pending Floating point exceptions\r
+  #\r
+  # Store the BIST value in mm0\r
+  #\r
+  movd    %eax, %mm0\r
+\r
+  #\r
+  # Save time-stamp counter value\r
+  # rdtsc load 64bit time-stamp counter to EDX:EAX\r
+  #\r
+  rdtsc\r
+  movd    %edx, %mm5\r
+  movd    %ecx, %mm6\r
+\r
+  #\r
+  # Load the GDT table in GdtDesc\r
+  #\r
+  movl    $GdtDesc, %esi\r
+  .byte   0x66\r
+  lgdt    %cs:(%si)\r
+\r
+  #\r
+  # Transition to 16 bit protected mode\r
+  #\r
+  movl    %cr0, %eax                 # Get control register 0\r
+  orl     $0x00000003, %eax          # Set PE bit (bit #0) & MP bit (bit #1)\r
+  movl    %eax, %cr0                 # Activate protected mode\r
+\r
+  movl    %cr4, %eax                 # Get control register 4\r
+  orl     $0x00000600, %eax          # Set OSFXSR bit (bit #9) & OSXMMEXCPT bit (bit #10)\r
+  movl    %eax, %cr4\r
+\r
+  #\r
+  # Now we're in 16 bit protected mode\r
+  # Set up the selectors for 32 bit protected mode entry\r
+  #\r
+  movw    SYS_DATA_SEL, %ax\r
+  movw    %ax, %ds\r
+  movw    %ax, %es\r
+  movw    %ax, %fs\r
+  movw    %ax, %gs\r
+  movw    %ax, %ss\r
+\r
+  #\r
+  # Transition to Flat 32 bit protected mode\r
+  # The jump to a far pointer causes the transition to 32 bit mode\r
+  #\r
+  movl    ASM_PFX(ProtectedModeEntryLinearAddress), %esi\r
+  jmp     *%cs:(%si)\r
+\r
+ASM_GLOBAL ASM_PFX(_TEXT_PROTECTED_MODE)\r
+ASM_PFX(_TEXT_PROTECTED_MODE):\r
+\r
+#----------------------------------------------------------------------------\r
+#\r
+# Procedure:    ProtectedModeEntryPoint\r
+#\r
+# Input:        None\r
+#\r
+# Output:       None\r
+#\r
+# Destroys:     Assume all registers\r
+#\r
+# Description:\r
+#\r
+# This function handles:\r
+#   Call two basic APIs from FSP binary\r
+#   Initializes stack with some early data (BIST, PEI entry, etc)\r
+#\r
+# Return:       None\r
+#\r
+#----------------------------------------------------------------------------\r
+\r
+.align 4\r
+ASM_GLOBAL ASM_PFX(ProtectedModeEntryPoint)\r
+ASM_PFX(ProtectedModeEntryPoint):\r
+\r
+  # Find the fsp info header\r
+  movl ASM_PFX(_gPcd_FixedAtBuild_PcdFsptBaseAddress), %edi\r
+\r
+  movl FVH_SIGINATURE_OFFSET(%edi), %eax\r
+  cmp  $FVH_SIGINATURE_VALID_VALUE, %eax\r
+  jnz  FspHeaderNotFound\r
+\r
+  xorl %eax, %eax\r
+  movw FVH_EXTHEADER_OFFSET_OFFSET(%edi), %ax\r
+  cmp  %ax, 0\r
+  jnz  FspFvExtHeaderExist\r
+\r
+  xorl %eax, %eax\r
+  movw FVH_HEADER_LENGTH_OFFSET(%edi), %ax   # Bypass Fv Header\r
+  addl %eax, %edi\r
+  jmp  FspCheckFfsHeader\r
+\r
+FspFvExtHeaderExist:\r
+  addl %eax, %edi\r
+  movl FVH_EXTHEADER_SIZE_OFFSET(%edi), %eax  # Bypass Ext Fv Header\r
+  addl %eax, %edi\r
+\r
+  # Round up to 8 byte alignment\r
+  movl %edi, %eax\r
+  andb $0x07, %al\r
+  jz FspCheckFfsHeader\r
+\r
+  and  $0xFFFFFFF8, %edi\r
+  add  $0x08, %edi\r
+\r
+FspCheckFfsHeader:\r
+  # Check the ffs guid\r
+  movl (%edi), %eax\r
+  cmp  $FSP_HEADER_GUID_DWORD1, %eax\r
+  jnz  FspHeaderNotFound\r
+\r
+  movl 0x4(%edi), %eax\r
+  cmp  $FSP_HEADER_GUID_DWORD2, %eax\r
+  jnz  FspHeaderNotFound\r
+\r
+  movl 0x08(%edi), %eax\r
+  cmp  $FSP_HEADER_GUID_DWORD3, %eax\r
+  jnz  FspHeaderNotFound\r
+\r
+  movl 0x0c(%edi), %eax\r
+  cmp  $FSP_HEADER_GUID_DWORD4, %eax\r
+  jnz  FspHeaderNotFound\r
+\r
+  add  $FFS_HEADER_SIZE_VALUE, %edi        # Bypass the ffs header\r
+\r
+  # Check the section type as raw section\r
+  movb SECTION_HEADER_TYPE_OFFSET(%edi), %al\r
+  cmp  $0x19, %al\r
+  jnz  FspHeaderNotFound\r
+\r
+  addl $RAW_SECTION_HEADER_SIZE_VALUE, %edi  # Bypass the section header\r
+  jmp  FspHeaderFound\r
+\r
+FspHeaderNotFound:\r
+  jmp  .\r
+\r
+FspHeaderFound:\r
+  # Get the fsp TempRamInit Api address\r
+  movl FSP_HEADER_IMAGEBASE_OFFSET(%edi), %eax\r
+  addl FSP_HEADER_TEMPRAMINIT_OFFSET(%edi), %eax\r
+\r
+  # Setup the hardcode stack\r
+  movl $TempRamInitStack, %esp\r
+\r
+  # Call the fsp TempRamInit Api\r
+  jmp  *%eax\r
+\r
+TempRamInitDone:\r
+  cmp  $0x8000000E, %eax   #Check if EFI_NOT_FOUND returned. Error code for Microcode Update not found.\r
+  je   CallSecFspInit      #If microcode not found, don't hang, but continue.\r
+\r
+  cmp  $0x0, %eax\r
+  jnz  FspApiFailed\r
+\r
+  #   ECX: start of range\r
+  #   EDX: end of range\r
+CallSecFspInit:\r
+  xorl    %eax, %eax\r
+  movl    %edx, %esp\r
+\r
+  # Align the stack at DWORD\r
+  addl  $3, %esp\r
+  andl  $0xFFFFFFFC, %esp\r
+\r
+  pushl   %edx\r
+  pushl   %ecx\r
+  pushl   %eax # zero - no hob list yet\r
+  call ASM_PFX(CallPeiCoreEntryPoint)\r
+\r
+FspApiFailed:\r
+  jmp .\r
+\r
+.align 0x10\r
+TempRamInitStack:\r
+    .long  TempRamInitDone\r
+    .long  ASM_PFX(FsptUpdDataPtr)\r
+\r
+#\r
+# ROM-based Global-Descriptor Table for the Tiano PEI Phase\r
+#\r
+.align 16\r
+\r
+#\r
+# GDT[0]: 0x00: Null entry, never used.\r
+#\r
+.equ NULL_SEL,             . - GDT_BASE    # Selector [0]\r
+GDT_BASE:\r
+BootGdtTable:       .long  0\r
+                    .long  0\r
+#\r
+# Linear data segment descriptor\r
+#\r
+.equ LINEAR_SEL,           . - GDT_BASE    # Selector [0x8]\r
+    .word  0xFFFF                          # limit 0xFFFFF\r
+    .word  0                               # base 0\r
+    .byte  0\r
+    .byte  0x92                            # present, ring 0, data, expand-up, writable\r
+    .byte  0xCF                            # page-granular, 32-bit\r
+    .byte  0\r
+#\r
+# Linear code segment descriptor\r
+#\r
+.equ LINEAR_CODE_SEL,      . - GDT_BASE    # Selector [0x10]\r
+    .word  0xFFFF                          # limit 0xFFFFF\r
+    .word  0                               # base 0\r
+    .byte  0\r
+    .byte  0x9B                            # present, ring 0, data, expand-up, not-writable\r
+    .byte  0xCF                            # page-granular, 32-bit\r
+    .byte  0\r
+#\r
+# System data segment descriptor\r
+#\r
+.equ SYS_DATA_SEL,         . - GDT_BASE    # Selector [0x18]\r
+    .word  0xFFFF                          # limit 0xFFFFF\r
+    .word  0                               # base 0\r
+    .byte  0\r
+    .byte  0x93                            # present, ring 0, data, expand-up, not-writable\r
+    .byte  0xCF                            # page-granular, 32-bit\r
+    .byte  0\r
+\r
+#\r
+# System code segment descriptor\r
+#\r
+.equ SYS_CODE_SEL,         . - GDT_BASE    # Selector [0x20]\r
+    .word  0xFFFF                          # limit 0xFFFFF\r
+    .word  0                               # base 0\r
+    .byte  0\r
+    .byte  0x9A                            # present, ring 0, data, expand-up, writable\r
+    .byte  0xCF                            # page-granular, 32-bit\r
+    .byte  0\r
+#\r
+# Spare segment descriptor\r
+#\r
+.equ SYS16_CODE_SEL,       . - GDT_BASE    # Selector [0x28]\r
+    .word  0xFFFF                          # limit 0xFFFFF\r
+    .word  0                               # base 0\r
+    .byte  0x0E                            # Changed from F000 to E000.\r
+    .byte  0x9B                            # present, ring 0, code, expand-up, writable\r
+    .byte  0x00                            # byte-granular, 16-bit\r
+    .byte  0\r
+#\r
+# Spare segment descriptor\r
+#\r
+.equ SYS16_DATA_SEL,       . - GDT_BASE    # Selector [0x30]\r
+    .word  0xFFFF                          # limit 0xFFFF\r
+    .word  0                               # base 0\r
+    .byte  0\r
+    .byte  0x93                            # present, ring 0, data, expand-up, not-writable\r
+    .byte  0x00                            # byte-granular, 16-bit\r
+    .byte  0\r
+\r
+#\r
+# Spare segment descriptor\r
+#\r
+.equ SPARE5_SEL,           . - GDT_BASE    # Selector [0x38]\r
+    .word  0                               # limit 0\r
+    .word  0                               # base 0\r
+    .byte  0\r
+    .byte  0                               # present, ring 0, data, expand-up, writable\r
+    .byte  0                               # page-granular, 32-bit\r
+    .byte  0\r
+.equ GDT_SIZE,             . - BootGdtTable    # Size, in bytes\r
+\r
+#\r
+# GDT Descriptor\r
+#\r
+GdtDesc:                                # GDT descriptor\r
+    .word  GDT_SIZE - 1                    # GDT limit\r
+    .long  BootGdtTable                    # GDT base address\r
+\r
+ASM_PFX(ProtectedModeEntryLinearAddress):\r
+ProtectedModeEntryLinearOffset:\r
+  .long      ASM_PFX(ProtectedModeEntryPoint)  # Offset of our 32 bit code\r
+  .word      LINEAR_CODE_SEL\r
diff --git a/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/SecEntry.asm b/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/SecEntry.asm
new file mode 100644 (file)
index 0000000..ab8d46e
--- /dev/null
@@ -0,0 +1,353 @@
+;------------------------------------------------------------------------------\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
+; Module Name:\r
+;\r
+;  SecEntry.asm\r
+;\r
+; Abstract:\r
+;\r
+;  This is the code that goes from real-mode to protected mode.\r
+;  It consumes the reset vector, calls TempRamInit API from FSP binary.\r
+;\r
+;------------------------------------------------------------------------------\r
+\r
+#include "Fsp.h"\r
+\r
+.686p\r
+.xmm\r
+.model small, c\r
+\r
+EXTRN   CallPeiCoreEntryPoint:NEAR\r
+EXTRN   FsptUpdDataPtr:FAR\r
+\r
+; Pcds\r
+EXTRN   PcdGet32 (PcdFsptBaseAddress):DWORD\r
+\r
+_TEXT_REALMODE      SEGMENT PARA PUBLIC USE16 'CODE'\r
+                    ASSUME  CS:_TEXT_REALMODE, DS:_TEXT_REALMODE\r
+\r
+;----------------------------------------------------------------------------\r
+;\r
+; Procedure:    _ModuleEntryPoint\r
+;\r
+; Input:        None\r
+;\r
+; Output:       None\r
+;\r
+; Destroys:     Assume all registers\r
+;\r
+; Description:\r
+;\r
+;   Transition to non-paged flat-model protected mode from a\r
+;   hard-coded GDT that provides exactly two descriptors.\r
+;   This is a bare bones transition to protected mode only\r
+;   used for a while in PEI and possibly DXE.\r
+;\r
+;   After enabling protected mode, a far jump is executed to\r
+;   transfer to PEI using the newly loaded GDT.\r
+;\r
+; Return:       None\r
+;\r
+;  MMX Usage:\r
+;              MM0 = BIST State\r
+;              MM5 = Save time-stamp counter value high32bit\r
+;              MM6 = Save time-stamp counter value low32bit.\r
+;\r
+;----------------------------------------------------------------------------\r
+\r
+align 4\r
+_ModuleEntryPoint PROC NEAR C PUBLIC\r
+  fninit                                ; clear any pending Floating point exceptions\r
+  ;\r
+  ; Store the BIST value in mm0\r
+  ;\r
+  movd    mm0, eax\r
+\r
+  ;\r
+  ; Save time-stamp counter value\r
+  ; rdtsc load 64bit time-stamp counter to EDX:EAX\r
+  ;\r
+  rdtsc\r
+  movd    mm5, edx\r
+  movd    mm6, eax\r
+\r
+  ;\r
+  ; Load the GDT table in GdtDesc\r
+  ;\r
+  mov     esi,  OFFSET GdtDesc\r
+  DB      66h\r
+  lgdt    fword ptr cs:[si]\r
+\r
+  ;\r
+  ; Transition to 16 bit protected mode\r
+  ;\r
+  mov     eax, cr0                   ; Get control register 0\r
+  or      eax, 00000003h             ; Set PE bit (bit #0) & MP bit (bit #1)\r
+  mov     cr0, eax                   ; Activate protected mode\r
+\r
+  mov     eax, cr4                   ; Get control register 4\r
+  or      eax, 00000600h             ; Set OSFXSR bit (bit #9) & OSXMMEXCPT bit (bit #10)\r
+  mov     cr4, eax\r
+\r
+  ;\r
+  ; Now we're in 16 bit protected mode\r
+  ; Set up the selectors for 32 bit protected mode entry\r
+  ;\r
+  mov     ax, SYS_DATA_SEL\r
+  mov     ds, ax\r
+  mov     es, ax\r
+  mov     fs, ax\r
+  mov     gs, ax\r
+  mov     ss, ax\r
+\r
+  ;\r
+  ; Transition to Flat 32 bit protected mode\r
+  ; The jump to a far pointer causes the transition to 32 bit mode\r
+  ;\r
+  mov esi, offset ProtectedModeEntryLinearAddress\r
+  jmp     fword ptr cs:[si]\r
+\r
+_ModuleEntryPoint   ENDP\r
+_TEXT_REALMODE      ENDS\r
+\r
+_TEXT_PROTECTED_MODE      SEGMENT PARA PUBLIC USE32 'CODE'\r
+                          ASSUME  CS:_TEXT_PROTECTED_MODE, DS:_TEXT_PROTECTED_MODE\r
+\r
+;----------------------------------------------------------------------------\r
+;\r
+; Procedure:    ProtectedModeEntryPoint\r
+;\r
+; Input:        None\r
+;\r
+; Output:       None\r
+;\r
+; Destroys:     Assume all registers\r
+;\r
+; Description:\r
+;\r
+; This function handles:\r
+;   Call two basic APIs from FSP binary\r
+;   Initializes stack with some early data (BIST, PEI entry, etc)\r
+;\r
+; Return:       None\r
+;\r
+;----------------------------------------------------------------------------\r
+\r
+align 4\r
+ProtectedModeEntryPoint PROC NEAR PUBLIC\r
+\r
+  ; Find the fsp info header\r
+  mov  edi, PcdGet32 (PcdFsptBaseAddress)\r
+\r
+  mov  eax, dword ptr [edi + FVH_SIGINATURE_OFFSET]\r
+  cmp  eax, FVH_SIGINATURE_VALID_VALUE\r
+  jnz  FspHeaderNotFound\r
+\r
+  xor  eax, eax\r
+  mov  ax, word ptr [edi + FVH_EXTHEADER_OFFSET_OFFSET]\r
+  cmp  ax, 0\r
+  jnz  FspFvExtHeaderExist\r
+\r
+  xor  eax, eax\r
+  mov  ax, word ptr [edi + FVH_HEADER_LENGTH_OFFSET]   ; Bypass Fv Header\r
+  add  edi, eax\r
+  jmp  FspCheckFfsHeader\r
+\r
+FspFvExtHeaderExist:\r
+  add  edi, eax\r
+  mov  eax, dword ptr [edi + FVH_EXTHEADER_SIZE_OFFSET]  ; Bypass Ext Fv Header\r
+  add  edi, eax\r
+\r
+  ; Round up to 8 byte alignment\r
+  mov  eax, edi\r
+  and  al,  07h\r
+  jz   FspCheckFfsHeader\r
+\r
+  and  edi, 0FFFFFFF8h\r
+  add  edi, 08h\r
+\r
+FspCheckFfsHeader:\r
+  ; Check the ffs guid\r
+  mov  eax, dword ptr [edi]\r
+  cmp  eax, FSP_HEADER_GUID_DWORD1\r
+  jnz  FspHeaderNotFound\r
+\r
+  mov  eax, dword ptr [edi + 4]\r
+  cmp  eax, FSP_HEADER_GUID_DWORD2\r
+  jnz  FspHeaderNotFound\r
+\r
+  mov  eax, dword ptr [edi + 8]\r
+  cmp  eax, FSP_HEADER_GUID_DWORD3\r
+  jnz  FspHeaderNotFound\r
+\r
+  mov  eax, dword ptr [edi + 0Ch]\r
+  cmp  eax, FSP_HEADER_GUID_DWORD4\r
+  jnz  FspHeaderNotFound\r
+\r
+  add  edi, FFS_HEADER_SIZE_VALUE       ; Bypass the ffs header\r
+\r
+  ; Check the section type as raw section\r
+  mov  al, byte ptr [edi + SECTION_HEADER_TYPE_OFFSET]\r
+  cmp  al, 019h\r
+  jnz FspHeaderNotFound\r
+\r
+  add  edi, RAW_SECTION_HEADER_SIZE_VALUE ; Bypass the section header\r
+  jmp FspHeaderFound\r
+\r
+FspHeaderNotFound:\r
+  jmp  $\r
+\r
+FspHeaderFound:\r
+  ; Get the fsp TempRamInit Api address\r
+  mov eax, dword ptr [edi + FSP_HEADER_IMAGEBASE_OFFSET]\r
+  add eax, dword ptr [edi + FSP_HEADER_TEMPRAMINIT_OFFSET]\r
+\r
+  ; Setup the hardcode stack\r
+  mov esp, OFFSET TempRamInitStack\r
+\r
+  ; Call the fsp TempRamInit Api\r
+  jmp eax\r
+\r
+TempRamInitDone:\r
+  cmp eax, 8000000Eh      ;Check if EFI_NOT_FOUND returned. Error code for Microcode Update not found.\r
+  je  CallSecFspInit      ;If microcode not found, don't hang, but continue.\r
+\r
+  cmp eax, 0              ;Check if EFI_SUCCESS retuned.\r
+  jnz FspApiFailed\r
+\r
+  ;   ECX: start of range\r
+  ;   EDX: end of range\r
+CallSecFspInit:\r
+  xor     eax, eax\r
+  mov     esp, edx\r
+\r
+  ; Align the stack at DWORD\r
+  add  esp,  3\r
+  and  esp, 0FFFFFFFCh\r
+\r
+  push    edx\r
+  push    ecx\r
+  push    eax ; zero - no hob list yet\r
+  call    CallPeiCoreEntryPoint\r
+\r
+FspApiFailed:\r
+  jmp $\r
+\r
+align 10h\r
+TempRamInitStack:\r
+    DD  OFFSET TempRamInitDone\r
+    DD  OFFSET FsptUpdDataPtr ; TempRamInitParams\r
+\r
+ProtectedModeEntryPoint ENDP\r
+\r
+;\r
+; ROM-based Global-Descriptor Table for the Tiano PEI Phase\r
+;\r
+align 16\r
+PUBLIC  BootGdtTable\r
+\r
+;\r
+; GDT[0]: 0x00: Null entry, never used.\r
+;\r
+NULL_SEL            EQU $ - GDT_BASE    ; Selector [0]\r
+GDT_BASE:\r
+BootGdtTable        DD  0\r
+                    DD  0\r
+;\r
+; Linear data segment descriptor\r
+;\r
+LINEAR_SEL          EQU $ - GDT_BASE    ; Selector [0x8]\r
+    DW  0FFFFh                          ; limit 0xFFFFF\r
+    DW  0                               ; base 0\r
+    DB  0\r
+    DB  092h                            ; present, ring 0, data, expand-up, writable\r
+    DB  0CFh                            ; page-granular, 32-bit\r
+    DB  0\r
+;\r
+; Linear code segment descriptor\r
+;\r
+LINEAR_CODE_SEL     EQU $ - GDT_BASE    ; Selector [0x10]\r
+    DW  0FFFFh                          ; limit 0xFFFFF\r
+    DW  0                               ; base 0\r
+    DB  0\r
+    DB  09Bh                            ; present, ring 0, data, expand-up, not-writable\r
+    DB  0CFh                            ; page-granular, 32-bit\r
+    DB  0\r
+;\r
+; System data segment descriptor\r
+;\r
+SYS_DATA_SEL        EQU $ - GDT_BASE    ; Selector [0x18]\r
+    DW  0FFFFh                          ; limit 0xFFFFF\r
+    DW  0                               ; base 0\r
+    DB  0\r
+    DB  093h                            ; present, ring 0, data, expand-up, not-writable\r
+    DB  0CFh                            ; page-granular, 32-bit\r
+    DB  0\r
+\r
+;\r
+; System code segment descriptor\r
+;\r
+SYS_CODE_SEL        EQU $ - GDT_BASE    ; Selector [0x20]\r
+    DW  0FFFFh                          ; limit 0xFFFFF\r
+    DW  0                               ; base 0\r
+    DB  0\r
+    DB  09Ah                            ; present, ring 0, data, expand-up, writable\r
+    DB  0CFh                            ; page-granular, 32-bit\r
+    DB  0\r
+;\r
+; Spare segment descriptor\r
+;\r
+SYS16_CODE_SEL      EQU $ - GDT_BASE    ; Selector [0x28]\r
+    DW  0FFFFh                          ; limit 0xFFFFF\r
+    DW  0                               ; base 0\r
+    DB  0Eh                             ; Changed from F000 to E000.\r
+    DB  09Bh                            ; present, ring 0, code, expand-up, writable\r
+    DB  00h                             ; byte-granular, 16-bit\r
+    DB  0\r
+;\r
+; Spare segment descriptor\r
+;\r
+SYS16_DATA_SEL      EQU $ - GDT_BASE    ; Selector [0x30]\r
+    DW  0FFFFh                          ; limit 0xFFFF\r
+    DW  0                               ; base 0\r
+    DB  0\r
+    DB  093h                            ; present, ring 0, data, expand-up, not-writable\r
+    DB  00h                             ; byte-granular, 16-bit\r
+    DB  0\r
+\r
+;\r
+; Spare segment descriptor\r
+;\r
+SPARE5_SEL          EQU $ - GDT_BASE    ; Selector [0x38]\r
+    DW  0                               ; limit 0\r
+    DW  0                               ; base 0\r
+    DB  0\r
+    DB  0                               ; present, ring 0, data, expand-up, writable\r
+    DB  0                               ; page-granular, 32-bit\r
+    DB  0\r
+GDT_SIZE            EQU $ - BootGdtTable    ; Size, in bytes\r
+\r
+;\r
+; GDT Descriptor\r
+;\r
+GdtDesc:                                ; GDT descriptor\r
+    DW  GDT_SIZE - 1                    ; GDT limit\r
+    DD  OFFSET BootGdtTable             ; GDT base address\r
+\r
+\r
+ProtectedModeEntryLinearAddress   LABEL   FWORD\r
+ProtectedModeEntryLinearOffset    LABEL   DWORD\r
+  DD      OFFSET ProtectedModeEntryPoint  ; Offset of our 32 bit code\r
+  DW      LINEAR_CODE_SEL\r
+\r
+_TEXT_PROTECTED_MODE    ENDS\r
+END\r
diff --git a/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/Stack.S b/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/Stack.S
new file mode 100644 (file)
index 0000000..ae42935
--- /dev/null
@@ -0,0 +1,77 @@
+#------------------------------------------------------------------------------\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
+\r
+#------------------------------------------------------------------------------\r
+# VOID\r
+# EFIAPI\r
+# SecSwitchStack (\r
+#   UINT32   TemporaryMemoryBase,\r
+#   UINT32   PermanentMemoryBase\r
+#   )#\r
+#------------------------------------------------------------------------------\r
+ASM_GLOBAL ASM_PFX (SecSwitchStack)\r
+ASM_PFX(SecSwitchStack):\r
+    #\r
+    # Save standard registers so they can be used to change stack\r
+    #\r
+    pushl %eax\r
+    pushl %ebx\r
+    pushl %ecx\r
+    pushl %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 permanent\r
+    # memory at first!\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 permanent memory at first.\r
+    # Then, Fixup the esp point to permanent memory\r
+    #\r
+    movl  %esp, %eax\r
+    subl  %ebx, %eax\r
+    addl  %ecx, %eax\r
+    movl  0(%esp), %edx          # copy pushed register's value to permanent memory\r
+    movl  %edx, 0(%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 permanent memory\r
+    movl  %edx, 16(%eax)\r
+    movl  %eax, %esp            # From now, esp is pointed to permanent memory\r
+\r
+    #\r
+    # Fixup the ebp point to permanent memory\r
+    #\r
+    movl  %ebp, %eax\r
+    subl  %ebx, %eax\r
+    addl  %ecx, %eax\r
+    movl  %eax, %ebp            # From now, ebp is pointed to permanent memory\r
+\r
+    popl  %edx\r
+    popl  %ecx\r
+    popl  %ebx\r
+    popl  %eax\r
+    ret\r
+\r
diff --git a/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/Stack.asm b/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/Stack.asm
new file mode 100644 (file)
index 0000000..116b738
--- /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   PermanentMemoryBase\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 permanent\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 permanent memory at first.\r
+    ; Then, Fixup the esp point to permanent 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 permanent 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 permanent memory\r
+    mov   dword ptr [eax + 16], edx\r
+    mov   esp, eax                     ; From now, esp is pointed to permanent memory\r
+\r
+    ;\r
+    ; Fixup the ebp point to permanent memory\r
+    ;\r
+    mov   eax, ebp\r
+    sub   eax, ebx\r
+    add   eax, ecx\r
+    mov   ebp, eax                ; From now, ebp is pointed to permanent 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/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/PlatformInit.c b/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/PlatformInit.c
new file mode 100644 (file)
index 0000000..ba75e0f
--- /dev/null
@@ -0,0 +1,45 @@
+/** @file\r
+  Sample to provide platform init function.\r
+\r
+  Copyright (c) 2014 - 2016, 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 <PiPei.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/SerialPortLib.h>\r
+\r
+/**\r
+  Platform initialization.\r
+\r
+  @param[in] FspHobList   HobList produced by FSP.\r
+  @param[in] StartOfRange Start of temporary RAM.\r
+  @param[in] EndOfRange   End of temporary RAM.\r
+**/\r
+VOID\r
+EFIAPI\r
+PlatformInit (\r
+  IN VOID                 *FspHobList,\r
+  IN VOID                 *StartOfRange,\r
+  IN VOID                 *EndOfRange\r
+  )\r
+{\r
+  //\r
+  // Platform initialization\r
+  // Enable Serial port here\r
+  //\r
+  SerialPortInitialize ();\r
+\r
+  DEBUG ((DEBUG_INFO, "PrintPeiCoreEntryPointParam in PlatformInit\n"));\r
+  DEBUG ((DEBUG_INFO, "FspHobList - 0x%x\n", FspHobList));\r
+  DEBUG ((DEBUG_INFO, "StartOfRange - 0x%x\n", StartOfRange));\r
+  DEBUG ((DEBUG_INFO, "EndOfRange - 0x%x\n", EndOfRange));\r
+}\r
diff --git a/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/SecFspWrapperPlatformSecLibSample.inf b/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/SecFspWrapperPlatformSecLibSample.inf
new file mode 100644 (file)
index 0000000..10df778
--- /dev/null
@@ -0,0 +1,89 @@
+## @file\r
+#  Sample to provide FSP wrapper platform sec related function.\r
+#\r
+#  Copyright (c) 2014 - 2016, 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                      = SecFspWrapperPlatformSecLibSample\r
+  FILE_GUID                      = 8F1AC44A-CE7E-4E29-95BB-92E321BB1573\r
+  MODULE_TYPE                    = SEC\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = FspWrapperPlatformSecLib\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
+  FspWrapperPlatformSecLibSample.c\r
+  SecRamInitData.c\r
+  SecPlatformInformation.c\r
+  SecGetPerformance.c\r
+  SecTempRamDone.c\r
+  PlatformInit.c\r
+\r
+[Sources.IA32]\r
+  Ia32/SecEntry.asm\r
+  Ia32/PeiCoreEntry.asm\r
+  Ia32/Stack.asm\r
+  Ia32/Fsp.h\r
+  Ia32/SecEntry.S\r
+  Ia32/PeiCoreEntry.S\r
+  Ia32/Stack.S\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
+  MdeModulePkg/MdeModulePkg.dec\r
+  UefiCpuPkg/UefiCpuPkg.dec\r
+  IntelFsp2Pkg/IntelFsp2Pkg.dec\r
+  IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec\r
+\r
+[LibraryClasses]\r
+  LocalApicLib\r
+  SerialPortLib\r
+\r
+[Ppis]\r
+  gEfiSecPlatformInformationPpiGuid       ## CONSUMES\r
+  gPeiSecPerformancePpiGuid               ## CONSUMES\r
+  gTopOfTemporaryRamPpiGuid               ## PRODUCES\r
+\r
+[Pcd]\r
+  gFspWrapperTokenSpaceGuid.PcdFsptBaseAddress                  ## CONSUMES\r
+  gFspWrapperTokenSpaceGuid.PcdFspmBaseAddress                  ## CONSUMES\r
+\r
+[FixedPcd]\r
+  gFspWrapperTokenSpaceGuid.PcdCpuMicrocodePatchAddress         ## CONSUMES\r
+  gFspWrapperTokenSpaceGuid.PcdCpuMicrocodePatchRegionSize      ## CONSUMES\r
+  gFspWrapperTokenSpaceGuid.PcdFlashMicrocodeOffset             ## CONSUMES\r
+  gFspWrapperTokenSpaceGuid.PcdFlashCodeCacheAddress            ## CONSUMES\r
+  gFspWrapperTokenSpaceGuid.PcdFlashCodeCacheSize               ## CONSUMES\r
diff --git a/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/SecGetPerformance.c b/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/SecGetPerformance.c
new file mode 100644 (file)
index 0000000..e2d6b3d
--- /dev/null
@@ -0,0 +1,90 @@
+/** @file\r
+  Sample to provide SecGetPerformance function.\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
+#include <Ppi/SecPerformance.h>\r
+#include <Ppi/TopOfTemporaryRam.h>\r
+\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/TimerLib.h>\r
+#include <Library/DebugLib.h>\r
+\r
+/**\r
+  This interface conveys performance information out of the Security (SEC) phase into PEI.\r
+\r
+  This service is published by the SEC phase. The SEC phase handoff has an optional\r
+  EFI_PEI_PPI_DESCRIPTOR list as its final argument when control is passed from SEC into the\r
+  PEI Foundation. As such, if the platform supports collecting performance data in SEC,\r
+  this information is encapsulated into the data structure abstracted by this service.\r
+  This information is collected for the boot-strap processor (BSP) on IA-32.\r
+\r
+  @param[in]  PeiServices  The pointer to the PEI Services Table.\r
+  @param[in]  This         The pointer to this instance of the PEI_SEC_PERFORMANCE_PPI.\r
+  @param[out] Performance  The pointer to performance data collected in SEC phase.\r
+\r
+  @retval EFI_SUCCESS  The data was successfully returned.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+SecGetPerformance (\r
+  IN CONST EFI_PEI_SERVICES          **PeiServices,\r
+  IN       PEI_SEC_PERFORMANCE_PPI   *This,\r
+  OUT      FIRMWARE_SEC_PERFORMANCE  *Performance\r
+  )\r
+{\r
+  UINT32      Size;\r
+  UINT32      Count;\r
+  UINT32      TopOfTemporaryRam;\r
+  UINT64      Ticker;\r
+  VOID        *TopOfTemporaryRamPpi;\r
+  EFI_STATUS  Status;\r
+\r
+  DEBUG ((DEBUG_INFO, "SecGetPerformance\n"));\r
+\r
+  Status = (*PeiServices)->LocatePpi (\r
+                             PeiServices,\r
+                             &gTopOfTemporaryRamPpiGuid,\r
+                             0,\r
+                             NULL,\r
+                             (VOID **) &TopOfTemporaryRamPpi\r
+                             );\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  //\r
+  // |--------------| <- TopOfTemporaryRam\r
+  // |Number of BSPs|\r
+  // |--------------|\r
+  // |     BIST     |\r
+  // |--------------|\r
+  // |     ....     |\r
+  // |--------------|\r
+  // |  TSC[63:32]  |\r
+  // |--------------|\r
+  // |  TSC[31:00]  |\r
+  // |--------------|\r
+  //\r
+  TopOfTemporaryRam = (UINT32)(UINTN)TopOfTemporaryRamPpi - sizeof(UINT32);\r
+  TopOfTemporaryRam -= sizeof(UINT32) * 2;\r
+  Count             = *(UINT32 *) (UINTN) (TopOfTemporaryRam - sizeof (UINT32));\r
+  Size              = Count * sizeof (UINT64);\r
+\r
+  Ticker = *(UINT64 *) (UINTN) (TopOfTemporaryRam - sizeof (UINT32) - Size - sizeof (UINT32) * 2);\r
+  Performance->ResetEnd = GetTimeInNanoSecond (Ticker);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
diff --git a/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/SecPlatformInformation.c b/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/SecPlatformInformation.c
new file mode 100644 (file)
index 0000000..b879080
--- /dev/null
@@ -0,0 +1,84 @@
+/** @file\r
+  Sample to provide SecPlatformInformation function.\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
+#include <Ppi/SecPlatformInformation.h>\r
+#include <Ppi/TopOfTemporaryRam.h>\r
+\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/DebugLib.h>\r
+\r
+/**\r
+  This interface conveys state information out of the Security (SEC) phase into PEI.\r
+\r
+  @param[in]     PeiServices               Pointer to the PEI Services Table.\r
+  @param[in,out] StructureSize             Pointer to the variable describing size of the input buffer.\r
+  @param[out]    PlatformInformationRecord Pointer to the EFI_SEC_PLATFORM_INFORMATION_RECORD.\r
+\r
+  @retval EFI_SUCCESS           The data was successfully returned.\r
+  @retval EFI_BUFFER_TOO_SMALL  The buffer was too small.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+SecPlatformInformation (\r
+  IN CONST EFI_PEI_SERVICES                     **PeiServices,\r
+  IN OUT   UINT64                               *StructureSize,\r
+     OUT   EFI_SEC_PLATFORM_INFORMATION_RECORD  *PlatformInformationRecord\r
+  )\r
+{\r
+  UINT32      *Bist;\r
+  UINT32      Size;\r
+  UINT32      Count;\r
+  UINT32      TopOfTemporaryRam;\r
+  VOID        *TopOfTemporaryRamPpi;\r
+  EFI_STATUS  Status;\r
+\r
+  DEBUG ((DEBUG_INFO, "SecPlatformInformation\n"));\r
+\r
+  Status = (*PeiServices)->LocatePpi (\r
+                             PeiServices,\r
+                             &gTopOfTemporaryRamPpiGuid,\r
+                             0,\r
+                             NULL,\r
+                             (VOID **) &TopOfTemporaryRamPpi\r
+                             );\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  //\r
+  // The entries of BIST information, together with the number of them,\r
+  // reside in the bottom of stack, left untouched by normal stack operation.\r
+  // This routine copies the BIST information to the buffer pointed by\r
+  // PlatformInformationRecord for output.\r
+  //\r
+  TopOfTemporaryRam = (UINT32)(UINTN)TopOfTemporaryRamPpi - sizeof (UINT32);\r
+  TopOfTemporaryRam -= sizeof(UINT32) * 2;\r
+  Count             = *((UINT32 *)(UINTN) (TopOfTemporaryRam - sizeof (UINT32)));\r
+  Size              = Count * sizeof (IA32_HANDOFF_STATUS);\r
+\r
+  if ((*StructureSize) < (UINT64) Size) {\r
+    *StructureSize = Size;\r
+    return EFI_BUFFER_TOO_SMALL;\r
+  }\r
+\r
+  *StructureSize  = Size;\r
+  Bist            = (UINT32 *) (TopOfTemporaryRam - sizeof (UINT32) - Size);\r
+\r
+  CopyMem (PlatformInformationRecord, Bist, Size);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
diff --git a/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/SecRamInitData.c b/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/SecRamInitData.c
new file mode 100644 (file)
index 0000000..e2fbc45
--- /dev/null
@@ -0,0 +1,45 @@
+/** @file\r
+  Sample to provide TempRamInitParams data.\r
+\r
+  Copyright (c) 2014 - 2016, 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 <Library/PcdLib.h>\r
+#include <FspEas.h>\r
+\r
+typedef struct {\r
+  UINT32                      MicrocodeRegionBase;\r
+  UINT32                      MicrocodeRegionSize;\r
+  UINT32                      CodeRegionBase;\r
+  UINT32                      CodeRegionSize;\r
+} FSPT_CORE_UPD;\r
+\r
+typedef struct {\r
+  FSP_UPD_HEADER    FspUpdHeader;\r
+  FSPT_CORE_UPD     FsptCoreUpd;\r
+} FSPT_UPD_CORE_DATA;\r
+\r
+GLOBAL_REMOVE_IF_UNREFERENCED CONST FSPT_UPD_CORE_DATA FsptUpdDataPtr = {\r
+  {\r
+    0x4450555F54505346,\r
+    0x00,\r
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00\r
+    }\r
+  },\r
+  {\r
+    ((UINT32)FixedPcdGet64 (PcdCpuMicrocodePatchAddress) + FixedPcdGet32 (PcdFlashMicrocodeOffset)),\r
+    ((UINT32)FixedPcdGet64 (PcdCpuMicrocodePatchRegionSize) - FixedPcdGet32 (PcdFlashMicrocodeOffset)),\r
+    FixedPcdGet32 (PcdFlashCodeCacheAddress),\r
+    FixedPcdGet32 (PcdFlashCodeCacheSize),\r
+  }\r
+};\r
+\r
diff --git a/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/SecTempRamDone.c b/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/SecTempRamDone.c
new file mode 100644 (file)
index 0000000..76d2f42
--- /dev/null
@@ -0,0 +1,52 @@
+/** @file\r
+  Sample to provide SecTemporaryRamDone function.\r
+\r
+  Copyright (c) 2014 - 2016, 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
+#include <Ppi/TemporaryRamDone.h>\r
+\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/PcdLib.h>\r
+#include <Library/DebugAgentLib.h>\r
+#include <Library/FspPlatformInfoLib.h>\r
+#include <Library/FspApiLib.h>\r
+\r
+/**\r
+This interface disables temporary memory in SEC Phase.\r
+**/\r
+VOID\r
+EFIAPI\r
+SecPlatformDisableTemporaryMemory (\r
+  VOID\r
+  )\r
+{\r
+  EFI_STATUS                Status;\r
+  VOID                      *TempRamExitParam;\r
+  FSP_INFO_HEADER           *FspHeader;\r
+\r
+  FspHeader = FspFindFspHeader (PcdGet32(PcdFspmBaseAddress));\r
+  if (FspHeader == NULL) {\r
+    return ;\r
+  }\r
+\r
+  DEBUG((DEBUG_INFO, "SecPlatformDisableTemporaryMemory enter\n"));\r
+\r
+  TempRamExitParam = GetTempRamExitParam ();\r
+  Status = CallTempRamExit (FspHeader, TempRamExitParam);\r
+  DEBUG((DEBUG_INFO, "TempRamExit status: 0x%x\n", Status));\r
+  ASSERT_EFI_ERROR(Status);\r
+\r
+  return ;\r
+}\r