From cf1d454983fb4fd3b580a92bd242310467a5eaef Mon Sep 17 00:00:00 2001 From: Jiewen Yao Date: Fri, 13 May 2016 13:00:53 +0800 Subject: [PATCH] Add IntelFsp2Pkg and IntelFsp2WrapperPkg. 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 Cc: Maurice Ma Cc: Ravi P Rangarajan Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Jiewen Yao Reviewed-by: Giri P Mudusuru Reviewed-by: Maurice Ma Reviewed-by: Ravi P Rangarajan --- IntelFsp2Pkg/Contributions.txt | 218 +++ .../FspNotifyPhase/FspNotifyPhasePeim.c | 142 ++ .../FspNotifyPhase/FspNotifyPhasePeim.h | 23 + .../FspNotifyPhase/FspNotifyPhasePeim.inf | 49 + IntelFsp2Pkg/FspSecCore/FspSecCoreM.inf | 74 + IntelFsp2Pkg/FspSecCore/FspSecCoreS.inf | 68 + IntelFsp2Pkg/FspSecCore/FspSecCoreT.inf | 66 + .../FspSecCore/Ia32/FspApiEntryCommon.nasm | 76 + .../FspSecCore/Ia32/FspApiEntryM.nasm | 202 +++ .../FspSecCore/Ia32/FspApiEntryS.nasm | 62 + .../FspSecCore/Ia32/FspApiEntryT.nasm | 469 ++++++ IntelFsp2Pkg/FspSecCore/Ia32/FspHelper.nasm | 35 + .../FspSecCore/Ia32/InitializeFpu.nasm | 78 + .../FspSecCore/Ia32/MicrocodeLoadNasm.inc | 16 + .../FspSecCore/Ia32/SaveRestoreSseNasm.inc | 187 +++ IntelFsp2Pkg/FspSecCore/Ia32/Stack.nasm | 78 + IntelFsp2Pkg/FspSecCore/SecFsp.c | 216 +++ IntelFsp2Pkg/FspSecCore/SecFsp.h | 99 ++ IntelFsp2Pkg/FspSecCore/SecFspApiChk.c | 97 ++ IntelFsp2Pkg/FspSecCore/SecMain.c | 227 +++ IntelFsp2Pkg/FspSecCore/SecMain.h | 140 ++ .../FspSecCore/Vtf0/Bin/ResetVec.ia32.raw | Bin 0 -> 68 bytes IntelFsp2Pkg/FspSecCore/Vtf0/Build.py | 53 + .../FspSecCore/Vtf0/Ia16/ResetVec.asm16 | 103 ++ .../FspSecCore/Vtf0/ResetVectorCode.asm | 17 + .../Vtf0/Tools/FixupForRawSection.py | 110 ++ IntelFsp2Pkg/Include/FspDataTable.h | 32 + IntelFsp2Pkg/Include/FspEas.h | 24 + IntelFsp2Pkg/Include/FspEas/FspApi.h | 241 +++ IntelFsp2Pkg/Include/FspGlobalData.h | 68 + IntelFsp2Pkg/Include/FspMeasurePointId.h | 62 + IntelFsp2Pkg/Include/FspStatusCode.h | 46 + IntelFsp2Pkg/Include/Guid/FspHeaderFile.h | 204 +++ IntelFsp2Pkg/Include/Guid/GuidHobFspEas.h | 23 + IntelFsp2Pkg/Include/Library/CacheAsRamLib.h | 30 + IntelFsp2Pkg/Include/Library/CacheLib.h | 62 + IntelFsp2Pkg/Include/Library/DebugDeviceLib.h | 29 + IntelFsp2Pkg/Include/Library/FspCommonLib.h | 312 ++++ IntelFsp2Pkg/Include/Library/FspPlatformLib.h | 105 ++ .../Include/Library/FspSecPlatformLib.h | 88 + .../Include/Library/FspSwitchStackLib.h | 45 + IntelFsp2Pkg/IntelFsp2Pkg.dec | 80 + IntelFsp2Pkg/IntelFsp2Pkg.dsc | 77 + .../BaseCacheAsRamLibNull.inf | 31 + .../DisableCacheAsRamNull.c | 41 + .../Library/BaseCacheLib/BaseCacheLib.inf | 34 + IntelFsp2Pkg/Library/BaseCacheLib/CacheLib.c | 703 ++++++++ .../Library/BaseCacheLib/CacheLibInternal.h | 59 + .../BaseDebugDeviceLibNull.inf | 34 + .../DebugDeviceLibNull.c | 31 + .../BaseFspCommonLib/BaseFspCommonLib.inf | 39 + .../Library/BaseFspCommonLib/FspCommonLib.c | 546 ++++++ .../BaseFspDebugLibSerialPort.inf | 51 + .../BaseFspDebugLibSerialPort/DebugLib.c | 328 ++++ .../Ia32/FspDebug.asm | 34 + .../BaseFspDebugLibSerialPort/Ia32/FspDebug.s | 30 + .../BaseFspPlatformLib/BaseFspPlatformLib.inf | 50 + .../BaseFspPlatformLib/FspPlatformMemory.c | 189 +++ .../BaseFspPlatformLib/FspPlatformNotify.c | 279 ++++ .../BaseFspSwitchStackLib.inf | 43 + .../BaseFspSwitchStackLib/FspSwitchStackLib.c | 42 + .../BaseFspSwitchStackLib/Ia32/Stack.asm | 77 + .../BaseFspSwitchStackLib/Ia32/Stack.s | 78 + .../SecFspSecPlatformLibNull/Ia32/Flat32.asm | 131 ++ .../SecFspSecPlatformLibNull/Ia32/Flat32.s | 110 ++ .../Ia32/SecCarInit.asm | 51 + .../Ia32/SecCarInit.s | 37 + .../PlatformSecLibNull.c | 33 + .../SecFspSecPlatformLibNull.inf | 58 + IntelFsp2Pkg/Tools/GenCfgOpt.py | 1465 +++++++++++++++++ IntelFsp2Pkg/Tools/PatchFv.py | 947 +++++++++++ IntelFsp2Pkg/Tools/SplitFspBin.py | 363 ++++ .../UserManuals/GenCfgOptUserManual.docx | Bin 0 -> 28336 bytes .../Tools/UserManuals/PatchFvUserManual.docx | Bin 0 -> 21481 bytes IntelFsp2WrapperPkg/Contributions.txt | 218 +++ .../FspWrapperNotifyDxe/FspWrapperNotifyDxe.c | 250 +++ .../FspWrapperNotifyDxe.inf | 66 + .../FspWrapperNotifyDxe/LoadBelow4G.c | 152 ++ .../FspmWrapperPeim/FspmWrapperPeim.c | 161 ++ .../FspmWrapperPeim/FspmWrapperPeim.inf | 77 + .../FspsWrapperPeim/FspsWrapperPeim.c | 313 ++++ .../FspsWrapperPeim/FspsWrapperPeim.inf | 79 + .../Include/Library/FspWrapperApiLib.h | 87 + .../Include/Library/FspWrapperApiTestLib.h | 61 + .../Include/Library/FspWrapperHobProcessLib.h | 44 + .../Include/Library/FspWrapperPlatformLib.h | 73 + .../Include/Ppi/FspSiliconInitDone.h | 43 + .../Include/Ppi/TopOfTemporaryRam.h | 20 + IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec | 77 + IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dsc | 87 + .../BaseFspWrapperApiLib.inf | 71 + .../BaseFspWrapperApiLib/FspWrapperApiLib.c | 203 +++ .../IA32/DispatchExecute.c | 58 + .../X64/DispatchExecute.c | 108 ++ .../BaseFspWrapperApiLib/X64/Thunk64To32.S | 230 +++ .../BaseFspWrapperApiLib/X64/Thunk64To32.asm | 230 +++ .../BaseFspWrapperApiTestLibNull.inf | 53 + .../FspWrapperApiTestNull.c | 65 + .../BaseFspWrapperPlatformLibSample.inf | 60 + .../FspWrapperPlatformLibSample.c | 83 + .../FspWrapperApiTest.c | 88 + .../PeiFspWrapperApiTestLib.inf | 56 + .../FspWrapperHobProcessLibSample.c | 390 +++++ .../PeiFspWrapperHobProcessLibSample.inf | 76 + .../FspWrapperPlatformSecLibSample.c | 133 ++ .../Ia32/Fsp.h | 51 + .../Ia32/PeiCoreEntry.S | 130 ++ .../Ia32/PeiCoreEntry.asm | 140 ++ .../Ia32/SecEntry.S | 336 ++++ .../Ia32/SecEntry.asm | 353 ++++ .../Ia32/Stack.S | 77 + .../Ia32/Stack.asm | 82 + .../PlatformInit.c | 45 + .../SecFspWrapperPlatformSecLibSample.inf | 89 + .../SecGetPerformance.c | 90 + .../SecPlatformInformation.c | 84 + .../SecRamInitData.c | 45 + .../SecTempRamDone.c | 52 + 118 files changed, 15633 insertions(+) create mode 100644 IntelFsp2Pkg/Contributions.txt create mode 100644 IntelFsp2Pkg/FspNotifyPhase/FspNotifyPhasePeim.c create mode 100644 IntelFsp2Pkg/FspNotifyPhase/FspNotifyPhasePeim.h create mode 100644 IntelFsp2Pkg/FspNotifyPhase/FspNotifyPhasePeim.inf create mode 100644 IntelFsp2Pkg/FspSecCore/FspSecCoreM.inf create mode 100644 IntelFsp2Pkg/FspSecCore/FspSecCoreS.inf create mode 100644 IntelFsp2Pkg/FspSecCore/FspSecCoreT.inf create mode 100644 IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryCommon.nasm create mode 100644 IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryM.nasm create mode 100644 IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryS.nasm create mode 100644 IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryT.nasm create mode 100644 IntelFsp2Pkg/FspSecCore/Ia32/FspHelper.nasm create mode 100644 IntelFsp2Pkg/FspSecCore/Ia32/InitializeFpu.nasm create mode 100644 IntelFsp2Pkg/FspSecCore/Ia32/MicrocodeLoadNasm.inc create mode 100644 IntelFsp2Pkg/FspSecCore/Ia32/SaveRestoreSseNasm.inc create mode 100644 IntelFsp2Pkg/FspSecCore/Ia32/Stack.nasm create mode 100644 IntelFsp2Pkg/FspSecCore/SecFsp.c create mode 100644 IntelFsp2Pkg/FspSecCore/SecFsp.h create mode 100644 IntelFsp2Pkg/FspSecCore/SecFspApiChk.c create mode 100644 IntelFsp2Pkg/FspSecCore/SecMain.c create mode 100644 IntelFsp2Pkg/FspSecCore/SecMain.h create mode 100644 IntelFsp2Pkg/FspSecCore/Vtf0/Bin/ResetVec.ia32.raw create mode 100644 IntelFsp2Pkg/FspSecCore/Vtf0/Build.py create mode 100644 IntelFsp2Pkg/FspSecCore/Vtf0/Ia16/ResetVec.asm16 create mode 100644 IntelFsp2Pkg/FspSecCore/Vtf0/ResetVectorCode.asm create mode 100644 IntelFsp2Pkg/FspSecCore/Vtf0/Tools/FixupForRawSection.py create mode 100644 IntelFsp2Pkg/Include/FspDataTable.h create mode 100644 IntelFsp2Pkg/Include/FspEas.h create mode 100644 IntelFsp2Pkg/Include/FspEas/FspApi.h create mode 100644 IntelFsp2Pkg/Include/FspGlobalData.h create mode 100644 IntelFsp2Pkg/Include/FspMeasurePointId.h create mode 100644 IntelFsp2Pkg/Include/FspStatusCode.h create mode 100644 IntelFsp2Pkg/Include/Guid/FspHeaderFile.h create mode 100644 IntelFsp2Pkg/Include/Guid/GuidHobFspEas.h create mode 100644 IntelFsp2Pkg/Include/Library/CacheAsRamLib.h create mode 100644 IntelFsp2Pkg/Include/Library/CacheLib.h create mode 100644 IntelFsp2Pkg/Include/Library/DebugDeviceLib.h create mode 100644 IntelFsp2Pkg/Include/Library/FspCommonLib.h create mode 100644 IntelFsp2Pkg/Include/Library/FspPlatformLib.h create mode 100644 IntelFsp2Pkg/Include/Library/FspSecPlatformLib.h create mode 100644 IntelFsp2Pkg/Include/Library/FspSwitchStackLib.h create mode 100644 IntelFsp2Pkg/IntelFsp2Pkg.dec create mode 100644 IntelFsp2Pkg/IntelFsp2Pkg.dsc create mode 100644 IntelFsp2Pkg/Library/BaseCacheAsRamLibNull/BaseCacheAsRamLibNull.inf create mode 100644 IntelFsp2Pkg/Library/BaseCacheAsRamLibNull/DisableCacheAsRamNull.c create mode 100644 IntelFsp2Pkg/Library/BaseCacheLib/BaseCacheLib.inf create mode 100644 IntelFsp2Pkg/Library/BaseCacheLib/CacheLib.c create mode 100644 IntelFsp2Pkg/Library/BaseCacheLib/CacheLibInternal.h create mode 100644 IntelFsp2Pkg/Library/BaseDebugDeviceLibNull/BaseDebugDeviceLibNull.inf create mode 100644 IntelFsp2Pkg/Library/BaseDebugDeviceLibNull/DebugDeviceLibNull.c create mode 100644 IntelFsp2Pkg/Library/BaseFspCommonLib/BaseFspCommonLib.inf create mode 100644 IntelFsp2Pkg/Library/BaseFspCommonLib/FspCommonLib.c create mode 100644 IntelFsp2Pkg/Library/BaseFspDebugLibSerialPort/BaseFspDebugLibSerialPort.inf create mode 100644 IntelFsp2Pkg/Library/BaseFspDebugLibSerialPort/DebugLib.c create mode 100644 IntelFsp2Pkg/Library/BaseFspDebugLibSerialPort/Ia32/FspDebug.asm create mode 100644 IntelFsp2Pkg/Library/BaseFspDebugLibSerialPort/Ia32/FspDebug.s create mode 100644 IntelFsp2Pkg/Library/BaseFspPlatformLib/BaseFspPlatformLib.inf create mode 100644 IntelFsp2Pkg/Library/BaseFspPlatformLib/FspPlatformMemory.c create mode 100644 IntelFsp2Pkg/Library/BaseFspPlatformLib/FspPlatformNotify.c create mode 100644 IntelFsp2Pkg/Library/BaseFspSwitchStackLib/BaseFspSwitchStackLib.inf create mode 100644 IntelFsp2Pkg/Library/BaseFspSwitchStackLib/FspSwitchStackLib.c create mode 100644 IntelFsp2Pkg/Library/BaseFspSwitchStackLib/Ia32/Stack.asm create mode 100644 IntelFsp2Pkg/Library/BaseFspSwitchStackLib/Ia32/Stack.s create mode 100644 IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/Ia32/Flat32.asm create mode 100644 IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/Ia32/Flat32.s create mode 100644 IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/Ia32/SecCarInit.asm create mode 100644 IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/Ia32/SecCarInit.s create mode 100644 IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/PlatformSecLibNull.c create mode 100644 IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/SecFspSecPlatformLibNull.inf create mode 100644 IntelFsp2Pkg/Tools/GenCfgOpt.py create mode 100644 IntelFsp2Pkg/Tools/PatchFv.py create mode 100644 IntelFsp2Pkg/Tools/SplitFspBin.py create mode 100644 IntelFsp2Pkg/Tools/UserManuals/GenCfgOptUserManual.docx create mode 100644 IntelFsp2Pkg/Tools/UserManuals/PatchFvUserManual.docx create mode 100644 IntelFsp2WrapperPkg/Contributions.txt create mode 100644 IntelFsp2WrapperPkg/FspWrapperNotifyDxe/FspWrapperNotifyDxe.c create mode 100644 IntelFsp2WrapperPkg/FspWrapperNotifyDxe/FspWrapperNotifyDxe.inf create mode 100644 IntelFsp2WrapperPkg/FspWrapperNotifyDxe/LoadBelow4G.c create mode 100644 IntelFsp2WrapperPkg/FspmWrapperPeim/FspmWrapperPeim.c create mode 100644 IntelFsp2WrapperPkg/FspmWrapperPeim/FspmWrapperPeim.inf create mode 100644 IntelFsp2WrapperPkg/FspsWrapperPeim/FspsWrapperPeim.c create mode 100644 IntelFsp2WrapperPkg/FspsWrapperPeim/FspsWrapperPeim.inf create mode 100644 IntelFsp2WrapperPkg/Include/Library/FspWrapperApiLib.h create mode 100644 IntelFsp2WrapperPkg/Include/Library/FspWrapperApiTestLib.h create mode 100644 IntelFsp2WrapperPkg/Include/Library/FspWrapperHobProcessLib.h create mode 100644 IntelFsp2WrapperPkg/Include/Library/FspWrapperPlatformLib.h create mode 100644 IntelFsp2WrapperPkg/Include/Ppi/FspSiliconInitDone.h create mode 100644 IntelFsp2WrapperPkg/Include/Ppi/TopOfTemporaryRam.h create mode 100644 IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec create mode 100644 IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dsc create mode 100644 IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/BaseFspWrapperApiLib.inf create mode 100644 IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/FspWrapperApiLib.c create mode 100644 IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/IA32/DispatchExecute.c create mode 100644 IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/X64/DispatchExecute.c create mode 100644 IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/X64/Thunk64To32.S create mode 100644 IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/X64/Thunk64To32.asm create mode 100644 IntelFsp2WrapperPkg/Library/BaseFspWrapperApiTestLibNull/BaseFspWrapperApiTestLibNull.inf create mode 100644 IntelFsp2WrapperPkg/Library/BaseFspWrapperApiTestLibNull/FspWrapperApiTestNull.c create mode 100644 IntelFsp2WrapperPkg/Library/BaseFspWrapperPlatformLibSample/BaseFspWrapperPlatformLibSample.inf create mode 100644 IntelFsp2WrapperPkg/Library/BaseFspWrapperPlatformLibSample/FspWrapperPlatformLibSample.c create mode 100644 IntelFsp2WrapperPkg/Library/PeiFspWrapperApiTestLib/FspWrapperApiTest.c create mode 100644 IntelFsp2WrapperPkg/Library/PeiFspWrapperApiTestLib/PeiFspWrapperApiTestLib.inf create mode 100644 IntelFsp2WrapperPkg/Library/PeiFspWrapperHobProcessLibSample/FspWrapperHobProcessLibSample.c create mode 100644 IntelFsp2WrapperPkg/Library/PeiFspWrapperHobProcessLibSample/PeiFspWrapperHobProcessLibSample.inf create mode 100644 IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/FspWrapperPlatformSecLibSample.c create mode 100644 IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/Fsp.h create mode 100644 IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/PeiCoreEntry.S create mode 100644 IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/PeiCoreEntry.asm create mode 100644 IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/SecEntry.S create mode 100644 IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/SecEntry.asm create mode 100644 IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/Stack.S create mode 100644 IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/Stack.asm create mode 100644 IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/PlatformInit.c create mode 100644 IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/SecFspWrapperPlatformSecLibSample.inf create mode 100644 IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/SecGetPerformance.c create mode 100644 IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/SecPlatformInformation.c create mode 100644 IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/SecRamInitData.c create mode 100644 IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/SecTempRamDone.c diff --git a/IntelFsp2Pkg/Contributions.txt b/IntelFsp2Pkg/Contributions.txt new file mode 100644 index 0000000000..f87cbd73c6 --- /dev/null +++ b/IntelFsp2Pkg/Contributions.txt @@ -0,0 +1,218 @@ + +====================== += Code Contributions = +====================== + +To make a contribution to a TianoCore project, follow these steps. +1. Create a change description in the format specified below to + use in the source control commit log. +2. Your commit message must include your "Signed-off-by" signature, + and "Contributed-under" message. +3. Your "Contributed-under" message explicitly states that the + contribution is made under the terms of the specified + contribution agreement. Your "Contributed-under" message + must include the name of contribution agreement and version. + For example: Contributed-under: TianoCore Contribution Agreement 1.0 + The "TianoCore Contribution Agreement" is included below in + this document. +4. Submit your code to the TianoCore project using the process + that the project documents on its web page. If the process is + not documented, then submit the code on development email list + for the project. +5. It is preferred that contributions are submitted using the same + copyright license as the base project. When that is not possible, + then contributions using the following licenses can be accepted: + * BSD (2-clause): http://opensource.org/licenses/BSD-2-Clause + * BSD (3-clause): http://opensource.org/licenses/BSD-3-Clause + * MIT: http://opensource.org/licenses/MIT + * Python-2.0: http://opensource.org/licenses/Python-2.0 + * Zlib: http://opensource.org/licenses/Zlib + + Contributions of code put into the public domain can also be + accepted. + + Contributions using other licenses might be accepted, but further + review will be required. + +===================================================== += Change Description / Commit Message / Patch Email = +===================================================== + +Your change description should use the standard format for a +commit message, and must include your "Signed-off-by" signature +and the "Contributed-under" message. + +== Sample Change Description / Commit Message = + +=== Start of sample patch email message === + +From: Contributor Name +Subject: [PATCH] CodeModule: Brief-single-line-summary + +Full-commit-message + +Contributed-under: TianoCore Contribution Agreement 1.0 +Signed-off-by: Contributor Name +--- + +An extra message for the patch email which will not be considered part +of the commit message can be added here. + +Patch content inline or attached + +=== End of sample patch email message === + +=== Notes for sample patch email === + +* The first line of commit message is taken from the email's subject + line following [PATCH]. The remaining portion of the commit message + is the email's content until the '---' line. +* git format-patch is one way to create this format + +=== Definitions for sample patch email === + +* "CodeModule" is a short idenfier for the affected code. For + example MdePkg, or MdeModulePkg UsbBusDxe. +* "Brief-single-line-summary" is a short summary of the change. +* The entire first line should be less than ~70 characters. +* "Full-commit-message" a verbose multiple line comment describing + the change. Each line should be less than ~70 characters. +* "Contributed-under" explicitely states that the contribution is + made under the terms of the contribtion agreement. This + agreement is included below in this document. +* "Signed-off-by" is the contributor's signature identifying them + by their real/legal name and their email address. + +======================================== += TianoCore Contribution Agreement 1.0 = +======================================== + +INTEL CORPORATION ("INTEL") MAKES AVAILABLE SOFTWARE, DOCUMENTATION, +INFORMATION AND/OR OTHER MATERIALS FOR USE IN THE TIANOCORE OPEN SOURCE +PROJECT (COLLECTIVELY "CONTENT"). USE OF THE CONTENT IS GOVERNED BY THE +TERMS AND CONDITIONS OF THIS AGREEMENT BETWEEN YOU AND INTEL AND/OR THE +TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR +REFERENCED BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE OF THE +CONTENT IS GOVERNED BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS +OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED +BELOW. IF YOU DO NOT AGREE TO THE TERMS AND CONDITIONS OF THIS +AGREEMENT AND THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE +AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU MAY NOT +USE THE CONTENT. + +Unless otherwise indicated, all Content made available on the TianoCore +site is provided to you under the terms and conditions of the BSD +License ("BSD"). A copy of the BSD License is available at +http://opensource.org/licenses/bsd-license.php +or when applicable, in the associated License.txt file. + +Certain other content may be made available under other licenses as +indicated in or with such Content. (For example, in a License.txt file.) + +You accept and agree to the following terms and conditions for Your +present and future Contributions submitted to TianoCore site. Except +for the license granted to Intel hereunder, You reserve all right, +title, and interest in and to Your Contributions. + +== SECTION 1: Definitions == +* "You" or "Contributor" shall mean the copyright owner or legal + entity authorized by the copyright owner that is making a + Contribution hereunder. All other entities that control, are + controlled by, or are under common control with that entity are + considered to be a single Contributor. For the purposes of this + definition, "control" means (i) the power, direct or indirect, to + cause the direction or management of such entity, whether by + contract or otherwise, or (ii) ownership of fifty percent (50%) + or more of the outstanding shares, or (iii) beneficial ownership + of such entity. +* "Contribution" shall mean any original work of authorship, + including any modifications or additions to an existing work, + that is intentionally submitted by You to the TinaoCore site for + inclusion in, or documentation of, any of the Content. For the + purposes of this definition, "submitted" means any form of + electronic, verbal, or written communication sent to the + TianoCore site or its representatives, including but not limited + to communication on electronic mailing lists, source code + control systems, and issue tracking systems that are managed by, + or on behalf of, the TianoCore site for the purpose of + discussing and improving the Content, but excluding + communication that is conspicuously marked or otherwise + designated in writing by You as "Not a Contribution." + +== SECTION 2: License for Contributions == +* Contributor hereby agrees that redistribution and use of the + Contribution in source and binary forms, with or without + modification, are permitted provided that the following + conditions are met: +** Redistributions of source code must retain the Contributor's + copyright notice, this list of conditions and the following + disclaimer. +** Redistributions in binary form must reproduce the Contributor's + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. +* Disclaimer. None of the names of Contributor, Intel, or the names + of their respective contributors may be used to endorse or + promote products derived from this software without specific + prior written permission. +* Contributor grants a license (with the right to sublicense) under + claims of Contributor's patents that Contributor can license that + are infringed by the Contribution (as delivered by Contributor) to + make, use, distribute, sell, offer for sale, and import the + Contribution and derivative works thereof solely to the minimum + extent necessary for licensee to exercise the granted copyright + license; this patent license applies solely to those portions of + the Contribution that are unmodified. No hardware per se is + licensed. +* EXCEPT AS EXPRESSLY SET FORTH IN SECTION 3 BELOW, THE + CONTRIBUTION IS PROVIDED BY THE CONTRIBUTOR "AS IS" AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + CONTRIBUTOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THE + CONTRIBUTION, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + DAMAGE. + +== SECTION 3: Representations == +* You represent that You are legally entitled to grant the above + license. If your employer(s) has rights to intellectual property + that You create that includes Your Contributions, You represent + that You have received permission to make Contributions on behalf + of that employer, that Your employer has waived such rights for + Your Contributions. +* You represent that each of Your Contributions is Your original + creation (see Section 4 for submissions on behalf of others). + You represent that Your Contribution submissions include complete + details of any third-party license or other restriction + (including, but not limited to, related patents and trademarks) + of which You are personally aware and which are associated with + any part of Your Contributions. + +== SECTION 4: Third Party Contributions == +* Should You wish to submit work that is not Your original creation, + You may submit it to TianoCore site separately from any + Contribution, identifying the complete details of its source + and of any license or other restriction (including, but not + limited to, related patents, trademarks, and license agreements) + of which You are personally aware, and conspicuously marking the + work as "Submitted on behalf of a third-party: [named here]". + +== SECTION 5: Miscellaneous == +* Applicable Laws. Any claims arising under or relating to this + Agreement shall be governed by the internal substantive laws of + the State of Delaware or federal courts located in Delaware, + without regard to principles of conflict of laws. +* Language. This Agreement is in the English language only, which + language shall be controlling in all respects, and all versions + of this Agreement in any other language shall be for accommodation + only and shall not be binding. All communications and notices made + or given pursuant to this Agreement, and all documentation and + support to be provided, unless otherwise noted, shall be in the + English language. + diff --git a/IntelFsp2Pkg/FspNotifyPhase/FspNotifyPhasePeim.c b/IntelFsp2Pkg/FspNotifyPhase/FspNotifyPhasePeim.c new file mode 100644 index 0000000000..6acdeb3b60 --- /dev/null +++ b/IntelFsp2Pkg/FspNotifyPhase/FspNotifyPhasePeim.c @@ -0,0 +1,142 @@ +/** @file + Source file for FSP notify phase PEI module + + Copyright (c) 2016, Intel Corporation. All rights reserved. + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +**/ + +#include "FspNotifyPhasePeim.h" + +/** + + This function waits for FSP notify. + + @param This Entry point for DXE IPL PPI. + @param PeiServices General purpose services available to every PEIM. + @param HobList Address to the Pei HOB list. + + @return EFI_SUCCESS This function never returns. + +**/ +EFI_STATUS +EFIAPI +WaitForNotify ( + IN CONST EFI_DXE_IPL_PPI *This, + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_HOB_POINTERS HobList + ); + +CONST EFI_DXE_IPL_PPI mDxeIplPpi = { + WaitForNotify +}; + +CONST EFI_PEI_PPI_DESCRIPTOR mInstallDxeIplPpi = { + EFI_PEI_PPI_DESCRIPTOR_PPI, + &gEfiDxeIplPpiGuid, + (VOID *) &mDxeIplPpi +}; + +CONST EFI_PEI_PPI_DESCRIPTOR gEndOfPeiSignalPpi = { + (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gEfiEndOfPeiSignalPpiGuid, + NULL +}; + +/** + + This function waits for FSP notify. + + @param This Entry point for DXE IPL PPI. + @param PeiServices General purpose services available to every PEIM. + @param HobList Address to the Pei HOB list. + + @return EFI_SUCCESS This function never returns. + +**/ +EFI_STATUS +EFIAPI +WaitForNotify ( + IN CONST EFI_DXE_IPL_PPI *This, + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_HOB_POINTERS HobList + ) +{ + EFI_STATUS Status; + + DEBUG ((DEBUG_INFO | DEBUG_INIT, "FSP HOB is located at 0x%08X\n", HobList)); + + // + // End of PEI phase signal + // + Status = PeiServicesInstallPpi (&gEndOfPeiSignalPpi); + ASSERT_EFI_ERROR (Status); + + // + // Give control back to BootLoader after FspSiliconInit + // + DEBUG ((DEBUG_INFO | DEBUG_INIT, "FSP is waiting for NOTIFY\n")); + FspSiliconInitDone (); + + // + // BootLoader called FSP again through NotifyPhase + // + FspWaitForNotify (); + + // + // Should not come here + // + while (TRUE) { + DEBUG ((DEBUG_ERROR, "No FSP API should be called after FSP is DONE!\n")); + SetFspApiReturnStatus (EFI_UNSUPPORTED); + Pei2LoaderSwitchStack (); + } + + return EFI_SUCCESS; +} + +/** + FSP notify phase PEI module entry point + + @param[in] FileHandle Not used. + @param[in] PeiServices General purpose services available to every PEIM. + + @retval EFI_SUCCESS The function completes successfully + @retval EFI_OUT_OF_RESOURCES Insufficient resources to create database +**/ +EFI_STATUS +FspNotifyPhasePeimEntryPoint ( + IN EFI_PEI_FILE_HANDLE FileHandle, + IN CONST EFI_PEI_SERVICES **PeiServices + ) +{ + EFI_STATUS Status; + VOID *OldDxeIplPpi; + EFI_PEI_PPI_DESCRIPTOR *OldDescriptor; + + DEBUG ((DEBUG_INFO | DEBUG_INIT, "The entry of FspNotificationPeim\n")); + + // + // Locate old DXE IPL PPI + // + Status = PeiServicesLocatePpi ( + &gEfiDxeIplPpiGuid, + 0, + &OldDescriptor, + &OldDxeIplPpi + ); + ASSERT_EFI_ERROR (Status); + + // + // Re-install the DXE IPL PPI to wait for notify + // + Status = PeiServicesReInstallPpi (OldDescriptor, &mInstallDxeIplPpi); + ASSERT_EFI_ERROR (Status); + + return EFI_SUCCESS; +} diff --git a/IntelFsp2Pkg/FspNotifyPhase/FspNotifyPhasePeim.h b/IntelFsp2Pkg/FspNotifyPhase/FspNotifyPhasePeim.h new file mode 100644 index 0000000000..6e2ae591ec --- /dev/null +++ b/IntelFsp2Pkg/FspNotifyPhase/FspNotifyPhasePeim.h @@ -0,0 +1,23 @@ +/** @file + Header file for FSP notify phase PEI module + + Copyright (c) 2016 Intel Corporation. All rights reserved. + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +**/ + +#ifndef _FSP_NOTIFY_PHASE_PEIM_H_ +#define _FSP_NOTIFY_PHASE_PEIM_H_ + +#include +#include +#include +#include +#include +#include +#endif diff --git a/IntelFsp2Pkg/FspNotifyPhase/FspNotifyPhasePeim.inf b/IntelFsp2Pkg/FspNotifyPhase/FspNotifyPhasePeim.inf new file mode 100644 index 0000000000..75f7ae5fb7 --- /dev/null +++ b/IntelFsp2Pkg/FspNotifyPhase/FspNotifyPhasePeim.inf @@ -0,0 +1,49 @@ +## @file +# Component information file for the FSP notify phase PEI module. +# +#@copyright +# Copyright (c) 2016 Intel Corporation. All rights reserved. +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = FspNotifyPhasePeim + FILE_GUID = 29CBB005-C972-49F3-960F-292E2202CECD + MODULE_TYPE = PEIM + VERSION_STRING = 1.0 + ENTRY_POINT = FspNotifyPhasePeimEntryPoint + +[Sources] + FspNotifyPhasePeim.h + FspNotifyPhasePeim.c + +[Packages] + MdePkg/MdePkg.dec + IntelFsp2Pkg/IntelFsp2Pkg.dec + +[LibraryClasses] + PeimEntryPoint + DebugLib + FspPlatformLib + FspCommonLib + FspSwitchStackLib + +[Ppis] + gEfiDxeIplPpiGuid ## PRODUCES + gEfiEndOfPeiSignalPpiGuid ## PRODUCES + +[Protocols] + gEfiPciEnumerationCompleteProtocolGuid ## PRODUCES + +[Guids] + gEfiEventReadyToBootGuid ## PRODUCES ## Event + +[Depex] + gEfiDxeIplPpiGuid diff --git a/IntelFsp2Pkg/FspSecCore/FspSecCoreM.inf b/IntelFsp2Pkg/FspSecCore/FspSecCoreM.inf new file mode 100644 index 0000000000..611fab215a --- /dev/null +++ b/IntelFsp2Pkg/FspSecCore/FspSecCoreM.inf @@ -0,0 +1,74 @@ +## @file +# Sec Core for FSP +# +# Copyright (c) 2016, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = FspSecCoreM + FILE_GUID = C2F9AE46-3437-4FEF-9CB1-9A568B282FEE + MODULE_TYPE = SEC + VERSION_STRING = 1.0 + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 +# + +[Sources] + SecMain.c + SecMain.h + SecFsp.c + SecFsp.h + SecFspApiChk.c + +[Sources.IA32] + Ia32/Stack.nasm + Ia32/InitializeFpu.nasm + Ia32/FspApiEntryM.nasm + Ia32/FspApiEntryCommon.nasm + Ia32/FspHelper.nasm + +[Binaries.Ia32] + RAW|Vtf0/Bin/ResetVec.ia32.raw |GCC + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + IntelFsp2Pkg/IntelFsp2Pkg.dec + +[LibraryClasses] + BaseMemoryLib + DebugLib + BaseLib + PciCf8Lib + SerialPortLib + FspSwitchStackLib + FspCommonLib + FspSecPlatformLib + +[Pcd] + gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress ## UNDEFINED + gIntelFsp2PkgTokenSpaceGuid.PcdGlobalDataPointerAddress ## CONSUMES + gIntelFsp2PkgTokenSpaceGuid.PcdTemporaryRamBase ## CONSUMES + gIntelFsp2PkgTokenSpaceGuid.PcdTemporaryRamSize ## CONSUMES + gIntelFsp2PkgTokenSpaceGuid.PcdFspTemporaryRamSize ## CONSUMES + gIntelFsp2PkgTokenSpaceGuid.PcdFspHeapSizePercentage ## CONSUMES + +[FixedPcd] + gIntelFsp2PkgTokenSpaceGuid.PcdFspMaxPatchEntry ## CONSUMES + gIntelFsp2PkgTokenSpaceGuid.PcdFspMaxPerfEntry ## CONSUMES + +[Ppis] + gEfiTemporaryRamSupportPpiGuid ## PRODUCES + diff --git a/IntelFsp2Pkg/FspSecCore/FspSecCoreS.inf b/IntelFsp2Pkg/FspSecCore/FspSecCoreS.inf new file mode 100644 index 0000000000..8e1bb4a592 --- /dev/null +++ b/IntelFsp2Pkg/FspSecCore/FspSecCoreS.inf @@ -0,0 +1,68 @@ +## @file +# Sec Core for FSP +# +# Copyright (c) 2016, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = FspSecCoreS + FILE_GUID = 53AB1ACD-EDB1-4E3A-A2C7-978D721D179D + MODULE_TYPE = SEC + VERSION_STRING = 1.0 + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 +# + +[Sources] + SecFspApiChk.c + +[Sources.IA32] + Ia32/Stack.nasm + Ia32/FspApiEntryS.nasm + Ia32/FspApiEntryCommon.nasm + Ia32/FspHelper.nasm + +[Binaries.Ia32] + RAW|Vtf0/Bin/ResetVec.ia32.raw |GCC + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + IntelFsp2Pkg/IntelFsp2Pkg.dec + +[LibraryClasses] + BaseMemoryLib + DebugLib + BaseLib + PciCf8Lib + SerialPortLib + FspSwitchStackLib + FspCommonLib + FspSecPlatformLib + +[Pcd] + gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress ## UNDEFINED + gIntelFsp2PkgTokenSpaceGuid.PcdGlobalDataPointerAddress ## CONSUMES + gIntelFsp2PkgTokenSpaceGuid.PcdTemporaryRamBase ## CONSUMES + gIntelFsp2PkgTokenSpaceGuid.PcdTemporaryRamSize ## CONSUMES + gIntelFsp2PkgTokenSpaceGuid.PcdFspTemporaryRamSize ## CONSUMES + +[FixedPcd] + gIntelFsp2PkgTokenSpaceGuid.PcdFspMaxPatchEntry ## CONSUMES + gIntelFsp2PkgTokenSpaceGuid.PcdFspMaxPerfEntry ## CONSUMES + +[Ppis] + gEfiTemporaryRamSupportPpiGuid ## PRODUCES + diff --git a/IntelFsp2Pkg/FspSecCore/FspSecCoreT.inf b/IntelFsp2Pkg/FspSecCore/FspSecCoreT.inf new file mode 100644 index 0000000000..cf6a1918a3 --- /dev/null +++ b/IntelFsp2Pkg/FspSecCore/FspSecCoreT.inf @@ -0,0 +1,66 @@ +## @file +# Sec Core for FSP +# +# Copyright (c) 2016, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = FspSecCoreT + FILE_GUID = 5B94E419-C795-414D-A0D4-B80A877BE5FE + MODULE_TYPE = SEC + VERSION_STRING = 1.0 + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 +# + +[Sources] + + +[Sources.IA32] + Ia32/Stack.nasm + Ia32/InitializeFpu.nasm + Ia32/FspApiEntryT.nasm + Ia32/FspHelper.nasm + +[Binaries.Ia32] + RAW|Vtf0/Bin/ResetVec.ia32.raw |GCC + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + IntelFsp2Pkg/IntelFsp2Pkg.dec + +[LibraryClasses] + BaseMemoryLib + DebugLib + BaseLib + PciCf8Lib + SerialPortLib + FspSwitchStackLib + FspCommonLib + FspSecPlatformLib + +[Pcd] + gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress ## UNDEFINED + gIntelFsp2PkgTokenSpaceGuid.PcdTemporaryRamBase ## CONSUMES + gIntelFsp2PkgTokenSpaceGuid.PcdTemporaryRamSize ## CONSUMES + gIntelFsp2PkgTokenSpaceGuid.PcdFspReservedBufferSize ## CONSUMES + +[FixedPcd] + gIntelFsp2PkgTokenSpaceGuid.PcdFspMaxPatchEntry ## CONSUMES + gIntelFsp2PkgTokenSpaceGuid.PcdFspMaxPerfEntry ## CONSUMES + +[Ppis] + gEfiTemporaryRamSupportPpiGuid ## PRODUCES diff --git a/IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryCommon.nasm b/IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryCommon.nasm new file mode 100644 index 0000000000..c48a95694c --- /dev/null +++ b/IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryCommon.nasm @@ -0,0 +1,76 @@ +;; @file +; Provide FSP API entry points. +; +; Copyright (c) 2016, Intel Corporation. All rights reserved.
+; This program and the accompanying materials +; are licensed and made available under the terms and conditions of the BSD License +; which accompanies this distribution. The full text of the license may be found at +; http://opensource.org/licenses/bsd-license.php. +; +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +;; + + SECTION .text + +; +; Following functions will be provided in C +; +extern ASM_PFX(Loader2PeiSwitchStack) +extern ASM_PFX(FspApiCallingCheck) + +; +; Following functions will be provided in ASM +; +extern ASM_PFX(FspApiCommonContinue) +extern ASM_PFX(AsmGetFspInfoHeader) + +;---------------------------------------------------------------------------- +; FspApiCommon API +; +; This is the FSP API common entry point to resume the FSP execution +; +;---------------------------------------------------------------------------- +global ASM_PFX(FspApiCommon) +ASM_PFX(FspApiCommon): + ; + ; EAX holds the API index + ; + + ; + ; Stack must be ready + ; + push eax + add esp, 4 + cmp eax, dword [esp - 4] + jz FspApiCommon1 + mov eax, 080000003h + jmp exit + +FspApiCommon1: + ; + ; Verify the calling condition + ; + pushad + push DWORD [esp + (4 * 8 + 4)] ; push ApiParam + push eax ; push ApiIdx + call ASM_PFX(FspApiCallingCheck) + add esp, 8 + cmp eax, 0 + jz FspApiCommon2 + mov dword [esp + (4 * 7)], eax + popad +exit: + ret + +FspApiCommon2: + popad + cmp eax, 3 ; FspMemoryInit API + jz FspApiCommon3 + + call ASM_PFX(AsmGetFspInfoHeader) + jmp ASM_PFX(Loader2PeiSwitchStack) + +FspApiCommon3: + jmp ASM_PFX(FspApiCommonContinue) + diff --git a/IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryM.nasm b/IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryM.nasm new file mode 100644 index 0000000000..9744e1682d --- /dev/null +++ b/IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryM.nasm @@ -0,0 +1,202 @@ +;; @file +; Provide FSP API entry points. +; +; Copyright (c) 2016, Intel Corporation. All rights reserved.
+; This program and the accompanying materials +; are licensed and made available under the terms and conditions of the BSD License +; which accompanies this distribution. The full text of the license may be found at +; http://opensource.org/licenses/bsd-license.php. +; +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +;; + + SECTION .text + +; +; Following are fixed PCDs +; +extern ASM_PFX(PcdGet32(PcdTemporaryRamBase)) +extern ASM_PFX(PcdGet32(PcdTemporaryRamSize)) +extern ASM_PFX(PcdGet32(PcdFspTemporaryRamSize)) + +struc FSPM_UPD_COMMON + ; FSP_UPD_HEADER { + .FspUpdHeader: resd 8 + ; } + ; FSPM_ARCH_UPD { + .Revision: resb 1 + .Reserved: resb 3 + .NvsBufferPtr: resd 1 + .StackBase: resd 1 + .StackSize: resd 1 + .BootLoaderTolumSize: resd 1 + .BootMode: resd 1 + .Reserved1: resb 8 + ; } + .size: +endstruc + +; +; Following functions will be provided in C +; +extern ASM_PFX(SecStartup) +extern ASM_PFX(FspApiCommon) + +; +; Following functions will be provided in PlatformSecLib +; +extern ASM_PFX(AsmGetFspBaseAddress) +extern ASM_PFX(AsmGetFspInfoHeader) + +API_PARAM1_OFFSET EQU 34h ; ApiParam1 [ sub esp,8 + pushad + pushfd + push eax + call] +FSP_HEADER_IMGBASE_OFFSET EQU 1Ch +FSP_HEADER_CFGREG_OFFSET EQU 24h + +;---------------------------------------------------------------------------- +; FspMemoryInit API +; +; This FSP API is called after TempRamInit and initializes the memory. +; +;---------------------------------------------------------------------------- +global ASM_PFX(FspMemoryInitApi) +ASM_PFX(FspMemoryInitApi): + mov eax, 3 ; FSP_API_INDEX.FspMemoryInitApiIndex + jmp ASM_PFX(FspApiCommon) + +;---------------------------------------------------------------------------- +; TempRamExitApi API +; +; This API tears down temporary RAM +; +;---------------------------------------------------------------------------- +global ASM_PFX(TempRamExitApi) +ASM_PFX(TempRamExitApi): + mov eax, 4 ; FSP_API_INDEX.TempRamExitApiIndex + jmp ASM_PFX(FspApiCommon) + +;---------------------------------------------------------------------------- +; FspApiCommonContinue API +; +; This is the FSP API common entry point to resume the FSP execution +; +;---------------------------------------------------------------------------- +global ASM_PFX(FspApiCommonContinue) +ASM_PFX(FspApiCommonContinue): + ; + ; EAX holds the API index + ; + + ; + ; FspMemoryInit API setup the initial stack frame + ; + + ; + ; Place holder to store the FspInfoHeader pointer + ; + push eax + + ; + ; Update the FspInfoHeader pointer + ; + push eax + call ASM_PFX(AsmGetFspInfoHeader) + mov [esp + 4], eax + pop eax + + ; + ; Create a Task Frame in the stack for the Boot Loader + ; + pushfd ; 2 pushf for 4 byte alignment + cli + pushad + + ; Reserve 8 bytes for IDT save/restore + sub esp, 8 + sidt [esp] + + + ; Get Stackbase and StackSize from FSPM_UPD Param + mov edx, [esp + API_PARAM1_OFFSET] + cmp edx, 0 + jnz FspStackSetup + + ; Get UPD default values if FspmUpdDataPtr (ApiParam1) is null + push eax + call ASM_PFX(AsmGetFspInfoHeader) + mov edx, [eax + FSP_HEADER_IMGBASE_OFFSET] + add edx, [eax + FSP_HEADER_CFGREG_OFFSET] + pop eax + + FspStackSetup: + mov edi, [edx + FSPM_UPD_COMMON.StackBase] + mov ecx, [edx + FSPM_UPD_COMMON.StackSize] + add edi, ecx + ; + ; Setup new FSP stack + ; + xchg edi, esp ; Exchange edi and esp, edi will be assigned to the current esp pointer and esp will be Stack base + Stack size + mov ebx, esp ; Put Stack base + Stack size in ebx + + ; + ; Pass the API Idx to SecStartup + ; + push eax + + ; + ; Pass the BootLoader stack to SecStartup + ; + push edi + + ; + ; Pass entry point of the PEI core + ; + call ASM_PFX(AsmGetFspBaseAddress) + mov edi, eax + call ASM_PFX(AsmGetPeiCoreOffset) + add edi, eax + push edi + + ; + ; Pass BFV into the PEI Core + ; It uses relative address to calucate the actual boot FV base + ; For FSP implementation with single FV, PcdFspBootFirmwareVolumeBase and + ; PcdFspAreaBaseAddress are the same. For FSP with mulitple FVs, + ; they are different. The code below can handle both cases. + ; + call ASM_PFX(AsmGetFspBaseAddress) + push eax + + ; + ; Pass stack base and size into the PEI Core + ; + sub ebx, ecx ; Stack base + Stack size - Stack size + push ebx + push ecx + + ; + ; Pass Control into the PEI Core + ; + call ASM_PFX(SecStartup) + add esp, 4 +exit: + ret + +global ASM_PFX(FspPeiCoreEntryOff) +ASM_PFX(FspPeiCoreEntryOff): + ; + ; This value will be pached by the build script + ; + DD 0x12345678 + +global ASM_PFX(AsmGetPeiCoreOffset) +ASM_PFX(AsmGetPeiCoreOffset): + mov eax, dword [ASM_PFX(FspPeiCoreEntryOff)] + ret + +;---------------------------------------------------------------------------- +; Module Entrypoint API +;---------------------------------------------------------------------------- +global ASM_PFX(_ModuleEntryPoint) +ASM_PFX(_ModuleEntryPoint): + jmp $ diff --git a/IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryS.nasm b/IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryS.nasm new file mode 100644 index 0000000000..cdc1149d6c --- /dev/null +++ b/IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryS.nasm @@ -0,0 +1,62 @@ +;; @file +; Provide FSP API entry points. +; +; Copyright (c) 2016, Intel Corporation. All rights reserved.
+; This program and the accompanying materials +; are licensed and made available under the terms and conditions of the BSD License +; which accompanies this distribution. The full text of the license may be found at +; http://opensource.org/licenses/bsd-license.php. +; +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +;; + + SECTION .text + +; +; Following functions will be provided in C +; +extern ASM_PFX(FspApiCommon) + +;---------------------------------------------------------------------------- +; NotifyPhase API +; +; This FSP API will notify the FSP about the different phases in the boot +; process +; +;---------------------------------------------------------------------------- +global ASM_PFX(NotifyPhaseApi) +ASM_PFX(NotifyPhaseApi): + mov eax, 2 ; FSP_API_INDEX.NotifyPhaseApiIndex + jmp ASM_PFX(FspApiCommon) + +;---------------------------------------------------------------------------- +; FspSiliconInit API +; +; This FSP API initializes the CPU and the chipset including the IO +; controllers in the chipset to enable normal operation of these devices. +; +;---------------------------------------------------------------------------- +global ASM_PFX(FspSiliconInitApi) +ASM_PFX(FspSiliconInitApi): + mov eax, 5 ; FSP_API_INDEX.FspSiliconInitApiIndex + jmp ASM_PFX(FspApiCommon) + +;---------------------------------------------------------------------------- +; FspApiCommonContinue API +; +; This is the FSP API common entry point to resume the FSP execution +; +;---------------------------------------------------------------------------- +global ASM_PFX(FspApiCommonContinue) +ASM_PFX(FspApiCommonContinue): + jmp $ + ret + +;---------------------------------------------------------------------------- +; Module Entrypoint API +;---------------------------------------------------------------------------- +global ASM_PFX(_ModuleEntryPoint) +ASM_PFX(_ModuleEntryPoint): + jmp $ + diff --git a/IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryT.nasm b/IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryT.nasm new file mode 100644 index 0000000000..55ee85a06e --- /dev/null +++ b/IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryT.nasm @@ -0,0 +1,469 @@ +;; @file +; Provide FSP API entry points. +; +; Copyright (c) 2016, Intel Corporation. All rights reserved.
+; This program and the accompanying materials +; are licensed and made available under the terms and conditions of the BSD License +; which accompanies this distribution. The full text of the license may be found at +; http://opensource.org/licenses/bsd-license.php. +; +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +;; + + SECTION .text + +%include "SaveRestoreSseNasm.inc" +%include "MicrocodeLoadNasm.inc" + +; +; Following are fixed PCDs +; +extern ASM_PFX(PcdGet32 (PcdTemporaryRamBase)) +extern ASM_PFX(PcdGet32 (PcdTemporaryRamSize)) +extern ASM_PFX(PcdGet32 (PcdFspReservedBufferSize)) + +; +; Following functions will be provided in PlatformSecLib +; +extern ASM_PFX(AsmGetFspBaseAddress) +extern ASM_PFX(AsmGetFspInfoHeader) +;extern ASM_PFX(LoadMicrocode) ; @todo: needs a weak implementation +extern ASM_PFX(SecPlatformInit) ; @todo: needs a weak implementation +extern ASM_PFX(SecCarInit) + +; +; Define the data length that we saved on the stack top +; +DATA_LEN_OF_PER0 EQU 18h +DATA_LEN_OF_MCUD EQU 18h +DATA_LEN_AT_STACK_TOP EQU (DATA_LEN_OF_PER0 + DATA_LEN_OF_MCUD + 4) + +; +; @todo: These structures are moved from MicrocodeLoadNasm.inc to avoid +; build error. This needs to be fixed later on. +; +struc MicrocodeHdr + .MicrocodeHdrVersion: resd 1 + .MicrocodeHdrRevision: resd 1 + .MicrocodeHdrDate: resd 1 + .MicrocodeHdrProcessor: resd 1 + .MicrocodeHdrChecksum: resd 1 + .MicrocodeHdrLoader: resd 1 + .MicrocodeHdrFlags: resd 1 + .MicrocodeHdrDataSize: resd 1 + .MicrocodeHdrTotalSize: resd 1 + .MicrocodeHdrRsvd: resd 3 + .size: +endstruc + +struc ExtSigHdr + .ExtSigHdrCount: resd 1 + .ExtSigHdrChecksum: resd 1 + .ExtSigHdrRsvd: resd 3 + .size: +endstruc + +struc ExtSig + .ExtSigProcessor: resd 1 + .ExtSigFlags: resd 1 + .ExtSigChecksum: resd 1 + .size: +endstruc + +struc LoadMicrocodeParams + ; FSP_UPD_HEADER { + .FspUpdHeader: resd 8 + ; } + ; FSPT_CORE_UPD { + .MicrocodeCodeAddr: resd 1 + .MicrocodeCodeSize: resd 1 + .CodeRegionBase: resd 1 + .CodeRegionSize: resd 1 + ; } + .size: +endstruc + + +; +; Define SSE macros +; +; +;args 1: ReturnAddress 2:MmxRegister +; +%macro LOAD_MMX_EXT 2 + mov esi, %1 + movd %2, esi ; save ReturnAddress into MMX +%endmacro + +; +;args 1: RoutineLabel 2:MmxRegister +; +%macro CALL_MMX_EXT 2 + mov esi, %%ReturnAddress + movd %2, esi ; save ReturnAddress into MMX + jmp %1 +%%ReturnAddress: +%endmacro + +; +;arg 1:MmxRegister +; +%macro RET_ESI_EXT 1 + movd esi, %1 ; move ReturnAddress from MMX to ESI + jmp esi +%endmacro + +; +;arg 1:RoutineLabel +; +%macro CALL_MMX 1 + CALL_MMX_EXT %1, mm7 +%endmacro + +%macro RET_ESI 0 + RET_ESI_EXT mm7 +%endmacro + +; +; @todo: The strong/weak implementation does not work. +; This needs to be reviewed later. +; +;------------------------------------------------------------------------------ +; +;;global ASM_PFX(SecPlatformInitDefault) +;ASM_PFX(SecPlatformInitDefault): +; ; Inputs: +; ; mm7 -> Return address +; ; Outputs: +; ; eax -> 0 - Successful, Non-zero - Failed. +; ; Register Usage: +; ; eax is cleared and ebp is used for return address. +; ; All others reserved. +; +; ; Save return address to EBP +; movd ebp, mm7 +; +; xor eax, eax +;Exit1: +; jmp ebp + +;------------------------------------------------------------------------------ +global ASM_PFX(LoadMicrocodeDefault) +ASM_PFX(LoadMicrocodeDefault): + ; Inputs: + ; esp -> LoadMicrocodeParams pointer + ; Register Usage: + ; esp Preserved + ; All others destroyed + ; Assumptions: + ; No memory available, stack is hard-coded and used for return address + ; Executed by SBSP and NBSP + ; Beginning of microcode update region starts on paragraph boundary + + ; + ; + ; Save return address to EBP + movd ebp, mm7 + + cmp esp, 0 + jz ParamError + mov eax, dword [esp + 4] ; Parameter pointer + cmp eax, 0 + jz ParamError + mov esp, eax + + mov esi, dword [esp + LoadMicrocodeParams.MicrocodeCodeAddr] + cmp esi, 0 + jnz CheckMainHeader + +ParamError: + mov eax, 080000002h + jmp Exit2 + +CheckMainHeader: + ; Get processor signature and platform ID from the installed processor + ; and save into registers for later use + ; ebx = processor signature + ; edx = platform ID + mov eax, 1 + cpuid + mov ebx, eax + mov ecx, MSR_IA32_PLATFORM_ID + rdmsr + mov ecx, edx + shr ecx, 50-32 ; shift (50d-32d=18d=0x12) bits + and ecx, 7h ; platform id at bit[52..50] + mov edx, 1 + shl edx, cl + + ; Current register usage + ; esp -> stack with parameters + ; esi -> microcode update to check + ; ebx = processor signature + ; edx = platform ID + + ; Check for valid microcode header + ; Minimal test checking for header version and loader version as 1 + mov eax, dword 1 + cmp dword [esi + MicrocodeHdr.MicrocodeHdrVersion], eax + jne AdvanceFixedSize + cmp dword [esi + MicrocodeHdr.MicrocodeHdrLoader], eax + jne AdvanceFixedSize + + ; Check if signature and plaform ID match + cmp ebx, dword [esi + MicrocodeHdr.MicrocodeHdrProcessor] + jne LoadMicrocodeDefault1 + test edx, dword [esi + MicrocodeHdr.MicrocodeHdrFlags ] + jnz LoadCheck ; Jif signature and platform ID match + +LoadMicrocodeDefault1: + ; Check if extended header exists + ; First check if MicrocodeHdrTotalSize and MicrocodeHdrDataSize are valid + xor eax, eax + cmp dword [esi + MicrocodeHdr.MicrocodeHdrTotalSize], eax + je NextMicrocode + cmp dword [esi + MicrocodeHdr.MicrocodeHdrDataSize], eax + je NextMicrocode + + ; Then verify total size - sizeof header > data size + mov ecx, dword [esi + MicrocodeHdr.MicrocodeHdrTotalSize] + sub ecx, MicrocodeHdr.size + cmp ecx, dword [esi + MicrocodeHdr.MicrocodeHdrDataSize] + jng NextMicrocode ; Jif extended header does not exist + + ; Set edi -> extended header + mov edi, esi + add edi, MicrocodeHdr.size + add edi, dword [esi + MicrocodeHdr.MicrocodeHdrDataSize] + + ; Get count of extended structures + mov ecx, dword [edi + ExtSigHdr.ExtSigHdrCount] + + ; Move pointer to first signature structure + add edi, ExtSigHdr.size + +CheckExtSig: + ; Check if extended signature and platform ID match + cmp dword [edi + ExtSig.ExtSigProcessor], ebx + jne LoadMicrocodeDefault2 + test dword [edi + ExtSig.ExtSigFlags], edx + jnz LoadCheck ; Jif signature and platform ID match +LoadMicrocodeDefault2: + ; Check if any more extended signatures exist + add edi, ExtSig.size + loop CheckExtSig + +NextMicrocode: + ; Advance just after end of this microcode + xor eax, eax + cmp dword [esi + MicrocodeHdr.MicrocodeHdrTotalSize], eax + je LoadMicrocodeDefault3 + add esi, dword [esi + MicrocodeHdr.MicrocodeHdrTotalSize] + jmp CheckAddress +LoadMicrocodeDefault3: + add esi, dword 2048 + jmp CheckAddress + +AdvanceFixedSize: + ; Advance by 4X dwords + add esi, dword 1024 + +CheckAddress: + ; Is valid Microcode start point ? + cmp dword [esi + MicrocodeHdr.MicrocodeHdrVersion], 0ffffffffh + jz Done + + ; Is automatic size detection ? + mov eax, dword [esp + LoadMicrocodeParams.MicrocodeCodeSize] + cmp eax, 0ffffffffh + jz LoadMicrocodeDefault4 + + ; Address >= microcode region address + microcode region size? + add eax, dword [esp + LoadMicrocodeParams.MicrocodeCodeAddr] + cmp esi, eax + jae Done ;Jif address is outside of microcode region + jmp CheckMainHeader + +LoadMicrocodeDefault4: +LoadCheck: + ; Get the revision of the current microcode update loaded + mov ecx, MSR_IA32_BIOS_SIGN_ID + xor eax, eax ; Clear EAX + xor edx, edx ; Clear EDX + wrmsr ; Load 0 to MSR at 8Bh + + mov eax, 1 + cpuid + mov ecx, MSR_IA32_BIOS_SIGN_ID + rdmsr ; Get current microcode signature + + ; Verify this microcode update is not already loaded + cmp dword [esi + MicrocodeHdr.MicrocodeHdrRevision], edx + je Continue + +LoadMicrocode: + ; EAX contains the linear address of the start of the Update Data + ; EDX contains zero + ; ECX contains 79h (IA32_BIOS_UPDT_TRIG) + ; Start microcode load with wrmsr + mov eax, esi + add eax, MicrocodeHdr.size + xor edx, edx + mov ecx, MSR_IA32_BIOS_UPDT_TRIG + wrmsr + mov eax, 1 + cpuid + +Continue: + jmp NextMicrocode + +Done: + mov eax, 1 + cpuid + mov ecx, MSR_IA32_BIOS_SIGN_ID + rdmsr ; Get current microcode signature + xor eax, eax + cmp edx, 0 + jnz Exit2 + mov eax, 08000000Eh + +Exit2: + jmp ebp + + +global ASM_PFX(EstablishStackFsp) +ASM_PFX(EstablishStackFsp): + ; + ; Save parameter pointer in edx + ; + mov edx, dword [esp + 4] + + ; + ; Enable FSP STACK + ; + mov esp, DWORD [ASM_PFX(PcdGet32 (PcdTemporaryRamBase))] + add esp, DWORD [ASM_PFX(PcdGet32 (PcdTemporaryRamSize))] + + push DATA_LEN_OF_MCUD ; Size of the data region + push 4455434Dh ; Signature of the data region 'MCUD' + push dword [edx + 2Ch] ; Code size sizeof(FSPT_UPD_COMMON) + 12 + push dword [edx + 28h] ; Code base sizeof(FSPT_UPD_COMMON) + 8 + push dword [edx + 24h] ; Microcode size sizeof(FSPT_UPD_COMMON) + 4 + push dword [edx + 20h] ; Microcode base sizeof(FSPT_UPD_COMMON) + 0 + + ; + ; Save API entry/exit timestamp into stack + ; + push DATA_LEN_OF_PER0 ; Size of the data region + push 30524550h ; Signature of the data region 'PER0' + rdtsc + push edx + push eax + LOAD_EDX + push edx + LOAD_EAX + push eax + + ; + ; Terminator for the data on stack + ; + push 0 + + ; + ; Set ECX/EDX to the BootLoader temporary memory range + ; + mov ecx, [ASM_PFX(PcdGet32 (PcdTemporaryRamBase))] + mov edx, ecx + add edx, [ASM_PFX(PcdGet32 (PcdTemporaryRamSize))] + sub edx, [ASM_PFX(PcdGet32 (PcdFspReservedBufferSize))] + + cmp ecx, edx ;If PcdFspReservedBufferSize >= PcdTemporaryRamSize, then error. + jb EstablishStackFspSuccess + mov eax, 80000003h ;EFI_UNSUPPORTED + jmp EstablishStackFspExit +EstablishStackFspSuccess: + xor eax, eax + +EstablishStackFspExit: + RET_ESI + +;---------------------------------------------------------------------------- +; TempRamInit API +; +; This FSP API will load the microcode update, enable code caching for the +; region specified by the boot loader and also setup a temporary stack to be +; used till main memory is initialized. +; +;---------------------------------------------------------------------------- +global ASM_PFX(TempRamInitApi) +ASM_PFX(TempRamInitApi): + ; + ; Ensure SSE is enabled + ; + ENABLE_SSE + + ; + ; Save EBP, EBX, ESI, EDI & ESP in XMM7 & XMM6 + ; + SAVE_REGS + + ; + ; Save timestamp into XMM6 + ; + rdtsc + SAVE_EAX + SAVE_EDX + + ; + ; Check Parameter + ; + mov eax, dword [esp + 4] + cmp eax, 0 + mov eax, 80000002h + jz TempRamInitExit + + ; + ; Sec Platform Init + ; + CALL_MMX ASM_PFX(SecPlatformInit) + cmp eax, 0 + jnz TempRamInitExit + + ; Load microcode + LOAD_ESP + CALL_MMX ASM_PFX(LoadMicrocodeDefault) + SXMMN xmm6, 3, eax ;Save microcode return status in ECX-SLOT 3 in xmm6. + ;@note If return value eax is not 0, microcode did not load, but continue and attempt to boot. + + ; Call Sec CAR Init + LOAD_ESP + CALL_MMX ASM_PFX(SecCarInit) + cmp eax, 0 + jnz TempRamInitExit + + LOAD_ESP + CALL_MMX ASM_PFX(EstablishStackFsp) + cmp eax, 0 + jnz TempRamInitExit + + LXMMN xmm6, eax, 3 ;Restore microcode status if no CAR init error from ECX-SLOT 3 in xmm6. + +TempRamInitExit: + mov bl, al ; save al data in bl + mov al, 07Fh ; API exit postcode 7f + out 080h, al + mov al, bl ; restore al data from bl + + ; + ; Load EBP, EBX, ESI, EDI & ESP from XMM7 & XMM6 + ; + LOAD_REGS + ret + +;---------------------------------------------------------------------------- +; Module Entrypoint API +;---------------------------------------------------------------------------- +global ASM_PFX(_ModuleEntryPoint) +ASM_PFX(_ModuleEntryPoint): + jmp $ diff --git a/IntelFsp2Pkg/FspSecCore/Ia32/FspHelper.nasm b/IntelFsp2Pkg/FspSecCore/Ia32/FspHelper.nasm new file mode 100644 index 0000000000..00e953b4f1 --- /dev/null +++ b/IntelFsp2Pkg/FspSecCore/Ia32/FspHelper.nasm @@ -0,0 +1,35 @@ +;; @file +; Provide FSP helper function. +; +; Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.
+; This program and the accompanying materials +; are licensed and made available under the terms and conditions of the BSD License +; which accompanies this distribution. The full text of the license may be found at +; http://opensource.org/licenses/bsd-license.php. +; +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +;; + + SECTION .text + +global ASM_PFX(FspInfoHeaderRelativeOff) +ASM_PFX(FspInfoHeaderRelativeOff): + ; + ; This value will be pached by the build script + ; + DD 0x12345678 + +global ASM_PFX(AsmGetFspBaseAddress) +ASM_PFX(AsmGetFspBaseAddress): + mov eax, ASM_PFX(AsmGetFspInfoHeader) + sub eax, dword [ASM_PFX(FspInfoHeaderRelativeOff)] + add eax, 0x1C + mov eax, dword [eax] + ret + +global ASM_PFX(AsmGetFspInfoHeader) +ASM_PFX(AsmGetFspInfoHeader): + mov eax, ASM_PFX(AsmGetFspInfoHeader) + sub eax, dword [ASM_PFX(FspInfoHeaderRelativeOff)] + ret diff --git a/IntelFsp2Pkg/FspSecCore/Ia32/InitializeFpu.nasm b/IntelFsp2Pkg/FspSecCore/Ia32/InitializeFpu.nasm new file mode 100644 index 0000000000..cc87e893d5 --- /dev/null +++ b/IntelFsp2Pkg/FspSecCore/Ia32/InitializeFpu.nasm @@ -0,0 +1,78 @@ +;------------------------------------------------------------------------------ +; +; Copyright (c) 2015, Intel Corporation. All rights reserved.
+; This program and the accompanying materials +; are licensed and made available under the terms and conditions of the BSD License +; which accompanies this distribution. The full text of the license may be found at +; http://opensource.org/licenses/bsd-license.php. +; +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +; +; Abstract: +; +;------------------------------------------------------------------------------ + + +SECTION .data +; +; Float control word initial value: +; all exceptions masked, double-precision, round-to-nearest +; +ASM_PFX(mFpuControlWord): + dw 0x027F +; +; Multimedia-extensions control word: +; all exceptions masked, round-to-nearest, flush to zero for masked underflow +; +ASM_PFX(mMmxControlWord): + dd 0x01F80 + +SECTION .text + +; +; Initializes floating point units for requirement of UEFI specification. +; +; This function initializes floating-point control word to 0x027F (all exceptions +; masked,double-precision, round-to-nearest) and multimedia-extensions control word +; (if supported) to 0x1F80 (all exceptions masked, round-to-nearest, flush to zero +; for masked underflow). +; + +global ASM_PFX(InitializeFloatingPointUnits) +ASM_PFX(InitializeFloatingPointUnits): + + + push ebx + + ; + ; Initialize floating point units + ; + finit + fldcw [ASM_PFX(mFpuControlWord)] + + ; + ; Use CpuId instructuion (CPUID.01H:EDX.SSE[bit 25] = 1) to test + ; whether the processor supports SSE instruction. + ; + mov eax, 1 + cpuid + bt edx, 25 + jnc Done + + ; + ; Set OSFXSR bit 9 in CR4 + ; + mov eax, cr4 + or eax, BIT9 + mov cr4, eax + + ; + ; The processor should support SSE instruction and we can use + ; ldmxcsr instruction + ; + ldmxcsr [ASM_PFX(mMmxControlWord)] +Done: + pop ebx + + ret diff --git a/IntelFsp2Pkg/FspSecCore/Ia32/MicrocodeLoadNasm.inc b/IntelFsp2Pkg/FspSecCore/Ia32/MicrocodeLoadNasm.inc new file mode 100644 index 0000000000..1663a85d11 --- /dev/null +++ b/IntelFsp2Pkg/FspSecCore/Ia32/MicrocodeLoadNasm.inc @@ -0,0 +1,16 @@ +;; @file +; +;@copyright +; Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.
+; This program and the accompanying materials +; are licensed and made available under the terms and conditions of the BSD License +; which accompanies this distribution. The full text of the license may be found at +; http://opensource.org/licenses/bsd-license.php. +; +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +;; + +MSR_IA32_PLATFORM_ID equ 000000017h +MSR_IA32_BIOS_UPDT_TRIG equ 000000079h +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 index 0000000000..ae0a93dc94 --- /dev/null +++ b/IntelFsp2Pkg/FspSecCore/Ia32/SaveRestoreSseNasm.inc @@ -0,0 +1,187 @@ +;------------------------------------------------------------------------------ +; +; Copyright (c) 2015, Intel Corporation. All rights reserved.
+; This program and the accompanying materials +; are licensed and made available under the terms and conditions of the BSD License +; which accompanies this distribution. The full text of the license may be found at +; http://opensource.org/licenses/bsd-license.php. +; +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +; +; Abstract: +; +; Provide macro for register save/restore using SSE registers +; +;------------------------------------------------------------------------------ + +; +; Define SSE instruction set +; +%ifdef USE_SSE41_FLAG +; +; Define SSE macros using SSE 4.1 instructions +; args 1:XMM, 2:IDX, 3:REG +%macro SXMMN 3 + pinsrd %1, %3, (%2 & 3) + %endmacro + +; +;args 1:XMM, 2:REG, 3:IDX +; +%macro LXMMN 3 + pextrd %2, %1, (%3 & 3) + %endmacro +%else +; +; Define SSE macros using SSE 2 instructions +; args 1:XMM, 2:IDX, 3:REG +%macro SXMMN 3 + pinsrw %1, %3, (%2 & 3) * 2 + ror %3, 16 + pinsrw %1, %3, (%2 & 3) * 2 + 1 + rol %3, 16 + %endmacro + +; +;args 1:XMM, 2:REG, 3:IDX +; +%macro LXMMN 3 + pshufd %1, %1, ((0E4E4E4h >> (%3 * 2)) & 0FFh) + movd %2, %1 + pshufd %1, %1, ((0E4E4E4h >> (%3 * 2 + (%3 & 1) * 4)) & 0FFh) + %endmacro +%endif + +; +; XMM7 to save/restore EBP, EBX, ESI, EDI +; +%macro SAVE_REGS 0 + SXMMN xmm7, 0, ebp + SXMMN xmm7, 1, ebx + SXMMN xmm7, 2, esi + SXMMN xmm7, 3, edi + SAVE_ESP + %endmacro + +%macro LOAD_REGS 0 + LXMMN xmm7, ebp, 0 + LXMMN xmm7, ebx, 1 + LXMMN xmm7, esi, 2 + LXMMN xmm7, edi, 3 + LOAD_ESP + %endmacro + +; +; XMM6 to save/restore EAX, EDX, ECX, ESP +; +%macro LOAD_EAX 0 + LXMMN xmm6, eax, 1 + %endmacro + +%macro SAVE_EAX 0 + SXMMN xmm6, 1, eax + %endmacro + +%macro LOAD_EDX 0 + LXMMN xmm6, edx, 2 + %endmacro + +%macro SAVE_EDX 0 + SXMMN xmm6, 2, edx + %endmacro + +%macro SAVE_ECX 0 + SXMMN xmm6, 3, ecx + %endmacro + +%macro LOAD_ECX 0 + LXMMN xmm6, ecx, 3 + %endmacro + +%macro SAVE_ESP 0 + SXMMN xmm6, 0, esp + %endmacro + +%macro LOAD_ESP 0 + movd esp, xmm6 + %endmacro +; +; XMM5 for calling stack +; arg 1:Entry +%macro CALL_XMM 1 + mov esi, %%ReturnAddress + pslldq xmm5, 4 +%ifdef USE_SSE41_FLAG + pinsrd xmm5, esi, 0 +%else + pinsrw xmm5, esi, 0 + ror esi, 16 + pinsrw xmm5, esi, 1 +%endif + mov esi, %1 + jmp esi +%%ReturnAddress: + %endmacro + +%macro RET_XMM 0 + movd esi, xmm5 + psrldq xmm5, 4 + jmp esi + %endmacro + +%macro ENABLE_SSE 0 + ; + ; Initialize floating point units + ; + jmp NextAddress +align 4 + ; + ; Float control word initial value: + ; all exceptions masked, double-precision, round-to-nearest + ; +FpuControlWord DW 027Fh + ; + ; Multimedia-extensions control word: + ; all exceptions masked, round-to-nearest, flush to zero for masked underflow + ; +MmxControlWord DD 01F80h +SseError: + ; + ; Processor has to support SSE + ; + jmp SseError +NextAddress: + finit + fldcw [FpuControlWord] + + ; + ; Use CpuId instructuion (CPUID.01H:EDX.SSE[bit 25] = 1) to test + ; whether the processor supports SSE instruction. + ; + mov eax, 1 + cpuid + bt edx, 25 + jnc SseError + +%ifdef USE_SSE41_FLAG + ; + ; SSE 4.1 support + ; + bt ecx, 19 + jnc SseError +%endif + + ; + ; Set OSFXSR bit (bit #9) & OSXMMEXCPT bit (bit #10) + ; + mov eax, cr4 + or eax, 00000600h + mov cr4, eax + + ; + ; The processor should support SSE instruction and we can use + ; ldmxcsr instruction + ; + ldmxcsr [MmxControlWord] + %endmacro diff --git a/IntelFsp2Pkg/FspSecCore/Ia32/Stack.nasm b/IntelFsp2Pkg/FspSecCore/Ia32/Stack.nasm new file mode 100644 index 0000000000..338e700751 --- /dev/null +++ b/IntelFsp2Pkg/FspSecCore/Ia32/Stack.nasm @@ -0,0 +1,78 @@ +;------------------------------------------------------------------------------ +; +; Copyright (c) 2015, Intel Corporation. All rights reserved.
+; This program and the accompanying materials +; are licensed and made available under the terms and conditions of the BSD License +; which accompanies this distribution. The full text of the license may be found at +; http://opensource.org/licenses/bsd-license.php. +; +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +; +; Abstract: +; +; Switch the stack from temporary memory to permanent memory. +; +;------------------------------------------------------------------------------ + +SECTION .text + +;------------------------------------------------------------------------------ +; VOID +; EFIAPI +; SecSwitchStack ( +; UINT32 TemporaryMemoryBase, +; UINT32 PermenentMemoryBase +; ); +;------------------------------------------------------------------------------ +global ASM_PFX(SecSwitchStack) +ASM_PFX(SecSwitchStack): + ; + ; Save three register: eax, ebx, ecx + ; + push eax + push ebx + push ecx + push edx + + ; + ; !!CAUTION!! this function address's is pushed into stack after + ; migration of whole temporary memory, so need save it to permanent + ; memory at first! + ; + + mov ebx, [esp + 20] ; Save the first parameter + mov ecx, [esp + 24] ; Save the second parameter + + ; + ; Save this function's return address into permanent memory at first. + ; Then, Fixup the esp point to permanent memory + ; + mov eax, esp + sub eax, ebx + add eax, ecx + mov edx, dword [esp] ; copy pushed register's value to permanent memory + mov dword [eax], edx + mov edx, dword [esp + 4] + mov dword [eax + 4], edx + mov edx, dword [esp + 8] + mov dword [eax + 8], edx + mov edx, dword [esp + 12] + mov dword [eax + 12], edx + mov edx, dword [esp + 16] ; Update this function's return address into permanent memory + mov dword [eax + 16], edx + mov esp, eax ; From now, esp is pointed to permanent memory + + ; + ; Fixup the ebp point to permenent memory + ; + mov eax, ebp + sub eax, ebx + add eax, ecx + mov ebp, eax ; From now, ebp is pointed to permanent memory + + pop edx + pop ecx + pop ebx + pop eax + ret diff --git a/IntelFsp2Pkg/FspSecCore/SecFsp.c b/IntelFsp2Pkg/FspSecCore/SecFsp.c new file mode 100644 index 0000000000..7259a55bbd --- /dev/null +++ b/IntelFsp2Pkg/FspSecCore/SecFsp.c @@ -0,0 +1,216 @@ +/** @file + + Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "SecFsp.h" + +/** + + Calculate the FSP IDT gate descriptor. + + @param[in] IdtEntryTemplate IDT gate descriptor template. + + @return FSP specific IDT gate descriptor. + +**/ +UINT64 +FspGetExceptionHandler( + IN UINT64 IdtEntryTemplate + ) +{ + UINT32 Entry; + UINT64 ExceptionHandler; + IA32_IDT_GATE_DESCRIPTOR *IdtGateDescriptor; + FSP_INFO_HEADER *FspInfoHeader; + + FspInfoHeader = (FSP_INFO_HEADER *)AsmGetFspInfoHeader(); + ExceptionHandler = IdtEntryTemplate; + IdtGateDescriptor = (IA32_IDT_GATE_DESCRIPTOR *)&ExceptionHandler; + Entry = (IdtGateDescriptor->Bits.OffsetHigh << 16) | IdtGateDescriptor->Bits.OffsetLow; + Entry = FspInfoHeader->ImageBase + FspInfoHeader->ImageSize - (~Entry + 1); + IdtGateDescriptor->Bits.OffsetHigh = (UINT16)(Entry >> 16); + IdtGateDescriptor->Bits.OffsetLow = (UINT16)Entry; + + return ExceptionHandler; +} + +/** + This interface fills platform specific data. + + @param[in,out] FspData Pointer to the FSP global data. + +**/ +VOID +EFIAPI +SecGetPlatformData ( + IN OUT FSP_GLOBAL_DATA *FspData + ) +{ + FSP_PLAT_DATA *FspPlatformData; + UINT32 TopOfCar; + UINT32 *StackPtr; + UINT32 DwordSize; + + FspPlatformData = &FspData->PlatformData; + + // + // The entries of platform information, together with the number of them, + // reside in the bottom of stack, left untouched by normal stack operation. + // + + FspPlatformData->DataPtr = NULL; + FspPlatformData->MicrocodeRegionBase = 0; + FspPlatformData->MicrocodeRegionSize = 0; + FspPlatformData->CodeRegionBase = 0; + FspPlatformData->CodeRegionSize = 0; + + // + // Pointer to the size field + // + TopOfCar = FspPlatformData->CarBase + FspPlatformData->CarSize; + StackPtr = (UINT32 *)(TopOfCar - sizeof (UINT32)); + + if (*(StackPtr - 1) == FSP_MCUD_SIGNATURE) { + while (*StackPtr != 0) { + if (*(StackPtr - 1) == FSP_MCUD_SIGNATURE) { + // + // This following data was pushed onto stack after TempRamInit API + // + DwordSize = 4; + StackPtr = StackPtr - 1 - DwordSize; + CopyMem (&(FspPlatformData->MicrocodeRegionBase), StackPtr, (DwordSize << 2)); + StackPtr--; + } else if (*(StackPtr - 1) == FSP_PER0_SIGNATURE) { + // + // This is the performance data for InitTempMemory API entry/exit + // + DwordSize = 4; + StackPtr = StackPtr - 1 - DwordSize; + CopyMem (FspData->PerfData, StackPtr, (DwordSize << 2)); + + ((UINT8 *)(&FspData->PerfData[0]))[7] = FSP_PERF_ID_API_TEMP_RAM_INIT_ENTRY; + ((UINT8 *)(&FspData->PerfData[1]))[7] = FSP_PERF_ID_API_TEMP_RAM_INIT_EXIT; + + StackPtr--; + } else { + StackPtr -= (*StackPtr); + } + } + } +} + +/** + + Initialize the FSP global data region. + It needs to be done as soon as possible after the stack is setup. + + @param[in,out] PeiFspData Pointer of the FSP global data. + @param[in] BootLoaderStack BootLoader stack. + @param[in] ApiIdx The index of the FSP API. + +**/ +VOID +FspGlobalDataInit ( + IN OUT FSP_GLOBAL_DATA *PeiFspData, + IN UINT32 BootLoaderStack, + IN UINT8 ApiIdx + ) +{ + VOID *FspmUpdDataPtr; + CHAR8 ImageId[9]; + UINTN Idx; + + // + // Set FSP Global Data pointer + // + SetFspGlobalDataPointer (PeiFspData); + ZeroMem ((VOID *)PeiFspData, sizeof(FSP_GLOBAL_DATA)); + + PeiFspData->Signature = FSP_GLOBAL_DATA_SIGNATURE; + PeiFspData->Version = 0; + PeiFspData->CoreStack = BootLoaderStack; + PeiFspData->PerfIdx = 2; + PeiFspData->PerfSig = FSP_PERFORMANCE_DATA_SIGNATURE; + PeiFspData->PlatformData.CarBase = AsmReadMsr32 (0x200) & ~(0x6); + PeiFspData->PlatformData.CarSize = ~(AsmReadMsr32(0x201) & ~(0x800)) + 1; + + SetFspMeasurePoint (FSP_PERF_ID_API_FSP_MEMORY_INIT_ENTRY); + + // + // Get FSP Header offset + // It may have multiple FVs, so look into the last one for FSP header + // + PeiFspData->FspInfoHeader = (FSP_INFO_HEADER *)AsmGetFspInfoHeader(); + SecGetPlatformData (PeiFspData); + + // + // Set API calling mode + // + SetFspApiCallingIndex (ApiIdx); + + // + // Set UPD pointer + // + FspmUpdDataPtr = (VOID *) GetFspApiParameter (); + if (FspmUpdDataPtr == NULL) { + FspmUpdDataPtr = (VOID *)(PeiFspData->FspInfoHeader->ImageBase + PeiFspData->FspInfoHeader->CfgRegionOffset); + } + SetFspUpdDataPointer (FspmUpdDataPtr); + SetFspMemoryInitUpdDataPointer (FspmUpdDataPtr); + SetFspSiliconInitUpdDataPointer (NULL); + + // + // Initialize serial port + // It might have been done in ProcessLibraryConstructorList(), however, + // the FSP global data is not initialized at that time. So do it again + // for safe. + // + SerialPortInitialize (); + + // + // Ensure the golbal data pointer is valid + // + ASSERT (GetFspGlobalDataPointer () == PeiFspData); + + for (Idx = 0; Idx < 8; Idx++) { + ImageId[Idx] = PeiFspData->FspInfoHeader->ImageId[Idx]; + } + ImageId[Idx] = 0; + + DEBUG ((DEBUG_INFO | DEBUG_INIT, "\n============= FSP Spec v%d.%d Header Revision v%x (%a v%x.%x.%x.%x) =============\n", \ + (PeiFspData->FspInfoHeader->SpecVersion >> 4) & 0xF, \ + PeiFspData->FspInfoHeader->SpecVersion & 0xF, \ + PeiFspData->FspInfoHeader->HeaderRevision, \ + ImageId, \ + (PeiFspData->FspInfoHeader->ImageRevision >> 24) & 0xFF, \ + (PeiFspData->FspInfoHeader->ImageRevision >> 16) & 0xFF, \ + (PeiFspData->FspInfoHeader->ImageRevision >> 8) & 0xFF, \ + PeiFspData->FspInfoHeader->ImageRevision & 0xFF)); +} + +/** + + Adjust the FSP data pointers after the stack is migrated to memory. + + @param[in] OffsetGap The offset gap between the old stack and the new stack. + +**/ +VOID +FspDataPointerFixUp ( + IN UINT32 OffsetGap + ) +{ + FSP_GLOBAL_DATA *NewFspData; + + NewFspData = (FSP_GLOBAL_DATA *)((UINTN)GetFspGlobalDataPointer() + (UINTN)OffsetGap); + SetFspGlobalDataPointer (NewFspData); +} diff --git a/IntelFsp2Pkg/FspSecCore/SecFsp.h b/IntelFsp2Pkg/FspSecCore/SecFsp.h new file mode 100644 index 0000000000..f199b12e4d --- /dev/null +++ b/IntelFsp2Pkg/FspSecCore/SecFsp.h @@ -0,0 +1,99 @@ +/** @file + + Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef _SEC_FSP_H_ +#define _SEC_FSP_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define FSP_MCUD_SIGNATURE SIGNATURE_32 ('M', 'C', 'U', 'D') +#define FSP_PER0_SIGNATURE SIGNATURE_32 ('P', 'E', 'R', '0') + +/** + + Calculate the FSP IDT gate descriptor. + + @param[in] IdtEntryTemplate IDT gate descriptor template. + + @return FSP specific IDT gate descriptor. + +**/ +UINT64 +FspGetExceptionHandler( + IN UINT64 IdtEntryTemplate + ); + +/** + + Initialize the FSP global data region. + It needs to be done as soon as possible after the stack is setup. + + @param[in,out] PeiFspData Pointer of the FSP global data. + @param[in] BootLoaderStack BootLoader stack. + @param[in] ApiIdx The index of the FSP API. + +**/ +VOID +FspGlobalDataInit ( + IN OUT FSP_GLOBAL_DATA *PeiFspData, + IN UINT32 BootLoaderStack, + IN UINT8 ApiIdx + ); + + +/** + + Adjust the FSP data pointers after the stack is migrated to memory. + + @param[in] OffsetGap The offset gap between the old stack and the new stack. + +**/ +VOID +FspDataPointerFixUp ( + IN UINT32 OffsetGap + ); + + +/** + This interface returns the base address of FSP binary. + + @return FSP binary base address. + +**/ +UINT32 +EFIAPI +AsmGetFspBaseAddress ( + VOID + ); + +/** + This interface gets FspInfoHeader pointer + + @return FSP binary base address. + +**/ +UINT32 +EFIAPI +AsmGetFspInfoHeader ( + VOID + ); + +#endif diff --git a/IntelFsp2Pkg/FspSecCore/SecFspApiChk.c b/IntelFsp2Pkg/FspSecCore/SecFspApiChk.c new file mode 100644 index 0000000000..bace5eca43 --- /dev/null +++ b/IntelFsp2Pkg/FspSecCore/SecFspApiChk.c @@ -0,0 +1,97 @@ +/** @file + + Copyright (c) 2016, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "SecFsp.h" + + +/** + This function check the FSP API calling condition. + + @param[in] ApiIdx Internal index of the FSP API. + @param[in] ApiParam Parameter of the FSP API. + +**/ +EFI_STATUS +EFIAPI +FspApiCallingCheck ( + IN UINT8 ApiIdx, + IN VOID *ApiParam + ) +{ + EFI_STATUS Status; + FSP_GLOBAL_DATA *FspData; + + Status = EFI_SUCCESS; + FspData = GetFspGlobalDataPointer (); + + if (ApiIdx == NotifyPhaseApiIndex) { + // + // NotifyPhase check + // + if ((FspData == NULL) || ((UINT32)FspData == 0xFFFFFFFF)) { + Status = EFI_UNSUPPORTED; + } else { + if (FspData->Signature != FSP_GLOBAL_DATA_SIGNATURE) { + Status = EFI_UNSUPPORTED; + } + } + } else if (ApiIdx == FspMemoryInitApiIndex) { + // + // FspMemoryInit check + // + if ((UINT32)FspData != 0xFFFFFFFF) { + Status = EFI_UNSUPPORTED; + } else if (EFI_ERROR (FspUpdSignatureCheck (ApiIdx, ApiParam))) { + Status = EFI_INVALID_PARAMETER; + } + } else if (ApiIdx == TempRamExitApiIndex) { + // + // TempRamExit check + // + if ((FspData == NULL) || ((UINT32)FspData == 0xFFFFFFFF)) { + Status = EFI_UNSUPPORTED; + } else { + if (FspData->Signature != FSP_GLOBAL_DATA_SIGNATURE) { + Status = EFI_UNSUPPORTED; + } + } + } else if (ApiIdx == FspSiliconInitApiIndex) { + // + // FspSiliconInit check + // + if ((FspData == NULL) || ((UINT32)FspData == 0xFFFFFFFF)) { + Status = EFI_UNSUPPORTED; + } else { + if (FspData->Signature != FSP_GLOBAL_DATA_SIGNATURE) { + Status = EFI_UNSUPPORTED; + } else if (EFI_ERROR (FspUpdSignatureCheck (ApiIdx, ApiParam))) { + Status = EFI_INVALID_PARAMETER; + } + } + } else { + Status = EFI_UNSUPPORTED; + } + + if (!EFI_ERROR (Status)) { + if ((ApiIdx != FspMemoryInitApiIndex)) { + // + // For FspMemoryInit, the global data is not valid yet + // The API index will be updated by SecCore after the global data + // is initialized + // + SetFspApiCallingIndex (ApiIdx); + } + } + + return Status; +} diff --git a/IntelFsp2Pkg/FspSecCore/SecMain.c b/IntelFsp2Pkg/FspSecCore/SecMain.c new file mode 100644 index 0000000000..fa556bf058 --- /dev/null +++ b/IntelFsp2Pkg/FspSecCore/SecMain.c @@ -0,0 +1,227 @@ +/** @file + + Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "SecMain.h" +#include "SecFsp.h" + +EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI gSecTemporaryRamSupportPpi = { + SecTemporaryRamSupport +}; + +EFI_PEI_PPI_DESCRIPTOR mPeiSecPlatformInformationPpi[] = { + { + (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gEfiTemporaryRamSupportPpiGuid, + &gSecTemporaryRamSupportPpi + } +}; + +// +// These are IDT entries pointing to 08:FFFFFFE4h. +// +UINT64 mIdtEntryTemplate = 0xffff8e000008ffe4ULL; + +/** + + Entry point to the C language phase of SEC. After the SEC assembly + code has initialized some temporary memory and set up the stack, + the control is transferred to this function. + + + @param[in] SizeOfRam Size of the temporary memory available for use. + @param[in] TempRamBase Base address of tempory ram + @param[in] BootFirmwareVolume Base address of the Boot Firmware Volume. + @param[in] PeiCore PeiCore entry point. + @param[in] BootLoaderStack BootLoader stack. + @param[in] ApiIdx the index of API. + + @return This function never returns. + +**/ +VOID +EFIAPI +SecStartup ( + IN UINT32 SizeOfRam, + IN UINT32 TempRamBase, + IN VOID *BootFirmwareVolume, + IN PEI_CORE_ENTRY PeiCore, + IN UINT32 BootLoaderStack, + IN UINT32 ApiIdx + ) +{ + EFI_SEC_PEI_HAND_OFF SecCoreData; + IA32_DESCRIPTOR IdtDescriptor; + SEC_IDT_TABLE IdtTableInStack; + UINT32 Index; + FSP_GLOBAL_DATA PeiFspData; + UINT64 ExceptionHandler; + + // + // Process all libraries constructor function linked to SecCore. + // + ProcessLibraryConstructorList (); + + // + // Initialize floating point operating environment + // to be compliant with UEFI spec. + // + InitializeFloatingPointUnits (); + + + // |-------------------|----> + // |Idt Table | + // |-------------------| + // |PeiService Pointer | PeiStackSize + // |-------------------| + // | | + // | Stack | + // |-------------------|----> + // | | + // | | + // | Heap | PeiTemporayRamSize + // | | + // | | + // |-------------------|----> TempRamBase + IdtTableInStack.PeiService = NULL; + ExceptionHandler = FspGetExceptionHandler(mIdtEntryTemplate); + for (Index = 0; Index < SEC_IDT_ENTRY_COUNT; Index ++) { + CopyMem ((VOID*)&IdtTableInStack.IdtTable[Index], (VOID*)&ExceptionHandler, sizeof (UINT64)); + } + + IdtDescriptor.Base = (UINTN) &IdtTableInStack.IdtTable; + IdtDescriptor.Limit = (UINT16)(sizeof (IdtTableInStack.IdtTable) - 1); + + AsmWriteIdtr (&IdtDescriptor); + + // + // Initialize the global FSP data region + // + FspGlobalDataInit (&PeiFspData, BootLoaderStack, (UINT8)ApiIdx); + + // + // Update the base address and length of Pei temporary memory + // + SecCoreData.DataSize = sizeof (EFI_SEC_PEI_HAND_OFF); + SecCoreData.BootFirmwareVolumeBase = BootFirmwareVolume; + SecCoreData.BootFirmwareVolumeSize = (UINT32)((EFI_FIRMWARE_VOLUME_HEADER *)BootFirmwareVolume)->FvLength; + + SecCoreData.TemporaryRamBase = (VOID*)(UINTN) TempRamBase; + SecCoreData.TemporaryRamSize = SizeOfRam; + SecCoreData.PeiTemporaryRamBase = SecCoreData.TemporaryRamBase; + SecCoreData.PeiTemporaryRamSize = SecCoreData.TemporaryRamSize * PcdGet8 (PcdFspHeapSizePercentage) / 100; + SecCoreData.StackBase = (VOID*)(UINTN)((UINTN)SecCoreData.TemporaryRamBase + SecCoreData.PeiTemporaryRamSize); + SecCoreData.StackSize = SecCoreData.TemporaryRamSize - SecCoreData.PeiTemporaryRamSize; + + DEBUG ((DEBUG_INFO, "Fsp BootFirmwareVolumeBase - 0x%x\n", SecCoreData.BootFirmwareVolumeBase)); + DEBUG ((DEBUG_INFO, "Fsp BootFirmwareVolumeSize - 0x%x\n", SecCoreData.BootFirmwareVolumeSize)); + DEBUG ((DEBUG_INFO, "Fsp TemporaryRamBase - 0x%x\n", SecCoreData.TemporaryRamBase)); + DEBUG ((DEBUG_INFO, "Fsp TemporaryRamSize - 0x%x\n", SecCoreData.TemporaryRamSize)); + DEBUG ((DEBUG_INFO, "Fsp PeiTemporaryRamBase - 0x%x\n", SecCoreData.PeiTemporaryRamBase)); + DEBUG ((DEBUG_INFO, "Fsp PeiTemporaryRamSize - 0x%x\n", SecCoreData.PeiTemporaryRamSize)); + DEBUG ((DEBUG_INFO, "Fsp StackBase - 0x%x\n", SecCoreData.StackBase)); + DEBUG ((DEBUG_INFO, "Fsp StackSize - 0x%x\n", SecCoreData.StackSize)); + + // + // Call PeiCore Entry + // + PeiCore (&SecCoreData, mPeiSecPlatformInformationPpi); + + // + // Should never be here + // + CpuDeadLoop (); +} + +/** + This service of the TEMPORARY_RAM_SUPPORT_PPI that migrates temporary RAM into + permanent memory. + + @param[in] PeiServices Pointer to the PEI Services Table. + @param[in] TemporaryMemoryBase Source Address in temporary memory from which the SEC or PEIM will copy the + Temporary RAM contents. + @param[in] PermanentMemoryBase Destination Address in permanent memory into which the SEC or PEIM will copy the + Temporary RAM contents. + @param[in] CopySize Amount of memory to migrate from temporary to permanent memory. + + @retval EFI_SUCCESS The data was successfully returned. + @retval EFI_INVALID_PARAMETER PermanentMemoryBase + CopySize > TemporaryMemoryBase when + TemporaryMemoryBase > PermanentMemoryBase. + +**/ +EFI_STATUS +EFIAPI +SecTemporaryRamSupport ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase, + IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase, + IN UINTN CopySize + ) +{ + IA32_DESCRIPTOR IdtDescriptor; + VOID* OldHeap; + VOID* NewHeap; + VOID* OldStack; + VOID* NewStack; + UINTN HeapSize; + UINTN StackSize; + + HeapSize = CopySize * PcdGet8 (PcdFspHeapSizePercentage) / 100 ; + StackSize = CopySize - HeapSize; + + OldHeap = (VOID*)(UINTN)TemporaryMemoryBase; + NewHeap = (VOID*)((UINTN)PermanentMemoryBase + StackSize); + + OldStack = (VOID*)((UINTN)TemporaryMemoryBase + HeapSize); + NewStack = (VOID*)(UINTN)PermanentMemoryBase; + + // + // Migrate Heap + // + CopyMem (NewHeap, OldHeap, HeapSize); + + // + // Migrate Stack + // + CopyMem (NewStack, OldStack, StackSize); + + + // + // We need *not* fix the return address because currently, + // The PeiCore is executed in flash. + // + + // + // Rebase IDT table in permanent memory + // + AsmReadIdtr (&IdtDescriptor); + IdtDescriptor.Base = IdtDescriptor.Base - (UINTN)OldStack + (UINTN)NewStack; + + AsmWriteIdtr (&IdtDescriptor); + + // + // Fixed the FSP data pointer + // + FspDataPointerFixUp ((UINTN)NewStack - (UINTN)OldStack); + + // + // SecSwitchStack function must be invoked after the memory migration + // immediatly, also we need fixup the stack change caused by new call into + // permenent memory. + // + SecSwitchStack ( + (UINT32) (UINTN) OldStack, + (UINT32) (UINTN) NewStack + ); + + return EFI_SUCCESS; +} diff --git a/IntelFsp2Pkg/FspSecCore/SecMain.h b/IntelFsp2Pkg/FspSecCore/SecMain.h new file mode 100644 index 0000000000..33f73625ca --- /dev/null +++ b/IntelFsp2Pkg/FspSecCore/SecMain.h @@ -0,0 +1,140 @@ +/** @file + + Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef _SEC_CORE_H_ +#define _SEC_CORE_H_ + + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define SEC_IDT_ENTRY_COUNT 34 + +typedef VOID (*PEI_CORE_ENTRY) ( \ + IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData, \ + IN CONST EFI_PEI_PPI_DESCRIPTOR *PpiList \ +); + +typedef struct _SEC_IDT_TABLE { + EFI_PEI_SERVICES *PeiService; + UINT64 IdtTable[SEC_IDT_ENTRY_COUNT]; +} SEC_IDT_TABLE; + +/** + Switch the stack in the temporary memory to the one in the permanent memory. + + This function must be invoked after the memory migration immediately. The relative + position of the stack in the temporary and permanent memory is same. + + @param[in] TemporaryMemoryBase Base address of the temporary memory. + @param[in] PermenentMemoryBase Base address of the permanent memory. +**/ +VOID +EFIAPI +SecSwitchStack ( + IN UINT32 TemporaryMemoryBase, + IN UINT32 PermenentMemoryBase + ); + +/** + This service of the TEMPORARY_RAM_SUPPORT_PPI that migrates temporary RAM into + permanent memory. + + @param[in] PeiServices Pointer to the PEI Services Table. + @param[in] TemporaryMemoryBase Source Address in temporary memory from which the SEC or PEIM will copy the + Temporary RAM contents. + @param[in] PermanentMemoryBase Destination Address in permanent memory into which the SEC or PEIM will copy the + Temporary RAM contents. + @param[in] CopySize Amount of memory to migrate from temporary to permanent memory. + + @retval EFI_SUCCESS The data was successfully returned. + @retval EFI_INVALID_PARAMETER PermanentMemoryBase + CopySize > TemporaryMemoryBase when + TemporaryMemoryBase > PermanentMemoryBase. + +**/ +EFI_STATUS +EFIAPI +SecTemporaryRamSupport ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase, + IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase, + IN UINTN CopySize + ); + +/** + Initializes floating point units for requirement of UEFI specification. + + This function initializes floating-point control word to 0x027F (all exceptions + masked,double-precision, round-to-nearest) and multimedia-extensions control word + (if supported) to 0x1F80 (all exceptions masked, round-to-nearest, flush to zero + for masked underflow). + +**/ +VOID +EFIAPI +InitializeFloatingPointUnits ( + VOID + ); + +/** + + Entry point to the C language phase of SEC. After the SEC assembly + code has initialized some temporary memory and set up the stack, + the control is transferred to this function. + + + @param[in] SizeOfRam Size of the temporary memory available for use. + @param[in] TempRamBase Base address of tempory ram + @param[in] BootFirmwareVolume Base address of the Boot Firmware Volume. + @param[in] PeiCore PeiCore entry point. + @param[in] BootLoaderStack BootLoader stack. + @param[in] ApiIdx the index of API. + + @return This function never returns. + +**/ +VOID +EFIAPI +SecStartup ( + IN UINT32 SizeOfRam, + IN UINT32 TempRamBase, + IN VOID *BootFirmwareVolume, + IN PEI_CORE_ENTRY PeiCore, + IN UINT32 BootLoaderStack, + IN UINT32 ApiIdx + ); + +/** + Autogenerated function that calls the library constructors for all of the module's + dependent libraries. This function must be called by the SEC Core once a stack has + been established. + +**/ +VOID +EFIAPI +ProcessLibraryConstructorList ( + VOID + ); + +#endif diff --git a/IntelFsp2Pkg/FspSecCore/Vtf0/Bin/ResetVec.ia32.raw b/IntelFsp2Pkg/FspSecCore/Vtf0/Bin/ResetVec.ia32.raw new file mode 100644 index 0000000000000000000000000000000000000000..2dc9f178d356d4ab4393963428f32ad3f0dfabf2 GIT binary patch literal 68 scmbO*VZwxWP{05M`yB&b%fdK7x+2U(==HzzaFGcUUjF?L6$i-y0C9#E0ssI2 literal 0 HcmV?d00001 diff --git a/IntelFsp2Pkg/FspSecCore/Vtf0/Build.py b/IntelFsp2Pkg/FspSecCore/Vtf0/Build.py new file mode 100644 index 0000000000..3018391445 --- /dev/null +++ b/IntelFsp2Pkg/FspSecCore/Vtf0/Build.py @@ -0,0 +1,53 @@ +## @file +# Automate the process of building the various reset vector types +# +# Copyright (c) 2014, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# + +import glob +import os +import subprocess +import sys + +def RunCommand(commandLine): + #print ' '.join(commandLine) + return subprocess.call(commandLine) + +for filename in glob.glob(os.path.join('Bin', '*.raw')): + os.remove(filename) + +arch = 'ia32' +debugType = None +output = os.path.join('Bin', 'ResetVec') +output += '.' + arch +if debugType is not None: + output += '.' + debugType +output += '.raw' +commandLine = ( + 'nasm', + '-D', 'ARCH_%s' % arch.upper(), + '-D', 'DEBUG_%s' % str(debugType).upper(), + '-o', output, + 'ResetVectorCode.asm', + ) +ret = RunCommand(commandLine) +print '\tASM\t' + output +if ret != 0: sys.exit(ret) + +commandLine = ( + 'python', + 'Tools/FixupForRawSection.py', + output, + ) +print '\tFIXUP\t' + output +ret = RunCommand(commandLine) +if ret != 0: sys.exit(ret) + diff --git a/IntelFsp2Pkg/FspSecCore/Vtf0/Ia16/ResetVec.asm16 b/IntelFsp2Pkg/FspSecCore/Vtf0/Ia16/ResetVec.asm16 new file mode 100644 index 0000000000..585876fa86 --- /dev/null +++ b/IntelFsp2Pkg/FspSecCore/Vtf0/Ia16/ResetVec.asm16 @@ -0,0 +1,103 @@ +;; @file +; Reset Vector Data structure +; This structure is located at 0xFFFFFFC0 +; +; Copyright (c) 2014, Intel Corporation. All rights reserved.
+; This program and the accompanying materials +; are licensed and made available under the terms and conditions of the BSD License +; which accompanies this distribution. The full text of the license may be found at +; http://opensource.org/licenses/bsd-license.php. +; +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +; +;; + +BITS 16 + + +; +; The layout of this file is fixed. The build tool makes assumption of the layout. +; + +ORG 0x0 +; +; Reserved +; +ReservedData: DD 0eeeeeeeeh, 0eeeeeeeeh + + ; ORG 0x10 + TIMES 0x10-($-$$) DB 0 +; +; This is located at 0xFFFFFFD0h +; + mov di, "AP" + jmp ApStartup + + ; ORG 0x20 + + TIMES 0x20-($-$$) DB 0 + +; Pointer to the entry point of the PEI core +; It is located at 0xFFFFFFE0, and is fixed up by some build tool +; So if the value 8..1 appears in the final FD image, tool failure occurs. +; +PeiCoreEntryPoint: DD 0x12345678 + +; +; This is the handler for all kinds of exceptions. Since it's for debugging +; purpose only, nothing except a deadloop would be done here. Developers could +; analyze the cause of the exception if a debugger had been attached. +; +InterruptHandler: + jmp $ + iret + + ; ORG 0x30 + TIMES 0x30-($-$$) DB 0 +; +; For IA32, the reset vector must be at 0xFFFFFFF0, i.e., 4G-16 byte +; Execution starts here upon power-on/platform-reset. +; +ResetHandler: + nop + nop + +ApStartup: + ; + ; Jmp Rel16 instruction + ; Use machine code directly in case of the assembler optimization + ; SEC entry point relatvie address will be fixed up by some build tool. + ; + ; Typically, SEC entry point is the function _ModuleEntryPoint() defined in + ; SecEntry.asm + ; + DB 0x0e9 + DW -3 + + ; ORG 0x38 + + TIMES 0x38-($-$$) DB 0 +; +; Ap reset vector segment address is at 0xFFFFFFF8 +; This will be fixed up by some build tool, +; so if the value 1..8 appears in the final FD image, +; tool failure occurs +; +ApSegAddress: dd 0x12345678 + + ; ORG 0x3c + TIMES 0x3c-($-$$) DB 0 +; +; BFV Base is at 0xFFFFFFFC +; This will be fixed up by some build tool, +; so if the value 1..8 appears in the final FD image, +; tool failure occurs. +; +BfvBase: DD 0x12345678 + +; +; Nothing can go here, otherwise the layout of this file would change. +; + + ; END diff --git a/IntelFsp2Pkg/FspSecCore/Vtf0/ResetVectorCode.asm b/IntelFsp2Pkg/FspSecCore/Vtf0/ResetVectorCode.asm new file mode 100644 index 0000000000..72b252491f --- /dev/null +++ b/IntelFsp2Pkg/FspSecCore/Vtf0/ResetVectorCode.asm @@ -0,0 +1,17 @@ +;------------------------------------------------------------------------------ +; @file +; This file includes all other code files to assemble the reset vector code +; +; Copyright (c) 2014, Intel Corporation. All rights reserved.
+; This program and the accompanying materials +; are licensed and made available under the terms and conditions of the BSD License +; which accompanies this distribution. The full text of the license may be found at +; http://opensource.org/licenses/bsd-license.php +; +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +; +;------------------------------------------------------------------------------ + + +%include "Ia16/ResetVec.asm16" diff --git a/IntelFsp2Pkg/FspSecCore/Vtf0/Tools/FixupForRawSection.py b/IntelFsp2Pkg/FspSecCore/Vtf0/Tools/FixupForRawSection.py new file mode 100644 index 0000000000..8e7c20b401 --- /dev/null +++ b/IntelFsp2Pkg/FspSecCore/Vtf0/Tools/FixupForRawSection.py @@ -0,0 +1,110 @@ +## @file +# Apply fixup to VTF binary image for FFS Raw section +# +# Copyright (c) 2014, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# + +import sys + +filename = sys.argv[1] + +if filename.lower().find('ia32') >= 0: + d = open(sys.argv[1], 'rb').read() + c = ((len(d) + 4 + 7) & ~7) - 4 + if c > len(d): + c -= len(d) + f = open(sys.argv[1], 'wb') + f.write('\x90' * c) + f.write(d) + f.close() +else: + from struct import pack + + PAGE_PRESENT = 0x01 + PAGE_READ_WRITE = 0x02 + PAGE_USER_SUPERVISOR = 0x04 + PAGE_WRITE_THROUGH = 0x08 + PAGE_CACHE_DISABLE = 0x010 + PAGE_ACCESSED = 0x020 + PAGE_DIRTY = 0x040 + PAGE_PAT = 0x080 + PAGE_GLOBAL = 0x0100 + PAGE_2M_MBO = 0x080 + PAGE_2M_PAT = 0x01000 + + def NopAlign4k(s): + c = ((len(s) + 0xfff) & ~0xfff) - len(s) + return ('\x90' * c) + s + + def PageDirectoryEntries4GbOf2MbPages(baseAddress): + + s = '' + for i in range(0x800): + i = ( + baseAddress + long(i << 21) + + PAGE_2M_MBO + + PAGE_CACHE_DISABLE + + PAGE_ACCESSED + + PAGE_DIRTY + + PAGE_READ_WRITE + + PAGE_PRESENT + ) + s += pack('Q', i) + return s + + def PageDirectoryPointerTable4GbOf2MbPages(pdeBase): + s = '' + for i in range(0x200): + i = ( + pdeBase + + (min(i, 3) << 12) + + PAGE_CACHE_DISABLE + + PAGE_ACCESSED + + PAGE_READ_WRITE + + PAGE_PRESENT + ) + s += pack('Q', i) + return s + + def PageMapLevel4Table4GbOf2MbPages(pdptBase): + s = '' + for i in range(0x200): + i = ( + pdptBase + + (min(i, 0) << 12) + + PAGE_CACHE_DISABLE + + PAGE_ACCESSED + + PAGE_READ_WRITE + + PAGE_PRESENT + ) + s += pack('Q', i) + return s + + def First4GbPageEntries(topAddress): + PDE = PageDirectoryEntries4GbOf2MbPages(0L) + pml4tBase = topAddress - 0x1000 + pdptBase = pml4tBase - 0x1000 + pdeBase = pdptBase - len(PDE) + PDPT = PageDirectoryPointerTable4GbOf2MbPages(pdeBase) + PML4T = PageMapLevel4Table4GbOf2MbPages(pdptBase) + return PDE + PDPT + PML4T + + def AlignAndAddPageTables(): + d = open(sys.argv[1], 'rb').read() + code = NopAlign4k(d) + topAddress = 0x100000000 - len(code) + d = ('\x90' * 4) + First4GbPageEntries(topAddress) + code + f = open(sys.argv[1], 'wb') + f.write(d) + f.close() + + AlignAndAddPageTables() + diff --git a/IntelFsp2Pkg/Include/FspDataTable.h b/IntelFsp2Pkg/Include/FspDataTable.h new file mode 100644 index 0000000000..3c79f34e47 --- /dev/null +++ b/IntelFsp2Pkg/Include/FspDataTable.h @@ -0,0 +1,32 @@ +/** @file + The header file of FSP data table + + Copyright (c) 2016, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef _FSP_DATA_TABLE_H_ +#define _FSP_DATA_TABLE_H_ + +#pragma pack(1) + +#define FSP_DATA_SIGNATURE SIGNATURE_32 ('F', 'S', 'P', 'D') + +typedef struct { + UINT32 Signature; + UINT32 Length; + UINT32 FsptBase; + UINT32 FspmBase; + UINT32 FspsBase; +} FSP_DATA_TABLE; + +#pragma pack() + +#endif diff --git a/IntelFsp2Pkg/Include/FspEas.h b/IntelFsp2Pkg/Include/FspEas.h new file mode 100644 index 0000000000..79bb0b8e8e --- /dev/null +++ b/IntelFsp2Pkg/Include/FspEas.h @@ -0,0 +1,24 @@ +/** @file + Intel FSP definition from Intel Firmware Support Package External + Architecture Specification v2.0. + + Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef _FSP_EAS_H_ +#define _FSP_EAS_H_ + +#include +#include +#include +#include + +#endif diff --git a/IntelFsp2Pkg/Include/FspEas/FspApi.h b/IntelFsp2Pkg/Include/FspEas/FspApi.h new file mode 100644 index 0000000000..f7c71681c8 --- /dev/null +++ b/IntelFsp2Pkg/Include/FspEas/FspApi.h @@ -0,0 +1,241 @@ +/** @file + Intel FSP API definition from Intel Firmware Support Package External + Architecture Specification v2.0. + + Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef _FSP_API_H_ +#define _FSP_API_H_ + +#pragma pack(1) +typedef struct { + /// + /// UPD Region Signature. This signature will be + /// "XXXXXX_T" for FSP-T + /// "XXXXXX_M" for FSP-M + /// "XXXXXX_S" for FSP-S + /// Where XXXXXX is an unique signature + /// + UINT64 Signature; + /// + /// Revision of the Data structure. For FSP v2.0 value is 1. + /// + UINT8 Revision; + UINT8 Reserved[23]; +} FSP_UPD_HEADER; + +typedef struct { + /// + /// Revision of the structure. For FSP v2.0 value is 1. + /// + UINT8 Revision; + UINT8 Reserved[3]; + /// + /// Pointer to the non-volatile storage (NVS) data buffer. + /// If it is NULL it indicates the NVS data is not available. + /// + VOID *NvsBufferPtr; + /// + /// Pointer to the temporary stack base address to be + /// consumed inside FspMemoryInit() API. + /// + VOID *StackBase; + /// + /// Temporary stack size to be consumed inside + /// FspMemoryInit() API. + /// + UINT32 StackSize; + /// + /// Size of memory to be reserved by FSP below "top + /// of low usable memory" for bootloader usage. + /// + UINT32 BootLoaderTolumSize; + /// + /// Current boot mode. + /// + UINT32 BootMode; + UINT8 Reserved1[8]; +} FSPM_ARCH_UPD; + +typedef struct { + FSP_UPD_HEADER FspUpdHeader; +} FSPT_UPD_COMMON; + +typedef struct { + FSP_UPD_HEADER FspUpdHeader; + FSPM_ARCH_UPD FspmArchUpd; +} FSPM_UPD_COMMON; + +typedef struct { + FSP_UPD_HEADER FspUpdHeader; +} FSPS_UPD_COMMON; + +typedef enum { + /// + /// This stage is notified when the bootloader completes the + /// PCI enumeration and the resource allocation for the + /// PCI devices is complete. + /// + EnumInitPhaseAfterPciEnumeration = 0x20, + /// + /// This stage is notified just before the bootloader hand-off + /// to the OS loader. + /// + EnumInitPhaseReadyToBoot = 0x40, + /// + /// This stage is notified just before the firmware/Preboot + /// environment transfers management of all system resources + /// to the OS or next level execution environment. + /// + EnumInitPhaseEndOfFirmware = 0xF0 +} FSP_INIT_PHASE; + +typedef struct { + /// + /// Notification phase used for NotifyPhase API + /// + FSP_INIT_PHASE Phase; +} NOTIFY_PHASE_PARAMS; + +#pragma pack() + +/** + This FSP API is called soon after coming out of reset and before memory and stack is + available. This FSP API will load the microcode update, enable code caching for the + region specified by the boot loader and also setup a temporary stack to be used until + main memory is initialized. + + A hardcoded stack can be set up with the following values, and the "esp" register + initialized to point to this hardcoded stack. + 1. The return address where the FSP will return control after setting up a temporary + stack. + 2. A pointer to the input parameter structure + + However, since the stack is in ROM and not writeable, this FSP API cannot be called + using the "call" instruction, but needs to be jumped to. + + @param[in] FsptUpdDataPtr Pointer to the FSPT_UPD data structure. + + @retval EFI_SUCCESS Temporary RAM was initialized successfully. + @retval EFI_INVALID_PARAMETER Input parameters are invalid. + @retval EFI_UNSUPPORTED The FSP calling conditions were not met. + @retval EFI_DEVICE_ERROR Temp RAM initialization failed. + + If this function is successful, the FSP initializes the ECX and EDX registers to point to + a temporary but writeable memory range available to the boot loader and returns with + FSP_SUCCESS in register EAX. Register ECX points to the start of this temporary + memory range and EDX points to the end of the range. Boot loader is free to use the + whole range described. Typically the boot loader can reload the ESP register to point + to the end of this returned range so that it can be used as a standard stack. +**/ +typedef +EFI_STATUS +(EFIAPI *FSP_TEMP_RAM_INIT) ( + IN VOID *FsptUpdDataPtr + ); + +/** + This FSP API is used to notify the FSP about the different phases in the boot process. + This allows the FSP to take appropriate actions as needed during different initialization + phases. The phases will be platform dependent and will be documented with the FSP + release. The current FSP supports two notify phases: + Post PCI enumeration + Ready To Boot + + @param[in] NotifyPhaseParamPtr Address pointer to the NOTIFY_PHASE_PRAMS + + @retval EFI_SUCCESS The notification was handled successfully. + @retval EFI_UNSUPPORTED The notification was not called in the proper order. + @retval EFI_INVALID_PARAMETER The notification code is invalid. +**/ +typedef +EFI_STATUS +(EFIAPI *FSP_NOTIFY_PHASE) ( + IN NOTIFY_PHASE_PARAMS *NotifyPhaseParamPtr + ); + +/** + This FSP API is called after TempRamInit and initializes the memory. + This FSP API accepts a pointer to a data structure that will be platform dependent + and defined for each FSP binary. This will be documented in Integration guide with + each FSP release. + After FspMemInit completes its execution, it passes the pointer to the HobList and + returns to the boot loader from where it was called. BootLoader is responsible to + migrate it's stack and data to Memory. + FspMemoryInit, TempRamExit and FspSiliconInit APIs provide an alternate method to + complete the silicon initialization and provides bootloader an opportunity to get + control after system memory is available and before the temporary RAM is torn down. + + @param[in] FspmUpdDataPtr Pointer to the FSPM_UPD data sructure. + @param[out] HobListPtr Pointer to receive the address of the HOB list. + + @retval EFI_SUCCESS FSP execution environment was initialized successfully. + @retval EFI_INVALID_PARAMETER Input parameters are invalid. + @retval EFI_UNSUPPORTED The FSP calling conditions were not met. + @retval EFI_DEVICE_ERROR FSP initialization failed. + @retval EFI_OUT_OF_RESOURCES Stack range requested by FSP is not met. + @retval FSP_STATUS_RESET_REQUIREDx A reset is reuired. These status codes will not be returned during S3. +**/ +typedef +EFI_STATUS +(EFIAPI *FSP_MEMORY_INIT) ( + IN VOID *FspmUpdDataPtr, + OUT VOID **HobListPtr + ); + + +/** + This FSP API is called after FspMemoryInit API. This FSP API tears down the temporary + memory setup by TempRamInit API. This FSP API accepts a pointer to a data structure + that will be platform dependent and defined for each FSP binary. This will be + documented in Integration Guide. + FspMemoryInit, TempRamExit and FspSiliconInit APIs provide an alternate method to + complete the silicon initialization and provides bootloader an opportunity to get + control after system memory is available and before the temporary RAM is torn down. + + @param[in] TempRamExitParamPtr Pointer to the Temp Ram Exit parameters structure. + This structure is normally defined in the Integration Guide. + And if it is not defined in the Integration Guide, pass NULL. + + @retval EFI_SUCCESS FSP execution environment was initialized successfully. + @retval EFI_INVALID_PARAMETER Input parameters are invalid. + @retval EFI_UNSUPPORTED The FSP calling conditions were not met. + @retval EFI_DEVICE_ERROR FSP initialization failed. +**/ +typedef +EFI_STATUS +(EFIAPI *FSP_TEMP_RAM_EXIT) ( + IN VOID *TempRamExitParamPtr + ); + + +/** + This FSP API is called after TempRamExit API. + FspMemoryInit, TempRamExit and FspSiliconInit APIs provide an alternate method to complete the + silicon initialization. + + @param[in] FspsUpdDataPtr Pointer to the FSPS_UPD data structure. + If NULL, FSP will use the default parameters. + + @retval EFI_SUCCESS FSP execution environment was initialized successfully. + @retval EFI_INVALID_PARAMETER Input parameters are invalid. + @retval EFI_UNSUPPORTED The FSP calling conditions were not met. + @retval EFI_DEVICE_ERROR FSP initialization failed. + @retval FSP_STATUS_RESET_REQUIREDx A reset is reuired. These status codes will not be returned during S3. +**/ +typedef +EFI_STATUS +(EFIAPI *FSP_SILICON_INIT) ( + IN VOID *FspsUpdDataPtr + ); + +#endif diff --git a/IntelFsp2Pkg/Include/FspGlobalData.h b/IntelFsp2Pkg/Include/FspGlobalData.h new file mode 100644 index 0000000000..a484d16dcc --- /dev/null +++ b/IntelFsp2Pkg/Include/FspGlobalData.h @@ -0,0 +1,68 @@ +/** @file + + Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef _FSP_GLOBAL_DATA_H_ +#define _FSP_GLOBAL_DATA_H_ + +#include + +#pragma pack(1) + +typedef enum { + TempRamInitApiIndex, + FspInitApiIndex, + NotifyPhaseApiIndex, + FspMemoryInitApiIndex, + TempRamExitApiIndex, + FspSiliconInitApiIndex, + FspApiIndexMax +} FSP_API_INDEX; + +typedef struct { + VOID *DataPtr; + UINT32 MicrocodeRegionBase; + UINT32 MicrocodeRegionSize; + UINT32 CodeRegionBase; + UINT32 CodeRegionSize; + UINT32 CarBase; + UINT32 CarSize; +} FSP_PLAT_DATA; + +#define FSP_GLOBAL_DATA_SIGNATURE SIGNATURE_32 ('F', 'S', 'P', 'D') +#define FSP_PERFORMANCE_DATA_SIGNATURE SIGNATURE_32 ('P', 'E', 'R', 'F') + +typedef struct { + UINT32 Signature; + UINT8 Version; + UINT8 Reserved1[3]; + UINT32 CoreStack; + UINT32 StatusCode; + UINT32 Reserved2[8]; + FSP_PLAT_DATA PlatformData; + FSP_INFO_HEADER *FspInfoHeader; + VOID *UpdDataPtr; + VOID *TempRamInitUpdPtr; + VOID *MemoryInitUpdPtr; + VOID *SiliconInitUpdPtr; + UINT8 ApiIdx; + UINT8 Reserved3[31]; + UINT32 PerfSig; + UINT16 PerfLen; + UINT16 Reserved4; + UINT32 PerfIdx; + UINT64 PerfData[32]; +} FSP_GLOBAL_DATA; + +#pragma pack() + +#endif diff --git a/IntelFsp2Pkg/Include/FspMeasurePointId.h b/IntelFsp2Pkg/Include/FspMeasurePointId.h new file mode 100644 index 0000000000..ee103df795 --- /dev/null +++ b/IntelFsp2Pkg/Include/FspMeasurePointId.h @@ -0,0 +1,62 @@ +/** @file + + Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef _FSP_MEASURE_POINT_ID_H_ +#define _FSP_MEASURE_POINT_ID_H_ + +// +// 0xD0 - 0xEF are reserved for FSP common measure point +// +#define FSP_PERF_ID_MRC_INIT_ENTRY 0xD0 +#define FSP_PERF_ID_MRC_INIT_EXIT (FSP_PERF_ID_MRC_INIT_ENTRY + 1) + +#define FSP_PERF_ID_SYSTEM_AGENT_INIT_ENTRY 0xD8 +#define FSP_PERF_ID_SYSTEM_AGENT_INIT_EXIT (FSP_PERF_ID_SYSTEM_AGENT_INIT_ENTRY + 1) + +#define FSP_PERF_ID_PCH_INIT_ENTRY 0xDA +#define FSP_PERF_ID_PCH_INIT_EXIT (FSP_PERF_ID_PCH_INIT_ENTRY + 1) + +#define FSP_PERF_ID_CPU_INIT_ENTRY 0xE0 +#define FSP_PERF_ID_CPU_INIT_EXIT (FSP_PERF_ID_CPU_INIT_ENTRY + 1) + +#define FSP_PERF_ID_GFX_INIT_ENTRY 0xE8 +#define FSP_PERF_ID_GFX_INIT_EXIT (FSP_PERF_ID_GFX_INIT_ENTRY + 1) + +#define FSP_PERF_ID_ME_INIT_ENTRY 0xEA +#define FSP_PERF_ID_ME_INIT_EXIT (FSP_PERF_ID_ME_INIT_ENTRY + 1) + +// +// 0xF0 - 0xFF are reserved for FSP API +// +#define FSP_PERF_ID_API_TEMP_RAM_INIT_ENTRY 0xF0 +#define FSP_PERF_ID_API_TEMP_RAM_INIT_EXIT (FSP_PERF_ID_API_TEMP_RAM_INIT_ENTRY + 1) + +#define FSP_PERF_ID_API_FSP_MEMORY_INIT_ENTRY 0xF2 +#define FSP_PERF_ID_API_FSP_MEMORY_INIT_EXIT (FSP_PERF_ID_API_FSP_MEMORY_INIT_ENTRY + 1) + +#define FSP_PERF_ID_API_TEMP_RAM_EXIT_ENTRY 0xF4 +#define FSP_PERF_ID_API_TEMP_RAM_EXIT_EXIT (FSP_PERF_ID_API_TEMP_RAM_EXIT_ENTRY + 1) + +#define FSP_PERF_ID_API_FSP_SILICON_INIT_ENTRY 0xF6 +#define FSP_PERF_ID_API_FSP_SILICON_INIT_EXIT (FSP_PERF_ID_API_FSP_SILICON_INIT_ENTRY + 1) + +#define FSP_PERF_ID_API_NOTIFY_POST_PCI_ENTRY 0xF8 +#define FSP_PERF_ID_API_NOTIFY_POST_PCI_EXIT (FSP_PERF_ID_API_NOTIFY_POST_PCI_ENTRY + 1) + +#define FSP_PERF_ID_API_NOTIFY_READY_TO_BOOT_ENTRY 0xFA +#define FSP_PERF_ID_API_NOTIFY_READY_TO_BOOT_EXIT (FSP_PERF_ID_API_NOTIFY_READY_TO_BOOT_ENTRY + 1) + +#define FSP_PERF_ID_API_NOTIFY_END_OF_FIRMWARE_ENTRY 0xFC +#define FSP_PERF_ID_API_NOTIFY_END_OF_FIRMWARE_EXIT (FSP_PERF_ID_API_NOTIFY_END_OF_FIRMWARE_ENTRY + 1) + +#endif diff --git a/IntelFsp2Pkg/Include/FspStatusCode.h b/IntelFsp2Pkg/Include/FspStatusCode.h new file mode 100644 index 0000000000..c9a316e6e7 --- /dev/null +++ b/IntelFsp2Pkg/Include/FspStatusCode.h @@ -0,0 +1,46 @@ +/** @file + Intel FSP status code definition + + Copyright (c) 2016, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef _FSP_STATUS_CODE_H_ +#define _FSP_STATUS_CODE_H_ + +// +// FSP API - 4 BITS +// +#define FSP_STATUS_CODE_TEMP_RAM_INIT 0xF000 +#define FSP_STATUS_CODE_MEMORY_INIT 0xD000 +#define FSP_STATUS_CODE_TEMP_RAM_EXIT 0xB000 +#define FSP_STATUS_CODE_SILICON_INIT 0x9000 +#define FSP_STATUS_CODE_POST_PCIE_ENUM_NOTIFICATION 0x6000 +#define FSP_STATUS_CODE_READY_TO_BOOT_NOTIFICATION 0x4000 +#define FSP_STATUS_CODE_END_OF_FIRMWARE_NOTIFICATION 0x2000 + +// +// MODULE - 4 BITS +// +#define FSP_STATUS_CODE_GFX_PEIM 0x0700 +#define FSP_STATUS_CODE_COMMON_CODE 0x0800 +#define FSP_STATUS_CODE_SILICON_COMMON_CODE 0x0900 +#define FSP_STATUS_CODE_SYSTEM_AGENT 0x0A00 +#define FSP_STATUS_CODE_PCH 0x0B00 +#define FSP_STATUS_CODE_CPU 0x0C00 +#define FSP_STATUS_CODE_MRC 0x0D00 +#define FSP_STATUS_CODE_ME_BIOS 0x0E00 +// +// Individual Codes - 1 BYTE +// +#define FSP_STATUS_CODE_API_ENTRY 0x0000 +#define FSP_STATUS_CODE_API_EXIT 0x007F + +#endif diff --git a/IntelFsp2Pkg/Include/Guid/FspHeaderFile.h b/IntelFsp2Pkg/Include/Guid/FspHeaderFile.h new file mode 100644 index 0000000000..96cac00124 --- /dev/null +++ b/IntelFsp2Pkg/Include/Guid/FspHeaderFile.h @@ -0,0 +1,204 @@ +/** @file + Intel FSP Header File definition from Intel Firmware Support Package External + Architecture Specification v2.0. + + Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef __FSP_HEADER_FILE_H__ +#define __FSP_HEADER_FILE_H__ + +#define FSP_HEADER_REVISION_3 3 + +#define FSPE_HEADER_REVISION_1 1 +#define FSPP_HEADER_REVISION_1 1 + +/// +/// Fixed FSP header offset in the FSP image +/// +#define FSP_INFO_HEADER_OFF 0x94 + +#define OFFSET_IN_FSP_INFO_HEADER(x) (UINT32)&((FSP_INFO_HEADER *)(UINTN)0)->x + +#define FSP_INFO_HEADER_SIGNATURE SIGNATURE_32 ('F', 'S', 'P', 'H') + +#pragma pack(1) + +/// +/// FSP Information Header as described in FSP v2.0 Spec section 5.1.1. +/// +typedef struct { + /// + /// Byte 0x00: Signature ('FSPH') for the FSP Information Header. + /// + UINT32 Signature; + /// + /// Byte 0x04: Length of the FSP Information Header. + /// + UINT32 HeaderLength; + /// + /// Byte 0x08: Reserved. + /// + UINT8 Reserved1[2]; + /// + /// Byte 0x0A: Indicates compliance with a revision of this specification in the BCD format. + /// + UINT8 SpecVersion; + /// + /// Byte 0x0B: Revision of the FSP Information Header. + /// + UINT8 HeaderRevision; + /// + /// Byte 0x0C: Revision of the FSP binary. + /// + UINT32 ImageRevision; + /// + /// Byte 0x10: Signature string that will help match the FSP Binary to a supported HW configuration. + /// + CHAR8 ImageId[8]; + /// + /// Byte 0x18: Size of the entire FSP binary. + /// + UINT32 ImageSize; + /// + /// Byte 0x1C: FSP binary preferred base address. + /// + UINT32 ImageBase; + /// + /// Byte 0x20: Attribute for the FSP binary. + /// + UINT16 ImageAttribute; + /// + /// Byte 0x22: Attributes of the FSP Component. + /// + UINT16 ComponentAttribute; + /// + /// Byte 0x24: Offset of the FSP configuration region. + /// + UINT32 CfgRegionOffset; + /// + /// Byte 0x28: Size of the FSP configuration region. + /// + UINT32 CfgRegionSize; + /// + /// Byte 0x2C: Reserved2. + /// + UINT32 Reserved2; + /// + /// Byte 0x30: The offset for the API to setup a temporary stack till the memory is initialized. + /// + UINT32 TempRamInitEntryOffset; + /// + /// Byte 0x34: Reserved3. + /// + UINT32 Reserved3; + /// + /// Byte 0x38: The offset for the API to inform the FSP about the different stages in the boot process. + /// + UINT32 NotifyPhaseEntryOffset; + /// + /// Byte 0x3C: The offset for the API to initialize the memory. + /// + UINT32 FspMemoryInitEntryOffset; + /// + /// Byte 0x40: The offset for the API to tear down temporary RAM. + /// + UINT32 TempRamExitEntryOffset; + /// + /// Byte 0x44: The offset for the API to initialize the CPU and chipset. + /// + UINT32 FspSiliconInitEntryOffset; +} FSP_INFO_HEADER; + +/// +/// Signature of the FSP Extended Header +/// +#define FSP_INFO_EXTENDED_HEADER_SIGNATURE SIGNATURE_32 ('F', 'S', 'P', 'E') + +/// +/// FSP Information Extended Header as described in FSP v2.0 Spec section 5.1.2. +/// +typedef struct { + /// + /// Byte 0x00: Signature ('FSPE') for the FSP Extended Information Header. + /// + UINT32 Signature; + /// + /// Byte 0x04: Length of the table in bytes, including all additional FSP producer defined data. + /// + UINT32 Length; + /// + /// Byte 0x08: FSP producer defined revision of the table. + /// + UINT8 Revision; + /// + /// Byte 0x09: Reserved for future use. + /// + UINT8 Reserved; + /// + /// Byte 0x0A: FSP producer identification string + /// + CHAR8 FspProducerId[6]; + /// + /// Byte 0x10: FSP producer implementation revision number. Larger numbers are assumed to be newer revisions. + /// + UINT32 FspProducerRevision; + /// + /// Byte 0x14: Size of the FSP producer defined data (n) in bytes. + /// + UINT32 FspProducerDataSize; + /// + /// Byte 0x18: FSP producer defined data of size (n) defined by FspProducerDataSize. + /// +} FSP_INFO_EXTENDED_HEADER; + +// +// A generic table search algorithm for additional tables can be implemented with a +// signature search algorithm until a terminator signature 'FSPP' is found. +// +#define FSP_FSPP_SIGNATURE SIGNATURE_32 ('F', 'S', 'P', 'P') +#define FSP_PATCH_TABLE_SIGNATURE FSP_FSPP_SIGNATURE + +/// +/// FSP Patch Table as described in FSP v2.0 Spec section 5.1.5. +/// +typedef struct { + /// + /// Byte 0x00: FSP Patch Table Signature "FSPP". + /// + UINT32 Signature; + /// + /// Byte 0x04: Size including the PatchData. + /// + UINT16 HeaderLength; + /// + /// Byte 0x06: Revision is set to 0x01. + /// + UINT8 HeaderRevision; + /// + /// Byte 0x07: Reserved for future use. + /// + UINT8 Reserved; + /// + /// Byte 0x08: Number of entries to Patch. + /// + UINT32 PatchEntryNum; + /// + /// Byte 0x0C: Patch Data. + /// +//UINT32 PatchData[]; +} FSP_PATCH_TABLE; + +#pragma pack() + +extern EFI_GUID gFspHeaderFileGuid; + +#endif diff --git a/IntelFsp2Pkg/Include/Guid/GuidHobFspEas.h b/IntelFsp2Pkg/Include/Guid/GuidHobFspEas.h new file mode 100644 index 0000000000..83c7f0068f --- /dev/null +++ b/IntelFsp2Pkg/Include/Guid/GuidHobFspEas.h @@ -0,0 +1,23 @@ +/** @file + Intel FSP Hob Guid definition from Intel Firmware Support Package External + Architecture Specification v2.0. + + Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef __GUID_HOB_FSP_EAS_GUID__ +#define __GUID_HOB_FSP_EAS_GUID__ + +extern EFI_GUID gFspBootLoaderTolumHobGuid; +extern EFI_GUID gFspReservedMemoryResourceHobGuid; +extern EFI_GUID gFspNonVolatileStorageHobGuid; + +#endif diff --git a/IntelFsp2Pkg/Include/Library/CacheAsRamLib.h b/IntelFsp2Pkg/Include/Library/CacheAsRamLib.h new file mode 100644 index 0000000000..6f3d068b67 --- /dev/null +++ b/IntelFsp2Pkg/Include/Library/CacheAsRamLib.h @@ -0,0 +1,30 @@ +/** @file + + Copyright (c) 2014, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef _CACHE_AS_RAM_LIB_H_ +#define _CACHE_AS_RAM_LIB_H_ + +/** + This function disable CAR. + + @param[in] DisableCar TRUE means use INVD, FALSE means use WBINVD + +**/ +VOID +EFIAPI +DisableCacheAsRam ( + IN BOOLEAN DisableCar + ); + +#endif + diff --git a/IntelFsp2Pkg/Include/Library/CacheLib.h b/IntelFsp2Pkg/Include/Library/CacheLib.h new file mode 100644 index 0000000000..909ae928f1 --- /dev/null +++ b/IntelFsp2Pkg/Include/Library/CacheLib.h @@ -0,0 +1,62 @@ +/** @file + + Copyright (c) 2014, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef _CACHE_LIB_H_ +#define _CACHE_LIB_H_ + +// +// EFI_MEMORY_CACHE_TYPE +// +typedef INT32 EFI_MEMORY_CACHE_TYPE; + +#define EFI_CACHE_UNCACHEABLE 0 +#define EFI_CACHE_WRITECOMBINING 1 +#define EFI_CACHE_WRITETHROUGH 4 +#define EFI_CACHE_WRITEPROTECTED 5 +#define EFI_CACHE_WRITEBACK 6 + +/** + Reset all the MTRRs to a known state. + + @retval EFI_SUCCESS All MTRRs have been reset successfully. + +**/ +EFI_STATUS +EFIAPI +ResetCacheAttributes ( + VOID + ); + +/** + Given the memory range and cache type, programs the MTRRs. + + @param[in] MemoryAddress Base Address of Memory to program MTRR. + @param[in] MemoryLength Length of Memory to program MTRR. + @param[in] MemoryCacheType Cache Type. + + @retval EFI_SUCCESS Mtrr are set successfully. + @retval EFI_LOAD_ERROR No empty MTRRs to use. + @retval EFI_INVALID_PARAMETER The input parameter is not valid. + @retval others An error occurs when setting MTTR. + +**/ +EFI_STATUS +EFIAPI +SetCacheAttributes ( + IN EFI_PHYSICAL_ADDRESS MemoryAddress, + IN UINT64 MemoryLength, + IN EFI_MEMORY_CACHE_TYPE MemoryCacheType + ); + +#endif + diff --git a/IntelFsp2Pkg/Include/Library/DebugDeviceLib.h b/IntelFsp2Pkg/Include/Library/DebugDeviceLib.h new file mode 100644 index 0000000000..5c35eda579 --- /dev/null +++ b/IntelFsp2Pkg/Include/Library/DebugDeviceLib.h @@ -0,0 +1,29 @@ +/** @file + + Copyright (c) 2014, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef __DEBUG_DEVICE_LIB_H__ +#define __DEBUG_DEVICE_LIB_H__ + +/** + Returns the debug print device enable state. + + @return Debug print device enable state. + +**/ +UINT8 +EFIAPI +GetDebugPrintDeviceEnable ( + VOID + ); + +#endif diff --git a/IntelFsp2Pkg/Include/Library/FspCommonLib.h b/IntelFsp2Pkg/Include/Library/FspCommonLib.h new file mode 100644 index 0000000000..0bb0c53786 --- /dev/null +++ b/IntelFsp2Pkg/Include/Library/FspCommonLib.h @@ -0,0 +1,312 @@ +/** @file + + Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef _FSP_COMMON_LIB_H_ +#define _FSP_COMMON_LIB_H_ + +#include +#include + +/** + This function sets the FSP global data pointer. + + @param[in] FspData Fsp global data pointer. + +**/ +VOID +EFIAPI +SetFspGlobalDataPointer ( + IN FSP_GLOBAL_DATA *FspData + ); + +/** + This function gets the FSP global data pointer. + +**/ +FSP_GLOBAL_DATA * +EFIAPI +GetFspGlobalDataPointer ( + VOID + ); + +/** + This function gets back the FSP API first parameter passed by the bootlaoder. + + @retval ApiParameter FSP API first parameter passed by the bootlaoder. +**/ +UINT32 +EFIAPI +GetFspApiParameter ( + VOID + ); + +/** + This function gets back the FSP API second parameter passed by the bootlaoder. + + @retval ApiParameter FSP API second parameter passed by the bootlaoder. +**/ +UINT32 +EFIAPI +GetFspApiParameter2 ( + VOID + ); + +/** + This function sets the FSP API parameter in the stack. + + @param[in] Value New parameter value. + +**/ +VOID +EFIAPI +SetFspApiParameter ( + IN UINT32 Value + ); + +/** + This function set the API status code returned to the BootLoader. + + @param[in] ReturnStatus Status code to return. + +**/ +VOID +EFIAPI +SetFspApiReturnStatus ( + IN UINT32 ReturnStatus + ); + +/** + This function sets the context switching stack to a new stack frame. + + @param[in] NewStackTop New core stack to be set. + +**/ +VOID +EFIAPI +SetFspCoreStackPointer ( + IN VOID *NewStackTop + ); + +/** + This function sets the platform specific data pointer. + + @param[in] PlatformData Fsp platform specific data pointer. + +**/ +VOID +EFIAPI +SetFspPlatformDataPointer ( + IN VOID *PlatformData + ); + +/** + This function gets the platform specific data pointer. + + @param[in] PlatformData Fsp platform specific data pointer. + +**/ +VOID * +EFIAPI +GetFspPlatformDataPointer ( + VOID + ); + +/** + This function sets the UPD data pointer. + + @param[in] UpdDataPtr UPD data pointer. +**/ +VOID +EFIAPI +SetFspUpdDataPointer ( + IN VOID *UpdDataPtr + ); + +/** + This function gets the UPD data pointer. + + @return UpdDataPtr UPD data pointer. +**/ +VOID * +EFIAPI +GetFspUpdDataPointer ( + VOID + ); + +/** + This function sets the memory init UPD data pointer. + + @param[in] MemoryInitUpdPtr memory init UPD data pointer. +**/ +VOID +EFIAPI +SetFspMemoryInitUpdDataPointer ( + IN VOID *MemoryInitUpdPtr + ); + +/** + This function gets the memory init UPD data pointer. + + @return memory init UPD data pointer. +**/ +VOID * +EFIAPI +GetFspMemoryInitUpdDataPointer ( + VOID + ); + +/** + This function sets the silicon init UPD data pointer. + + @param[in] SiliconInitUpdPtr silicon init UPD data pointer. +**/ +VOID +EFIAPI +SetFspSiliconInitUpdDataPointer ( + IN VOID *SiliconInitUpdPtr + ); + +/** + This function gets the silicon init UPD data pointer. + + @return silicon init UPD data pointer. +**/ +VOID * +EFIAPI +GetFspSiliconInitUpdDataPointer ( + VOID + ); + +/** + Set FSP measurement point timestamp. + + @param[in] Id Measurement point ID. + + @return performance timestamp. +**/ +UINT64 +EFIAPI +SetFspMeasurePoint ( + IN UINT8 Id + ); + +/** + This function gets the FSP info header pointer. + + @retval FspInfoHeader FSP info header pointer +**/ +FSP_INFO_HEADER * +EFIAPI +GetFspInfoHeader ( + VOID + ); + +/** + This function sets the FSP info header pointer. + + @param[in] FspInfoHeader FSP info header pointer +**/ +VOID +EFIAPI +SetFspInfoHeader ( + FSP_INFO_HEADER *FspInfoHeader + ); + +/** + This function gets the FSP info header pointer from the API context. + + @retval FspInfoHeader FSP info header pointer +**/ +FSP_INFO_HEADER * +EFIAPI +GetFspInfoHeaderFromApiContext ( + VOID + ); + +/** + This function gets the VPD data pointer. + + @return VpdDataRgnPtr VPD data pointer. +**/ +VOID * +EFIAPI +GetFspVpdDataPointer ( + VOID + ); + +/** + This function gets FSP API calling mode. + + @retval API calling mode +**/ +UINT8 +EFIAPI +GetFspApiCallingIndex ( + VOID + ); + +/** + This function sets FSP API calling mode. + + @param[in] Index API calling index +**/ +VOID +EFIAPI +SetFspApiCallingIndex ( + UINT8 Index + ); + +/** + This function gets FSP Phase StatusCode. + + @retval StatusCode +**/ +UINT32 +EFIAPI +GetPhaseStatusCode ( + VOID + ); + + +/** + This function sets FSP Phase StatusCode. + + @param[in] Mode Phase StatusCode +**/ +VOID +EFIAPI +SetPhaseStatusCode ( + UINT32 StatusCode + ); + +/** + This function gets FSP CAR base. + +**/ +UINT32 +EFIAPI +GetFspCarBase ( + VOID + ); + +/** + This function gets FSP CAR size. + +**/ +UINT32 +EFIAPI +GetFspCarSize ( + VOID + ); + +#endif diff --git a/IntelFsp2Pkg/Include/Library/FspPlatformLib.h b/IntelFsp2Pkg/Include/Library/FspPlatformLib.h new file mode 100644 index 0000000000..9247bd5221 --- /dev/null +++ b/IntelFsp2Pkg/Include/Library/FspPlatformLib.h @@ -0,0 +1,105 @@ +/** @file + + Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef _FSP_PLATFORM_LIB_H_ +#define _FSP_PLATFORM_LIB_H_ + +/** + Get system memory resource descriptor by owner. + + @param[in] OwnerGuid resource owner guid +**/ +EFI_HOB_RESOURCE_DESCRIPTOR * +EFIAPI +FspGetResourceDescriptorByOwner ( + IN EFI_GUID *OwnerGuid + ); + +/** + Get system memory from HOB. + + @param[in,out] LowMemoryLength less than 4G memory length + @param[in,out] HighMemoryLength greater than 4G memory length +**/ +VOID +EFIAPI +FspGetSystemMemorySize ( + IN OUT UINT64 *LowMemoryLength, + IN OUT UINT64 *HighMemoryLength + ); + +/** + Migrate BootLoader data before destroying CAR. + +**/ +VOID +EFIAPI +FspMigrateTemporaryMemory ( + VOID + ); + +/** + Set a new stack frame for the continuation function. + +**/ +VOID +EFIAPI +FspSetNewStackFrame ( + VOID + ); + +/** + This function transfer control back to BootLoader after FspSiliconInit. + +**/ +VOID +EFIAPI +FspSiliconInitDone ( + VOID + ); + +/** + This function returns control to BootLoader after MemoryInitApi. + + @param[in,out] HobListPtr The address of HobList pointer. +**/ +VOID +EFIAPI +FspMemoryInitDone ( + IN OUT VOID **HobListPtr + ); + +/** + This function returns control to BootLoader after TempRamExitApi. + +**/ +VOID +EFIAPI +FspTempRamExitDone ( + VOID + ); + +/** + This function handle NotifyPhase API call from the BootLoader. + It gives control back to the BootLoader after it is handled. If the + Notification code is a ReadyToBoot event, this function will return + and FSP continues the remaining execution until it reaches the DxeIpl. + +**/ +VOID +EFIAPI +FspWaitForNotify ( + VOID + ); + +#endif diff --git a/IntelFsp2Pkg/Include/Library/FspSecPlatformLib.h b/IntelFsp2Pkg/Include/Library/FspSecPlatformLib.h new file mode 100644 index 0000000000..cf2b0ffa2e --- /dev/null +++ b/IntelFsp2Pkg/Include/Library/FspSecPlatformLib.h @@ -0,0 +1,88 @@ +/** @file + + Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef _FSP_SEC_PLATFORM_LIB_H_ +#define _FSP_SEC_PLATFORM_LIB_H_ + +/** + This function performs platform level initialization. + + This function must be in ASM file, because stack is not established yet. + This function is optional. If a library instance does not provide this function, the default empty one will be used. + + The callee should not use XMM6/XMM7. + The return address is saved in MM7. + + @retval in saved in EAX - 0 means platform initialization success. + other means platform initialization fail. +**/ +UINT32 +EFIAPI +SecPlatformInit ( + VOID + ); + +/** + This function loads Microcode. + + This function must be in ASM file, because stack is not established yet. + This function is optional. If a library instance does not provide this function, the default one will be used. + + The callee should not use XMM6/XMM7. + The return address is saved in MM7. + + @param[in] FsptUpdDataPtr Address pointer to the FSPT_UPD data structure. It is saved in ESP. + + @retval in saved in EAX - 0 means Microcode is loaded successfully. + other means Microcode is not loaded successfully. +**/ +UINT32 +EFIAPI +LoadMicrocode ( + IN VOID *FsptUpdDataPtr + ); + +/** + This function initializes the CAR. + + This function must be in ASM file, because stack is not established yet. + + The callee should not use XMM6/XMM7. + The return address is saved in MM7. + + @param[in] FsptUpdDataPtr Address pointer to the FSPT_UPD data structure. It is saved in ESP. + + @retval in saved in EAX - 0 means CAR initialization success. + other means CAR initialization fail. +**/ +UINT32 +EFIAPI +SecCarInit ( + IN VOID *FsptUpdDataPtr + ); + +/** + This function check the signture of UPD. + + @param[in] ApiIdx Internal index of the FSP API. + @param[in] ApiParam Parameter of the FSP API. + +**/ +EFI_STATUS +EFIAPI +FspUpdSignatureCheck ( + IN UINT32 ApiIdx, + IN VOID *ApiParam + ); + +#endif diff --git a/IntelFsp2Pkg/Include/Library/FspSwitchStackLib.h b/IntelFsp2Pkg/Include/Library/FspSwitchStackLib.h new file mode 100644 index 0000000000..e90b13e8da --- /dev/null +++ b/IntelFsp2Pkg/Include/Library/FspSwitchStackLib.h @@ -0,0 +1,45 @@ +/** @file + + Copyright (c) 2014, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef _FSP_SWITCH_STACK_LIB_H_ +#define _FSP_SWITCH_STACK_LIB_H_ + +/** + + This funciton will switch the current stack to the previous saved stack. + Before calling the previous stack has to be set in FSP_GLOBAL_DATA.CoreStack. + EIP + FLAGS 16 bit FLAGS 16 bit + EDI + ESI + EBP + ESP + EBX + EDX + ECX + EAX + DWORD IDT base1 + StackPointer: DWORD IDT base2 + + @return ReturnKey After switching to the saved stack, + this value will be saved in eax before returning. + + +**/ +UINT32 +EFIAPI +Pei2LoaderSwitchStack ( + VOID + ); + +#endif diff --git a/IntelFsp2Pkg/IntelFsp2Pkg.dec b/IntelFsp2Pkg/IntelFsp2Pkg.dec new file mode 100644 index 0000000000..52024af4fb --- /dev/null +++ b/IntelFsp2Pkg/IntelFsp2Pkg.dec @@ -0,0 +1,80 @@ +## @file +# Provides driver and definitions to build fsp in EDKII bios. +# +# Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+# This program and the accompanying materials are licensed and made available under +# the terms and conditions of the BSD License that accompanies this distribution. +# The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +[Defines] + DEC_SPECIFICATION = 0x00010005 + PACKAGE_NAME = IntelFsp2Pkg + PACKAGE_GUID = A8C53B5E-D556-4F3E-874D-0D6FA2CDC7BF + PACKAGE_VERSION = 0.1 + +[Includes] + Include + +[LibraryClasses] + ## @libraryclass Provides cache-as-ram support. + CacheAsRamLib|Include/Library/CacheAsRamLib.h + + ## @libraryclass Provides cache setting on MTRR. + CacheLib|Include/Library/CacheLib.h + + ## @libraryclass Provides debug device abstraction. + DebugDeviceLib|Include/Library/DebugDeviceLib.h + + ## @libraryclass Provides FSP related services. + FspCommonLib|Include/Library/FspCommonLib.h + + ## @libraryclass Provides FSP platform related actions. + FspPlatformLib|Include/Library/FspPlatformLib.h + + ## @libraryclass Provides FSP switch stack function. + FspSwitchStackLib|Include/Library/FspSwitchStackLib.h + + ## @libraryclass Provides FSP platform sec related actions. + FspSecPlatformLib|Include/Library/FspSecPlatformLib.h + +[Guids] + # + # GUID defined in package + # + gIntelFsp2PkgTokenSpaceGuid = { 0xed6e0531, 0xf715, 0x4a3d, { 0x9b, 0x12, 0xc1, 0xca, 0x5e, 0xf6, 0x98, 0xa2 } } + + # Guid define in FSP EAS + gFspHeaderFileGuid = { 0x912740BE, 0x2284, 0x4734, { 0xB9, 0x71, 0x84, 0xB0, 0x27, 0x35, 0x3F, 0x0C } } + gFspReservedMemoryResourceHobGuid = { 0x69a79759, 0x1373, 0x4367, { 0xa6, 0xc4, 0xc7, 0xf5, 0x9e, 0xfd, 0x98, 0x6e } } + gFspNonVolatileStorageHobGuid = { 0x721acf02, 0x4d77, 0x4c2a, { 0xb3, 0xdc, 0x27, 0x0b, 0x7b, 0xa9, 0xe4, 0xb0 } } + gFspBootLoaderTolumHobGuid = { 0x73ff4f56, 0xaa8e, 0x4451, { 0xb3, 0x16, 0x36, 0x35, 0x36, 0x67, 0xad, 0x44 } } # FSP EAS v1.1 + + gFspPerformanceDataGuid = { 0x56ed21b6, 0xba23, 0x429e, { 0x89, 0x32, 0x37, 0x6d, 0x8e, 0x18, 0x2e, 0xe3 } } + gFspEventEndOfFirmwareGuid = { 0xbd44f629, 0xeae7, 0x4198, { 0x87, 0xf1, 0x39, 0xfa, 0xb0, 0xfd, 0x71, 0x7e } } + +[PcdsFixedAtBuild] + gIntelFsp2PkgTokenSpaceGuid.PcdGlobalDataPointerAddress |0xFED00108|UINT32|0x00000001 + gIntelFsp2PkgTokenSpaceGuid.PcdTemporaryRamBase |0xFEF00000|UINT32|0x10001001 + gIntelFsp2PkgTokenSpaceGuid.PcdTemporaryRamSize | 0x2000|UINT32|0x10001002 + gIntelFsp2PkgTokenSpaceGuid.PcdFspTemporaryRamSize | 0x1000|UINT32|0x10001003 + gIntelFsp2PkgTokenSpaceGuid.PcdFspReservedBufferSize | 0x100|UINT32|0x10001004 + gIntelFsp2PkgTokenSpaceGuid.PcdFspMaxPerfEntry | 32|UINT32|0x00002001 + gIntelFsp2PkgTokenSpaceGuid.PcdFspMaxPatchEntry | 6|UINT32|0x00002002 + gIntelFsp2PkgTokenSpaceGuid.PcdFspAreaBaseAddress |0xFFF80000|UINT32|0x10000001 + gIntelFsp2PkgTokenSpaceGuid.PcdFspAreaSize |0x00040000|UINT32|0x10000002 + gIntelFsp2PkgTokenSpaceGuid.PcdFspBootFirmwareVolumeBase|0xFFF80000|UINT32|0x10000003 + gIntelFsp2PkgTokenSpaceGuid.PcdFspHeaderSpecVersion | 0x20| UINT8|0x00000002 + + # x % of FSP temporary memory will be used for heap + # (100 - x) % of FSP temporary memory will be used for stack + gIntelFsp2PkgTokenSpaceGuid.PcdFspHeapSizePercentage | 50| UINT8|0x10000004 + +[PcdsFixedAtBuild,PcdsDynamic,PcdsDynamicEx] + gIntelFsp2PkgTokenSpaceGuid.PcdFspReservedMemoryLength |0x00100000|UINT32|0x46530000 + gIntelFsp2PkgTokenSpaceGuid.PcdBootLoaderEntry |0xFFFFFFE4|UINT32|0x46530100 diff --git a/IntelFsp2Pkg/IntelFsp2Pkg.dsc b/IntelFsp2Pkg/IntelFsp2Pkg.dsc new file mode 100644 index 0000000000..3b50bbf629 --- /dev/null +++ b/IntelFsp2Pkg/IntelFsp2Pkg.dsc @@ -0,0 +1,77 @@ +## @file +# Provides driver and definitions to build fsp. +# +# Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+# This program and the accompanying materials are licensed and made available under +# the terms and conditions of the BSD License that accompanies this distribution. +# The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +[Defines] + PLATFORM_NAME = IntelFsp2Pkg + PLATFORM_GUID = 55CA3D18-831B-469A-A1C3-7AE719EB6A97 + PLATFORM_VERSION = 0.1 + DSC_SPECIFICATION = 0x00010005 + OUTPUT_DIRECTORY = Build/IntelFsp2Pkg + SUPPORTED_ARCHITECTURES = IA32 + BUILD_TARGETS = DEBUG|RELEASE|NOOPT + SKUID_IDENTIFIER = DEFAULT + +[LibraryClasses] + BaseLib|MdePkg/Library/BaseLib/BaseLib.inf + BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf + PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf + PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf + DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf + PciCf8Lib|MdePkg/Library/BasePciCf8Lib/BasePciCf8Lib.inf + IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf + UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf + + ReportStatusCodeLib|MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.inf + PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf + SerialPortLib|MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.inf + ReportStatusCodeLib|MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.inf + DebugDeviceLib|IntelFsp2Pkg/Library/BaseDebugDeviceLibNull/BaseDebugDeviceLibNull.inf + + # FSP override + DebugLib|IntelFsp2Pkg/Library/BaseFspDebugLibSerialPort/BaseFspDebugLibSerialPort.inf + + # FSP specific lib + CacheAsRamLib|IntelFsp2Pkg/Library/BaseCacheAsRamLibNull/BaseCacheAsRamLibNull.inf + CacheLib|IntelFsp2Pkg/Library/BaseCacheLib/BaseCacheLib.inf + FspCommonLib|IntelFsp2Pkg/Library/BaseFspCommonLib/BaseFspCommonLib.inf + FspPlatformLib|IntelFsp2Pkg/Library/BaseFspPlatformLib/BaseFspPlatformLib.inf + FspSwitchStackLib|IntelFsp2Pkg/Library/BaseFspSwitchStackLib/BaseFspSwitchStackLib.inf + FspSecPlatformLib|IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/SecFspSecPlatformLibNull.inf + +[LibraryClasses.common.PEIM] + PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf + PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf + PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf + MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf + ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf + + HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf + +[Components] + IntelFsp2Pkg/Library/BaseCacheAsRamLibNull/BaseCacheAsRamLibNull.inf + IntelFsp2Pkg/Library/BaseCacheLib/BaseCacheLib.inf + IntelFsp2Pkg/Library/BaseFspCommonLib/BaseFspCommonLib.inf + IntelFsp2Pkg/Library/BaseFspDebugLibSerialPort/BaseFspDebugLibSerialPort.inf + IntelFsp2Pkg/Library/BaseFspPlatformLib/BaseFspPlatformLib.inf + IntelFsp2Pkg/Library/BaseFspSwitchStackLib/BaseFspSwitchStackLib.inf + + IntelFsp2Pkg/FspSecCore/FspSecCoreT.inf + IntelFsp2Pkg/FspSecCore/FspSecCoreM.inf + IntelFsp2Pkg/FspSecCore/FspSecCoreS.inf + IntelFsp2Pkg/FspNotifyPhase/FspNotifyPhasePeim.inf + +[PcdsFixedAtBuild.common] + gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x1f + gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80080046 + gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x07 diff --git a/IntelFsp2Pkg/Library/BaseCacheAsRamLibNull/BaseCacheAsRamLibNull.inf b/IntelFsp2Pkg/Library/BaseCacheAsRamLibNull/BaseCacheAsRamLibNull.inf new file mode 100644 index 0000000000..bdb6744f37 --- /dev/null +++ b/IntelFsp2Pkg/Library/BaseCacheAsRamLibNull/BaseCacheAsRamLibNull.inf @@ -0,0 +1,31 @@ +## @file +# NULL instance of Base cache as RAM. +# +# Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +[defines] + INF_VERSION = 0x00010005 + BASE_NAME = BaseCacheAsRamLibNull + FILE_GUID = 630AEB10-2106-4234-9DB3-836A3663F50D + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = CacheAsRamLib + +[sources.common] + DisableCacheAsRamNull.c + +[Packages] + MdePkg/MdePkg.dec + IntelFsp2Pkg/IntelFsp2Pkg.dec + +[LibraryClasses] + diff --git a/IntelFsp2Pkg/Library/BaseCacheAsRamLibNull/DisableCacheAsRamNull.c b/IntelFsp2Pkg/Library/BaseCacheAsRamLibNull/DisableCacheAsRamNull.c new file mode 100644 index 0000000000..9b45163c34 --- /dev/null +++ b/IntelFsp2Pkg/Library/BaseCacheAsRamLibNull/DisableCacheAsRamNull.c @@ -0,0 +1,41 @@ +/** @file + + Copyright (c) 2014, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include +#include + +/** + This function disable CAR. + + @param[in] DisableCar TRUE means use INVD, FALSE means use WBINVD + +**/ +VOID +EFIAPI +DisableCacheAsRam ( + IN BOOLEAN DisableCar + ) +{ + // + // Disable CAR + // + + if (DisableCar) { + AsmInvd (); + } else { + AsmWbinvd(); + } + + return ; +} diff --git a/IntelFsp2Pkg/Library/BaseCacheLib/BaseCacheLib.inf b/IntelFsp2Pkg/Library/BaseCacheLib/BaseCacheLib.inf new file mode 100644 index 0000000000..7b026b1dfc --- /dev/null +++ b/IntelFsp2Pkg/Library/BaseCacheLib/BaseCacheLib.inf @@ -0,0 +1,34 @@ +## @file +# Instance of BaseCache. +# +# Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +[defines] + INF_VERSION = 0x00010005 + BASE_NAME = BaseCacheLib + FILE_GUID = 8EF3A653-DA8B-4FFA-BB85-FF47406DB9F0 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = CacheLib + +[sources.IA32] + CacheLib.c + CacheLibInternal.h + +[Packages] + MdePkg/MdePkg.dec + IntelFsp2Pkg/IntelFsp2Pkg.dec + +[LibraryClasses] + BaseMemoryLib + CacheAsRamLib + diff --git a/IntelFsp2Pkg/Library/BaseCacheLib/CacheLib.c b/IntelFsp2Pkg/Library/BaseCacheLib/CacheLib.c new file mode 100644 index 0000000000..b38dce32a8 --- /dev/null +++ b/IntelFsp2Pkg/Library/BaseCacheLib/CacheLib.c @@ -0,0 +1,703 @@ +/** @file + + Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include +#include +#include +#include "CacheLibInternal.h" + +/** + Search the memory cache type for specific memory from MTRR. + + @param[in] MemoryAddress the address of target memory + @param[in] MemoryLength the length of target memory + @param[in] ValidMtrrAddressMask the MTRR address mask + @param[out] UsedMsrNum the used MSR number + @param[out] UsedMemoryCacheType the cache type for the target memory + + @retval EFI_SUCCESS The memory is found in MTRR and cache type is returned + @retval EFI_NOT_FOUND The memory is not found in MTRR + +**/ +EFI_STATUS +SearchForExactMtrr ( + IN EFI_PHYSICAL_ADDRESS MemoryAddress, + IN UINT64 MemoryLength, + IN UINT64 ValidMtrrAddressMask, + OUT UINT32 *UsedMsrNum, + OUT EFI_MEMORY_CACHE_TYPE *MemoryCacheType + ); + +/** + Check if CacheType match current default setting. + + @param[in] MemoryCacheType input cache type to be checked. + + @retval TRUE MemoryCacheType is default MTRR setting. + @retval FALSE MemoryCacheType is NOT default MTRR setting. +**/ +BOOLEAN +IsDefaultType ( + IN EFI_MEMORY_CACHE_TYPE MemoryCacheType + ); + +/** + Return MTRR alignment requirement for base address and size. + + @param[in] BaseAddress Base address. + @param[in] Size Size. + + @retval Zero Alligned. + @retval Non-Zero Not alligned. + +**/ +UINT32 +CheckMtrrAlignment ( + IN UINT64 BaseAddress, + IN UINT64 Size + ); + +typedef struct { + UINT32 Msr; + UINT32 BaseAddress; + UINT32 Length; +} EFI_FIXED_MTRR; + +EFI_FIXED_MTRR mFixedMtrrTable[] = { + { EFI_MSR_IA32_MTRR_FIX64K_00000, 0, 0x10000}, + { EFI_MSR_IA32_MTRR_FIX16K_80000, 0x80000, 0x4000}, + { EFI_MSR_IA32_MTRR_FIX16K_A0000, 0xA0000, 0x4000}, + { EFI_MSR_IA32_MTRR_FIX4K_C0000, 0xC0000, 0x1000}, + { EFI_MSR_IA32_MTRR_FIX4K_C8000, 0xC8000, 0x1000}, + { EFI_MSR_IA32_MTRR_FIX4K_D0000, 0xD0000, 0x1000}, + { EFI_MSR_IA32_MTRR_FIX4K_D8000, 0xD8000, 0x1000}, + { EFI_MSR_IA32_MTRR_FIX4K_E0000, 0xE0000, 0x1000}, + { EFI_MSR_IA32_MTRR_FIX4K_E8000, 0xE8000, 0x1000}, + { EFI_MSR_IA32_MTRR_FIX4K_F0000, 0xF0000, 0x1000}, + { EFI_MSR_IA32_MTRR_FIX4K_F8000, 0xF8000, 0x1000} +}; + +/** + Given the input, check if the number of MTRR is lesser. + if positive or subtractive. + + @param[in] Input Length of Memory to program MTRR. + + @retval Zero do positive. + @retval Non-Zero do subtractive. + +**/ +INT8 +CheckDirection ( + IN UINT64 Input + ) +{ + return 0; +} + +/** + Disable cache and its mtrr. + + @param[out] OldMtrr To return the Old MTRR value + +**/ +VOID +EfiDisableCacheMtrr ( + OUT UINT64 *OldMtrr + ) +{ + UINT64 TempQword; + + // + // Disable Cache MTRR + // + *OldMtrr = AsmReadMsr64(EFI_MSR_CACHE_IA32_MTRR_DEF_TYPE); + TempQword = (*OldMtrr) & ~B_EFI_MSR_GLOBAL_MTRR_ENABLE & ~B_EFI_MSR_FIXED_MTRR_ENABLE; + AsmWriteMsr64(EFI_MSR_CACHE_IA32_MTRR_DEF_TYPE, TempQword); + AsmDisableCache (); +} + +/** + Recover cache MTRR. + + @param[in] EnableMtrr Whether to enable the MTRR + @param[in] OldMtrr The saved old MTRR value to restore when not to enable the MTRR + +**/ +VOID +EfiRecoverCacheMtrr ( + IN BOOLEAN EnableMtrr, + IN UINT64 OldMtrr + ) +{ + UINT64 TempQword; + + // + // Enable Cache MTRR + // + if (EnableMtrr) { + TempQword = AsmReadMsr64(EFI_MSR_CACHE_IA32_MTRR_DEF_TYPE); + TempQword |= (UINT64)(B_EFI_MSR_GLOBAL_MTRR_ENABLE | B_EFI_MSR_FIXED_MTRR_ENABLE); + } else { + TempQword = OldMtrr; + } + + AsmWriteMsr64 (EFI_MSR_CACHE_IA32_MTRR_DEF_TYPE, TempQword); + + AsmEnableCache (); +} + +/** + Programming MTRR according to Memory address, length, and type. + + @param[in] MtrrNumber the variable MTRR index number + @param[in] MemoryAddress the address of target memory + @param[in] MemoryLength the length of target memory + @param[in] MemoryCacheType the cache type of target memory + @param[in] ValidMtrrAddressMask the MTRR address mask + +**/ +VOID +EfiProgramMtrr ( + IN UINTN MtrrNumber, + IN EFI_PHYSICAL_ADDRESS MemoryAddress, + IN UINT64 MemoryLength, + IN EFI_MEMORY_CACHE_TYPE MemoryCacheType, + IN UINT64 ValidMtrrAddressMask + ) +{ + UINT64 TempQword; + UINT64 OldMtrr; + + if (MemoryLength == 0) { + return; + } + + EfiDisableCacheMtrr (&OldMtrr); + + // + // MTRR Physical Base + // + TempQword = (MemoryAddress & ValidMtrrAddressMask) | MemoryCacheType; + AsmWriteMsr64 (MtrrNumber, TempQword); + + // + // MTRR Physical Mask + // + TempQword = ~(MemoryLength - 1); + AsmWriteMsr64 (MtrrNumber + 1, (TempQword & ValidMtrrAddressMask) | B_EFI_MSR_CACHE_MTRR_VALID); + + EfiRecoverCacheMtrr (TRUE, OldMtrr); +} + +/** + Calculate the maximum value which is a power of 2, but less the MemoryLength. + + @param[in] MemoryAddress Memory address. + @param[in] MemoryLength The number to pass in. + + @return The maximum value which is align to power of 2 and less the MemoryLength + +**/ +UINT64 +Power2MaxMemory ( + IN UINT64 MemoryAddress, + IN UINT64 MemoryLength + ) +{ + UINT64 Result; + + if (MemoryLength == 0) { + return EFI_INVALID_PARAMETER; + } + + // + // Compute inital power of 2 size to return + // + Result = GetPowerOfTwo64(MemoryLength); + + // + // Special case base of 0 as all ranges are valid + // + if (MemoryAddress == 0) { + return Result; + } + + // + // Loop till a value that can be mapped to this base address is found + // + while (CheckMtrrAlignment (MemoryAddress, Result) != 0) { + // + // Need to try the next smaller power of 2 + // + Result = RShiftU64 (Result, 1); + } + + return Result; +} + +/** + Return MTRR alignment requirement for base address and size. + + @param[in] BaseAddress Base address. + @param[in] Size Size. + + @retval Zero Alligned. + @retval Non-Zero Not alligned. + +**/ +UINT32 +CheckMtrrAlignment ( + IN UINT64 BaseAddress, + IN UINT64 Size + ) +{ + UINT32 ShiftedBase; + UINT32 ShiftedSize; + + // + // Shift base and size right 12 bits to allow for larger memory sizes. The + // MTRRs do not use the first 12 bits so this is safe for now. Only supports + // up to 52 bits of physical address space. + // + ShiftedBase = (UINT32) RShiftU64 (BaseAddress, 12); + ShiftedSize = (UINT32) RShiftU64 (Size, 12); + + // + // Return the results to the caller of the MOD + // + return ShiftedBase % ShiftedSize; +} + +/** + Programs fixed MTRRs registers. + + @param[in] MemoryCacheType The memory type to set. + @param[in] Base The base address of memory range. + @param[in] Length The length of memory range. + + @retval RETURN_SUCCESS The cache type was updated successfully + @retval RETURN_UNSUPPORTED The requested range or cache type was invalid + for the fixed MTRRs. + +**/ +EFI_STATUS +ProgramFixedMtrr ( + IN EFI_MEMORY_CACHE_TYPE MemoryCacheType, + IN UINT64 *Base, + IN UINT64 *Len + ) +{ + UINT32 MsrNum; + UINT32 ByteShift; + UINT64 TempQword; + UINT64 OrMask; + UINT64 ClearMask; + + TempQword = 0; + OrMask = 0; + ClearMask = 0; + + for (MsrNum = 0; MsrNum < V_EFI_FIXED_MTRR_NUMBER; MsrNum++) { + if ((*Base >= mFixedMtrrTable[MsrNum].BaseAddress) && + (*Base < (mFixedMtrrTable[MsrNum].BaseAddress + 8 * mFixedMtrrTable[MsrNum].Length))) { + break; + } + } + if (MsrNum == V_EFI_FIXED_MTRR_NUMBER ) { + return EFI_DEVICE_ERROR; + } + // + // We found the fixed MTRR to be programmed + // + for (ByteShift=0; ByteShift < 8; ByteShift++) { + if ( *Base == (mFixedMtrrTable[MsrNum].BaseAddress + ByteShift * mFixedMtrrTable[MsrNum].Length)) { + break; + } + } + if (ByteShift == 8 ) { + return EFI_DEVICE_ERROR; + } + for (; ((ByteShift<8) && (*Len >= mFixedMtrrTable[MsrNum].Length));ByteShift++) { + OrMask |= LShiftU64((UINT64) MemoryCacheType, (UINT32) (ByteShift* 8)); + ClearMask |= LShiftU64((UINT64) 0xFF, (UINT32) (ByteShift * 8)); + *Len -= mFixedMtrrTable[MsrNum].Length; + *Base += mFixedMtrrTable[MsrNum].Length; + } + TempQword = (AsmReadMsr64 (mFixedMtrrTable[MsrNum].Msr) & (~ClearMask)) | OrMask; + AsmWriteMsr64 (mFixedMtrrTable[MsrNum].Msr, TempQword); + + return EFI_SUCCESS; +} + +/** + Check if there is a valid variable MTRR that overlaps the given range. + + @param[in] Start Base Address of the range to check. + @param[in] End End address of the range to check. + + @retval TRUE Mtrr overlap. + @retval FALSE Mtrr not overlap. +**/ +BOOLEAN +CheckMtrrOverlap ( + IN EFI_PHYSICAL_ADDRESS Start, + IN EFI_PHYSICAL_ADDRESS End + ) +{ + return FALSE; +} + +/** + Given the memory range and cache type, programs the MTRRs. + + @param[in] MemoryAddress Base Address of Memory to program MTRR. + @param[in] MemoryLength Length of Memory to program MTRR. + @param[in] MemoryCacheType Cache Type. + + @retval EFI_SUCCESS Mtrr are set successfully. + @retval EFI_LOAD_ERROR No empty MTRRs to use. + @retval EFI_INVALID_PARAMETER The input parameter is not valid. + @retval others An error occurs when setting MTTR. + +**/ +EFI_STATUS +EFIAPI +SetCacheAttributes ( + IN EFI_PHYSICAL_ADDRESS MemoryAddress, + IN UINT64 MemoryLength, + IN EFI_MEMORY_CACHE_TYPE MemoryCacheType + ) +{ + EFI_STATUS Status; + UINT32 MsrNum, MsrNumEnd; + UINT64 TempQword; + UINT32 LastVariableMtrrForBios; + UINT64 OldMtrr; + UINT32 UsedMsrNum; + EFI_MEMORY_CACHE_TYPE UsedMemoryCacheType; + UINT64 ValidMtrrAddressMask; + UINT32 Cpuid_RegEax; + + AsmCpuid (CPUID_EXTENDED_FUNCTION, &Cpuid_RegEax, NULL, NULL, NULL); + if (Cpuid_RegEax >= CPUID_VIR_PHY_ADDRESS_SIZE) { + AsmCpuid (CPUID_VIR_PHY_ADDRESS_SIZE, &Cpuid_RegEax, NULL, NULL, NULL); + ValidMtrrAddressMask = (LShiftU64((UINT64) 1, (Cpuid_RegEax & 0xFF)) - 1) & (~(UINT64)0x0FFF); + } else { + ValidMtrrAddressMask = (LShiftU64((UINT64) 1, 36) - 1) & (~(UINT64)0x0FFF); + } + + // + // Check for invalid parameter + // + if ((MemoryAddress & ~ValidMtrrAddressMask) != 0 || (MemoryLength & ~ValidMtrrAddressMask) != 0) { + return EFI_INVALID_PARAMETER; + } + + if (MemoryLength == 0) { + return EFI_INVALID_PARAMETER; + } + + switch (MemoryCacheType) { + case EFI_CACHE_UNCACHEABLE: + case EFI_CACHE_WRITECOMBINING: + case EFI_CACHE_WRITETHROUGH: + case EFI_CACHE_WRITEPROTECTED: + case EFI_CACHE_WRITEBACK: + break; + + default: + return EFI_INVALID_PARAMETER; + } + + // + // Check if Fixed MTRR + // + if ((MemoryAddress + MemoryLength) <= (1 << 20)) { + Status = EFI_SUCCESS; + EfiDisableCacheMtrr (&OldMtrr); + while ((MemoryLength > 0) && (Status == EFI_SUCCESS)) { + Status = ProgramFixedMtrr (MemoryCacheType, &MemoryAddress, &MemoryLength); + } + EfiRecoverCacheMtrr (TRUE, OldMtrr); + return Status; + } + + // + // Search if the range attribute has been set before + // + Status = SearchForExactMtrr( + MemoryAddress, + MemoryLength, + ValidMtrrAddressMask, + &UsedMsrNum, + &UsedMemoryCacheType + ); + + if (!EFI_ERROR(Status)) { + // + // Compare if it has the same type as current setting + // + if (UsedMemoryCacheType == MemoryCacheType) { + return EFI_SUCCESS; + } else { + // + // Different type + // + + // + // Check if the set type is the same as Default Type + // + if (IsDefaultType(MemoryCacheType)) { + // + // Clear the MTRR + // + AsmWriteMsr64(UsedMsrNum, 0); + AsmWriteMsr64(UsedMsrNum + 1, 0); + + return EFI_SUCCESS; + } else { + // + // Modify the MTRR type + // + EfiProgramMtrr(UsedMsrNum, + MemoryAddress, + MemoryLength, + MemoryCacheType, + ValidMtrrAddressMask + ); + return EFI_SUCCESS; + } + } + } + +#if 0 + // + // @bug - Need to create memory map so that when checking for overlap we + // can determine if an overlap exists based on all caching requests. + // + // Don't waste a variable MTRR if the caching attrib is same as default in MTRR_DEF_TYPE + // + if (MemoryCacheType == (AsmReadMsr64(EFI_MSR_CACHE_IA32_MTRR_DEF_TYPE) & B_EFI_MSR_CACHE_MEMORY_TYPE)) { + if (!CheckMtrrOverlap (MemoryAddress, MemoryAddress+MemoryLength-1)) { + return EFI_SUCCESS; + } + } +#endif + + // + // Find first unused MTRR + // + MsrNumEnd = EFI_MSR_CACHE_VARIABLE_MTRR_BASE + (2 * (UINT32)(AsmReadMsr64(EFI_MSR_IA32_MTRR_CAP) & B_EFI_MSR_IA32_MTRR_CAP_VARIABLE_SUPPORT)); + for (MsrNum = EFI_MSR_CACHE_VARIABLE_MTRR_BASE; MsrNum < MsrNumEnd; MsrNum +=2) { + if ((AsmReadMsr64(MsrNum+1) & B_EFI_MSR_CACHE_MTRR_VALID) == 0 ) { + break; + } + } + + // + // Reserve 1 MTRR pair for OS. + // + LastVariableMtrrForBios = MsrNumEnd - 1 - (EFI_CACHE_NUM_VAR_MTRR_PAIRS_FOR_OS * 2); + if (MsrNum > LastVariableMtrrForBios) { + return EFI_LOAD_ERROR; + } + + // + // Special case for 1 MB base address + // + if (MemoryAddress == BASE_1MB) { + MemoryAddress = 0; + } + + // + // Program MTRRs + // + TempQword = MemoryLength; + + if (TempQword == Power2MaxMemory(MemoryAddress, TempQword)) { + EfiProgramMtrr(MsrNum, + MemoryAddress, + MemoryLength, + MemoryCacheType, + ValidMtrrAddressMask + ); + + } else { + // + // Fill in MTRRs with values. Direction can not be checked for this method + // as we are using WB as the default cache type and only setting areas to UC. + // + do { + // + // Do boundary check so we don't go past last MTRR register + // for BIOS use. Leave one MTRR pair for OS use. + // + if (MsrNum > LastVariableMtrrForBios) { + return EFI_LOAD_ERROR; + } + + // + // Set next power of 2 region + // + MemoryLength = Power2MaxMemory(MemoryAddress, TempQword); + EfiProgramMtrr(MsrNum, + MemoryAddress, + MemoryLength, + MemoryCacheType, + ValidMtrrAddressMask + ); + MemoryAddress += MemoryLength; + TempQword -= MemoryLength; + MsrNum += 2; + } while (TempQword != 0); + } + + return EFI_SUCCESS; +} + +/** + Reset all the MTRRs to a known state. + + @retval EFI_SUCCESS All MTRRs have been reset successfully. + +**/ +EFI_STATUS +EFIAPI +ResetCacheAttributes ( + VOID + ) +{ + UINT32 MsrNum, MsrNumEnd; + UINT16 Index; + UINT64 OldMtrr; + UINT64 CacheType; + BOOLEAN DisableCar; + Index = 0; + DisableCar = TRUE; + + // + // Determine default cache type + // + CacheType = EFI_CACHE_UNCACHEABLE; + + // + // Set default cache type + // + AsmWriteMsr64(EFI_MSR_CACHE_IA32_MTRR_DEF_TYPE, CacheType); + + // + // Disable CAR + // + DisableCacheAsRam (DisableCar); + + EfiDisableCacheMtrr (&OldMtrr); + + // + // Reset Fixed MTRRs + // + for (Index = 0; Index < V_EFI_FIXED_MTRR_NUMBER; Index++) { + AsmWriteMsr64 (mFixedMtrrTable[Index].Msr, 0); + } + + // + // Reset Variable MTRRs + // + MsrNumEnd = EFI_MSR_CACHE_VARIABLE_MTRR_BASE + (2 * (UINT32)(AsmReadMsr64(EFI_MSR_IA32_MTRR_CAP) & B_EFI_MSR_IA32_MTRR_CAP_VARIABLE_SUPPORT)); + for (MsrNum = EFI_MSR_CACHE_VARIABLE_MTRR_BASE; MsrNum < MsrNumEnd; MsrNum++) { + AsmWriteMsr64 (MsrNum, 0); + } + + // + // Enable Fixed and Variable MTRRs + // + EfiRecoverCacheMtrr (TRUE, OldMtrr); + + return EFI_SUCCESS; +} + +/** + Search the memory cache type for specific memory from MTRR. + + @param[in] MemoryAddress the address of target memory + @param[in] MemoryLength the length of target memory + @param[in] ValidMtrrAddressMask the MTRR address mask + @param[out] UsedMsrNum the used MSR number + @param[out] UsedMemoryCacheType the cache type for the target memory + + @retval EFI_SUCCESS The memory is found in MTRR and cache type is returned + @retval EFI_NOT_FOUND The memory is not found in MTRR + +**/ +EFI_STATUS +SearchForExactMtrr ( + IN EFI_PHYSICAL_ADDRESS MemoryAddress, + IN UINT64 MemoryLength, + IN UINT64 ValidMtrrAddressMask, + OUT UINT32 *UsedMsrNum, + OUT EFI_MEMORY_CACHE_TYPE *UsedMemoryCacheType + ) +{ + UINT32 MsrNum, MsrNumEnd; + UINT64 TempQword; + + if (MemoryLength == 0) { + return EFI_INVALID_PARAMETER; + } + + MsrNumEnd = EFI_MSR_CACHE_VARIABLE_MTRR_BASE + (2 * (UINT32)(AsmReadMsr64(EFI_MSR_IA32_MTRR_CAP) & B_EFI_MSR_IA32_MTRR_CAP_VARIABLE_SUPPORT)); + for (MsrNum = EFI_MSR_CACHE_VARIABLE_MTRR_BASE; MsrNum < MsrNumEnd; MsrNum +=2) { + TempQword = AsmReadMsr64(MsrNum+1); + if ((TempQword & B_EFI_MSR_CACHE_MTRR_VALID) == 0) { + continue; + } + + if ((TempQword & ValidMtrrAddressMask) != ((~(MemoryLength - 1)) & ValidMtrrAddressMask)) { + continue; + } + + TempQword = AsmReadMsr64 (MsrNum); + if ((TempQword & ValidMtrrAddressMask) != (MemoryAddress & ValidMtrrAddressMask)) { + continue; + } + + *UsedMemoryCacheType = (EFI_MEMORY_CACHE_TYPE)(TempQword & B_EFI_MSR_CACHE_MEMORY_TYPE); + *UsedMsrNum = MsrNum; + + return EFI_SUCCESS; + } + + return EFI_NOT_FOUND; +} + +/** + Check if CacheType match current default setting. + + @param[in] MemoryCacheType input cache type to be checked. + + @retval TRUE MemoryCacheType is default MTRR setting. + @retval TRUE MemoryCacheType is NOT default MTRR setting. +**/ +BOOLEAN +IsDefaultType ( + IN EFI_MEMORY_CACHE_TYPE MemoryCacheType + ) +{ + if ((AsmReadMsr64(EFI_MSR_CACHE_IA32_MTRR_DEF_TYPE) & B_EFI_MSR_CACHE_MEMORY_TYPE) != MemoryCacheType) { + return FALSE; + } + + return TRUE; +} + diff --git a/IntelFsp2Pkg/Library/BaseCacheLib/CacheLibInternal.h b/IntelFsp2Pkg/Library/BaseCacheLib/CacheLibInternal.h new file mode 100644 index 0000000000..fbbf551dde --- /dev/null +++ b/IntelFsp2Pkg/Library/BaseCacheLib/CacheLibInternal.h @@ -0,0 +1,59 @@ +/** @file + + Copyright (c) 2014, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef _CACHE_LIB_INTERNAL_H_ +#define _CACHE_LIB_INTERNAL_H_ + +#define EFI_MSR_CACHE_VARIABLE_MTRR_BASE 0x00000200 +#define EFI_MSR_CACHE_VARIABLE_MTRR_END 0x0000020F +#define V_EFI_FIXED_MTRR_NUMBER 11 + +#define EFI_MSR_IA32_MTRR_FIX64K_00000 0x00000250 +#define EFI_MSR_IA32_MTRR_FIX16K_80000 0x00000258 +#define EFI_MSR_IA32_MTRR_FIX16K_A0000 0x00000259 +#define EFI_MSR_IA32_MTRR_FIX4K_C0000 0x00000268 +#define EFI_MSR_IA32_MTRR_FIX4K_C8000 0x00000269 +#define EFI_MSR_IA32_MTRR_FIX4K_D0000 0x0000026A +#define EFI_MSR_IA32_MTRR_FIX4K_D8000 0x0000026B +#define EFI_MSR_IA32_MTRR_FIX4K_E0000 0x0000026C +#define EFI_MSR_IA32_MTRR_FIX4K_E8000 0x0000026D +#define EFI_MSR_IA32_MTRR_FIX4K_F0000 0x0000026E +#define EFI_MSR_IA32_MTRR_FIX4K_F8000 0x0000026F +#define EFI_MSR_CACHE_IA32_MTRR_DEF_TYPE 0x000002FF +#define B_EFI_MSR_CACHE_MTRR_VALID BIT11 +#define B_EFI_MSR_GLOBAL_MTRR_ENABLE BIT11 +#define B_EFI_MSR_FIXED_MTRR_ENABLE BIT10 +#define B_EFI_MSR_CACHE_MEMORY_TYPE (BIT2 | BIT1 | BIT0) + +#define EFI_MSR_VALID_MASK 0xFFFFFFFFF +#define EFI_CACHE_VALID_ADDRESS 0xFFFFFF000 +#define EFI_SMRR_CACHE_VALID_ADDRESS 0xFFFFF000 +#define EFI_CACHE_VALID_EXTENDED_ADDRESS 0xFFFFFFFFFF000 + +// Leave one MTRR pairs for OS use +#define EFI_CACHE_NUM_VAR_MTRR_PAIRS_FOR_OS 1 +#define EFI_CACHE_LAST_VARIABLE_MTRR_FOR_BIOS (EFI_MSR_CACHE_VARIABLE_MTRR_END) - \ + (EFI_CACHE_NUM_VAR_MTRR_PAIRS_FOR_OS * 2) + +#define EFI_MSR_IA32_MTRR_CAP 0x000000FE +#define B_EFI_MSR_IA32_MTRR_CAP_EMRR_SUPPORT BIT12 +#define B_EFI_MSR_IA32_MTRR_CAP_SMRR_SUPPORT BIT11 +#define B_EFI_MSR_IA32_MTRR_CAP_WC_SUPPORT BIT10 +#define B_EFI_MSR_IA32_MTRR_CAP_FIXED_SUPPORT BIT8 +#define B_EFI_MSR_IA32_MTRR_CAP_VARIABLE_SUPPORT (BIT7 | BIT6 | BIT5 | BIT4 | BIT3 | BIT2 | BIT1 | BIT0) + +#define CPUID_VIR_PHY_ADDRESS_SIZE 0x80000008 +#define CPUID_EXTENDED_FUNCTION 0x80000000 + +#endif + diff --git a/IntelFsp2Pkg/Library/BaseDebugDeviceLibNull/BaseDebugDeviceLibNull.inf b/IntelFsp2Pkg/Library/BaseDebugDeviceLibNull/BaseDebugDeviceLibNull.inf new file mode 100644 index 0000000000..5e4c572973 --- /dev/null +++ b/IntelFsp2Pkg/Library/BaseDebugDeviceLibNull/BaseDebugDeviceLibNull.inf @@ -0,0 +1,34 @@ +## @file +# Debug device library instance that retrieves the current enabling state for +# the platform debug output device. +# +# Copyright (c) 2014, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = BaseDebugDeviceLibNull + FILE_GUID = 5E975522-176F-4E2D-BB25-64ADCC7792A4 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = DebugDeviceLib + +# +# VALID_ARCHITECTURES = IA32 +# + +[Sources] + DebugDeviceLibNull.c + +[Packages] + MdePkg/MdePkg.dec + IntelFsp2Pkg/IntelFsp2Pkg.dec + diff --git a/IntelFsp2Pkg/Library/BaseDebugDeviceLibNull/DebugDeviceLibNull.c b/IntelFsp2Pkg/Library/BaseDebugDeviceLibNull/DebugDeviceLibNull.c new file mode 100644 index 0000000000..95c100472c --- /dev/null +++ b/IntelFsp2Pkg/Library/BaseDebugDeviceLibNull/DebugDeviceLibNull.c @@ -0,0 +1,31 @@ +/** @file + Debug device library instance that retrieves the current enabling state for + the platform debug output device. + + Copyright (c) 2014, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include + +/** + Returns the debug print device enable state. + + @return Debug print device enable state. + +**/ +UINT8 +EFIAPI +GetDebugPrintDeviceEnable ( + VOID + ) +{ + return 1; +} diff --git a/IntelFsp2Pkg/Library/BaseFspCommonLib/BaseFspCommonLib.inf b/IntelFsp2Pkg/Library/BaseFspCommonLib/BaseFspCommonLib.inf new file mode 100644 index 0000000000..0b0741b1c6 --- /dev/null +++ b/IntelFsp2Pkg/Library/BaseFspCommonLib/BaseFspCommonLib.inf @@ -0,0 +1,39 @@ +## @file +# Instance of FspCommonLib +# Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = BaseFspCommonLib + FILE_GUID = 38BE57E8-902C-485A-AB5E-D5AEC613194D + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = FspCommonLib + +[Sources] + FspCommonLib.c + +[Packages] + MdePkg/MdePkg.dec + IntelFsp2Pkg/IntelFsp2Pkg.dec + +[LibraryClasses] + BaseMemoryLib + +[Pcd] + gIntelFsp2PkgTokenSpaceGuid.PcdGlobalDataPointerAddress ## CONSUMES + +[FixedPcd] + gIntelFsp2PkgTokenSpaceGuid.PcdFspMaxPatchEntry ## CONSUMES + gIntelFsp2PkgTokenSpaceGuid.PcdFspMaxPerfEntry ## CONSUMES + gIntelFsp2PkgTokenSpaceGuid.PcdTemporaryRamBase ## CONSUMES + gIntelFsp2PkgTokenSpaceGuid.PcdTemporaryRamSize ## CONSUMES diff --git a/IntelFsp2Pkg/Library/BaseFspCommonLib/FspCommonLib.c b/IntelFsp2Pkg/Library/BaseFspCommonLib/FspCommonLib.c new file mode 100644 index 0000000000..efd55f464c --- /dev/null +++ b/IntelFsp2Pkg/Library/BaseFspCommonLib/FspCommonLib.c @@ -0,0 +1,546 @@ +/** @file + + Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include +#include +#include +#include +#include +#include + +#pragma pack(1) + +// +// API Parameter +0x34 +// API return address +0x30 +// +// push FspInfoHeader +0x2C +// pushfd +0x28 +// cli +// pushad +0x24 +// sub esp, 8 +0x00 +// sidt fword ptr [esp] +// +typedef struct { + UINT16 IdtrLimit; + UINT32 IdtrBase; + UINT16 Reserved; + UINT32 Edi; + UINT32 Esi; + UINT32 Ebp; + UINT32 Esp; + UINT32 Ebx; + UINT32 Edx; + UINT32 Ecx; + UINT32 Eax; + UINT16 Flags[2]; + UINT32 FspInfoHeader; + UINT32 ApiRet; + UINT32 ApiParam[2]; +} CONTEXT_STACK; + +#define CONTEXT_STACK_OFFSET(x) (UINT32)&((CONTEXT_STACK *)(UINTN)0)->x + +#pragma pack() + +/** + This function sets the FSP global data pointer. + + @param[in] FspData Fsp global data pointer. + +**/ +VOID +EFIAPI +SetFspGlobalDataPointer ( + IN FSP_GLOBAL_DATA *FspData + ) +{ + ASSERT (FspData != NULL); + *((volatile UINT32 *)(UINTN)PcdGet32(PcdGlobalDataPointerAddress)) = (UINT32)(UINTN)FspData; +} + +/** + This function gets the FSP global data pointer. + +**/ +FSP_GLOBAL_DATA * +EFIAPI +GetFspGlobalDataPointer ( + VOID + ) +{ + FSP_GLOBAL_DATA *FspData; + + FspData = *(FSP_GLOBAL_DATA **)(UINTN)PcdGet32(PcdGlobalDataPointerAddress); + return FspData; +} + +/** + This function gets back the FSP API first parameter passed by the bootlaoder. + + @retval ApiParameter FSP API first parameter passed by the bootlaoder. +**/ +UINT32 +EFIAPI +GetFspApiParameter ( + VOID + ) +{ + FSP_GLOBAL_DATA *FspData; + + FspData = GetFspGlobalDataPointer (); + return *(UINT32 *)(UINTN)(FspData->CoreStack + CONTEXT_STACK_OFFSET(ApiParam[0])); +} + +/** + This function gets back the FSP API second parameter passed by the bootlaoder. + + @retval ApiParameter FSP API second parameter passed by the bootlaoder. +**/ +UINT32 +EFIAPI +GetFspApiParameter2 ( + VOID + ) +{ + FSP_GLOBAL_DATA *FspData; + + FspData = GetFspGlobalDataPointer (); + return *(UINT32 *)(UINTN)(FspData->CoreStack + CONTEXT_STACK_OFFSET(ApiParam[1])); +} + +/** + This function sets the FSP API parameter in the stack. + + @param[in] Value New parameter value. + +**/ +VOID +EFIAPI +SetFspApiParameter ( + IN UINT32 Value + ) +{ + FSP_GLOBAL_DATA *FspData; + + FspData = GetFspGlobalDataPointer (); + *(UINT32 *)(UINTN)(FspData->CoreStack + CONTEXT_STACK_OFFSET(ApiParam)) = Value; +} + +/** + This function set the API status code returned to the BootLoader. + + @param[in] ReturnStatus Status code to return. + +**/ +VOID +EFIAPI +SetFspApiReturnStatus ( + IN UINT32 ReturnStatus + ) +{ + FSP_GLOBAL_DATA *FspData; + + FspData = GetFspGlobalDataPointer (); + *(UINT32 *)(UINTN)(FspData->CoreStack + CONTEXT_STACK_OFFSET(Eax)) = ReturnStatus; +} + +/** + This function sets the context switching stack to a new stack frame. + + @param[in] NewStackTop New core stack to be set. + +**/ +VOID +EFIAPI +SetFspCoreStackPointer ( + IN VOID *NewStackTop + ) +{ + FSP_GLOBAL_DATA *FspData; + UINT32 *OldStack; + UINT32 *NewStack; + UINT32 StackContextLen; + + FspData = GetFspGlobalDataPointer (); + StackContextLen = sizeof(CONTEXT_STACK) / sizeof(UINT32); + + // + // Reserve space for the ContinuationFunc two parameters + // + OldStack = (UINT32 *)FspData->CoreStack; + NewStack = (UINT32 *)NewStackTop - StackContextLen - 2; + FspData->CoreStack = (UINT32)NewStack; + while (StackContextLen-- != 0) { + *NewStack++ = *OldStack++; + } +} + +/** + This function sets the platform specific data pointer. + + @param[in] PlatformData Fsp platform specific data pointer. + +**/ +VOID +EFIAPI +SetFspPlatformDataPointer ( + IN VOID *PlatformData + ) +{ + FSP_GLOBAL_DATA *FspData; + + FspData = GetFspGlobalDataPointer (); + FspData->PlatformData.DataPtr = PlatformData; +} + + +/** + This function gets the platform specific data pointer. + + @param[in] PlatformData Fsp platform specific data pointer. + +**/ +VOID * +EFIAPI +GetFspPlatformDataPointer ( + VOID + ) +{ + FSP_GLOBAL_DATA *FspData; + + FspData = GetFspGlobalDataPointer (); + return FspData->PlatformData.DataPtr; +} + + +/** + This function sets the UPD data pointer. + + @param[in] UpdDataPtr UPD data pointer. +**/ +VOID +EFIAPI +SetFspUpdDataPointer ( + IN VOID *UpdDataPtr + ) +{ + FSP_GLOBAL_DATA *FspData; + + // + // Get the Fsp Global Data Pointer + // + FspData = GetFspGlobalDataPointer (); + + // + // Set the UPD pointer. + // + FspData->UpdDataPtr = UpdDataPtr; +} + +/** + This function gets the UPD data pointer. + + @return UpdDataPtr UPD data pointer. +**/ +VOID * +EFIAPI +GetFspUpdDataPointer ( + VOID + ) +{ + FSP_GLOBAL_DATA *FspData; + + FspData = GetFspGlobalDataPointer (); + return FspData->UpdDataPtr; +} + + +/** + This function sets the memory init UPD data pointer. + + @param[in] MemoryInitUpdPtr memory init UPD data pointer. +**/ +VOID +EFIAPI +SetFspMemoryInitUpdDataPointer ( + IN VOID *MemoryInitUpdPtr + ) +{ + FSP_GLOBAL_DATA *FspData; + + // + // Get the Fsp Global Data Pointer + // + FspData = GetFspGlobalDataPointer (); + + // + // Set the memory init UPD pointer. + // + FspData->MemoryInitUpdPtr = MemoryInitUpdPtr; +} + +/** + This function gets the memory init UPD data pointer. + + @return memory init UPD data pointer. +**/ +VOID * +EFIAPI +GetFspMemoryInitUpdDataPointer ( + VOID + ) +{ + FSP_GLOBAL_DATA *FspData; + + FspData = GetFspGlobalDataPointer (); + return FspData->MemoryInitUpdPtr; +} + + +/** + This function sets the silicon init UPD data pointer. + + @param[in] SiliconInitUpdPtr silicon init UPD data pointer. +**/ +VOID +EFIAPI +SetFspSiliconInitUpdDataPointer ( + IN VOID *SiliconInitUpdPtr + ) +{ + FSP_GLOBAL_DATA *FspData; + + // + // Get the Fsp Global Data Pointer + // + FspData = GetFspGlobalDataPointer (); + + // + // Set the silicon init UPD data pointer. + // + FspData->SiliconInitUpdPtr = SiliconInitUpdPtr; +} + +/** + This function gets the silicon init UPD data pointer. + + @return silicon init UPD data pointer. +**/ +VOID * +EFIAPI +GetFspSiliconInitUpdDataPointer ( + VOID + ) +{ + FSP_GLOBAL_DATA *FspData; + + FspData = GetFspGlobalDataPointer (); + return FspData->SiliconInitUpdPtr; +} + + +/** + Set FSP measurement point timestamp. + + @param[in] Id Measurement point ID. + + @return performance timestamp. +**/ +UINT64 +EFIAPI +SetFspMeasurePoint ( + IN UINT8 Id + ) +{ + FSP_GLOBAL_DATA *FspData; + + // + // Bit [55: 0] will be the timestamp + // Bit [63:56] will be the ID + // + FspData = GetFspGlobalDataPointer (); + if (FspData->PerfIdx < sizeof(FspData->PerfData) / sizeof(FspData->PerfData[0])) { + FspData->PerfData[FspData->PerfIdx] = AsmReadTsc (); + ((UINT8 *)(&FspData->PerfData[FspData->PerfIdx]))[7] = Id; + } + + return FspData->PerfData[(FspData->PerfIdx)++]; +} + +/** + This function gets the FSP info header pointer. + + @retval FspInfoHeader FSP info header pointer +**/ +FSP_INFO_HEADER * +EFIAPI +GetFspInfoHeader ( + VOID + ) +{ + return GetFspGlobalDataPointer()->FspInfoHeader; +} + +/** + This function sets the FSP info header pointer. + + @param[in] FspInfoHeader FSP info header pointer +**/ +VOID +EFIAPI +SetFspInfoHeader ( + FSP_INFO_HEADER *FspInfoHeader + ) +{ + GetFspGlobalDataPointer()->FspInfoHeader = FspInfoHeader; +} + +/** + This function gets the FSP info header pointer using the API stack context. + + @retval FspInfoHeader FSP info header pointer using the API stack context +**/ +FSP_INFO_HEADER * +EFIAPI +GetFspInfoHeaderFromApiContext ( + VOID + ) +{ + FSP_GLOBAL_DATA *FspData; + + FspData = GetFspGlobalDataPointer (); + return (FSP_INFO_HEADER *)(*(UINT32 *)(UINTN)(FspData->CoreStack + CONTEXT_STACK_OFFSET(FspInfoHeader))); +} + +/** + This function gets the VPD data pointer. + + @return VpdDataRgnPtr VPD data pointer. +**/ +VOID * +EFIAPI +GetFspVpdDataPointer ( + VOID + ) +{ + FSP_INFO_HEADER *FspInfoHeader; + + FspInfoHeader = GetFspInfoHeader (); + return (VOID *)(FspInfoHeader->ImageBase + FspInfoHeader->CfgRegionOffset); +} + +/** + This function gets FSP API calling index. + + @retval API calling index +**/ +UINT8 +EFIAPI +GetFspApiCallingIndex ( + VOID + ) +{ + return GetFspGlobalDataPointer()->ApiIdx; +} + +/** + This function sets FSP API calling mode. + + @param[in] Index API calling index +**/ +VOID +EFIAPI +SetFspApiCallingIndex ( + UINT8 Index + ) +{ + FSP_GLOBAL_DATA *FspData; + + FspData = GetFspGlobalDataPointer (); + FspData->ApiIdx = Index; +} + +/** + This function gets FSP Phase StatusCode. + + @retval StatusCode +**/ +UINT32 +EFIAPI +GetPhaseStatusCode ( + VOID + ) +{ + return GetFspGlobalDataPointer()->StatusCode; +} + +/** + This function sets FSP Phase StatusCode. + + @param[in] Mode Phase StatusCode +**/ +VOID +EFIAPI +SetPhaseStatusCode ( + UINT32 StatusCode + ) +{ + FSP_GLOBAL_DATA *FspData; + + FspData = GetFspGlobalDataPointer (); + FspData->StatusCode = StatusCode; +} + +/** + This function gets FSP CAR base. + +**/ +UINT32 +EFIAPI +GetFspCarBase ( + VOID + ) +{ + FSP_GLOBAL_DATA *FspData; + UINT32 CarBase; + + FspData = GetFspGlobalDataPointer (); + CarBase = FspData->PlatformData.CarBase; + if (CarBase == 0) { + CarBase = PcdGet32(PcdTemporaryRamBase); + } + return CarBase; +} + +/** + This function gets FSP CAR size. + +**/ +UINT32 +EFIAPI +GetFspCarSize ( + VOID + ) +{ + FSP_GLOBAL_DATA *FspData; + UINT32 CarSize; + + FspData = GetFspGlobalDataPointer (); + CarSize = FspData->PlatformData.CarSize; + if (FspData->PlatformData.CarBase == 0) { + CarSize = PcdGet32(PcdTemporaryRamSize); + } + return CarSize; +} diff --git a/IntelFsp2Pkg/Library/BaseFspDebugLibSerialPort/BaseFspDebugLibSerialPort.inf b/IntelFsp2Pkg/Library/BaseFspDebugLibSerialPort/BaseFspDebugLibSerialPort.inf new file mode 100644 index 0000000000..a7f10d4262 --- /dev/null +++ b/IntelFsp2Pkg/Library/BaseFspDebugLibSerialPort/BaseFspDebugLibSerialPort.inf @@ -0,0 +1,51 @@ +## @file +# Instance of BaseFspDebugLib +# +# Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = BaseFspDebugLibSerialPort + FILE_GUID = CEA4FF9C-D7BC-4F07-96F1-03F41F2B17AE + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = DebugLib + +# +# VALID_ARCHITECTURES = IA32 +# + +[Sources] + DebugLib.c + +[Sources.Ia32] + Ia32/FspDebug.asm | MSFT + Ia32/FspDebug.s | GCC + +[Packages] + MdePkg/MdePkg.dec + IntelFsp2Pkg/IntelFsp2Pkg.dec + +[LibraryClasses] + SerialPortLib + BaseMemoryLib + PcdLib + PrintLib + BaseLib + DebugDeviceLib + DebugPrintErrorLevelLib + +[Pcd] + gEfiMdePkgTokenSpaceGuid.PcdDebugClearMemoryValue ## CONSUMES + gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask ## CONSUMES + gEfiMdePkgTokenSpaceGuid.PcdFixedDebugPrintErrorLevel ## CONSUMES + diff --git a/IntelFsp2Pkg/Library/BaseFspDebugLibSerialPort/DebugLib.c b/IntelFsp2Pkg/Library/BaseFspDebugLibSerialPort/DebugLib.c new file mode 100644 index 0000000000..73bb08e357 --- /dev/null +++ b/IntelFsp2Pkg/Library/BaseFspDebugLibSerialPort/DebugLib.c @@ -0,0 +1,328 @@ +/** @file + + Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// +// Define the maximum debug and assert message length that this library supports +// +#define MAX_DEBUG_MESSAGE_LENGTH 0x100 + +CONST CHAR8 *mHexTable = "0123456789ABCDEF"; + +/** + Get stack frame pointer of function call. + + @return StackFramePointer stack frame pointer of function call. +**/ +UINT32 * +EFIAPI +GetStackFramePointer ( + VOID + ); + + +/** + Prints a debug message to the debug output device if the specified error level is enabled. + + If any bit in ErrorLevel is also set in DebugPrintErrorLevelLib function + GetDebugPrintErrorLevel (), then print the message specified by Format and the + associated variable argument list to the debug output device. + + If Format is NULL, then ASSERT(). + + @param ErrorLevel The error level of the debug message. + @param Format Format string for the debug message to print. + @param ... Variable argument list whose contents are accessed + based on the format string specified by Format. + +**/ +VOID +EFIAPI +DebugPrint ( + IN UINTN ErrorLevel, + IN CONST CHAR8 *Format, + ... + ) +{ + CHAR8 Buffer[MAX_DEBUG_MESSAGE_LENGTH]; + VA_LIST Marker; + + // + // If Format is NULL, then ASSERT(). + // + if (!GetDebugPrintDeviceEnable ()) { + return; + } + + // + // Check driver debug mask value and global mask + // + if ((ErrorLevel & GetDebugPrintErrorLevel ()) == 0) { + return; + } + + // + // If Format is NULL, then ASSERT(). + // + ASSERT (Format != NULL); + + // + // Convert the DEBUG() message to an ASCII String + // + VA_START (Marker, Format); + AsciiVSPrint (Buffer, sizeof (Buffer), Format, Marker); + VA_END (Marker); + + // + // Send the print string to a Serial Port + // + SerialPortWrite ((UINT8 *)Buffer, AsciiStrLen (Buffer)); +} + +/** + Convert an UINT32 value into HEX string sepcified by Buffer. + + @param Value The HEX value to convert to string + @param Buffer The pointer to the target buffer to be filled with HEX string + +**/ +VOID +FillHex ( + UINT32 Value, + CHAR8 *Buffer + ) +{ + INTN Idx; + for (Idx = 7; Idx >= 0; Idx--) { + Buffer[Idx] = mHexTable[Value & 0x0F]; + Value >>= 4; + } +} + +/** + Prints an assert message containing a filename, line number, and description. + This may be followed by a breakpoint or a dead loop. + + Print a message of the form "ASSERT (): \n" + to the debug output device. If DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED bit of + PcdDebugProperyMask is set then CpuBreakpoint() is called. Otherwise, if + DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED bit of PcdDebugProperyMask is set then + CpuDeadLoop() is called. If neither of these bits are set, then this function + returns immediately after the message is printed to the debug output device. + DebugAssert() must actively prevent recursion. If DebugAssert() is called while + processing another DebugAssert(), then DebugAssert() must return immediately. + + If FileName is NULL, then a string of "(NULL) Filename" is printed. + If Description is NULL, then a string of "(NULL) Description" is printed. + +**/ +VOID +DebugAssertInternal ( + VOID + ) +{ + CHAR8 Buffer[MAX_DEBUG_MESSAGE_LENGTH]; + UINT32 *Frame; + + Frame = (UINT32 *)GetStackFramePointer (); + + // + // Generate the ASSERT() message in Ascii format + // + AsciiStrnCpyS ( + Buffer, + sizeof(Buffer) / sizeof(CHAR8), + "-> EBP:0x00000000 EIP:0x00000000\n", + sizeof(Buffer) / sizeof(CHAR8) - 1 + ); + SerialPortWrite ((UINT8 *)"ASSERT DUMP:\n", 13); + while (Frame != NULL) { + FillHex ((UINT32)Frame, Buffer + 9); + FillHex (Frame[1], Buffer + 9 + 8 + 8); + SerialPortWrite ((UINT8 *)Buffer, AsciiStrLen (Buffer)); + if ((Frame[0] > (UINT32)Frame) && (Frame[0] < (UINT32)Frame + 0x00100000)) { + Frame = (UINT32 *)Frame[0]; + } else { + Frame = NULL; + } + } + + // + // Dead loop + // + CpuDeadLoop (); +} + +/** + Prints an assert message containing a filename, line number, and description. + This may be followed by a breakpoint or a dead loop. + + Print a message of the form "ASSERT (): \n" + to the debug output device. If DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED bit of + PcdDebugProperyMask is set then CpuBreakpoint() is called. Otherwise, if + DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED bit of PcdDebugProperyMask is set then + CpuDeadLoop() is called. If neither of these bits are set, then this function + returns immediately after the message is printed to the debug output device. + DebugAssert() must actively prevent recursion. If DebugAssert() is called while + processing another DebugAssert(), then DebugAssert() must return immediately. + + If FileName is NULL, then a string of "(NULL) Filename" is printed. + If Description is NULL, then a string of "(NULL) Description" is printed. + + @param FileName The pointer to the name of the source file that generated the assert condition. + @param LineNumber The line number in the source file that generated the assert condition + @param Description The pointer to the description of the assert condition. + +**/ +VOID +EFIAPI +DebugAssert ( + IN CONST CHAR8 *FileName, + IN UINTN LineNumber, + IN CONST CHAR8 *Description + ) +{ + DebugAssertInternal (); +} + + +/** + Fills a target buffer with PcdDebugClearMemoryValue, and returns the target buffer. + + This function fills Length bytes of Buffer with the value specified by + PcdDebugClearMemoryValue, and returns Buffer. + + If Buffer is NULL, then ASSERT(). + If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). + + @param Buffer The pointer to the target buffer to be filled with PcdDebugClearMemoryValue. + @param Length The number of bytes in Buffer to fill with zeros PcdDebugClearMemoryValue. + + @return Buffer The pointer to the target buffer filled with PcdDebugClearMemoryValue. + +**/ +VOID * +EFIAPI +DebugClearMemory ( + OUT VOID *Buffer, + IN UINTN Length + ) +{ + return Buffer; +} + + +/** + Returns TRUE if ASSERT() macros are enabled. + + This function returns TRUE if the DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of + PcdDebugProperyMask is set. Otherwise FALSE is returned. + + @retval TRUE The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugProperyMask is set. + @retval FALSE The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugProperyMask is clear. + +**/ +BOOLEAN +EFIAPI +DebugAssertEnabled ( + VOID + ) +{ + return (BOOLEAN) ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED) != 0); +} + + +/** + Returns TRUE if DEBUG() macros are enabled. + + This function returns TRUE if the DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of + PcdDebugProperyMask is set. Otherwise FALSE is returned. + + @retval TRUE The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugProperyMask is set. + @retval FALSE The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugProperyMask is clear. + +**/ +BOOLEAN +EFIAPI +DebugPrintEnabled ( + VOID + ) +{ + return (BOOLEAN) ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_PRINT_ENABLED) != 0); +} + +/** + Returns TRUE if DEBUG_CODE() macros are enabled. + + This function returns TRUE if the DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of + PcdDebugProperyMask is set. Otherwise FALSE is returned. + + @retval TRUE The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask is set. + @retval FALSE The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask is clear. + +**/ +BOOLEAN +EFIAPI +DebugCodeEnabled ( + VOID + ) +{ + return (BOOLEAN) ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_CODE_ENABLED) != 0); +} + + +/** + Returns TRUE if DEBUG_CLEAR_MEMORY() macro is enabled. + + This function returns TRUE if the DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of + PcdDebugProperyMask is set. Otherwise FALSE is returned. + + @retval TRUE The DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of PcdDebugProperyMask is set. + @retval FALSE The DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of PcdDebugProperyMask is clear. + +**/ +BOOLEAN +EFIAPI +DebugClearMemoryEnabled ( + VOID + ) +{ + return (BOOLEAN) ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED) != 0); +} + +/** + Returns TRUE if any one of the bit is set both in ErrorLevel and PcdFixedDebugPrintErrorLevel. + + This function compares the bit mask of ErrorLevel and PcdFixedDebugPrintErrorLevel. + + @retval TRUE Current ErrorLevel is supported. + @retval FALSE Current ErrorLevel is not supported. + +**/ +BOOLEAN +EFIAPI +DebugPrintLevelEnabled ( + IN CONST UINTN ErrorLevel + ) +{ + return (BOOLEAN) ((ErrorLevel & PcdGet32(PcdFixedDebugPrintErrorLevel)) != 0); +} diff --git a/IntelFsp2Pkg/Library/BaseFspDebugLibSerialPort/Ia32/FspDebug.asm b/IntelFsp2Pkg/Library/BaseFspDebugLibSerialPort/Ia32/FspDebug.asm new file mode 100644 index 0000000000..8ac18ec4ec --- /dev/null +++ b/IntelFsp2Pkg/Library/BaseFspDebugLibSerialPort/Ia32/FspDebug.asm @@ -0,0 +1,34 @@ +;------------------------------------------------------------------------------ +; +; Copyright (c) 2014, Intel Corporation. All rights reserved.
+; This program and the accompanying materials +; are licensed and made available under the terms and conditions of the BSD License +; which accompanies this distribution. The full text of the license may be found at +; http://opensource.org/licenses/bsd-license.php. +; +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +; +; Abstract: +; +; FSP Debug functions +; +;------------------------------------------------------------------------------ + + .386 + .model flat,C + .code + +;------------------------------------------------------------------------------ +; UINT32 * +; EFIAPI +; GetStackFramePointer ( +; VOID +; ); +;------------------------------------------------------------------------------ +GetStackFramePointer PROC PUBLIC + mov eax, ebp + ret +GetStackFramePointer ENDP + + END diff --git a/IntelFsp2Pkg/Library/BaseFspDebugLibSerialPort/Ia32/FspDebug.s b/IntelFsp2Pkg/Library/BaseFspDebugLibSerialPort/Ia32/FspDebug.s new file mode 100644 index 0000000000..0f8475fa62 --- /dev/null +++ b/IntelFsp2Pkg/Library/BaseFspDebugLibSerialPort/Ia32/FspDebug.s @@ -0,0 +1,30 @@ +#------------------------------------------------------------------------------ +# +# Copyright (c) 2014, Intel Corporation. All rights reserved.
+# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +# Abstract: +# +# FSP Debug functions +# +#------------------------------------------------------------------------------ + +#------------------------------------------------------------------------------ +# UINT32 * +# EFIAPI +# GetStackFramePointer ( +# VOID +# ) +#------------------------------------------------------------------------------ +ASM_GLOBAL ASM_PFX(GetStackFramePointer) +ASM_PFX(GetStackFramePointer): + mov %ebp, %eax + ret + + diff --git a/IntelFsp2Pkg/Library/BaseFspPlatformLib/BaseFspPlatformLib.inf b/IntelFsp2Pkg/Library/BaseFspPlatformLib/BaseFspPlatformLib.inf new file mode 100644 index 0000000000..d04689ef88 --- /dev/null +++ b/IntelFsp2Pkg/Library/BaseFspPlatformLib/BaseFspPlatformLib.inf @@ -0,0 +1,50 @@ +## @file +# Instance of FspPlatformLib +# +# Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = BaseFspPlatformLib + FILE_GUID = B6380BFB-7140-4C52-AC42-8C966C9A3F34 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = FspPlatformLib + +[Sources] + FspPlatformMemory.c + FspPlatformNotify.c + +[Packages] + MdePkg/MdePkg.dec + IntelFsp2Pkg/IntelFsp2Pkg.dec + +[LibraryClasses] + BaseMemoryLib + MemoryAllocationLib + FspCommonLib + PerformanceLib + ReportStatusCodeLib + +[Pcd] + gIntelFsp2PkgTokenSpaceGuid.PcdGlobalDataPointerAddress ## CONSUMES + gIntelFsp2PkgTokenSpaceGuid.PcdTemporaryRamBase ## CONSUMES + gIntelFsp2PkgTokenSpaceGuid.PcdTemporaryRamSize ## CONSUMES + gIntelFsp2PkgTokenSpaceGuid.PcdFspTemporaryRamSize ## CONSUMES + +[Guids] + gFspPerformanceDataGuid ## CONSUMES ## GUID + gFspEventEndOfFirmwareGuid ## PRODUCES ## GUID + +[FixedPcd] + gIntelFsp2PkgTokenSpaceGuid.PcdFspMaxPatchEntry ## CONSUMES + gIntelFsp2PkgTokenSpaceGuid.PcdFspMaxPerfEntry ## CONSUMES diff --git a/IntelFsp2Pkg/Library/BaseFspPlatformLib/FspPlatformMemory.c b/IntelFsp2Pkg/Library/BaseFspPlatformLib/FspPlatformMemory.c new file mode 100644 index 0000000000..d6684f3b06 --- /dev/null +++ b/IntelFsp2Pkg/Library/BaseFspPlatformLib/FspPlatformMemory.c @@ -0,0 +1,189 @@ +/** @file + + Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** + Get system memory resource descriptor by owner. + + @param[in] OwnerGuid resource owner guid +**/ +EFI_HOB_RESOURCE_DESCRIPTOR * +EFIAPI +FspGetResourceDescriptorByOwner ( + IN EFI_GUID *OwnerGuid + ) +{ + EFI_PEI_HOB_POINTERS Hob; + + // + // Get the HOB list for processing + // + Hob.Raw = GetHobList (); + + // + // Collect memory ranges + // + while (!END_OF_HOB_LIST (Hob)) { + if (Hob.Header->HobType == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) { + if ((Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_MEMORY_RESERVED) && \ + (CompareGuid (&Hob.ResourceDescriptor->Owner, OwnerGuid))) { + return Hob.ResourceDescriptor; + } + } + Hob.Raw = GET_NEXT_HOB (Hob); + } + + return NULL; +} + +/** + Get system memory from HOB. + + @param[in,out] LowMemoryLength less than 4G memory length + @param[in,out] HighMemoryLength greater than 4G memory length +**/ +VOID +EFIAPI +FspGetSystemMemorySize ( + IN OUT UINT64 *LowMemoryLength, + IN OUT UINT64 *HighMemoryLength + ) +{ + EFI_STATUS Status; + EFI_BOOT_MODE BootMode; + EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttribute; + EFI_PEI_HOB_POINTERS Hob; + + ResourceAttribute = ( + EFI_RESOURCE_ATTRIBUTE_PRESENT | + EFI_RESOURCE_ATTRIBUTE_INITIALIZED | + EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE | + EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE | + EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE | + EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE + ); + + Status = PeiServicesGetBootMode (&BootMode); + ASSERT_EFI_ERROR (Status); + + if (BootMode != BOOT_ON_S3_RESUME) { + ResourceAttribute |= EFI_RESOURCE_ATTRIBUTE_TESTED; + } + + *HighMemoryLength = 0; + *LowMemoryLength = SIZE_1MB; + // + // Get the HOB list for processing + // + Hob.Raw = GetHobList (); + + // + // Collect memory ranges + // + while (!END_OF_HOB_LIST (Hob)) { + if (Hob.Header->HobType == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) { + if ((Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) || + ((Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_MEMORY_RESERVED) && + (Hob.ResourceDescriptor->ResourceAttribute == ResourceAttribute))) { + // + // Need memory above 1MB to be collected here + // + if (Hob.ResourceDescriptor->PhysicalStart >= BASE_1MB && + Hob.ResourceDescriptor->PhysicalStart < (EFI_PHYSICAL_ADDRESS) BASE_4GB) { + *LowMemoryLength += (UINT64) (Hob.ResourceDescriptor->ResourceLength); + } else if (Hob.ResourceDescriptor->PhysicalStart >= (EFI_PHYSICAL_ADDRESS) BASE_4GB) { + *HighMemoryLength += (UINT64) (Hob.ResourceDescriptor->ResourceLength); + } + } + } + Hob.Raw = GET_NEXT_HOB (Hob); + } +} + +/** + Migrate BootLoader data before destroying CAR. + +**/ +VOID +EFIAPI +FspMigrateTemporaryMemory ( + VOID + ) +{ + UINT32 BootLoaderTempRamStart; + UINT32 BootLoaderTempRamEnd; + UINT32 BootLoaderTempRamSize; + UINT32 OffsetGap; + UINT32 FspParamPtr; + VOID *BootLoaderTempRamHob; + UINT32 MemoryInitUpdPtr; + VOID *PlatformDataPtr; + + // + // Get the temporary memory range used by the BootLoader + // + BootLoaderTempRamStart = GetFspCarBase (); + BootLoaderTempRamSize = GetFspCarSize () - PcdGet32(PcdFspTemporaryRamSize); + + BootLoaderTempRamEnd = BootLoaderTempRamStart + BootLoaderTempRamSize; + + // + // Build a Boot Loader Temporary Memory GUID HOB + // + BootLoaderTempRamHob = (VOID *)AllocatePages (EFI_SIZE_TO_PAGES (BootLoaderTempRamSize)); + ASSERT(BootLoaderTempRamHob != NULL); + + DEBUG ((DEBUG_INFO, "FSP_BOOT_LOADER_TEMPORARY_MEMORY_HOB\n")); + DEBUG ((DEBUG_INFO, "FspBootLoaderTemporaryMemory Base : %x\n", BootLoaderTempRamStart)); + DEBUG ((DEBUG_INFO, "FspBootLoaderTemporaryMemory Size : %x\n", BootLoaderTempRamSize)); + + CopyMem (BootLoaderTempRamHob, (VOID *)BootLoaderTempRamStart, BootLoaderTempRamSize); + OffsetGap = (UINT32)BootLoaderTempRamHob - BootLoaderTempRamStart; + + // + // Fix the FspMemoryinit Parameter Pointers to the new location. + // + FspParamPtr = GetFspApiParameter (); + if ((VOID *)FspParamPtr != NULL && FspParamPtr >= BootLoaderTempRamStart && + FspParamPtr < BootLoaderTempRamEnd) { + SetFspApiParameter (FspParamPtr + OffsetGap); + } + + // + // Update UPD pointer in FSP Global Data + // + MemoryInitUpdPtr = (UINT32)((UINT32 *)GetFspMemoryInitUpdDataPointer ()); + if (MemoryInitUpdPtr >= BootLoaderTempRamStart && MemoryInitUpdPtr < BootLoaderTempRamEnd) { + SetFspMemoryInitUpdDataPointer ((VOID *)(MemoryInitUpdPtr + OffsetGap)); + } + + // + // Update Platform data pointer in FSP Global Data + // + PlatformDataPtr = GetFspPlatformDataPointer (); + if (((UINT32)PlatformDataPtr >= BootLoaderTempRamStart) && + ((UINT32)PlatformDataPtr < BootLoaderTempRamEnd)) { + SetFspPlatformDataPointer ((UINT8 *)PlatformDataPtr + OffsetGap); + } +} diff --git a/IntelFsp2Pkg/Library/BaseFspPlatformLib/FspPlatformNotify.c b/IntelFsp2Pkg/Library/BaseFspPlatformLib/FspPlatformNotify.c new file mode 100644 index 0000000000..66b6cdb878 --- /dev/null +++ b/IntelFsp2Pkg/Library/BaseFspPlatformLib/FspPlatformNotify.c @@ -0,0 +1,279 @@ +/** @file + + Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +extern EFI_GUID gFspPerformanceDataGuid; + +EFI_PEI_PPI_DESCRIPTOR mPeiPostPciEnumerationPpi = { + (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gEfiPciEnumerationCompleteProtocolGuid, + NULL +}; + +EFI_PEI_PPI_DESCRIPTOR mPeiReadyToBootPpi = { + (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gEfiEventReadyToBootGuid, + NULL +}; + +EFI_PEI_PPI_DESCRIPTOR mPeiEndOfFirmwarePpi = { + (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gFspEventEndOfFirmwareGuid, + NULL +}; + +UINT32 mFspNotifySequence[] = { + EnumInitPhaseAfterPciEnumeration, + EnumInitPhaseReadyToBoot, + EnumInitPhaseEndOfFirmware +}; + +/** + Install FSP notification. + + @param[in] NotificationCode FSP notification code + + @retval EFI_SUCCESS Notify FSP successfully + @retval EFI_INVALID_PARAMETER NotificationCode is invalid + +**/ +EFI_STATUS +EFIAPI +FspNotificationHandler ( + IN UINT32 NotificationCode + ) +{ + EFI_STATUS Status; + + Status = EFI_SUCCESS; + + switch (NotificationCode) { + case EnumInitPhaseAfterPciEnumeration: + // + // Do POST PCI initialization if needed + // + DEBUG ((DEBUG_INFO | DEBUG_INIT, "FSP Post PCI Enumeration ...\n")); + PeiServicesInstallPpi (&mPeiPostPciEnumerationPpi); + break; + + case EnumInitPhaseReadyToBoot: + // + // Ready To Boot + // + DEBUG ((DEBUG_INFO| DEBUG_INIT, "FSP Ready To Boot ...\n")); + PeiServicesInstallPpi (&mPeiReadyToBootPpi); + break; + + case EnumInitPhaseEndOfFirmware: + // + // End of Firmware + // + DEBUG ((DEBUG_INFO| DEBUG_INIT, "FSP End of Firmware ...\n")); + PeiServicesInstallPpi (&mPeiEndOfFirmwarePpi); + break; + + default: + Status = EFI_INVALID_PARAMETER; + break; + } + + return Status; +} + +/** + This function transfer control back to BootLoader after FspSiliconInit. + +**/ +VOID +EFIAPI +FspSiliconInitDone ( + VOID + ) +{ + // + // This is the end of the FspSiliconInit API + // Give control back to the boot loader + // + SetFspMeasurePoint (FSP_PERF_ID_API_FSP_SILICON_INIT_EXIT); + DEBUG ((DEBUG_INFO | DEBUG_INIT, "FspSiliconInitApi() - End\n")); + + PERF_END_EX (&gFspPerformanceDataGuid, "EventRec", NULL, 0, 0x907F); + + REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT); + SetFspApiReturnStatus (EFI_SUCCESS); + + Pei2LoaderSwitchStack(); + + PERF_START_EX (&gFspPerformanceDataGuid, "EventRec", NULL, 0, 0x6000); +} + +/** + This function returns control to BootLoader after MemoryInitApi. + + @param[in,out] HobListPtr The address of HobList pointer. +**/ +VOID +EFIAPI +FspMemoryInitDone ( + IN OUT VOID **HobListPtr + ) +{ + // + // Calling use FspMemoryInit API + // Update HOB and return the control directly + // + if (HobListPtr != NULL) { + *HobListPtr = (VOID *) GetHobList (); + } + + // + // This is the end of the FspMemoryInit API + // Give control back to the boot loader + // + SetFspMeasurePoint (FSP_PERF_ID_API_FSP_MEMORY_INIT_EXIT); + DEBUG ((DEBUG_INFO | DEBUG_INIT, "FspMemoryInitApi() - End\n")); + REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_MEMORY_INIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT); + SetFspApiReturnStatus (EFI_SUCCESS); + Pei2LoaderSwitchStack (); + + // + // The TempRamExitApi is called + // + if (GetFspApiCallingIndex () == TempRamExitApiIndex) { + SetPhaseStatusCode (FSP_STATUS_CODE_TEMP_RAM_EXIT); + REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_TEMP_RAM_EXIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY); + SetFspMeasurePoint (FSP_PERF_ID_API_TEMP_RAM_EXIT_ENTRY); + DEBUG ((DEBUG_INFO | DEBUG_INIT, "TempRamExitApi() - Begin\n")); + } else { + SetFspMeasurePoint (FSP_PERF_ID_API_FSP_SILICON_INIT_ENTRY); + DEBUG ((DEBUG_INFO | DEBUG_INIT, "FspSiliconInitApi() - Begin\n")); + SetPhaseStatusCode (FSP_STATUS_CODE_SILICON_INIT); + REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_SILICON_INIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY); + } +} + +/** + This function returns control to BootLoader after TempRamExitApi. + +**/ +VOID +EFIAPI +FspTempRamExitDone ( + VOID + ) +{ + + // + // This is the end of the TempRamExit API + // Give control back to the boot loader + // + SetFspMeasurePoint (FSP_PERF_ID_API_TEMP_RAM_EXIT_EXIT); + DEBUG ((DEBUG_INFO | DEBUG_INIT, "TempRamExitApi() - End\n")); + REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_TEMP_RAM_EXIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT); + SetFspApiReturnStatus (EFI_SUCCESS); + Pei2LoaderSwitchStack (); + + SetPhaseStatusCode (FSP_STATUS_CODE_SILICON_INIT); + SetFspMeasurePoint (FSP_PERF_ID_API_FSP_SILICON_INIT_ENTRY); + DEBUG ((DEBUG_INFO | DEBUG_INIT, "SiliconInitApi() - Begin\n")); + REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_SILICON_INIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY); +} + +/** + This function handle NotifyPhase API call from the BootLoader. + It gives control back to the BootLoader after it is handled. If the + Notification code is a ReadyToBoot event, this function will return + and FSP continues the remaining execution until it reaches the DxeIpl. + +**/ +VOID +FspWaitForNotify ( + VOID + ) +{ + EFI_STATUS Status; + UINT32 NotificationValue; + UINT32 NotificationCount; + UINT8 Count; + + NotificationCount = 0; + while (NotificationCount < sizeof(mFspNotifySequence) / sizeof(UINT32)) { + + Count = (UINT8)((NotificationCount << 1) & 0x07); + SetFspMeasurePoint (FSP_PERF_ID_API_NOTIFY_POST_PCI_ENTRY + Count); + + if (NotificationCount == 0) { + SetPhaseStatusCode (FSP_STATUS_CODE_POST_PCIE_ENUM_NOTIFICATION); + REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_POST_PCIE_ENUM_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY); + } else if (NotificationCount == 1) { + SetPhaseStatusCode (FSP_STATUS_CODE_READY_TO_BOOT_NOTIFICATION); + REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_READY_TO_BOOT_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY); + } else if (NotificationCount == 2) { + SetPhaseStatusCode (FSP_STATUS_CODE_END_OF_FIRMWARE_NOTIFICATION); + REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_END_OF_FIRMWARE_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY); + } + + NotificationValue = ((NOTIFY_PHASE_PARAMS *)(UINTN)GetFspApiParameter ())->Phase; + DEBUG ((DEBUG_INFO | DEBUG_INIT, "NotifyPhaseApi() - Begin [Phase: %08X]\n", NotificationValue)); + if (mFspNotifySequence[NotificationCount] != NotificationValue) { + // + // Notify code does not follow the predefined order + // + DEBUG ((DEBUG_INFO, "Unsupported FSP Notification Value\n")); + Status = EFI_UNSUPPORTED; + } else { + // + // Process Notification and Give control back to the boot loader framework caller + // + Status = FspNotificationHandler (NotificationValue); + if (!EFI_ERROR(Status)) { + NotificationCount++; + } + } + + SetFspApiReturnStatus(Status); + DEBUG ((DEBUG_INFO | DEBUG_INIT, "NotifyPhaseApi() - End [Status: 0x%08X]\n", Status)); + + SetFspMeasurePoint (FSP_PERF_ID_API_NOTIFY_POST_PCI_EXIT + Count); + + if ((NotificationCount - 1) == 0) { + REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_POST_PCIE_ENUM_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT); + } else if ((NotificationCount - 1) == 1) { + REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_READY_TO_BOOT_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT); + } else if ((NotificationCount - 1) == 2) { + REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_END_OF_FIRMWARE_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT); + } + Pei2LoaderSwitchStack(); + } + + // + // Control goes back to the PEI Core and it dispatches further PEIMs. + // DXEIPL is the final one to transfer control back to the boot loader. + // +} + diff --git a/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/BaseFspSwitchStackLib.inf b/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/BaseFspSwitchStackLib.inf new file mode 100644 index 0000000000..bbeeb744ff --- /dev/null +++ b/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/BaseFspSwitchStackLib.inf @@ -0,0 +1,43 @@ +## @file +# Instance of BaseFspSwitchStackLib +# +# Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = BaseFspSwitchStackLib + FILE_GUID = 68E79161-F7CE-4A61-8C72-F4DF6FF35CAA + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = FspSwitchStackLib + +[Sources.IA32] + FspSwitchStackLib.c + +[Sources.IA32] + Ia32/Stack.asm | MSFT + Ia32/Stack.s | GCC + +[Packages] + MdePkg/MdePkg.dec + IntelFsp2Pkg/IntelFsp2Pkg.dec + +[LibraryClasses] + BaseLib + IoLib + +[FixedPcd] + gIntelFsp2PkgTokenSpaceGuid.PcdFspMaxPatchEntry ## CONSUMES + gIntelFsp2PkgTokenSpaceGuid.PcdFspMaxPerfEntry ## CONSUMES + + + diff --git a/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/FspSwitchStackLib.c b/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/FspSwitchStackLib.c new file mode 100644 index 0000000000..42a57a27c0 --- /dev/null +++ b/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/FspSwitchStackLib.c @@ -0,0 +1,42 @@ +/** @file + + Copyright (c) 2014, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include +#include + +/** + + Switch the current stack to the previous saved stack. + + @param[in] NewStack The new stack to be switched. + + @return OldStack After switching to the saved stack, + this value will be saved in eax before returning. + + +**/ +UINT32 +SwapStack ( + IN UINT32 NewStack + ) +{ + FSP_GLOBAL_DATA *FspData; + UINT32 OldStack; + + FspData = GetFspGlobalDataPointer (); + OldStack = FspData->CoreStack; + FspData->CoreStack = NewStack; + return OldStack; +} + diff --git a/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/Ia32/Stack.asm b/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/Ia32/Stack.asm new file mode 100644 index 0000000000..1efab52059 --- /dev/null +++ b/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/Ia32/Stack.asm @@ -0,0 +1,77 @@ +;------------------------------------------------------------------------------ +; +; Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.
+; This program and the accompanying materials +; are licensed and made available under the terms and conditions of the BSD License +; which accompanies this distribution. The full text of the license may be found at +; http://opensource.org/licenses/bsd-license.php. +; +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +; +; Abstract: +; +; Switch the stack from temporary memory to permenent memory. +; +;------------------------------------------------------------------------------ + + .586p + .model flat,C + .code + +;------------------------------------------------------------------------------ +; UINT32 +; EFIAPI +; Pei2LoaderSwitchStack ( +; VOID +; ) +;------------------------------------------------------------------------------ +EXTERNDEF C MeasurePoint:PROC +Pei2LoaderSwitchStack PROC C PUBLIC + xor eax, eax + jmp FspSwitchStack +Pei2LoaderSwitchStack ENDP + +;------------------------------------------------------------------------------ +; UINT32 +; EFIAPI +; Loader2PeiSwitchStack ( +; VOID +; ) +;------------------------------------------------------------------------------ +Loader2PeiSwitchStack PROC C PUBLIC + jmp FspSwitchStack +Loader2PeiSwitchStack ENDP + +;------------------------------------------------------------------------------ +; UINT32 +; EFIAPI +; FspSwitchStack ( +; VOID +; ) +;------------------------------------------------------------------------------ +EXTERNDEF C SwapStack:PROC +FspSwitchStack PROC C PUBLIC + ; Save current contexts + push eax + pushfd + cli + pushad + sub esp, 8 + sidt fword ptr [esp] + + ; Load new stack + push esp + call SwapStack + mov esp, eax + + ; Restore previous contexts + lidt fword ptr [esp] + add esp, 8 + popad + popfd + add esp, 4 + ret +FspSwitchStack ENDP + + END diff --git a/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/Ia32/Stack.s b/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/Ia32/Stack.s new file mode 100644 index 0000000000..a21a5b6c61 --- /dev/null +++ b/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/Ia32/Stack.s @@ -0,0 +1,78 @@ +#------------------------------------------------------------------------------ +# +# Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.
+# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +# Abstract: +# +# Switch the stack from temporary memory to permenent memory. +# +#------------------------------------------------------------------------------ + + +#------------------------------------------------------------------------------ +# UINT32 +# EFIAPI +# Pei2LoaderSwitchStack ( +# VOID +# ) +#------------------------------------------------------------------------------ +ASM_GLOBAL ASM_PFX(Pei2LoaderSwitchStack) +ASM_PFX(Pei2LoaderSwitchStack): + xorl %eax, %eax + jmp ASM_PFX(FspSwitchStack) + +#------------------------------------------------------------------------------ +# UINT32 +# EFIAPI +# Loader2PeiSwitchStack ( +# VOID +# ) +#------------------------------------------------------------------------------ +ASM_GLOBAL ASM_PFX(Loader2PeiSwitchStack) +ASM_PFX(Loader2PeiSwitchStack): + jmp ASM_PFX(FspSwitchStack) + +#------------------------------------------------------------------------------ +# UINT32 +# EFIAPI +# FspSwitchStack ( +# VOID +# ) +#------------------------------------------------------------------------------ +ASM_GLOBAL ASM_PFX(FspSwitchStack) +ASM_PFX(FspSwitchStack): + # + #Save current contexts + # + push %eax + pushf + cli + pusha + sub $0x08, %esp + sidt (%esp) + + # + # Load new stack + # + push %esp + call ASM_PFX(SwapStack) + movl %eax, %esp + + # + # Restore previous contexts + # + lidt (%esp) + add $0x08,%esp + popa + popf + add $0x04,%esp + ret + + diff --git a/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/Ia32/Flat32.asm b/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/Ia32/Flat32.asm new file mode 100644 index 0000000000..9f144fc4ca --- /dev/null +++ b/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/Ia32/Flat32.asm @@ -0,0 +1,131 @@ +;; @file +; This is the code that goes from real-mode to protected mode. +; It consumes the reset vector, configures the stack. +; +; Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.
+; This program and the accompanying materials +; are licensed and made available under the terms and conditions of the BSD License +; which accompanies this distribution. The full text of the license may be found at +; http://opensource.org/licenses/bsd-license.php. +; +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +;; + +; +; Define assembler characteristics +; +.586p +.xmm +.model flat, c + +EXTRN TempRamInitApi:NEAR + +.code + +RET_ESI MACRO + + movd esi, mm7 ; restore ESP from MM7 + jmp esi + +ENDM + +; +; Perform early platform initialization +; +SecPlatformInit PROC NEAR PUBLIC + + RET_ESI + +SecPlatformInit ENDP + +; +; Protected mode portion initializes stack, configures cache, and calls C entry point +; + +;---------------------------------------------------------------------------- +; +; Procedure: ProtectedModeEntryPoint +; +; Input: Executing in 32 Bit Protected (flat) mode +; cs: 0-4GB +; ds: 0-4GB +; es: 0-4GB +; fs: 0-4GB +; gs: 0-4GB +; ss: 0-4GB +; +; Output: This function never returns +; +; Destroys: +; ecx +; edi +; esi +; esp +; +; Description: +; Perform any essential early platform initilaisation +; Setup a stack +; +;---------------------------------------------------------------------------- + +ProtectedModeEntryPoint PROC NEAR C PUBLIC + ; + ; Dummy function. Consume 2 API to make sure they can be linked. + ; + mov eax, TempRamInitApi + + ; Should never return + jmp $ + +ProtectedModeEntryPoint ENDP + +; +; ROM-based Global-Descriptor Table for the PEI Phase +; +align 16 +PUBLIC BootGdtTable + +; +; GDT[0]: 0x00: Null entry, never used. +; +NULL_SEL equ $ - GDT_BASE ; Selector [0] +GDT_BASE: +BootGdtTable DD 0 + DD 0 +; +; Linear code segment descriptor +; +LINEAR_CODE_SEL equ $ - GDT_BASE ; Selector [0x8] + DW 0FFFFh ; limit 0xFFFF + DW 0 ; base 0 + DB 0 + DB 09Bh ; present, ring 0, data, expand-up, not-writable + DB 0CFh ; page-granular, 32-bit + DB 0 +; +; System data segment descriptor +; +SYS_DATA_SEL equ $ - GDT_BASE ; Selector [0x10] + DW 0FFFFh ; limit 0xFFFF + DW 0 ; base 0 + DB 0 + DB 093h ; present, ring 0, data, expand-up, not-writable + DB 0CFh ; page-granular, 32-bit + DB 0 + +GDT_SIZE EQU $ - BootGDTtable ; Size, in bytes + +; +; GDT Descriptor +; +GdtDesc: ; GDT descriptor + DW GDT_SIZE - 1 ; GDT limit + DD OFFSET BootGdtTable ; GDT base address + +ProtectedModeEntryLinearAddress LABEL FWORD +ProtectedModeEntryLinearOffset LABEL DWORD + DD OFFSET ProtectedModeEntryPoint ; Offset of our 32 bit code + DW LINEAR_CODE_SEL + +END diff --git a/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/Ia32/Flat32.s b/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/Ia32/Flat32.s new file mode 100644 index 0000000000..d46d792477 --- /dev/null +++ b/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/Ia32/Flat32.s @@ -0,0 +1,110 @@ +#------------------------------------------------------------------------------ +# +# Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.
+# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +# Abstract: +# +# This is the code that goes from real-mode to protected mode. +# It consumes the reset vector, configures the stack. +# +#------------------------------------------------------------------------------ + + +# +# Contrary to the name, this file contains 16 bit code as well. +# +.text + +ASM_GLOBAL ASM_PFX(SecPlatformInit) +ASM_PFX(SecPlatformInit): + movd %mm7, %esi # restore ESP from MM7 + jmp *%esi + +#---------------------------------------------------------------------------- +# +# Procedure: ProtectedModeEntryPoint +# +# Input: Executing in 32 Bit Protected (flat) mode +# cs: 0-4GB +# ds: 0-4GB +# es: 0-4GB +# fs: 0-4GB +# gs: 0-4GB +# ss: 0-4GB +# +# Output: This function never returns +# +# Destroys: +# ecx +# edi +# esi +# esp +# +# Description: +# Perform any essential early platform initilaisation +# Setup a stack +# +#---------------------------------------------------------------------------- +ProtectedModeEntryPoint: + # + # Dummy function. Consume 2 API to make sure they can be linked. + # + movl ASM_PFX(TempRamInitApi), %eax + # + # Should never return + # + jmp . #'$' + +# +# ROM-based Global-Descriptor Table for the PEI Phase +# +.align 16 +# +# GDT[0]: 000h: Null entry, never used. +# +.equ NULL_SEL, . - GDT_BASE # Selector [0] +GDT_BASE: +BootGdtTable: + .long 0 + .long 0 +# +# Linear code segment descriptor +# +.equ LINEAR_CODE_SEL, . - GDT_BASE # Selector [08h] + .word 0xFFFF # limit 0FFFFh + .word 0 # base 0 + .byte 0 + .byte 0x9B # present, ring 0, data, expand-up, not-writable + .byte 0xCF # page-granular, 32-bit + .byte 0 +# +# System data segment descriptor +# +.equ SYS_DATA_SEL, . - GDT_BASE # Selector [010h] + .word 0xFFFF # limit 0FFFFh + .word 0 # base 0 + .byte 0 + .byte 0x93 # present, ring 0, data, expand-up, not-writable + .byte 0xCF # page-granular, 32-bit + .byte 0 + +.equ GDT_SIZE, . - BootGdtTable # Size, in bytes + +# +# GDT Descriptor +# +GdtDesc: # GDT descriptor + .word GDT_SIZE - 1 + .long BootGdtTable + +ProtectedModeEntryLinearAddress: +ProtectedModeEntryLinearOffset: + .long ProtectedModeEntryPoint + .word LINEAR_CODE_SEL diff --git a/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/Ia32/SecCarInit.asm b/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/Ia32/SecCarInit.asm new file mode 100644 index 0000000000..31296e0043 --- /dev/null +++ b/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/Ia32/SecCarInit.asm @@ -0,0 +1,51 @@ +;; @file +; SEC CAR function +; +; Copyright (c) 2015, Intel Corporation. All rights reserved.
+; This program and the accompanying materials +; are licensed and made available under the terms and conditions of the BSD License +; which accompanies this distribution. The full text of the license may be found at +; http://opensource.org/licenses/bsd-license.php. +; +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +;; + +; +; Define assembler characteristics +; +.586p +.xmm +.model flat, c + +RET_ESI MACRO + + movd esi, mm7 ; move ReturnAddress from MM7 to ESI + jmp esi + +ENDM + +.code + +;----------------------------------------------------------------------------- +; +; Section: SecCarInit +; +; Description: This function initializes the Cache for Data, Stack, and Code +; +;----------------------------------------------------------------------------- +SecCarInit PROC NEAR PUBLIC + + ; + ; Set up CAR + ; + + xor eax, eax + +SecCarInitExit: + + RET_ESI + +SecCarInit ENDP + +END diff --git a/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/Ia32/SecCarInit.s b/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/Ia32/SecCarInit.s new file mode 100644 index 0000000000..7bd40df36a --- /dev/null +++ b/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/Ia32/SecCarInit.s @@ -0,0 +1,37 @@ +#------------------------------------------------------------------------------ +# +# Copyright (c) 2015, Intel Corporation. All rights reserved.
+# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +# Abstract: +# +# SEC CAR function +# +#------------------------------------------------------------------------------ + +#----------------------------------------------------------------------------- +# +# Section: SecCarInit +# +# Description: This function initializes the Cache for Data, Stack, and Code +# +#----------------------------------------------------------------------------- +ASM_GLOBAL ASM_PFX(SecCarInit) +ASM_PFX(SecCarInit): + + # + # Set up CAR + # + + xor %eax, %eax + +SecCarInitExit: + + movd %mm7, %esi #RET_ESI + jmp *%esi diff --git a/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/PlatformSecLibNull.c b/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/PlatformSecLibNull.c new file mode 100644 index 0000000000..7bb95a9054 --- /dev/null +++ b/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/PlatformSecLibNull.c @@ -0,0 +1,33 @@ +/** @file + Null instance of Platform Sec Lib. + + Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include + +/** + This function check the signture of UPD. + + @param[in] ApiIdx Internal index of the FSP API. + @param[in] ApiParam Parameter of the FSP API. + +**/ +EFI_STATUS +EFIAPI +FspUpdSignatureCheck ( + IN UINT32 ApiIdx, + IN VOID *ApiParam + ) +{ + return EFI_SUCCESS; +} diff --git a/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/SecFspSecPlatformLibNull.inf b/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/SecFspSecPlatformLibNull.inf new file mode 100644 index 0000000000..1c18a587c3 --- /dev/null +++ b/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/SecFspSecPlatformLibNull.inf @@ -0,0 +1,58 @@ +## @file +# NULL instance of Platform Sec Lib. +# +# Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +################################################################################ +# +# Defines Section - statements that will be processed to create a Makefile. +# +################################################################################ +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = BaseFspSecPlatformLibNull + FILE_GUID = C128CADC-623E-4E41-97CB-A7138E627460 + MODULE_TYPE = SEC + VERSION_STRING = 1.0 + LIBRARY_CLASS = FspSecPlatformLib + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 +# + +################################################################################ +# +# Sources Section - list of files that are required for the build to succeed. +# +################################################################################ + +[Sources] + PlatformSecLibNull.c + +[Sources.IA32] + Ia32/Flat32.asm + Ia32/Flat32.s + Ia32/SecCarInit.asm + Ia32/SecCarInit.s + +################################################################################ +# +# Package Dependency Section - list of Package files that are required for +# this module. +# +################################################################################ + +[Packages] + MdePkg/MdePkg.dec + IntelFsp2Pkg/IntelFsp2Pkg.dec diff --git a/IntelFsp2Pkg/Tools/GenCfgOpt.py b/IntelFsp2Pkg/Tools/GenCfgOpt.py new file mode 100644 index 0000000000..4fd0562e75 --- /dev/null +++ b/IntelFsp2Pkg/Tools/GenCfgOpt.py @@ -0,0 +1,1465 @@ +## @ GenCfgOpt.py +# +# Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+# This program and the accompanying materials are licensed and made available under +# the terms and conditions of the BSD License that accompanies this distribution. +# The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +import os +import re +import sys +import struct +from datetime import date + +# Generated file copyright header + +__copyright_txt__ = """## @file +# +# THIS IS AUTO-GENERATED FILE BY BUILD TOOLS AND PLEASE DO NOT MAKE MODIFICATION. +# +# This file lists all VPD informations for a platform collected by build.exe. +# +# Copyright (c) %4d, Intel Corporation. All rights reserved.
+# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +""" + +__copyright_bsf__ = """/** @file + + Boot Setting File for Platform Configuration. + + Copyright (c) %4d, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + This file is automatically generated. Please do NOT modify !!! + +**/ + +""" + +__copyright_h__ = """/** @file + +Copyright (c) %4d, Intel Corporation. All rights reserved.
+ +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright notice, this + list of conditions and the following disclaimer in the documentation and/or + other materials provided with the distribution. +* Neither the name of Intel Corporation nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + THE POSSIBILITY OF SUCH DAMAGE. + + This file is automatically generated. Please do NOT modify !!! + +**/ +""" + +class CLogicalExpression: + def __init__(self): + self.index = 0 + self.string = '' + + def errExit(self, err = ''): + print "ERROR: Express parsing for:" + print " %s" % self.string + print " %s^" % (' ' * self.index) + if err: + print "INFO : %s" % err + raise SystemExit + + def getNonNumber (self, n1, n2): + if not n1.isdigit(): + return n1 + if not n2.isdigit(): + return n2 + return None + + def getCurr(self, lens = 1): + try: + if lens == -1: + return self.string[self.index :] + else: + if self.index + lens > len(self.string): + lens = len(self.string) - self.index + return self.string[self.index : self.index + lens] + except Exception: + return '' + + def isLast(self): + return self.index == len(self.string) + + def moveNext(self, len = 1): + self.index += len + + def skipSpace(self): + while not self.isLast(): + if self.getCurr() in ' \t': + self.moveNext() + else: + return + + def normNumber (self, val): + return True if val else False + + def getNumber(self, var): + var = var.strip() + if re.match('^0x[a-fA-F0-9]+$', var): + value = int(var, 16) + elif re.match('^[+-]?\d+$', var): + value = int(var, 10) + else: + value = None + return value + + def parseValue(self): + self.skipSpace() + var = '' + while not self.isLast(): + char = self.getCurr() + if re.match('^[\w.]', char): + var += char + self.moveNext() + else: + break + val = self.getNumber(var) + if val is None: + value = var + else: + value = "%d" % val + return value + + def parseSingleOp(self): + self.skipSpace() + if re.match('^NOT\W', self.getCurr(-1)): + self.moveNext(3) + op = self.parseBrace() + val = self.getNumber (op) + if val is None: + self.errExit ("'%s' is not a number" % op) + return "%d" % (not self.normNumber(int(op))) + else: + return self.parseValue() + + def parseBrace(self): + self.skipSpace() + char = self.getCurr() + if char == '(': + self.moveNext() + value = self.parseExpr() + self.skipSpace() + if self.getCurr() != ')': + self.errExit ("Expecting closing brace or operator") + self.moveNext() + return value + else: + value = self.parseSingleOp() + return value + + def parseCompare(self): + value = self.parseBrace() + while True: + self.skipSpace() + char = self.getCurr() + if char in ['<', '>']: + self.moveNext() + next = self.getCurr() + if next == '=': + op = char + next + self.moveNext() + else: + op = char + result = self.parseBrace() + test = self.getNonNumber(result, value) + if test is None: + value = "%d" % self.normNumber(eval (value + op + result)) + else: + self.errExit ("'%s' is not a valid number for comparision" % test) + elif char in ['=', '!']: + op = self.getCurr(2) + if op in ['==', '!=']: + self.moveNext(2) + result = self.parseBrace() + test = self.getNonNumber(result, value) + if test is None: + value = "%d" % self.normNumber((eval (value + op + result))) + else: + value = "%d" % self.normNumber(eval ("'" + value + "'" + op + "'" + result + "'")) + else: + break + else: + break + return value + + def parseAnd(self): + value = self.parseCompare() + while True: + self.skipSpace() + if re.match('^AND\W', self.getCurr(-1)): + self.moveNext(3) + result = self.parseCompare() + test = self.getNonNumber(result, value) + if test is None: + value = "%d" % self.normNumber(int(value) & int(result)) + else: + self.errExit ("'%s' is not a valid op number for AND" % test) + else: + break + return value + + def parseOrXor(self): + value = self.parseAnd() + op = None + while True: + self.skipSpace() + op = None + if re.match('^XOR\W', self.getCurr(-1)): + self.moveNext(3) + op = '^' + elif re.match('^OR\W', self.getCurr(-1)): + self.moveNext(2) + op = '|' + else: + break + if op: + result = self.parseAnd() + test = self.getNonNumber(result, value) + if test is None: + value = "%d" % self.normNumber(eval (value + op + result)) + else: + self.errExit ("'%s' is not a valid op number for XOR/OR" % test) + return value + + def parseExpr(self): + return self.parseOrXor() + + def getResult(self): + value = self.parseExpr() + self.skipSpace() + if not self.isLast(): + self.errExit ("Unexpected character found '%s'" % self.getCurr()) + test = self.getNumber(value) + if test is None: + self.errExit ("Result '%s' is not a number" % value) + return int(value) + + def evaluateExpress (self, Expr): + self.index = 0 + self.string = Expr + if self.getResult(): + Result = True + else: + Result = False + return Result + +class CGenCfgOpt: + def __init__(self): + self.Debug = False + self.Error = '' + self.ReleaseMode = True + + self._GlobalDataDef = """ +GlobalDataDef + SKUID = 0, "DEFAULT" +EndGlobalData + +""" + self._BuidinOptionTxt = """ +List &EN_DIS + Selection 0x1 , "Enabled" + Selection 0x0 , "Disabled" +EndList + +""" + + self._BsfKeyList = ['FIND','NAME','HELP','TYPE','PAGE','OPTION','ORDER'] + self._HdrKeyList = ['HEADER','STRUCT', 'EMBED', 'COMMENT'] + self._BuidinOption = {'$EN_DIS' : 'EN_DIS'} + + self._MacroDict = {} + self._CfgBlkDict = {} + self._CfgPageDict = {} + self._CfgItemList = [] + self._DscFile = '' + self._FvDir = '' + self._MapVer = 0 + + def ParseBuildMode (self, OutputStr): + if "RELEASE_" in OutputStr: + self.ReleaseMode = True + if "DEBUG_" in OutputStr: + self.ReleaseMode = False + return + + def ParseMacros (self, MacroDefStr): + # ['-DABC=1', '-D', 'CFG_DEBUG=1', '-D', 'CFG_OUTDIR=Build'] + self._MacroDict = {} + IsExpression = False + for Macro in MacroDefStr: + if Macro.startswith('-D'): + IsExpression = True + if len(Macro) > 2: + Macro = Macro[2:] + else : + continue + if IsExpression: + IsExpression = False + Match = re.match("(\w+)=(.+)", Macro) + if Match: + self._MacroDict[Match.group(1)] = Match.group(2) + else: + Match = re.match("(\w+)", Macro) + if Match: + self._MacroDict[Match.group(1)] = '' + if len(self._MacroDict) == 0: + Error = 1 + else: + Error = 0 + if self.Debug: + print "INFO : Macro dictionary:" + for Each in self._MacroDict: + print " $(%s) = [ %s ]" % (Each , self._MacroDict[Each]) + return Error + + def EvaulateIfdef (self, Macro): + Result = Macro in self._MacroDict + if self.Debug: + print "INFO : Eval Ifdef [%s] : %s" % (Macro, Result) + return Result + + def ExpandMacros (self, Input): + Line = Input + Match = re.findall("\$\(\w+\)", Input) + if Match: + for Each in Match: + Variable = Each[2:-1] + if Variable in self._MacroDict: + Line = Line.replace(Each, self._MacroDict[Variable]) + else: + if self.Debug: + print "WARN : %s is not defined" % Each + Line = Line.replace(Each, Each[2:-1]) + return Line + + def EvaluateExpress (self, Expr): + ExpExpr = self.ExpandMacros(Expr) + LogExpr = CLogicalExpression() + Result = LogExpr.evaluateExpress (ExpExpr) + if self.Debug: + print "INFO : Eval Express [%s] : %s" % (Expr, Result) + return Result + + def FormatListValue(self, ConfigDict): + Struct = ConfigDict['struct'] + if Struct not in ['UINT8','UINT16','UINT32','UINT64']: + return + + dataarray = [] + binlist = ConfigDict['value'][1:-1].split(',') + for each in binlist: + each = each.strip() + if each.startswith('0x'): + value = int(each, 16) + else: + value = int(each) + dataarray.append(value) + + unit = int(Struct[4:]) / 8 + if int(ConfigDict['length']) != unit * len(dataarray): + raise Exception("Array size is not proper for '%s' !" % ConfigDict['cname']) + + bytearray = [] + for each in dataarray: + value = each + for loop in xrange(unit): + bytearray.append("0x%02X" % (value & 0xFF)) + value = value >> 8 + newvalue = '{' + ','.join(bytearray) + '}' + ConfigDict['value'] = newvalue + return "" + + def ParseDscFile (self, DscFile, FvDir, ConfigDscFile, ExtConfigDscFile): + self._CfgItemList = [] + self._CfgPageDict = {} + self._CfgBlkDict = {} + self._DscFile = DscFile + self._FvDir = FvDir + + IsDefSect = False + IsUpdSect = False + IsVpdSect = False + Found = False + + IfStack = [] + ElifStack = [] + Error = 0 + ConfigDict = {} + + DscFd = open(DscFile, "r") + DscLines = DscFd.readlines() + DscFd.close() + + while len(DscLines): + DscLine = DscLines.pop(0).strip() + Handle = False + Match = re.match("^\[(.+)\]", DscLine) + if Match is not None: + if Match.group(1).lower() == "Defines".lower(): + IsDefSect = True + IsVpdSect = False + IsUpdSect = False + elif Match.group(1).lower() == "PcdsDynamicVpd.Upd".lower(): + ConfigDict = {} + ConfigDict['header'] = 'ON' + ConfigDict['region'] = 'UPD' + ConfigDict['order'] = -1 + ConfigDict['page'] = '' + ConfigDict['name'] = '' + ConfigDict['find'] = '' + ConfigDict['struct'] = '' + ConfigDict['embed'] = '' + ConfigDict['comment'] = '' + ConfigDict['subreg'] = [] + IsDefSect = False + IsUpdSect = True + IsVpdSect = False + Found = True + else: + IsDefSect = False + IsUpdSect = False + IsVpdSect = False + else: + if IsDefSect or IsUpdSect or IsVpdSect: + if re.match("^!else($|\s+#.+)", DscLine): + if IfStack: + IfStack[-1] = not IfStack[-1] + else: + print("ERROR: No paired '!if' found for '!else' for line '%s'" % DscLine) + raise SystemExit + elif re.match("^!endif($|\s+#.+)", DscLine): + if IfStack: + IfStack.pop() + Level = ElifStack.pop() + if Level > 0: + del IfStack[-Level:] + else: + print("ERROR: No paired '!if' found for '!endif' for line '%s'" % DscLine) + raise SystemExit + else: + Result = False + Match = re.match("!(ifdef|ifndef)\s+(.+)", DscLine) + if Match: + Result = self.EvaulateIfdef (Match.group(2)) + if Match.group(1) == 'ifndef': + Result = not Result + IfStack.append(Result) + ElifStack.append(0) + else: + Match = re.match("!(if|elseif)\s+(.+)", DscLine) + if Match: + IsFoundInFile = False + MatchPcdFormat = re.match("^\s*(.+)\.(.+)\s*==\s*(.+)", Match.group(2)) + if MatchPcdFormat: + ExtConfigDsc = open(ExtConfigDscFile, "r") + ExtConfigDscLines = ExtConfigDsc.readlines() + ExtConfigDsc.close() + + while len(ExtConfigDscLines): + ExtConfigDscLine = ExtConfigDscLines.pop(0).strip() + MatchExtConfigPcd = re.match("^\s*(.+)\s*\|\s*(.+)", ExtConfigDscLine) + if MatchExtConfigPcd and IsFoundInFile == False: + PcdFormatStr = str(str(MatchPcdFormat.group(1)) + "." + str(MatchPcdFormat.group(2))) + ExtConfigPcd = str(MatchExtConfigPcd.group(1)) + Result = False + if PcdFormatStr.strip() == ExtConfigPcd.strip(): + Result = self.EvaluateExpress(str(str(MatchExtConfigPcd.group(2)) + " == " + str(MatchPcdFormat.group(3)))) + IsFoundInFile = True + break + if IsFoundInFile == False: + ConfigDsc = open(ConfigDscFile, "r") + ConfigDscLines = ConfigDsc.readlines() + ConfigDsc.close() + while len(ConfigDscLines): + ConfigDscLine = ConfigDscLines.pop(0).strip() + MatchConfigPcd = re.match("^\s*(.+)\s*\|\s*(.+)", ConfigDscLine) + if MatchConfigPcd: + PcdFormatStr = str(str(MatchPcdFormat.group(1)) + "." + str(MatchPcdFormat.group(2))) + ConfigPcd = str(MatchConfigPcd.group(1)) + Result = False + if PcdFormatStr.strip() == ConfigPcd.strip(): + Result = self.EvaluateExpress(str(str(MatchConfigPcd.group(2)) + " == " + str(MatchPcdFormat.group(3)))) + IsFoundInFile = True + break + else: + Result = self.EvaluateExpress(Match.group(2)) + if Match.group(1) == "if": + ElifStack.append(0) + IfStack.append(Result) + else: #elseif + if IfStack: + IfStack[-1] = not IfStack[-1] + IfStack.append(Result) + ElifStack[-1] = ElifStack[-1] + 1 + else: + print("ERROR: No paired '!if' found for '!elif' for line '%s'" % DscLine) + raise SystemExit + else: + if IfStack: + Handle = reduce(lambda x,y: x and y, IfStack) + else: + Handle = True + if Handle: + Match = re.match("!include\s+(.+)", DscLine) + if Match: + IncludeFilePath = Match.group(1) + IncludeFilePath = self.ExpandMacros(IncludeFilePath) + try: + IncludeDsc = open(IncludeFilePath, "r") + except: + print("ERROR: Cannot open file '%s'" % IncludeFilePath) + raise SystemExit + NewDscLines = IncludeDsc.readlines() + IncludeDsc.close() + DscLines = NewDscLines + DscLines + else: + if DscLine.startswith('!'): + print("ERROR: Unrecoginized directive for line '%s'" % DscLine) + raise SystemExit + if not Handle: + continue + + if IsDefSect: + #DEFINE UPD_TOOL_GUID = 8C3D856A-9BE6-468E-850A-24F7A8D38E09 + #DEFINE FSP_T_UPD_TOOL_GUID = 34686CA3-34F9-4901-B82A-BA630F0714C6 + #DEFINE FSP_M_UPD_TOOL_GUID = 39A250DB-E465-4DD1-A2AC-E2BD3C0E2385 + #DEFINE FSP_S_UPD_TOOL_GUID = CAE3605B-5B34-4C85-B3D7-27D54273C40F + Match = re.match("^\s*(?:DEFINE\s+)*(\w+)\s*=\s*([-.\w]+)", DscLine) + if Match: + self._MacroDict[Match.group(1)] = Match.group(2) + if self.Debug: + print "INFO : DEFINE %s = [ %s ]" % (Match.group(1), Match.group(2)) + else: + Match = re.match("^\s*#\s+(!BSF|@Bsf|!HDR)\s+(.+)", DscLine) + if Match: + Remaining = Match.group(2) + if Match.group(1) == '!BSF' or Match.group(1) == '@Bsf': + Match = re.match("(?:^|.+\s+)PAGES:{(.+?)}", Remaining) + if Match: + # !BSF PAGES:{HSW:"Haswell System Agent", LPT:"Lynx Point PCH"} + PageList = Match.group(1).split(',') + for Page in PageList: + Page = Page.strip() + Match = re.match("(\w+):\"(.+)\"", Page) + self._CfgPageDict[Match.group(1)] = Match.group(2) + + Match = re.match("(?:^|.+\s+)BLOCK:{NAME:\"(.+)\"\s*,\s*VER:\"(.+)\"\s*}", Remaining) + if Match: + self._CfgBlkDict['name'] = Match.group(1) + self._CfgBlkDict['ver'] = Match.group(2) + + for Key in self._BsfKeyList: + Match = re.match("(?:^|.+\s+)%s:{(.+?)}" % Key, Remaining) + if Match: + if Key in ['NAME', 'HELP', 'OPTION'] and Match.group(1).startswith('+'): + ConfigDict[Key.lower()] += Match.group(1)[1:] + else: + ConfigDict[Key.lower()] = Match.group(1) + else: + for Key in self._HdrKeyList: + Match = re.match("(?:^|.+\s+)%s:{(.+?)}" % Key, Remaining) + if Match: + ConfigDict[Key.lower()] = Match.group(1) + + Match = re.match("^\s*#\s+@Prompt\s+(.+)", DscLine) + if Match: + ConfigDict['name'] = Match.group(1) + + Match = re.match("^\s*#\s*@ValidList\s*(.+)\s*\|\s*(.+)\s*\|\s*(.+)\s*", DscLine) + if Match: + if Match.group(2).strip() in self._BuidinOption: + ConfigDict['option'] = Match.group(2).strip() + else: + OptionValueList = Match.group(2).split(',') + OptionStringList = Match.group(3).split(',') + Index = 0 + for Option in OptionValueList: + Option = Option.strip() + ConfigDict['option'] = ConfigDict['option'] + str(Option) + ':' + OptionStringList[Index].strip() + Index += 1 + if Index in range(len(OptionValueList)): + ConfigDict['option'] += ', ' + ConfigDict['type'] = "Combo" + + Match = re.match("^\s*#\s*@ValidRange\s*(.+)\s*\|\s*(.+)\s*-\s*(.+)\s*", DscLine) + if Match: + if "0x" in Match.group(2) or "0x" in Match.group(3): + ConfigDict['type'] = "EditNum, HEX, (%s,%s)" % (Match.group(2), Match.group(3)) + else: + ConfigDict['type'] = "EditNum, DEC, (%s,%s)" % (Match.group(2), Match.group(3)) + + Match = re.match("^\s*##\s+(.+)", DscLine) + if Match: + ConfigDict['help'] = Match.group(1) + + # Check VPD/UPD + if IsUpdSect: + 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) + else: + Match = re.match("^([_a-zA-Z0-9]+).([_a-zA-Z0-9]+)\s*\|\s*(0x[0-9A-F]+)(?:\s*\|\s*(.+))?", DscLine) + if Match: + ConfigDict['space'] = Match.group(1) + ConfigDict['cname'] = Match.group(2) + ConfigDict['offset'] = int (Match.group(3), 16) + if ConfigDict['order'] == -1: + ConfigDict['order'] = ConfigDict['offset'] << 8 + else: + (Major, Minor) = ConfigDict['order'].split('.') + ConfigDict['order'] = (int (Major, 16) << 8 ) + int (Minor, 16) + if IsUpdSect: + Value = Match.group(5).strip() + if Match.group(4).startswith("0x"): + Length = int (Match.group(4), 16) + else : + Length = int (Match.group(4)) + else: + Value = Match.group(4) + if Value is None: + Value = '' + Value = Value.strip() + if '|' in Value: + Match = re.match("^.+\s*\|\s*(.+)", Value) + if Match: + Value = Match.group(1) + Length = -1 + + ConfigDict['length'] = Length + Match = re.match("\$\((\w+)\)", Value) + if Match: + if Match.group(1) in self._MacroDict: + Value = self._MacroDict[Match.group(1)] + + ConfigDict['value'] = Value + if (len(Value) > 0) and (Value[0] == '{'): + Value = self.FormatListValue(ConfigDict) + + if ConfigDict['name'] == '': + # Clear BSF specific items + ConfigDict['bsfname'] = '' + ConfigDict['help'] = '' + ConfigDict['type'] = '' + ConfigDict['option'] = '' + + self._CfgItemList.append(ConfigDict.copy()) + ConfigDict['name'] = '' + ConfigDict['find'] = '' + ConfigDict['struct'] = '' + ConfigDict['embed'] = '' + ConfigDict['comment'] = '' + ConfigDict['order'] = -1 + ConfigDict['subreg'] = [] + ConfigDict['option'] = '' + else: + # It could be a virtual item as below + # !BSF FIELD:{1:SerialDebugPortAddress0} + # or + # @Bsf FIELD:{1:SerialDebugPortAddress0} + Match = re.match("^\s*#\s+(!BSF|@Bsf)\s+FIELD:{(.+):(\d+)}", DscLine) + if Match: + SubCfgDict = ConfigDict + SubCfgDict['cname'] = Match.group(2) + SubCfgDict['length'] = int (Match.group(3)) + if SubCfgDict['length'] > 0: + LastItem = self._CfgItemList[-1] + if len(LastItem['subreg']) == 0: + SubOffset = 0 + else: + SubOffset += LastItem['subreg'][-1]['length'] + SubCfgDict['offset'] = SubOffset + LastItem['subreg'].append (SubCfgDict.copy()) + ConfigDict['name'] = '' + return Error + + def UpdateSubRegionDefaultValue (self): + Error = 0 + for Item in self._CfgItemList: + if len(Item['subreg']) == 0: + continue + bytearray = [] + if Item['value'][0] == '{': + binlist = Item['value'][1:-1].split(',') + for each in binlist: + each = each.strip() + if each.startswith('0x'): + value = int(each, 16) + else: + value = int(each) + bytearray.append(value) + else: + if Item['value'].startswith('0x'): + value = int(Item['value'], 16) + else: + value = int(Item['value']) + idx = 0; + while idx < Item['length']: + bytearray.append(value & 0xFF) + value = value >> 8 + idx = idx + 1 + for SubItem in Item['subreg']: + if SubItem['length'] in (1,2,4,8): + valuelist = [b for b in bytearray[SubItem['offset']:SubItem['offset']+SubItem['length']]] + valuelist.reverse() + valuestr = "".join('%02X' % b for b in valuelist) + SubItem['value'] = '0x%s' % valuestr + else: + valuestr = ",".join('0x%02X' % b for b in bytearray[SubItem['offset']:SubItem['offset']+SubItem['length']]) + SubItem['value'] = '{%s}' % valuestr + return Error + + def CreateSplitUpdTxt (self, UpdTxtFile): + GuidList = ['FSP_T_UPD_TOOL_GUID','FSP_M_UPD_TOOL_GUID','FSP_S_UPD_TOOL_GUID'] + SignatureList = ['0x545F', '0x4D5F','0x535F'] # _T, _M, and _S signature for FSPT, FSPM, FSPS + for Index in range(len(GuidList)): + UpdTxtFile = '' + FvDir = self._FvDir + if GuidList[Index] not in self._MacroDict: + self.Error = "%s definition is missing in DSC file" % (GuidList[Index]) + return 1 + + if UpdTxtFile == '': + UpdTxtFile = os.path.join(FvDir, self._MacroDict[GuidList[Index]] + '.txt') + + ReCreate = False + if not os.path.exists(UpdTxtFile): + ReCreate = True + else: + DscTime = os.path.getmtime(self._DscFile) + TxtTime = os.path.getmtime(UpdTxtFile) + if DscTime > TxtTime: + ReCreate = True + + if not ReCreate: + # DSC has not been modified yet + # So don't have to re-generate other files + self.Error = 'No DSC file change, skip to create UPD TXT file' + return 256 + + TxtFd = open(UpdTxtFile, "w") + TxtFd.write("%s\n" % (__copyright_txt__ % date.today().year)) + + NextOffset = 0 + SpaceIdx = 0 + StartAddr = 0 + EndAddr = 0 + Default = 'DEFAULT|' + InRange = False + for Item in self._CfgItemList: + if Item['cname'] == 'Signature' and str(Item['value'])[0:6] == SignatureList[Index]: + StartAddr = Item['offset'] + NextOffset = StartAddr + InRange = True + if Item['cname'] == 'UpdTerminator' and InRange == True: + EndAddr = Item['offset'] + InRange = False + InRange = False + for Item in self._CfgItemList: + if Item['cname'] == 'Signature' and str(Item['value'])[0:6] == SignatureList[Index]: + InRange = True + if InRange != True: + continue + if Item['cname'] == 'UpdTerminator': + InRange = False + if Item['region'] != 'UPD': + continue + Offset = Item['offset'] + if StartAddr > Offset or EndAddr < Offset: + continue + if NextOffset < Offset: + # insert one line + TxtFd.write("%s.UnusedUpdSpace%d|%s0x%04X|0x%04X|{0}\n" % (Item['space'], SpaceIdx, Default, NextOffset - StartAddr, Offset - NextOffset)) + SpaceIdx = SpaceIdx + 1 + NextOffset = Offset + Item['length'] + if Item['cname'] == 'PcdSerialIoUartDebugEnable': + if self.ReleaseMode == False: + Item['value'] = 0x01 + TxtFd.write("%s.%s|%s0x%04X|%s|%s\n" % (Item['space'],Item['cname'],Default,Item['offset'] - StartAddr,Item['length'],Item['value'])) + TxtFd.close() + return 0 + + def ProcessMultilines (self, String, MaxCharLength): + Multilines = '' + StringLength = len(String) + CurrentStringStart = 0 + StringOffset = 0 + BreakLineDict = [] + if len(String) <= MaxCharLength: + while (StringOffset < StringLength): + if StringOffset >= 1: + if String[StringOffset - 1] == '\\' and String[StringOffset] == 'n': + BreakLineDict.append (StringOffset + 1) + StringOffset += 1 + if BreakLineDict != []: + for Each in BreakLineDict: + Multilines += " %s\n" % String[CurrentStringStart:Each].lstrip() + CurrentStringStart = Each + if StringLength - CurrentStringStart > 0: + Multilines += " %s\n" % String[CurrentStringStart:].lstrip() + else: + Multilines = " %s\n" % String + else: + NewLineStart = 0 + NewLineCount = 0 + FoundSpaceChar = False + while (StringOffset < StringLength): + if StringOffset >= 1: + if NewLineCount >= MaxCharLength - 1: + if String[StringOffset] == ' ' and StringLength - StringOffset > 10: + BreakLineDict.append (NewLineStart + NewLineCount) + NewLineStart = NewLineStart + NewLineCount + NewLineCount = 0 + FoundSpaceChar = True + elif StringOffset == StringLength - 1 and FoundSpaceChar == False: + BreakLineDict.append (0) + if String[StringOffset - 1] == '\\' and String[StringOffset] == 'n': + BreakLineDict.append (StringOffset + 1) + NewLineStart = StringOffset + 1 + NewLineCount = 0 + StringOffset += 1 + NewLineCount += 1 + if BreakLineDict != []: + BreakLineDict.sort () + for Each in BreakLineDict: + if Each > 0: + Multilines += " %s\n" % String[CurrentStringStart:Each].lstrip() + CurrentStringStart = Each + if StringLength - CurrentStringStart > 0: + Multilines += " %s\n" % String[CurrentStringStart:].lstrip() + return Multilines + + def CreateField (self, Item, Name, Length, Offset, Struct, BsfName, Help, Option): + PosName = 28 + PosComment = 30 + NameLine='' + HelpLine='' + OptionLine='' + + IsArray = False + if Length in [1,2,4,8]: + Type = "UINT%d" % (Length * 8) + else: + IsArray = True + Type = "UINT8" + + if Item and Item['value'].startswith('{'): + Type = "UINT8" + IsArray = True + + if Struct != '': + Type = Struct + if Struct in ['UINT8','UINT16','UINT32','UINT64']: + IsArray = True + Unit = int(Type[4:]) / 8 + Length = Length / Unit + else: + IsArray = False + + if IsArray: + Name = Name + '[%d]' % Length + + if len(Type) < PosName: + Space1 = PosName - len(Type) + else: + Space1 = 1 + + if BsfName != '': + NameLine=" - %s\n" % BsfName + else: + NameLine="\n" + + if Help != '': + HelpLine = self.ProcessMultilines (Help, 80) + + if Option != '': + OptionLine = self.ProcessMultilines (Option, 80) + + if Offset is None: + OffsetStr = '????' + else: + OffsetStr = '0x%04X' % Offset + + return "\n/** Offset %s%s%s%s**/\n %s%s%s;\n" % (OffsetStr, NameLine, HelpLine, OptionLine, Type, ' ' * Space1, Name,) + + def PostProcessBody (self, TextBody): + NewTextBody = [] + OldTextBody = [] + IncludeLine = False + StructName = '' + VariableName = '' + IsUpdHdrDefined = False + IsUpdHeader = False + for Line in TextBody: + SplitToLines = Line.splitlines() + MatchComment = re.match("^/\*\sCOMMENT:(\w+):([\w|\W|\s]+)\s\*/\s([\s\S]*)", SplitToLines[0]) + if MatchComment: + if MatchComment.group(1) == 'FSP_UPD_HEADER': + IsUpdHeader = True + else: + IsUpdHeader = False + if IsUpdHdrDefined != True or IsUpdHeader != True: + CommentLine = " " + MatchComment.group(2) + "\n" + NewTextBody.append("/**" + CommentLine + "**/\n") + Line = Line[(len(SplitToLines[0]) + 1):] + + Match = re.match("^/\*\sEMBED_STRUCT:(\w+):(\w+):(START|END)\s\*/\s([\s\S]*)", Line) + if Match: + Line = Match.group(4) + if Match.group(1) == 'FSP_UPD_HEADER': + IsUpdHeader = True + else: + IsUpdHeader = False + + if Match and Match.group(3) == 'START': + if IsUpdHdrDefined != True or IsUpdHeader != True: + NewTextBody.append ('typedef struct {\n') + StructName = Match.group(1) + VariableName = Match.group(2) + MatchOffset = re.search('/\*\*\sOffset\s0x([a-fA-F0-9]+)', Line) + if MatchOffset: + Offset = int(MatchOffset.group(1), 16) + else: + Offset = None + Line + IncludeLine = True + OldTextBody.append (self.CreateField (None, VariableName, 0, Offset, StructName, '', '', '')) + if IncludeLine: + if IsUpdHdrDefined != True or IsUpdHeader != True: + NewTextBody.append (Line) + else: + OldTextBody.append (Line) + + if Match and Match.group(3) == 'END': + if (StructName != Match.group(1)) or (VariableName != Match.group(2)): + print "Unmatched struct name '%s' and '%s' !" % (StructName, Match.group(1)) + else: + if IsUpdHdrDefined != True or IsUpdHeader != True: + NewTextBody.append ('} %s;\n\n' % StructName) + IsUpdHdrDefined = True + IncludeLine = False + NewTextBody.extend(OldTextBody) + return NewTextBody + + def CreateHeaderFile (self, InputHeaderFile): + FvDir = self._FvDir + + HeaderFileName = 'FspUpd.h' + HeaderFile = os.path.join(FvDir, HeaderFileName) + + # Check if header needs to be recreated + ReCreate = False + + TxtBody = [] + for Item in self._CfgItemList: + if str(Item['cname']) == 'Signature' and Item['length'] == 8: + Value = int(Item['value'], 16) + Chars = [] + while Value != 0x0: + Chars.append(chr(Value & 0xFF)) + Value = Value >> 8 + SignatureStr = ''.join(Chars) + # Signature will be _T / _M / _S for FSPT / FSPM / FSPS accordingly + if '_T' in SignatureStr[6:6+2]: + TxtBody.append("#define FSPT_UPD_SIGNATURE %s /* '%s' */\n\n" % (Item['value'], SignatureStr)) + elif '_M' in SignatureStr[6:6+2]: + TxtBody.append("#define FSPM_UPD_SIGNATURE %s /* '%s' */\n\n" % (Item['value'], SignatureStr)) + elif '_S' in SignatureStr[6:6+2]: + TxtBody.append("#define FSPS_UPD_SIGNATURE %s /* '%s' */\n\n" % (Item['value'], SignatureStr)) + TxtBody.append("\n") + + for Region in ['UPD']: + UpdOffsetTable = [] + UpdSignature = ['0x545F', '0x4D5F', '0x535F'] #['_T', '_M', '_S'] signature for FSPT, FSPM, FSPS + UpdStructure = ['FSPT_UPD', 'FSPM_UPD', 'FSPS_UPD'] + for Item in self._CfgItemList: + if Item["cname"] == 'Signature' and Item["value"][0:6] in UpdSignature: + UpdOffsetTable.append (Item["offset"]) + + for UpdIdx in range(len(UpdOffsetTable)): + CommentLine = "" + for Item in self._CfgItemList: + if Item["comment"] != '' and Item["offset"] >= UpdOffsetTable[UpdIdx]: + MatchComment = re.match("^(U|V)PD_DATA_REGION:([\w|\W|\s]+)", Item["comment"]) + if MatchComment and MatchComment.group(1) == Region[0]: + CommentLine = " " + MatchComment.group(2) + "\n" + TxtBody.append("/**" + CommentLine + "**/\n") + elif Item["offset"] >= UpdOffsetTable[UpdIdx] and Item["comment"] == '': + Match = re.match("^FSP([\w|\W|\s])_UPD", UpdStructure[UpdIdx]) + if Match: + TxtBody.append("/** Fsp " + Match.group(1) + " UPD Configuration\n**/\n") + TxtBody.append("typedef struct {\n") + NextOffset = 0 + SpaceIdx = 0 + Offset = 0 + + LastVisible = True + ResvOffset = 0 + ResvIdx = 0 + LineBuffer = [] + InRange = False + for Item in self._CfgItemList: + if Item['cname'] == 'Signature' and str(Item['value'])[0:6] == UpdSignature[UpdIdx] or Region[0] == 'V': + InRange = True + if InRange != True: + continue + if Item['cname'] == 'UpdTerminator': + InRange = False + + if Item['region'] != Region: + continue + + if Item["offset"] < UpdOffsetTable[UpdIdx]: + continue + + NextVisible = LastVisible + + if LastVisible and (Item['header'] == 'OFF'): + NextVisible = False + ResvOffset = Item['offset'] + elif (not LastVisible) and Item['header'] == 'ON': + NextVisible = True + Name = "Reserved" + Region[0] + "pdSpace%d" % ResvIdx + ResvIdx = ResvIdx + 1 + TxtBody.append(self.CreateField (Item, Name, Item["offset"] - ResvOffset, ResvOffset, '', '', '', '')) + + if Offset < Item["offset"]: + if LastVisible: + Name = "Unused" + Region[0] + "pdSpace%d" % SpaceIdx + LineBuffer.append(self.CreateField (Item, Name, Item["offset"] - Offset, Offset, '', '', '', '')) + SpaceIdx = SpaceIdx + 1 + Offset = Item["offset"] + + LastVisible = NextVisible + + Offset = Offset + Item["length"] + if LastVisible: + for Each in LineBuffer: + TxtBody.append (Each) + LineBuffer = [] + Comment = Item["comment"] + Embed = Item["embed"].upper() + if Embed.endswith(':START') or Embed.endswith(':END'): + if not Comment == '' and Embed.endswith(':START'): + Marker = '/* COMMENT:%s */ \n' % Item["comment"] + Marker = Marker + '/* EMBED_STRUCT:%s */ ' % Item["embed"] + else: + Marker = '/* EMBED_STRUCT:%s */ ' % Item["embed"] + else: + if Embed == '': + Marker = ''; + else: + self.Error = "Invalid embedded structure format '%s'!\n" % Item["embed"] + return 4 + Line = Marker + self.CreateField (Item, Item["cname"], Item["length"], Item["offset"], Item['struct'], Item['name'], Item['help'], Item['option']) + TxtBody.append(Line) + if Item['cname'] == 'UpdTerminator': + break + TxtBody.append("} " + UpdStructure[UpdIdx] + ";\n\n") + + # Handle the embedded data structure + TxtBody = self.PostProcessBody (TxtBody) + + HeaderTFileName = 'FsptUpd.h' + HeaderMFileName = 'FspmUpd.h' + HeaderSFileName = 'FspsUpd.h' + + UpdRegionCheck = ['FSPT', 'FSPM', 'FSPS'] # FSPX_UPD_REGION + UpdConfigCheck = ['FSP_T', 'FSP_M', 'FSP_S'] # FSP_X_CONFIG, FSP_X_TEST_CONFIG, FSP_X_RESTRICTED_CONFIG + UpdSignatureCheck = ['FSPT_UPD_SIGNATURE', 'FSPM_UPD_SIGNATURE', 'FSPS_UPD_SIGNATURE'] + ExcludedSpecificUpd = 'FSPM_ARCH_UPD' + + if InputHeaderFile != '': + if not os.path.exists(InputHeaderFile): + self.Error = "Input header file '%s' does not exist" % InputHeaderFile + return 6 + + InFd = open(InputHeaderFile, "r") + IncLines = InFd.readlines() + InFd.close() + + for item in range(len(UpdRegionCheck)): + if UpdRegionCheck[item] == 'FSPT': + HeaderFd = open(os.path.join(FvDir, HeaderTFileName), "w") + FileBase = os.path.basename(os.path.join(FvDir, HeaderTFileName)) + elif UpdRegionCheck[item] == 'FSPM': + HeaderFd = open(os.path.join(FvDir, HeaderMFileName), "w") + FileBase = os.path.basename(os.path.join(FvDir, HeaderMFileName)) + elif UpdRegionCheck[item] == 'FSPS': + HeaderFd = open(os.path.join(FvDir, HeaderSFileName), "w") + FileBase = os.path.basename(os.path.join(FvDir, HeaderSFileName)) + FileName = FileBase.replace(".", "_").upper() + HeaderFd.write("%s\n" % (__copyright_h__ % date.today().year)) + HeaderFd.write("#ifndef __%s__\n" % FileName) + HeaderFd.write("#define __%s__\n\n" % FileName) + HeaderFd.write("#include <%s>\n\n" % HeaderFileName) + HeaderFd.write("#pragma pack(push, 1)\n\n") + + Export = False + for Line in IncLines: + Match = re.search ("!EXPORT\s+([A-Z]+)\s+EXTERNAL_BOOTLOADER_STRUCT_(BEGIN|END)\s+", Line) + if Match: + if Match.group(2) == "BEGIN" and Match.group(1) == UpdRegionCheck[item]: + Export = True + continue + else: + Export = False + continue + if Export: + HeaderFd.write(Line) + HeaderFd.write("\n") + + Index = 0 + StartIndex = 0 + EndIndex = 0 + StructStart = [] + StructStartWithComment = [] + StructEnd = [] + for Line in TxtBody: + Index += 1 + Match = re.match("(typedef struct {)", Line) + if Match: + StartIndex = Index - 1 + Match = re.match("}\s([_A-Z0-9]+);", Line) + if Match and (UpdRegionCheck[item] in Match.group(1) or UpdConfigCheck[item] in Match.group(1)) and (ExcludedSpecificUpd not in Match.group(1)): + EndIndex = Index + StructStart.append(StartIndex) + StructEnd.append(EndIndex) + Index = 0 + for Line in TxtBody: + Index += 1 + for Item in range(len(StructStart)): + if Index == StructStart[Item]: + Match = re.match("^(/\*\*\s*)", Line) + if Match: + StructStartWithComment.append(StructStart[Item]) + else: + StructStartWithComment.append(StructStart[Item] + 1) + Index = 0 + for Line in TxtBody: + Index += 1 + for Item in range(len(StructStart)): + if Index >= StructStartWithComment[Item] and Index <= StructEnd[Item]: + HeaderFd.write (Line) + HeaderFd.write("#pragma pack(pop)\n\n") + HeaderFd.write("#endif\n") + HeaderFd.close() + + HeaderFd = open(HeaderFile, "w") + FileBase = os.path.basename(HeaderFile) + FileName = FileBase.replace(".", "_").upper() + HeaderFd.write("%s\n" % (__copyright_h__ % date.today().year)) + HeaderFd.write("#ifndef __%s__\n" % FileName) + HeaderFd.write("#define __%s__\n\n" % FileName) + HeaderFd.write("#include \n\n") + HeaderFd.write("#pragma pack(push, 1)\n\n") + + for item in range(len(UpdRegionCheck)): + Index = 0 + StartIndex = 0 + EndIndex = 0 + StructStart = [] + StructStartWithComment = [] + StructEnd = [] + for Line in TxtBody: + Index += 1 + Match = re.match("(typedef struct {)", Line) + if Match: + StartIndex = Index - 1 + Match = re.match("#define\s([_A-Z0-9]+)\s*", Line) + if Match and (UpdSignatureCheck[item] in Match.group(1) or UpdSignatureCheck[item] in Match.group(1)): + StructStart.append(Index - 1) + StructEnd.append(Index) + Index = 0 + for Line in TxtBody: + Index += 1 + for Item in range(len(StructStart)): + if Index == StructStart[Item]: + Match = re.match("^(/\*\*\s*)", Line) + if Match: + StructStartWithComment.append(StructStart[Item]) + else: + StructStartWithComment.append(StructStart[Item] + 1) + Index = 0 + for Line in TxtBody: + Index += 1 + for Item in range(len(StructStart)): + if Index >= StructStartWithComment[Item] and Index <= StructEnd[Item]: + HeaderFd.write (Line) + HeaderFd.write("#pragma pack(pop)\n\n") + HeaderFd.write("#endif\n") + HeaderFd.close() + + return 0 + + def WriteBsfStruct (self, BsfFd, Item): + if Item['type'] == "None": + Space = "gPlatformFspPkgTokenSpaceGuid" + else: + Space = Item['space'] + Line = " $%s_%s" % (Space, Item['cname']) + Match = re.match("\s*\{([x0-9a-fA-F,\s]+)\}\s*", Item['value']) + if Match: + DefaultValue = Match.group(1).strip() + else: + DefaultValue = Item['value'].strip() + BsfFd.write(" %s%s%4d bytes $_DEFAULT_ = %s\n" % (Line, ' ' * (64 - len(Line)), Item['length'], DefaultValue)) + TmpList = [] + if Item['type'] == "Combo": + if not Item['option'] in self._BuidinOption: + OptList = Item['option'].split(',') + for Option in OptList: + Option = Option.strip() + (OpVal, OpStr) = Option.split(':') + TmpList.append((OpVal, OpStr)) + return TmpList + + def WriteBsfOption (self, BsfFd, Item): + PcdName = Item['space'] + '_' + Item['cname'] + WriteHelp = 0 + if Item['type'] == "Combo": + if Item['option'] in self._BuidinOption: + Options = self._BuidinOption[Item['option']] + else: + Options = PcdName + BsfFd.write(' %s $%s, "%s", &%s,\n' % (Item['type'], PcdName, Item['name'], Options)); + WriteHelp = 1 + elif Item['type'].startswith("EditNum"): + 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']) + if Match: + BsfFd.write(' EditNum $%s, "%s", %s,\n' % (PcdName, Item['name'], Match.group(1))); + WriteHelp = 2 + elif Item['type'].startswith("EditText"): + BsfFd.write(' %s $%s, "%s",\n' % (Item['type'], PcdName, Item['name'])); + WriteHelp = 1 + elif Item['type'] == "Table": + Columns = Item['option'].split(',') + if len(Columns) != 0: + BsfFd.write(' %s $%s "%s",' % (Item['type'], PcdName, Item['name'])); + for Col in Columns: + Fmt = Col.split(':') + if len(Fmt) != 3: + raise Exception("Column format '%s' is invalid !" % Fmt) + try: + Dtype = int(Fmt[1].strip()) + except: + raise Exception("Column size '%s' is invalid !" % Fmt[1]) + BsfFd.write('\n Column "%s", %d bytes, %s' % (Fmt[0].strip(), Dtype, Fmt[2].strip())) + BsfFd.write(',\n') + WriteHelp = 1 + + if WriteHelp > 0: + HelpLines = Item['help'].split('\\n\\r') + FirstLine = True + for HelpLine in HelpLines: + if FirstLine: + FirstLine = False + BsfFd.write(' Help "%s"\n' % (HelpLine)); + else: + BsfFd.write(' "%s"\n' % (HelpLine)); + if WriteHelp == 2: + BsfFd.write(' "Valid range: %s ~ %s"\n' % (Match.group(2), Match.group(3))); + + def GenerateBsfFile (self, BsfFile): + + if BsfFile == '': + self.Error = "BSF output file '%s' is invalid" % BsfFile + return 1 + + Error = 0 + OptionDict = {} + BsfFd = open(BsfFile, "w") + BsfFd.write("%s\n" % (__copyright_bsf__ % date.today().year)) + BsfFd.write("%s\n" % self._GlobalDataDef); + BsfFd.write("StructDef\n") + NextOffset = -1 + for Item in self._CfgItemList: + if Item['find'] != '': + BsfFd.write('\n Find "%s"\n' % Item['find']) + NextOffset = Item['offset'] + Item['length'] + if Item['name'] != '': + if NextOffset != Item['offset']: + BsfFd.write(" Skip %d bytes\n" % (Item['offset'] - NextOffset)) + if len(Item['subreg']) > 0: + NextOffset = Item['offset'] + for SubItem in Item['subreg']: + NextOffset += SubItem['length'] + if SubItem['name'] == '': + BsfFd.write(" Skip %d bytes\n" % (SubItem['length'])) + else: + Options = self.WriteBsfStruct(BsfFd, SubItem) + if len(Options) > 0: + OptionDict[SubItem['space']+'_'+SubItem['cname']] = Options + if (Item['offset'] + Item['length']) < NextOffset: + self.Error = "BSF sub region '%s' length does not match" % (Item['space']+'.'+Item['cname']) + return 2 + else: + NextOffset = Item['offset'] + Item['length'] + Options = self.WriteBsfStruct(BsfFd, Item) + if len(Options) > 0: + OptionDict[Item['space']+'_'+Item['cname']] = Options + BsfFd.write("\nEndStruct\n\n") + + BsfFd.write("%s" % self._BuidinOptionTxt); + + for Each in OptionDict: + BsfFd.write("List &%s\n" % Each); + for Item in OptionDict[Each]: + BsfFd.write(' Selection %s , "%s"\n' % (Item[0], Item[1])); + BsfFd.write("EndList\n\n"); + + BsfFd.write("BeginInfoBlock\n"); + BsfFd.write(' PPVer "%s"\n' % (self._CfgBlkDict['ver'])); + BsfFd.write(' Description "%s"\n' % (self._CfgBlkDict['name'])); + BsfFd.write("EndInfoBlock\n\n"); + + for Each in self._CfgPageDict: + BsfFd.write('Page "%s"\n' % self._CfgPageDict[Each]); + BsfItems = [] + for Item in self._CfgItemList: + if Item['name'] != '': + if Item['page'] != Each: + continue + if len(Item['subreg']) > 0: + for SubItem in Item['subreg']: + if SubItem['name'] != '': + BsfItems.append(SubItem) + else: + BsfItems.append(Item) + + BsfItems.sort(key=lambda x: x['order']) + + for Item in BsfItems: + self.WriteBsfOption (BsfFd, Item) + BsfFd.write("EndPage\n\n"); + + BsfFd.close() + return Error + + +def Usage(): + print "GenCfgOpt Version 0.51" + print "Usage:" + print " GenCfgOpt UPDTXT PlatformDscFile BuildFvDir ConfigDscFile ExtConfigDscFile" + print " [-D Macros]" + print " GenCfgOpt HEADER PlatformDscFile BuildFvDir ConfigDscFile ExtConfigDscFile" + print " InputHFile [-D Macros]" + print " GenCfgOpt GENBSF PlatformDscFile BuildFvDir ConfigDscFile ExtConfigDscFile" + print " BsfOutFile [-D Macros]" + +def Main(): + # + # Parse the options and args + # + GenCfgOpt = CGenCfgOpt() + argc = len(sys.argv) + if argc < 4: + Usage() + return 1 + else: + DscFile = sys.argv[2] + if not os.path.exists(DscFile): + print "ERROR: Cannot open DSC file '%s' !" % DscFile + return 2 + ConfigDscFile = sys.argv[4] + if not os.path.exists(ConfigDscFile): + print "ERROR: Cannot open Config DSC file '%s' !" % ConfigDscFile + return 2 + ExtConfigDscFile = sys.argv[5] + if not os.path.exists(ExtConfigDscFile): + print "ERROR: Cannot open Ext Config DSC file '%s' !" % ExtConfigDscFile + return 2 + + OutFile = '' + if argc > 4: + if sys.argv[6][0] == '-': + Start = 4 + else: + OutFile = sys.argv[6] + Start = 5 + GenCfgOpt.ParseBuildMode(sys.argv[3]) + if GenCfgOpt.ParseMacros(sys.argv[Start:]) != 0: + print "ERROR: Macro parsing failed !" + return 3 + + FvDir = sys.argv[3] + if not os.path.exists(FvDir): + os.makedirs(FvDir) + + if GenCfgOpt.ParseDscFile(DscFile, FvDir, ConfigDscFile, ExtConfigDscFile) != 0: + print "ERROR: %s !" % GenCfgOpt.Error + return 5 + + if GenCfgOpt.UpdateSubRegionDefaultValue() != 0: + print "ERROR: %s !" % GenCfgOpt.Error + return 7 + + if sys.argv[1] == "UPDTXT": + Ret = GenCfgOpt.CreateSplitUpdTxt(OutFile) + if Ret != 0: + # No change is detected + if Ret == 256: + print "INFO: %s !" % (GenCfgOpt.Error) + else : + print "ERROR: %s !" % (GenCfgOpt.Error) + return Ret + elif sys.argv[1] == "HEADER": + if GenCfgOpt.CreateHeaderFile(OutFile) != 0: + print "ERROR: %s !" % GenCfgOpt.Error + return 8 + elif sys.argv[1] == "GENBSF": + if GenCfgOpt.GenerateBsfFile(OutFile) != 0: + print "ERROR: %s !" % GenCfgOpt.Error + return 9 + else: + if argc < 5: + Usage() + return 1 + print "ERROR: Unknown command '%s' !" % sys.argv[1] + Usage() + return 1 + return 0 + return 0 + + +if __name__ == '__main__': + sys.exit(Main()) diff --git a/IntelFsp2Pkg/Tools/PatchFv.py b/IntelFsp2Pkg/Tools/PatchFv.py new file mode 100644 index 0000000000..fc2ee19bcd --- /dev/null +++ b/IntelFsp2Pkg/Tools/PatchFv.py @@ -0,0 +1,947 @@ +## @ PatchFv.py +# +# Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+# This program and the accompanying materials are licensed and made available under +# the terms and conditions of the BSD License that accompanies this distribution. +# The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +import os +import re +import sys + +# +# Read data from file +# +# param [in] binfile Binary file +# param [in] offset Offset +# param [in] len Length +# +# retval value Value +# +def readDataFromFile (binfile, offset, len=1): + fd = open(binfile, "r+b") + fsize = os.path.getsize(binfile) + offval = offset & 0xFFFFFFFF + if (offval & 0x80000000): + offval = fsize - (0xFFFFFFFF - offval + 1) + fd.seek(offval) + bytearray = [ord(b) for b in fd.read(len)] + value = 0 + idx = len - 1 + while idx >= 0: + value = value << 8 | bytearray[idx] + idx = idx - 1 + fd.close() + return value + +# +# Check FSP header is valid or not +# +# param [in] binfile Binary file +# +# retval boolean True: valid; False: invalid +# +def IsFspHeaderValid (binfile): + fd = open (binfile, "rb") + bindat = fd.read(0x200) # only read first 0x200 bytes + fd.close() + HeaderList = ['FSPH' , 'FSPP' , 'FSPE'] # Check 'FSPH', 'FSPP', and 'FSPE' in the FSP header + OffsetList = [] + for each in HeaderList: + if each in bindat: + idx = bindat.index(each) + else: + idx = 0 + OffsetList.append(idx) + if not OffsetList[0] or not OffsetList[1]: # If 'FSPH' or 'FSPP' is missing, it will return false + return False + Revision = ord(bindat[OffsetList[0] + 0x0B]) + # + # if revision is bigger than 1, it means it is FSP v1.1 or greater revision, which must contain 'FSPE'. + # + if Revision > 1 and not OffsetList[2]: + return False # If FSP v1.1 or greater without 'FSPE', then return false + return True + +# +# Patch data in file +# +# param [in] binfile Binary file +# param [in] offset Offset +# param [in] value Patch value +# param [in] len Length +# +# retval len Length +# +def patchDataInFile (binfile, offset, value, len=1): + fd = open(binfile, "r+b") + fsize = os.path.getsize(binfile) + offval = offset & 0xFFFFFFFF + if (offval & 0x80000000): + offval = fsize - (0xFFFFFFFF - offval + 1) + bytearray = [] + idx = 0 + while idx < len: + bytearray.append(value & 0xFF) + value = value >> 8 + idx = idx + 1 + fd.seek(offval) + fd.write("".join(chr(b) for b in bytearray)) + fd.close() + return len + + +class Symbols: + def __init__(self): + self.dictSymbolAddress = {} + self.dictGuidNameXref = {} + self.dictFfsOffset = {} + self.dictVariable = {} + self.dictModBase = {} + self.fdFile = None + self.string = "" + self.fdBase = 0xFFFFFFFF + self.fdSize = 0 + self.index = 0 + self.fvList = [] + self.parenthesisOpenSet = '([{<' + self.parenthesisCloseSet = ')]}>' + + # + # Get FD file + # + # retval self.fdFile Retrieve FD file + # + def getFdFile (self): + return self.fdFile + + # + # Get FD size + # + # retval self.fdSize Retrieve the size of FD file + # + def getFdSize (self): + return self.fdSize + + def parseFvInfFile (self, infFile): + fvInfo = {} + fvFile = infFile[0:-4] + ".Fv" + fvInfo['Name'] = os.path.splitext(os.path.basename(infFile))[0] + fvInfo['Offset'] = self.getFvOffsetInFd(fvFile) + fvInfo['Size'] = readDataFromFile (fvFile, 0x20, 4) + fdIn = open(infFile, "r") + rptLines = fdIn.readlines() + fdIn.close() + fvInfo['Base'] = 0 + for rptLine in rptLines: + match = re.match("^EFI_BASE_ADDRESS\s*=\s*(0x[a-fA-F0-9]+)", rptLine) + if match: + fvInfo['Base'] = int(match.group(1), 16) + break + self.fvList.append(dict(fvInfo)) + return 0 + + # + # Create dictionaries + # + # param [in] fvDir FV's directory + # param [in] fvNames All FV's names + # + # retval 0 Created dictionaries successfully + # + def createDicts (self, fvDir, fvNames): + # + # If the fvDir is not a dirctory, then raise an exception + # + if not os.path.isdir(fvDir): + raise Exception ("'%s' is not a valid directory!" % FvDir) + + # + # If the Guid.xref is not existing in fvDir, then raise an exception + # + xrefFile = os.path.join(fvDir, "Guid.xref") + if not os.path.exists(xrefFile): + raise Exception("Cannot open GUID Xref file '%s'!" % xrefFile) + + # + # Add GUID reference to dictionary + # + self.dictGuidNameXref = {} + self.parseGuidXrefFile(xrefFile) + + # + # Split up each FV from fvNames and get the fdBase + # + fvList = fvNames.split(":") + fdBase = fvList.pop() + if len(fvList) == 0: + fvList.append(fdBase) + + # + # If the FD file is not existing, then raise an exception + # + fdFile = os.path.join(fvDir, fdBase.strip() + ".fd") + if not os.path.exists(fdFile): + raise Exception("Cannot open FD file '%s'!" % fdFile) + + # + # Get the size of the FD file + # + self.fdFile = fdFile + self.fdSize = os.path.getsize(fdFile) + + # + # If the INF file, which is the first element of fvList, is not existing, then raise an exception + # + infFile = os.path.join(fvDir, fvList[0].strip()) + ".inf" + if not os.path.exists(infFile): + raise Exception("Cannot open INF file '%s'!" % infFile) + + # + # Parse INF file in order to get fdBase and then assign those values to dictVariable + # + self.parseInfFile(infFile) + self.dictVariable = {} + self.dictVariable["FDSIZE"] = self.fdSize + self.dictVariable["FDBASE"] = self.fdBase + + # + # Collect information from FV MAP file and FV TXT file then + # put them into dictionaries + # + self.fvList = [] + self.dictSymbolAddress = {} + self.dictFfsOffset = {} + for file in fvList: + + # + # If the .Fv.map file is not existing, then raise an exception. + # Otherwise, parse FV MAP file + # + fvFile = os.path.join(fvDir, file.strip()) + ".Fv" + mapFile = fvFile + ".map" + if not os.path.exists(mapFile): + raise Exception("Cannot open MAP file '%s'!" % mapFile) + + infFile = fvFile[0:-3] + ".inf" + self.parseFvInfFile(infFile) + self.parseFvMapFile(mapFile) + + # + # If the .Fv.txt file is not existing, then raise an exception. + # Otherwise, parse FV TXT file + # + fvTxtFile = fvFile + ".txt" + if not os.path.exists(fvTxtFile): + raise Exception("Cannot open FV TXT file '%s'!" % fvTxtFile) + + self.parseFvTxtFile(fvTxtFile) + + for fv in self.fvList: + self.dictVariable['_BASE_%s_' % fv['Name']] = fv['Base'] + # + # Search all MAP files in FFS directory if it exists then parse MOD MAP file + # + ffsDir = os.path.join(fvDir, "Ffs") + if (os.path.isdir(ffsDir)): + for item in os.listdir(ffsDir): + if len(item) <= 0x24: + continue + mapFile =os.path.join(ffsDir, item, "%s.map" % item[0:0x24]) + if not os.path.exists(mapFile): + continue + self.parseModMapFile(item[0x24:], mapFile) + + return 0 + + # + # Get FV offset in FD file + # + # param [in] fvFile FV file + # + # retval offset Got FV offset successfully + # + def getFvOffsetInFd(self, fvFile): + # + # Check if the first 0x70 bytes of fvFile can be found in fdFile + # + fvHandle = open(fvFile, "r+b") + fdHandle = open(self.fdFile, "r+b") + offset = fdHandle.read().find(fvHandle.read(0x70)) + fvHandle.close() + fdHandle.close() + if offset == -1: + raise Exception("Could not locate FV file %s in FD!" % fvFile) + return offset + + # + # Parse INF file + # + # param [in] infFile INF file + # + # retval 0 Parsed INF file successfully + # + def parseInfFile(self, infFile): + # + # Get FV offset and search EFI_BASE_ADDRESS in the FD file + # then assign the value of EFI_BASE_ADDRESS to fdBase + # + fvOffset = self.getFvOffsetInFd(infFile[0:-4] + ".Fv") + fdIn = open(infFile, "r") + rptLine = fdIn.readline() + self.fdBase = 0xFFFFFFFF + while (rptLine != "" ): + #EFI_BASE_ADDRESS = 0xFFFDF400 + match = re.match("^EFI_BASE_ADDRESS\s*=\s*(0x[a-fA-F0-9]+)", rptLine) + if match is not None: + self.fdBase = int(match.group(1), 16) - fvOffset + rptLine = fdIn.readline() + fdIn.close() + if self.fdBase == 0xFFFFFFFF: + raise Exception("Could not find EFI_BASE_ADDRESS in INF file!" % fvFile) + return 0 + + # + # Parse FV TXT file + # + # param [in] fvTxtFile .Fv.txt file + # + # retval 0 Parsed FV TXT file successfully + # + def parseFvTxtFile(self, fvTxtFile): + fvName = os.path.basename(fvTxtFile)[0:-7].upper() + # + # Get information from .Fv.txt in order to create a dictionary + # For example, + # self.dictFfsOffset[912740BE-2284-4734-B971-84B027353F0C] = 0x000D4078 + # + fvOffset = self.getFvOffsetInFd(fvTxtFile[0:-4]) + fdIn = open(fvTxtFile, "r") + rptLine = fdIn.readline() + while (rptLine != "" ): + match = re.match("(0x[a-fA-F0-9]+)\s([0-9a-fA-F\-]+)", rptLine) + if match is not None: + if match.group(2) in self.dictFfsOffset: + self.dictFfsOffset[fvName + ':' + match.group(2)] = "0x%08X" % (int(match.group(1), 16) + fvOffset) + else: + self.dictFfsOffset[match.group(2)] = "0x%08X" % (int(match.group(1), 16) + fvOffset) + rptLine = fdIn.readline() + fdIn.close() + return 0 + + # + # Parse FV MAP file + # + # param [in] mapFile .Fv.map file + # + # retval 0 Parsed FV MAP file successfully + # + def parseFvMapFile(self, mapFile): + # + # Get information from .Fv.map in order to create dictionaries + # For example, + # self.dictModBase[FspSecCore:BASE] = 4294592776 (0xfffa4908) + # self.dictModBase[FspSecCore:ENTRY] = 4294606552 (0xfffa7ed8) + # self.dictModBase[FspSecCore:TEXT] = 4294593080 (0xfffa4a38) + # self.dictModBase[FspSecCore:DATA] = 4294612280 (0xfffa9538) + # self.dictSymbolAddress[FspSecCore:_SecStartup] = 0x00fffa4a38 + # + fdIn = open(mapFile, "r") + rptLine = fdIn.readline() + modName = "" + foundModHdr = False + while (rptLine != "" ): + if rptLine[0] != ' ': + #DxeIpl (Fixed Flash Address, BaseAddress=0x00fffb4310, EntryPoint=0x00fffb4958) + #(GUID=86D70125-BAA3-4296-A62F-602BEBBB9081 .textbaseaddress=0x00fffb4398 .databaseaddress=0x00fffb4178) + match = re.match("([_a-zA-Z0-9\-]+)\s\(.+BaseAddress=(0x[0-9a-fA-F]+),\s+EntryPoint=(0x[0-9a-fA-F]+)\)", rptLine) + if match is not None: + foundModHdr = True + modName = match.group(1) + if len(modName) == 36: + modName = self.dictGuidNameXref[modName.upper()] + self.dictModBase['%s:BASE' % modName] = int (match.group(2), 16) + self.dictModBase['%s:ENTRY' % modName] = int (match.group(3), 16) + match = re.match("\(GUID=([A-Z0-9\-]+)\s+\.textbaseaddress=(0x[0-9a-fA-F]+)\s+\.databaseaddress=(0x[0-9a-fA-F]+)\)", rptLine) + if match is not None: + if foundModHdr: + foundModHdr = False + else: + modName = match.group(1) + if len(modName) == 36: + modName = self.dictGuidNameXref[modName.upper()] + self.dictModBase['%s:TEXT' % modName] = int (match.group(2), 16) + self.dictModBase['%s:DATA' % modName] = int (match.group(3), 16) + else: + # 0x00fff8016c __ModuleEntryPoint + foundModHdr = False + match = re.match("^\s+(0x[a-z0-9]+)\s+([_a-zA-Z0-9]+)", rptLine) + if match is not None: + self.dictSymbolAddress["%s:%s"%(modName, match.group(2))] = match.group(1) + rptLine = fdIn.readline() + fdIn.close() + return 0 + + # + # Parse MOD MAP file + # + # param [in] moduleName Module name + # param [in] mapFile .Fv.map file + # + # retval 0 Parsed MOD MAP file successfully + # retval 1 There is no moduleEntryPoint in modSymbols + # + def parseModMapFile(self, moduleName, mapFile): + # + # Get information from mapFile by moduleName in order to create a dictionary + # For example, + # self.dictSymbolAddress[FspSecCore:___guard_fids_count] = 0x00fffa4778 + # + modSymbols = {} + fdIn = open(mapFile, "r") + reportLines = fdIn.readlines() + fdIn.close() + + moduleEntryPoint = "__ModuleEntryPoint" + reportLine = reportLines[0] + if reportLine.strip().find("Archive member included") != -1: + #GCC + # 0x0000000000001d55 IoRead8 + patchMapFileMatchString = "\s+(0x[0-9a-fA-F]{16})\s+([^\s][^0x][_a-zA-Z0-9\-]+)\s" + matchKeyGroupIndex = 2 + matchSymbolGroupIndex = 1 + prefix = '_' + else: + #MSFT + #0003:00000190 _gComBase 00007a50 SerialPo + patchMapFileMatchString = "^\s[0-9a-fA-F]{4}:[0-9a-fA-F]{8}\s+(\w+)\s+([0-9a-fA-F]{8}\s+)" + matchKeyGroupIndex = 1 + matchSymbolGroupIndex = 2 + prefix = '' + + for reportLine in reportLines: + match = re.match(patchMapFileMatchString, reportLine) + if match is not None: + modSymbols[prefix + match.group(matchKeyGroupIndex)] = match.group(matchSymbolGroupIndex) + + # Handle extra module patchable PCD variable in Linux map since it might have different format + # .data._gPcd_BinaryPatch_PcdVpdBaseAddress + # 0x0000000000003714 0x4 /tmp/ccmytayk.ltrans1.ltrans.o + handleNext = False + if matchSymbolGroupIndex == 1: + for reportLine in reportLines: + if handleNext: + handleNext = False + pcdName = match.group(1) + match = re.match("\s+(0x[0-9a-fA-F]{16})\s+", reportLine) + if match is not None: + modSymbols[prefix + pcdName] = match.group(1) + else: + match = re.match("^\s\.data\.(_gPcd_BinaryPatch[_a-zA-Z0-9\-]+)", reportLine) + if match is not None: + handleNext = True + continue + + if not moduleEntryPoint in modSymbols: + return 1 + + modEntry = '%s:%s' % (moduleName,moduleEntryPoint) + if not modEntry in self.dictSymbolAddress: + modKey = '%s:ENTRY' % moduleName + if modKey in self.dictModBase: + baseOffset = self.dictModBase['%s:ENTRY' % moduleName] - int(modSymbols[moduleEntryPoint], 16) + else: + return 2 + else: + baseOffset = int(self.dictSymbolAddress[modEntry], 16) - int(modSymbols[moduleEntryPoint], 16) + for symbol in modSymbols: + fullSym = "%s:%s" % (moduleName, symbol) + if not fullSym in self.dictSymbolAddress: + self.dictSymbolAddress[fullSym] = "0x00%08x" % (baseOffset+ int(modSymbols[symbol], 16)) + return 0 + + # + # Parse Guid.xref file + # + # param [in] xrefFile the full directory of Guid.xref file + # + # retval 0 Parsed Guid.xref file successfully + # + def parseGuidXrefFile(self, xrefFile): + # + # Get information from Guid.xref in order to create a GuidNameXref dictionary + # The dictGuidNameXref, for example, will be like + # dictGuidNameXref [1BA0062E-C779-4582-8566-336AE8F78F09] = FspSecCore + # + fdIn = open(xrefFile, "r") + rptLine = fdIn.readline() + while (rptLine != "" ): + match = re.match("([0-9a-fA-F\-]+)\s([_a-zA-Z0-9]+)", rptLine) + if match is not None: + self.dictGuidNameXref[match.group(1).upper()] = match.group(2) + rptLine = fdIn.readline() + fdIn.close() + return 0 + + # + # Get current character + # + # retval elf.string[self.index] + # retval '' Exception + # + def getCurr(self): + try: + return self.string[self.index] + except Exception: + return '' + + # + # Check to see if it is last index + # + # retval self.index + # + def isLast(self): + return self.index == len(self.string) + + # + # Move to next index + # + def moveNext(self): + self.index += 1 + + # + # Skip space + # + def skipSpace(self): + while not self.isLast(): + if self.getCurr() in ' \t': + self.moveNext() + else: + return + + # + # Parse value + # + # retval value + # + def parseValue(self): + self.skipSpace() + var = '' + while not self.isLast(): + char = self.getCurr() + if char.lower() in '_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789:-': + var += char + self.moveNext() + else: + break + + if ':' in var: + partList = var.split(':') + lenList = len(partList) + if lenList != 2 and lenList != 3: + raise Exception("Unrecognized expression %s" % var) + modName = partList[lenList-2] + modOff = partList[lenList-1] + if ('-' not in modName) and (modOff[0] in '0123456789'): + # MOD: OFFSET + var = self.getModGuid(modName) + ":" + modOff + if '-' in var: # GUID:OFFSET + value = self.getGuidOff(var) + else: + value = self.getSymbols(var) + self.synUsed = True + else: + if var[0] in '0123456789': + value = self.getNumber(var) + else: + value = self.getVariable(var) + return int(value) + + # + # Parse single operation + # + # retval ~self.parseBrace() or self.parseValue() + # + def parseSingleOp(self): + self.skipSpace() + char = self.getCurr() + if char == '~': + self.moveNext() + return ~self.parseBrace() + else: + return self.parseValue() + + # + # Parse symbol of Brace([, {, <) + # + # retval value or self.parseSingleOp() + # + def parseBrace(self): + self.skipSpace() + char = self.getCurr() + parenthesisType = self.parenthesisOpenSet.find(char) + if parenthesisType >= 0: + self.moveNext() + value = self.parseExpr() + self.skipSpace() + if self.getCurr() != self.parenthesisCloseSet[parenthesisType]: + raise Exception("No closing brace") + self.moveNext() + if parenthesisType == 1: # [ : Get content + value = self.getContent(value) + elif parenthesisType == 2: # { : To address + value = self.toAddress(value) + elif parenthesisType == 3: # < : To offset + value = self.toOffset(value) + return value + else: + return self.parseSingleOp() + + # + # Parse symbol of Multiplier(*) + # + # retval value or self.parseSingleOp() + # + def parseMul(self): + values = [self.parseBrace()] + while True: + self.skipSpace() + char = self.getCurr() + if char == '*': + self.moveNext() + values.append(self.parseBrace()) + else: + break + value = 1 + for each in values: + value *= each + return value + + # + # Parse symbol of And(&) and Or(|) + # + # retval value + # + def parseAndOr(self): + value = self.parseMul() + op = None + while True: + self.skipSpace() + char = self.getCurr() + if char == '&': + self.moveNext() + value &= self.parseMul() + elif char == '|': + div_index = self.index + self.moveNext() + value |= self.parseMul() + else: + break + + return value + + # + # Parse symbol of Add(+) and Minus(-) + # + # retval sum(values) + # + def parseAddMinus(self): + values = [self.parseAndOr()] + while True: + self.skipSpace() + char = self.getCurr() + if char == '+': + self.moveNext() + values.append(self.parseAndOr()) + elif char == '-': + self.moveNext() + values.append(-1 * self.parseAndOr()) + else: + break + return sum(values) + + # + # Parse expression + # + # retval self.parseAddMinus() + # + def parseExpr(self): + return self.parseAddMinus() + + # + # Get result + # + # retval value + # + def getResult(self): + value = self.parseExpr() + self.skipSpace() + if not self.isLast(): + raise Exception("Unexpected character found '%s'" % self.getCurr()) + return value + + # + # Get module GUID + # + # retval value + # + def getModGuid(self, var): + guid = (guid for guid,name in self.dictGuidNameXref.items() if name==var) + try: + value = guid.next() + except Exception: + raise Exception("Unknown module name %s !" % var) + return value + + # + # Get variable + # + # retval value + # + def getVariable(self, var): + value = self.dictVariable.get(var, None) + if value == None: + raise Exception("Unrecognized variable '%s'" % var) + return value + + # + # Get number + # + # retval value + # + def getNumber(self, var): + var = var.strip() + if var.startswith('0x'): # HEX + value = int(var, 16) + else: + value = int(var, 10) + return value + + # + # Get content + # + # param [in] value + # + # retval value + # + def getContent(self, value): + return readDataFromFile (self.fdFile, self.toOffset(value), 4) + + # + # Change value to address + # + # param [in] value + # + # retval value + # + def toAddress(self, value): + if value < self.fdSize: + value = value + self.fdBase + return value + + # + # Change value to offset + # + # param [in] value + # + # retval value + # + def toOffset(self, value): + offset = None + for fvInfo in self.fvList: + if (value >= fvInfo['Base']) and (value < fvInfo['Base'] + fvInfo['Size']): + offset = value - fvInfo['Base'] + fvInfo['Offset'] + if not offset: + if (value >= self.fdBase) and (value < self.fdBase + self.fdSize): + offset = value - self.fdBase + else: + offset = value + if offset >= self.fdSize: + raise Exception("Invalid file offset 0x%08x !" % value) + return offset + + # + # Get GUID offset + # + # param [in] value + # + # retval value + # + def getGuidOff(self, value): + # GUID:Offset + symbolName = value.split(':') + if len(symbolName) == 3: + fvName = symbolName[0].upper() + keyName = '%s:%s' % (fvName, symbolName[1]) + offStr = symbolName[2] + elif len(symbolName) == 2: + keyName = symbolName[0] + offStr = symbolName[1] + if keyName in self.dictFfsOffset: + value = (int(self.dictFfsOffset[keyName], 16) + int(offStr, 16)) & 0xFFFFFFFF + else: + raise Exception("Unknown GUID %s !" % value) + return value + + # + # Get symbols + # + # param [in] value + # + # retval ret + # + def getSymbols(self, value): + if self.dictSymbolAddress.has_key(value): + # Module:Function + ret = int (self.dictSymbolAddress[value], 16) + else: + raise Exception("Unknown symbol %s !" % value) + return ret + + # + # Evaluate symbols + # + # param [in] expression + # param [in] isOffset + # + # retval value & 0xFFFFFFFF + # + def evaluate(self, expression, isOffset): + self.index = 0 + self.synUsed = False + self.string = expression + value = self.getResult() + if isOffset: + if self.synUsed: + # Consider it as an address first + value = self.toOffset(value) + if value & 0x80000000: + # Consider it as a negative offset next + offset = (~value & 0xFFFFFFFF) + 1 + if offset < self.fdSize: + value = self.fdSize - offset + if value >= self.fdSize: + raise Exception("Invalid offset expression !") + return value & 0xFFFFFFFF + +# +# Print out the usage +# +def usage(): + print "Usage: \n\tPatchFv FvBuildDir [FvFileBaseNames:]FdFileBaseNameToPatch \"Offset, Value\"" + +def main(): + # + # Parse the options and args + # + symTables = Symbols() + + # + # If the arguments are less than 4, then return an error. + # + if len(sys.argv) < 4: + Usage() + return 1 + + # + # If it fails to create dictionaries, then return an error. + # + if symTables.createDicts(sys.argv[1], sys.argv[2]) != 0: + print "ERROR: Failed to create symbol dictionary!!" + return 2 + + # + # Get FD file and size + # + fdFile = symTables.getFdFile() + fdSize = symTables.getFdSize() + + try: + # + # Check to see if FSP header is valid + # + ret = IsFspHeaderValid(fdFile) + if ret == False: + raise Exception ("The FSP header is not valid. Stop patching FD.") + comment = "" + for fvFile in sys.argv[3:]: + # + # Check to see if it has enough arguments + # + items = fvFile.split(",") + if len (items) < 2: + raise Exception("Expect more arguments for '%s'!" % fvFile) + + comment = "" + command = "" + params = [] + for item in items: + item = item.strip() + if item.startswith("@"): + comment = item[1:] + elif item.startswith("$"): + command = item[1:] + else: + if len(params) == 0: + isOffset = True + else : + isOffset = False + # + # Parse symbols then append it to params + # + params.append (symTables.evaluate(item, isOffset)) + + # + # Patch a new value into FD file if it is not a command + # + if command == "": + # Patch a DWORD + if len (params) == 2: + offset = params[0] + value = params[1] + oldvalue = readDataFromFile(fdFile, offset, 4) + ret = patchDataInFile (fdFile, offset, value, 4) - 4 + else: + raise Exception ("Patch command needs 2 parameters !") + + if ret: + raise Exception ("Patch failed for offset 0x%08X" % offset) + else: + print "Patched offset 0x%08X:[%08X] with value 0x%08X # %s" % (offset, oldvalue, value, comment) + + elif command == "COPY": + # + # Copy binary block from source to destination + # + if len (params) == 3: + src = symTables.toOffset(params[0]) + dest = symTables.toOffset(params[1]) + clen = symTables.toOffset(params[2]) + if (dest + clen <= fdSize) and (src + clen <= fdSize): + oldvalue = readDataFromFile(fdFile, src, clen) + ret = patchDataInFile (fdFile, dest, oldvalue, clen) - clen + else: + raise Exception ("Copy command OFFSET or LENGTH parameter is invalid !") + else: + raise Exception ("Copy command needs 3 parameters !") + + if ret: + raise Exception ("Copy failed from offset 0x%08X to offset 0x%08X!" % (src, dest)) + else : + print "Copied %d bytes from offset 0x%08X ~ offset 0x%08X # %s" % (clen, src, dest, comment) + else: + raise Exception ("Unknown command %s!" % command) + return 0 + + except Exception as (ex): + print "ERROR: %s" % ex + return 1 + +if __name__ == '__main__': + sys.exit(main()) diff --git a/IntelFsp2Pkg/Tools/SplitFspBin.py b/IntelFsp2Pkg/Tools/SplitFspBin.py new file mode 100644 index 0000000000..cc2b87ecc1 --- /dev/null +++ b/IntelFsp2Pkg/Tools/SplitFspBin.py @@ -0,0 +1,363 @@ +## @ FspTool.py +# +# Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.
+# This program and the accompanying materials are licensed and made available under +# the terms and conditions of the BSD License that accompanies this distribution. +# The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +import os +import sys +import uuid +import copy +import struct +import argparse +from ctypes import * + +""" +This utility supports some operations for Intel FSP image. +It supports: + - Split a FSP 2.0 compatibale image into individual FSP-T/M/S/C + and generate the mapping header file. +""" + +class c_uint24(Structure): + """Little-Endian 24-bit Unsigned Integer""" + _pack_ = 1 + _fields_ = [ + ('Data', (c_uint8 * 3)) + ] + + def __init__(self, val=0): + self.set_value(val) + + def __str__(self, indent=0): + return '0x%.6x' % self.value + + def get_value(self): + return ( + (self.Data[0] ) + + (self.Data[1] << 8) + + (self.Data[2] << 16) + ) + + def set_value(self, val): + self.Data[0] = (val ) & 0xff + self.Data[1] = (val >> 8) & 0xff + self.Data[2] = (val >> 16) & 0xff + + value = property(get_value, set_value) + +class EFI_FIRMWARE_VOLUME_HEADER(Structure): + _fields_ = [ + ('ZeroVector', ARRAY(c_uint8, 16)), + ('FileSystemGuid', ARRAY(c_char, 16)), + ('FvLength', c_uint64), + ('Signature', c_uint32), + ('Attributes', c_uint32), + ('HeaderLength', c_uint16), + ('Checksum', c_uint16), + ('ExtHeaderOffset', c_uint16), + ('Reserved', c_uint8), + ('Revision', c_uint8) + ] + +class EFI_FIRMWARE_VOLUME_EXT_HEADER(Structure): + _fields_ = [ + ('FvName', ARRAY(c_char, 16)), + ('ExtHeaderSize', c_uint32) + ] + +class EFI_FFS_INTEGRITY_CHECK(Structure): + _fields_ = [ + ('Header', c_uint8), + ('File', c_uint8) + ] + +class EFI_FFS_FILE_HEADER(Structure): + _fields_ = [ + ('Name', ARRAY(c_char, 16)), + ('IntegrityCheck', EFI_FFS_INTEGRITY_CHECK), + ('Type', c_uint8), + ('Attributes', c_uint8), + ('Size', c_uint24), + ('State', c_uint8) + ] + +class EFI_COMMON_SECTION_HEADER(Structure): + _fields_ = [ + ('Size', c_uint24), + ('Type', c_uint8) + ] + +class FSP_INFORMATION_HEADER(Structure): + _fields_ = [ + ('Signature', c_uint32), + ('HeaderLength', c_uint32), + ('Reserved1', ARRAY(c_uint8, 3)), + ('HeaderRevision', c_uint8), + ('ImageRevision', c_uint32), + ('ImageId', c_uint64), + ('ImageSize', c_uint32), + ('ImageBase', c_uint32), + ('ImageAttribute', c_uint32), + ('CfgRegionOffset', c_uint32), + ('CfgRegionSize', c_uint32), + ('ApiEntryNum', c_uint32), + ('NemInitEntry', c_uint32), + ('FspInitEntry', c_uint32), + ('NotifyPhaseEntry', c_uint32), + ('FspMemoryInitEntry', c_uint32), + ('TempRamExitEntry', c_uint32), + ('FspSiliconInitEntry', c_uint32) + ] + +class FspFv: + HeaderFile = """/* + * + * Automatically generated file; DO NOT EDIT. + * FSP mapping file + * + */ +""" + FspNameDict = { + "0" : "-C.Fv", + "1" : "-T.Fv", + "2" : "-M.Fv", + "3" : "-S.Fv", + } + + def __init__(self, FvBin): + self.FspFv = {} + self.FvList = [] + self.FspBin = FvBin + hfsp = open (self.FspBin, 'r+b') + self.FspDat = bytearray(hfsp.read()) + hfsp.close() + + def OutputStruct (self, obj, indent = 0): + max_key_len = 20 + pstr = (' ' * indent + '{0:<%d} = {1}\n') % max_key_len + if indent: + s = '' + else: + s = (' ' * indent + '<%s>:\n') % obj.__class__.__name__ + for field in obj._fields_: + key = field[0] + val = getattr(obj, key) + rep = '' + + if not isinstance(val, c_uint24) and isinstance(val, Structure): + s += pstr.format(key, val.__class__.__name__) + s += self.OutputStruct (val, indent + 1) + else: + if type(val) in (int, long): + rep = hex(val) + elif isinstance(val, str) and (len(val) == 16): + rep = str(uuid.UUID(bytes = val)) + elif isinstance(val, c_uint24): + rep = hex(val.get_value()) + elif 'c_ubyte_Array' in str(type(val)): + rep = str(list(bytearray(val))) + else: + rep = str(val) + s += pstr.format(key, rep) + return s + + def PrintFv (self): + print ("FV LIST:") + idx = 0 + for (fvh, fvhe, offset) in self.FvList: + guid = uuid.UUID(bytes = fvhe.FvName) + print ("FV%d FV GUID:%s Offset:0x%08X Length:0x%08X" % (idx, str(guid), offset, fvh.FvLength)) + idx = idx + 1 + print ("\nFSP LIST:") + for fsp in self.FspFv: + print "FSP%s contains FV%s" % (fsp, str(self.FspFv[fsp][1])) + print "\nFSP%s Info Header:" % fsp + fih = self.FspFv[fsp][0] + + def AlaignPtr (self, offset, alignment = 8): + return (offset + alignment - 1) & ~(alignment - 1) + + def GetFspInfoHdr (self, fvh, fvhe, fvoffset): + if fvhe: + offset = fvh.ExtHeaderOffset + fvhe.ExtHeaderSize + else: + offset = fvh.HeaderLength + offset = self.AlaignPtr(offset) + + # Now it should be 1st FFS + ffs = EFI_FFS_FILE_HEADER.from_buffer (self.FspDat, offset) + offset += sizeof(ffs) + offset = self.AlaignPtr(offset) + + # Now it should be 1st Section + sec = EFI_COMMON_SECTION_HEADER.from_buffer (self.FspDat, offset) + offset += sizeof(sec) + + # Now it should be FSP_INFO_HEADER + offset += fvoffset + fih = FSP_INFORMATION_HEADER.from_buffer (self.FspDat, offset) + if 'FSPH' != bytearray.fromhex('%08X' % fih.Signature)[::-1]: + return None + + return fih + + def GetFvHdr (self, offset): + fvh = EFI_FIRMWARE_VOLUME_HEADER.from_buffer (self.FspDat, offset) + if '_FVH' != bytearray.fromhex('%08X' % fvh.Signature)[::-1]: + return None, None + if fvh.ExtHeaderOffset > 0: + offset += fvh.ExtHeaderOffset + fvhe = EFI_FIRMWARE_VOLUME_EXT_HEADER.from_buffer (self.FspDat, offset) + else: + fvhe = None + return fvh, fvhe + + def GetFvData(self, idx): + (fvh, fvhe, offset) = self.FvList[idx] + return self.FspDat[offset:offset+fvh.FvLength] + + def CheckFsp (self): + if len(self.FspFv) == 0: + return + + fih = None + for fv in self.FspFv: + if not fih: + fih = self.FspFv[fv][0] + else: + newfih = self.FspFv[fv][0] + if (newfih.ImageId != fih.ImageId) or (newfih.ImageRevision != fih.ImageRevision): + raise Exception("Inconsistent FSP ImageId or ImageRevision detected !") + return + + def WriteFsp(self, dir, name): + if not name: + name = self.FspBin + fspname, ext = os.path.splitext(os.path.basename(name)) + for fv in self.FspFv: + filename = os.path.join(dir, fspname + fv + ext) + hfsp = open(filename, 'w+b') + for fvidx in self.FspFv[fv][1]: + hfsp.write (self.GetFvData(fvidx)) + hfsp.close() + + def WriteMap(self, dir, hfile): + if not hfile: + hfile = os.path.splitext(os.path.basename(self.FspBin))[0] + '.h' + fspname, ext = os.path.splitext(os.path.basename(hfile)) + filename = os.path.join(dir, fspname + ext) + hfsp = open(filename, 'w') + hfsp.write ('%s\n\n' % self.HeaderFile) + + firstfv = True + for fsp in self.FspFv: + fih = self.FspFv[fsp][0] + fvs = self.FspFv[fsp][1] + if firstfv: + IdStr = str(bytearray.fromhex('%016X' % fih.ImageId)[::-1]) + hfsp.write("#define FSP_IMAGE_ID 0x%016X /* '%s' */\n" % (fih.ImageId, IdStr)) + hfsp.write("#define FSP_IMAGE_REV 0x%08X \n\n" % fih.ImageRevision) + firstfv = False + hfsp.write ('#define FSP%s_BASE 0x%08X\n' % (fsp, fih.ImageBase)) + hfsp.write ('#define FSP%s_OFFSET 0x%08X\n' % (fsp, self.FvList[fvs[0]][-1])) + hfsp.write ('#define FSP%s_LENGTH 0x%08X\n\n' % (fsp, fih.ImageSize)) + hfsp.close() + + def ParseFsp (self): + self.FspFv = {} + flen = 0 + for (fvh, fvhe, offset) in self.FvList: + fih = self.GetFspInfoHdr (fvh, fvhe, offset) + if fih: + if flen != 0: + raise Exception("Incorrect FV size in image !") + ftype = str((fih.ImageAttribute >> 28) & 0xF) + if ftype not in self.FspNameDict: + raise Exception("Unknown Attribute in image !") + fname = self.FspNameDict[str(ftype)] + if fname in self.FspFv: + raise Exception("Multiple '%s' in image !" % fname) + self.FspFv[fname] = (copy.deepcopy(fih), []) + flen = fih.ImageSize + if flen > 0: + flen = flen - fvh.FvLength + if flen < 0: + raise Exception("Incorrect FV size in image !") + self.FspFv[fname][1].append(self.FvList.index((fvh, fvhe, offset))) + + def AddFv(self, offset): + fvh, fvhe = self.GetFvHdr (offset) + if fvh is None: + raise Exception('FV signature is not valid !') + fvitem = (copy.deepcopy(fvh), copy.deepcopy(fvhe), offset) + self.FvList.append(fvitem) + return fvh.FvLength + + def ParseFv(self): + offset = 0 + while (offset < len(self.FspDat)): + fv_len = self.AddFv (offset) + offset += fv_len + +def GenFspHdr (fspfile, outdir, hfile, show): + fsp_fv = FspFv(fspfile) + fsp_fv.ParseFv() + fsp_fv.ParseFsp() + fsp_fv.CheckFsp() + if show: + fsp_fv.PrintFv() + fsp_fv.WriteMap(outdir, hfile) + +def SplitFspBin (fspfile, outdir, nametemplate, show): + fsp_fv = FspFv(fspfile) + fsp_fv.ParseFv() + fsp_fv.ParseFsp() + if show: + fsp_fv.PrintFv() + fsp_fv.WriteFsp(outdir, nametemplate) + +def main (): + parser = argparse.ArgumentParser() + subparsers = parser.add_subparsers(title='commands') + + parser_split = subparsers.add_parser('split', help='split a FSP into multiple components') + parser_split.set_defaults(which='split') + parser_split.add_argument('-f', '--fspbin' , dest='FspBinary', type=str, help='FSP binary file path', required = True) + parser_split.add_argument('-o', '--outdir' , dest='OutputDir', type=str, help='Output directory path', default = '.') + parser_split.add_argument('-n', '--nametpl', dest='NameTemplate', type=str, help='Output name template', default = '') + parser_split.add_argument('-p', action='store_true', help='Print FSP FV information', default = False) + + parser_genhdr = subparsers.add_parser('genhdr', help='generate a header file for FSP binary') + parser_genhdr.set_defaults(which='genhdr') + parser_genhdr.add_argument('-f', '--fspbin' , dest='FspBinary', type=str, help='FSP binary file path', required = True) + parser_genhdr.add_argument('-o', '--outdir' , dest='OutputDir', type=str, help='Output directory path', default = '.') + parser_genhdr.add_argument('-n', '--hfile', dest='HFileName', type=str, help='Output header file name', default = '') + parser_genhdr.add_argument('-p', action='store_true', help='Print FSP FV information', default = False) + + args = parser.parse_args() + if args.which in ['split', 'genhdr']: + if not os.path.exists(args.FspBinary): + raise Exception ("Could not locate FSP binary file '%s' !" % args.FspBinary) + if not os.path.exists(args.OutputDir): + raise Exception ("Invalid output directory '%s' !" % args.OutputDir) + + if args.which == 'split': + SplitFspBin (args.FspBinary, args.OutputDir, args.NameTemplate, args.p) + elif args.which == 'genhdr': + GenFspHdr (args.FspBinary, args.OutputDir, args.HFileName, args.p) + else: + pass + + print 'Done!' + return 0 + +if __name__ == '__main__': + sys.exit(main()) diff --git a/IntelFsp2Pkg/Tools/UserManuals/GenCfgOptUserManual.docx b/IntelFsp2Pkg/Tools/UserManuals/GenCfgOptUserManual.docx new file mode 100644 index 0000000000000000000000000000000000000000..c8766d5775158a3a6d17d9a0ffda598c8ea516ca GIT binary patch literal 28336 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�*=l>~ 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 Uu$FT(x`7RthBdwh^P8>z1HD}In*aa+ literal 0 HcmV?d00001 diff --git a/IntelFsp2Pkg/Tools/UserManuals/PatchFvUserManual.docx b/IntelFsp2Pkg/Tools/UserManuals/PatchFvUserManual.docx new file mode 100644 index 0000000000000000000000000000000000000000..ab1eda993e7b7d249a0390dc1db83ff4987395da GIT binary patch literal 21481 zcmeF2^Ot7LlBnOZZQHhOS9RI8ZQJbXQkT1I+cvvwSC{R&^?he%%{h0@z5l?>{vlVs zd+!w)J2T>q^+aYU%7B2P0>A-~004jp07V)e6bJ+W#DM_-C;&)cZ4rAr7gIYIeHBj! zQ)gXz4_h0;d{AJ@TmbOb`~Q3W51xUB6gh=pLBz02@(+kQb&xeL#-Wsl-1`!_it7$~ zk(CiY6Z6;mOFU_rvbsja{LR`8+)Cb2D=pf#JFw1EB0GTGs4r1357sNGqBhRAwjv6TW+-I_-vs)=5{5{jX zMiIUmGWc38{B*yjx9K81|C&13g4o9cIfL>)8z|>nDwIQ>@Jak`?)cbyWhaGA%jM^8!HATF%CcP_ zL5}LjEvgry8hx+h-AZSX?m_#k*vi*>eNd5~j4|SED8w@zAX_@G=FT=Iahh``vK_9H zul=9-=NmyKWyaWC5d4%DYNBfqY;g_VQx^zj=cz)!cPBa4T%Mo+fX`15fa1S+E`B0* z^X->8%6~Z~%$MitJDJ)zGtmFl{;$XW4|dak`t+EjHE9qb*sx2mEyEFCjx}iFxs^@H zJa^(hAR*~zK<@Apg{xhi1%z#iYkG%wN8<{=GlMf1c#3(!s|__5bC)v>B(|(QY@4GY z6g5Y*GlIo3Yds=!A}Rsk9~FNSt}LqMcSi|*_F zDiU1JV8QtsZ(TAA(-aETe0B zUaDQIdr|cc7(cc?=$B(3an0Dl5PA@wjlBZBW(cV*J&n0g4SGUl{a(Q$o=Q?55v^RX zl4LEVhSY+NV_aE?meCn@jiCgOz6|s)1`m?OWZD3RB$H8Jfnd|%35#TyLyl*v=q6i~ z5r1=@%Ge<5;%w_0)}U=j(H%2P=3fi}plj~C+oMk{eY*j|wkht%tb=2VZ^<7*otSzt zB#mg>1$j5()`|Nj?B#kf;PE;Cbe zY8PeM!|K-3yEgKX>dPCSUf(+p^+FK%bspgVos9_)mxQWd006lu007dL>HKYD|7=}n zeAdouBZ*tpryn3ujhl5Sn&7?7^hT))+NyPxNw}Bip1Smipk!G>0YHMItIpqE32vxV zM|0Nnoi=U(=HMWRq-2#1H0pKiKohbG3f)ER#YYPMAIy)jG8|EzjGPrJkCRb5;PRaJ zLAU*5`kS#i%{1a!%e@N^{XKjYI_-`J(;J^}@dCPdvLfbO?!f~A^g&PCRy(+A^hqX; zSG!_oIxWsTn>pU{s6#unEAD;I(GKjlxQ~OXm~#3WW{aesTB3P-LrgIoHNi4GRW%of zE1P|xI6WHmj2UZE9R%V>42N!ao~<76oeXCKnI2s~bVRnylHF18)l!uldH`P8z#($* zl!9jro5W)i!YuT*Tqc-=BwZ0Y1O|}7Pkq`IMYXo}jDs-nbEdPT^hf-k7gkD@=0h^Y zI%aTTiN0VmwWo~pKf$q-S1m4-dADDx)Kt%FtgFkbwyLdV6Rr~1|^n+vv`S236m!4uNu`aE|Rc4N6mYA#knI~{0-*10&j5&A~5 zp8&I}jdp}$YHftH z4VkJF{0i;x+mY<8CDW%C_$M9fV?BpQ71DfnBBb75W+_SEhTi%YrMHR>7x>a_<2*jD zzLv;~Cv(uQ&b*`f{nzW)&yObwO{-6MTj(~j(N)y$-Ka6bywR)0k&4ai>kY!J0tM*b zj(AjC1fxkm*M=Oigf4)fO&awYdnM3j^e{gU&WtORSGerm& zBrrYUb5w@cJ%ecwhsfi{0U2aFeTr9iwVbXgN~U>;Z0%GEjbRCT%SzJvrH(Slicgjna`J zs4J-u#xMu5O(Lhcf!~v_;>>szKcKHP`PplmII4rx5#&xMTk(?C0>&5%q~WZ&af`Wc zB)|YgOuPa1Ar@%hX9pFph7o0~LEr->Ci^`uGeh+m#sacZm-glv8_(|q?J|vnL!dzAW7oUs`68$kFN|y>>Q~eHoGG9Rthc8i zTRqXfDF%$w`el1o0dJYsMl!!wYS^==V9M_UH_OFRdDvpP=fw~uhgi}W%S2qbpSn6v z1OY~lVIa@2Z^;Z?cCqO}sRAr*x96l_g;GO0C2X(=HP>ZufX|jq?C()R@aScb>0zIG z?qeNNqdG~QHjrtv6)JBsanZXyt?+znk6<82X^j((>eMC2?Vg!W!zchLz=k!PTn~(6 zZ9)z5)2dint!Uxih}pTX`cP;Njd-7|J&K@E1S4V8r!2d-@7LiDp1|1P&U8c9yZg7# z@d_{f3YT8R3=)^wK3+E;XY;SKCo8jS912%kpBr}k&yH_h5eNeY8dwX*>YZxV86Z{u zX`aT7R(rq44v{7@1Mi-P8anvHZ00Rwf&0)sxX26>P~iu>3111>yC6uQY}25IR6Pst zM_)Hjl&bxCxxK#yY2I3PE`ZwW6GX=i*mln1(3t+|VZ=zYH-0tX5RX(6mpLk^+bWAw z2kMQrG?h_KLySWm0d{LNK#&RE7Kc_ zW6)t3q)5ancQ-5&N8=#~aT(P;Lefdl)`Gs39dd7@PIEvLFd117xx$485wu>&~=d6taVD37xiL-@c(=lL5kHsXu zVkAB!)i*j-!DFBBsumNStcDjTZ1Xt6;C~YUB8&t()maNn>kDE(UTNPPSGo^)GsWw; z=;XqVpV}v?_cZA%Eo=%jNQuaN)71=gB=~9(jH#RH~$`SH}(=yG~@V3 zEhCk984CxUlC7VfaVMdWyWe;>RxZ+4O=7m+vr5Ga#@-TR8P_EiqWDekTRXiR z&>G)fRfmgu;!8{z^{tc)Z&Srk0$G%sV-<8UGE&wLUD+5DG7;rOOruY)>tGLE&1Gh5 zX5SwiUC=ZIXh~l5SQQH8;+RiMVp}lMtS1*}zElrcEM$XO7^Z6M^t6@XBTgH-&k!7h z?vnyvOA!jZ4Nndrb<>B1Rn;A5Cvf`g1abwziDNkkZd4V!_`ctF2z?HJtVu@P8S>4B z-!ZC0%1ntdK~k>S4hb>8dqkY;|NQ0_#kDH zZ7A53)r6Bkk0DmUd4tl~QKOGxw8YG;$y~M_Ebe8a=X-}xoo?Alxtr$(=JUm{7AFle zhvAnrz1>*UF^=h5Aso_K>z`j(v<}n9;KFiWX;yvPmi+_AG%3FUnj7mbD3Da|oTs#TWn^uMr)yo-@B`DI^%tw{pM4d={yq3l?d zgBMR#5vd#l(Wq3cwyZR3!?WjQI}k^D*b|s8qi6uYbhOhi2-&gw$oCs2aW-*o|lTYQtkb0H644`MhY9l!`b z=;t~EWl0S$$g(aWv~v-dhVc#}B#u!AF1OagRZyW@x)$mDx2YWqxJs`AH3I8t-f@j_ zM^B+39oeBeiXQlZTbw)`%zNgDmwsso;nxX-iSACv#Y~Z)a4}Y*U8>^F)vVpS))x&_ z5bej8aP5tn%B1J@E19#DUG>8|iR+$l;F-B5mV`;*)IlwDV!?7Tg4X!^$Lh?Ap`E+Ruy{ z(9(LNIRvnLFPRn+`Ehg9EcT-m2KDv^U{gm8$$z`!)I(~aBwc@il9`9V(kLf`Xj1SS z_d(lYs-&3q!tA1tHT~zHgW%zCZ$3-4_9783O5V!}+SN9yywn6y;sq7v)^R3dcg2bU zD|aQ)vi0-EVVbm?O#mOv5eF$WNY=sQg0GnmTNtWf>GxE6oPt9Q#vQO(%5Eak5qu(i z%t#wj>_$q7HbbR24F&em0gAMorxeb`&3v0l#P* zmWVbjd-1%}Lr(sXEFUBwl-7U&t8^3bv7+rw*g2C+60rSkfJ7W5UsSj{+ z{NZDUmGa|n))| zb{ONFb$-Hmku07ooS}*TQ(>3%)}p$|ZhTz1NZfK@;?-cUhL5GjnP zkr1gz7;PzHhOBq7iX?~k;vsdi=$-a>4vG}H;;EKY)0nly$*y=x=W>$xw_n5#s?$5m z{p-PHcGWeKNL2+eqzln}+OJ6|%yV6iMpv=FI`2D6B_Of|f2i!&Y?aSLWm!Vm1T}=B zi;hZ12!HE%Oa=fSXFE)@Tj<3KlZXmGOYhSM)(PGLf#buPmO2@dp$Ss=i?&!Gt4PM_ zNFIP=pzimIB)~joGy1cv--iuG#n83F&_zgG5TkF9xI2D-ENLgsk5+4=@fT@Q^Uq`Y z7%_~;CCB<6k2}OkyQpu?1&bBS9u@F2La3u(JoRFs#Fkv!G(>yFPOH|%iE~vrOCJ`}20G9i{2(7=LcCAy03Jy9(aKA7yv`^R0cVHuljinuzlVq=hxi)LB zNuGsVC|!b>AA!Ma23LZA+We%z67MSP&6r6SEK2w^rw}WmuMJ(_MzXiFACHaVg{#(c-tmgxm0& z5l^_s8c&#<#mPnEQ=q-#cJ?h@6JkCT>|w8lkfQ)LN?lx80_vcEgNU?|AJqEw$rxla z4vO~87K3?(<5x)HWHY_kH(j8HB;Bn9Mo*Uq&r)s)OmDz;HHTE2>a{3#n3c>G8&r0j zr6#htix&A+d3_-0W|jQA!{p8y^3#sfF^Mlh%7~{Tk=WOWn5AIy)Gp$A495KCJbgB7 zl|dEhm8pxv5s?{>G~KQ9u0oeKJ5Y(0iMk%bg{u~evTEyg$z%)uuXCZ;(bVy#lyvo# z`GxFn_!kMPBf?wkYy+jXh2f#u_^jKsl%%!SWj7AlsrZbj@+VXx(##E@UXqqzt_ODx z(T!-F_e7o11uoZ5xxh(X&1mROuVb`)gAEfx2!RrkwDXJTBfDYl%~un1P3r~4mEDH- zel5W`C4AeUzbZ88u}rrYsxNfsr8h+vEtQ~yK&bLmKsK`FuV-j<7R%TXBc0c+?s49_ z=5d`r3SA&_78syxULp+!RY>Y#wBxxh#lvhTQ+cqF_iUn9|htT!L@=*6wj@1x{>N2F~7%L#}t-bx&EP#hI4{|#mFj)Y+Z2~6l;~*D9x!7YRVge z7nawdhI+u;*R#tpm-sBeUPa+#3JK?q^a~8r^O}Lcy$S!Wz|h}y?qlZpex_Z+I>#{D zTl9uT&&y4hq@14dvw{^V2j5ilAg^XGWote49v(Rp+)$c}FZ5J8!_49?XUA7!+s`2M zhm(A+RF^{e7Vdq+ePXVML}fO<=TJoT5lV+Pbd+rcS9HW~gSzc~#jfyqMFS_!^i|UGy}4%8x&5B4H@Ft6^g#h5=+tP-C#Ka}PeS9J6o;9daG5?T1B~_r_El2NuoH z_e$2wQgm>m;H}nH6D9DK$|4M_-B=xb&p`5XA0+OcC2xkb;wOHH^i`^DRQV3t?;5GL zMq6H#v5^?d4m|UqVzu<$?F=?(hm2o8iN$C&Bek*@?fFhl+oO_U4T zn_XVORtrmDq}wGgPEKmN^K#J0lWY(%+}Y+QYhgw{Ri(`}0jsY&8B9{&S8LQ+qi!#R zX_2PX6XuHL%%<~Ybs@S5qe9%~$aQ_K^~r|gfd84SofU;RXR`#+&!!y|EsRVZ_zhhn zfRP!7uV)deX#z>>wRPJJni5}MF4Qf~XSo*trWS$>4E2Eug#5d$TKgiVMJ0u&8dr^Z z66Z>s^IH4L3@!y5bZqeyOFwgYBi|k*H2L-gw^oRv5t6b+4E_w|Gc9{fp^eK)YUG=C zrB!3uhHE{?fM4X!%K}Oy&Wd(QUG!~zj-Zo)CHix= z1Ez@8V_9MFYC3@&{Oft1yMdlg8k%U{h03IQ0aBcu_$`@yKF94{&%`hBo**4rzI}m;O*DLD^w+-G*b&bTgq(Ke6B=+T~ zN`6x0=e^fYe1g*QrHf%$JY*s&g;l+Gr%4ggYfr)Cn)40(2Zl;dN$M=nwCj+DPO8Ms z#@NTL_NXOQQKKLOU*aXlwdfS-r5~w<2>lv*hg4Dqb`xSTXdO`wRESTI$3r%jt!mo3 zQA~2YDchJMo7nNC3NwnyckE8PeBjlQNnSnXM!8Zb=Apgd5U#Na$}6V8ct*b;0u*}U z!}hyw5c|LNimsKXf92#HU7@PYqtmo%ni{I?{Z`s+gdA#YJfa*_7%LxfDrvOAd_fGX z@R$DFw{?06O#^B!gNxKsnJ2~lD>p|iQw1L!v)!71SFq{$M1G8AO;pMk&)b;RY2<^O z5a2jJHLhA2JFoQOBn)yKUBynBHMgH`!;S2!A6>oER4#@^bL2+M?i;{Y;;mkqFTjkX z)t^g0VfQRqVflmwSy1N7)MMU?(nU35ZtdkG0N_kCWm#+Uehe5YQ5yDznWBIZ$Qj zem|QYCMXcd_Pf2A#aQ&v9Qu6er|5or^JGJuGbf*lX2^MaI2(0mq5Fc3zRT@ zN*EH&&)kPRzr{plQFA1tAaU$M>xZ1biJBx$;q1+j0ejDm!o8cMGD~;I<>DS_+{Obs zD1i3xb(%)JbK$JJXu`3LN$1^<#7Zn3?d&35?WV>d<#lvMbGB&CYo_|7ggN6Hw6zCcyNt1aD1W{tP%!NfzPa3`dD9j|*UhK=jKDsNdVoDwP$jzY^0 zvNJv*0`Plo=Uvi4D%#j>C39v*2Zy{KGdN@&Ur|-o2nT36?~Qp;;q*j!GU?Wk{(P*e z!piHJCmQbsn^Td9N?hb}UHs)8G`_4HHfUz?vKd?pXK|X09?kShozaLOyXyXms!(p0 z<~F2BRIzaFygK$;u9Vt{8gf=PNG+n88|tiQHfzo^194zm_df;ebVD#0C&XAg z0Ve!&Uem87c3COIV_C#n2sp4W+a6Ji((76oXE+W#(aB?H*f7fno8Bl42S~iP$cjAa zakNwv6f!ePYu0Q(GVyO5S09EPoj1 z*VW6Athzn0(fsnskH8e|MZ&I)Tpr%`!z;^G5G2!aPm9Xc-?o$2UXyJdgkJ{^ zCdQ?xfsbBgAP@Q%()}wiHiR+{q1Lt^MiEiTcF^h@#=hcbGnct#T0@vf;c77vGU@{f z8kF!uE^YcTPpAgpT05;&DiSl2DzbW!+8GiTsZELXcG>0{AF5DErd85+pkN*>{|oO_ zp#nt?t^*%uYR%fmRotgy9)iq?+!XC_Ig#YGZp2y(1he)sUHjA{Z+lH7J|^pWY)>^n z{hZp&*xU!380V3iHO=p=q47x_&a2&yAw~^WQL1$!qIZY~0csz!ZntAN*OAA(CgLZL zyhx#CK^6VFSco~WIrz9-$GTwlG*&9>)e6@+wQ-I=Fc&T`T@*2uWIWN`)0SuXT+S<8 ztsaR(Q?zHxt8sL!Y#t9LQGGL<0wb8iY11YL44OVJ2)LbKTd?G^QYf-lKcx+h^B~9( z2%qUB>Rt92{%vS09JtTg{5qR=hWt;v%g&}QE|zxY&VPlq28}hlHE~2=h8cgvI~@t{ zgCybope1&pEL7DSAR0$9B%;=Vq`F-n-*66^s$rp-+^gWx*7J$<`f|Lkk9QeW`iod= z7;XF1J2Xvt+0JH9B?69d1%i4U|5ghg-J`aK#uZuu+4i^hhb4VI{oj=*+>F*3i1~I) zi+=UIuDbPlm87PK3wr-(h)7=?I@Q^jo1 zPFLwE5ZRR(UD{Y9=w8+}g^Sd3%y+N!zmK#Pm>WGFjV)}{?2e@)JJq;)Q)jrvsl6{* zDDGOqf8|<A2=0lw&qe(#4G+Qsf<38%t?H|Uu6i>p?S znjAytc~XKB!l~tYK!eNuP4hp2T-Va-aGzQkV#5r6+|Qmsr!{KECG}EpK={(P$9pxO z+kl8aVmqnXK(`857C-)UTob<}(z5w8wc^w?e(t?C*z*m7Fit8a>wF$7r-|gVx8OIL z3X?R2{MO3)UHVVmYuFNuzze)ETA=tma33O=*G06}z&YvqbA0J!p_{eca;QIV=dI_^ z%VZ$+{=~tTWCo{x2M9Io0{pDxENwg>vY+!tA{2FX78lS*72e86J+V2uHf$WV_7u2& zo;(6?wzeG2feD<3LEt3lohzy$Es_PLa-VZgq(%Ivd&w#TCFFO&sks>g1=RhlDPBxF zC1KGaxw9oIZ(wqSQe`t1d4*l!mY9i2q9x)b8hKcZ@kJr|{88V=6y^4R?Z99UvanjC zm!^eTG^C+${RCFv83tI#J*50vkeQis%tsYr+J=h8yhx5nD>#OvCXRB`X3W^Wha43P zb5eQYm7A3oD@y_#loSeYcciY%5Tjb3)W_s$$ZRR2K0=8OIpzqG;b%0)bi!`IFyGf9 zntq>X>0z6(MlQw_;XS=ZJr5c#+_q5Qo6?B-z4uHkuULUrEEQ!|*@Cg7Nke53bOCmt zd|1#@s&WH*&`ej~GmP4)$CDv4=kq6Cp^FGV)cFdEWz^2?-0Ij=W277K*u7xnVA$EFo_l3JXd( z&J+(C3+k=|p6?gxSVF|CVm@pn>ZC)Qco#B*C`?EX7P1iA(`Fp=!QinJ5(+X@N&(Y> zVFWR@^92&>ET&tk=xijKDgNp?=Qn;o@*$>2z6Kbkw+|*4`);3N$%r6>wQ)>GkY9*}W&~ z_AKzJOvAUQ=UX3@WF~TyhBYi@-XXRi=fM1APijdeQI=oCk<3idp4hpVCR9=@JsvH^ z^3C&B8whFst!qnr%KiuXDtj%6f2@w6J6rxpC}QH4-B0<(MS1=TL%rSlt|7`{Fs(B9O($v1f%*oOw+x zzyR?WN2RCaei>zz+I+O(_E2UR^Cs?Eb&K#=h0xO0=d9^|b#I6nxq0%!xwS0kduzEC zPbuE4yNvEt|K`;ex%Ifo2%BQJ=HI~R-ezfl4cfkuXqRg0$m`nR{%4ymJRYNe{9=S0 z569)|_n$C~&dX@9KPPz{m;}96UM*u!w0r7UF^2^|TgLWjlhxBX#<%xIO?`uuCVF+= zuns4mYkv^fXs$+&erAPc9$?3UV$(2yu zNc*3dyRc^!CA*dqoV9uztx255W>Uajg5KC^Cx%TFzmy2d+?rR@m%2F1_Mnh6$t;Y18TBg$JtQ-lXKinjg z9;7HMDfBTS`f*$f(E5hM2NA>IKoMc07{}})9Jj$^uj$RF%01oV;}Aw6TrK?Bc=YXT zx5rWFYKWrV=>Sbm(&HdcWWs0A(7>?zm&Ho1PZ>c(j?9yIYQ$x!6g(MREd`2rb@ zQf71z_DKr{1)JYhIFA^!JLxyU!l}%Hl|!g&Pv|3Oyjo?p*&ME^S1=0^T`LHJ>G3XO z!+FF-VZvr~rX&rrWi~Gz9A_%cy1@oc0_>9d$k^p{iM&Z-(hep5pyQ|A@`5uZJBy}a zr4e)`kxTf{0bevTZrwH0EBTLd|2deNqh+cPz>5O@YdX5!qxjPfChJea8GGfR9B}Yd zN8J2KE=s}bWp2T>Fz%BxZnKZ_fL6GA3} zwj!Qb&K-`TOP=)_xlaQV{t)=Q@kDvZ*2n_o&3Fi}27kwo_UVGn54ZfBf1jNFk(DYc&6Xk$UIv`8x0K=f|%w$3P_GMMx+;mDBvu&@DfI{(SAYTfH(Qqh|{&a0sRU ztJ#$sPyME6cpCMi%cn9#gHneUo1#H2>;B}MKh1^Ufv!{&?^gC)8he1y7`f0~w zZ!o_797%G^%d!TtkMJG14kB3=Hs`_J(WMI9r4WL&Eo&U8R6sMnrBDp4>dbTSeIrba ziWq;GHiYSlQWIiLCsyQFVALNQNd;GFUfaI2uA}p-!jNLsqUCMshwNU|)}Ex6s8NkE z`Ao&B;2L|o#r%PtTzM>0BqHJXK;{tN2^&%zhKPo={-U8QorrMuk9X?{cWu5b+Zp*) z+q)9e$Ql>S6@#Ee^RiS^i39kL&&>0@B!7ke5NUIs;{gBYY6X3k4t~5O7S*nVOW7@w8D=D@?D!YOM1vXWgSo@2Mb%#zZ5Q)I0Fu>K^96~ zx{~Bu7)xah-Sdv>*${rvUToA)&*j6v3tVmLR54>iEX`G128X+@2CL>tw#FKuj2Et% z3y=8|ka9vauJ{-!{gUDw4MU06Uk&{nO6|2vmV+~7V@~wBFgOGTg|GFCk`IX-n_Vmk zWdw+UrPHsg3Oo2D<`=v+0rzl`{%j!UkNqm+xSF_CP^wvtpqw1MY)$;5S z#jCe7MhA*}aXQBtzzHe$az!-yAWLO&NnGLkKG6FRxY?l!xHgGR6~I$Y9VSp>+PLUu z#eU1}%nKHu0;e{J#jRO&tOQA5Iq@@52;>BHlLH@_^Qv6IoH8DV6@(_P%==uvZt#TT zt8>6dJ75pmOA5KSurQX{SDH-`81*?a*mH}V1}f17cL7-afW`};{V>$OJ0-RaZT zX?npPA+-liVBwH#QZ^UY+!Ud@&s>8a$@~(Y%j}7wm{n;^Vh@bIxw{JmMl0tET46Vm z3HVpRr(qpXg6E^{ScN<{M!G|izUw5YNasy>=$N@Wa^y`XJo0#_u@|&Qj<{;lk z{}TQaIPX-98fbh)@Js9_C~e2!AQmb*cXRZ&jRX#%f`1*w`^FCZB(4KWV`@E@Yw>S= z`78+k9^`M)G5@z{t85YjE}W8pUteQ|e#~WjspB!8CrFR&DzXV0`~R5|ry>YAlOztH zk#rpDQ5@s_!M~OLkC{*=RQXF)a}cx|)4hCsIK35Az;8Sn#6>T_^p2R^(6~SNI z5=}--Drj|w%_3UBX4u?>T3@@myJSc4e5=tL#?iqEc|l^B4nDtLVY+@9qY}qVTTw$@ z_~+bjjsmBB6L2Yg=djQ98llDLyCGHL1l^PEw#hRw&+OEsFBA$)DEae^Oi%;G3kFQ6 ztU|&C-Id>g1YNb%%*U==@!G#cK-cUM7QDWE7K)QcC$KhmBuvOcJAGM#bbr+L#%Y-w<)GKZDofhRYV^UtktyB^Us+RdKAD<56dD26njgRix8Ug- z|Fj$V?fWrwEm$zN24nxIwa?Qp=pk??T%R9N8MTiJhV1YigfIi3pbMKjIb&8lm(>|o zJdW2|s@qWGmuTzf_Y*J|qRx5_%?Zu|$=J`ksxvkzd!r|lI5B<|iz4u0+#Ej7O!ny0 z5JI=(IHeUzJ&)YhOwdm?aI6yF&$IV~k@yJ8F09ry(NvEg*J}!eCkjrCQ^#Ob+Rg~d zfJyX=$6p^dLBhyiTa=Y-6g_gFCfTfBF@DfZ{hVK!uah@fx~Eo0OXT34(GINqO_(TEkm23nK7BRRrQ zuRap(lR<-Jg}u_=My}tC2ueD8+@fg|%~$!G_y``{p=9CEz0oZ_<6ELW%IP1%ItJKwD@H7Y7##Xl8{q-v%o*--t{2biyOGXC4ixq)- zfDYp(FUj;!?&@f!{-g>u8c-0N3*Eov5fK(b1Srhs7Ort}7_;t=QW z-D&!IX4uymCE8{AjfEYp2Xwj>4tk-Vb06g$4n(d!y2eMFW@SdsoUZX3M=@OEM+5x! zy53n_LN#xr-BtxoLqtN_=l(zRFrDyKlk(fht>??vr-mZJW_%t-u3J7ifgI0?w2VZ3 zJ%D9M)ZJnp;}nbDz3nGCvNZyCM?t=nu~crWXY^vT5!KGH!FJFsn-7JFQ|&bI~zS1vuBvv#@`zOKZ*eI>>*LC=}BcG5cm7b>HZoA+_OT&#ZGS=9FLvr(m#OYkDz1MvXkZAV&A- zKf)PEyDZmw@jWWHcyC0&FK>J17JO_V1=NKg2_n0&b@kWxFZ0(83VcMswsHq!(=9p? z2Grw+pOT{5?K}3a)lJ3-x`<>AH!iyNv2RV6lD4v@WBs0ReVl&Q?7#T=P7R67WJeTK zzYP}epMU<_VyaQK=M}ZDCox|Ihe%(=R9`hNicag?Ado`}|1&$sqSZ6#IFX@91B^E&^u z>H6W?0P=^r(n*vYDoW6ij=FJlR=YLAoYE5!@_Shwc#|&mOI@tTNtaq7pvM}9^N!Tw) zAeEt7cd_N$c@<|aF-n#b%!IWzZ6h2^Md(rzlVSd8T2RVhY*SnKeom^tM5ms_i@_J@6Rym6#pQh`n!!`PM z2v68&f?ePAqPx^A6or6%8J~|&)PJ7}d1K_zfd3+EQbPa$;a|!6FH=0z(f$jk{RCK! z1RUM9M^#Rqw7iGpHbzc7izr8oM3A^i(T1Pzb!i0=iJ_c`=H?40lj#!H5thfB z0TBlZ0{)s3o93y7MDfMJJAe8Ehj#-Q`koxQpPn4vPhGZur4ul`MGV_;dzhVUAGv?N zPb(=Sl92n_||;;M*+GPF+0*hlmj-4xdo37q&J~L^V)k)3QS$ zXk_%|E+wWkKlE!vW8tfUR`wI_Q0bdh8!|%FNk9mr^78WzeEy#8(T1?MCos-_x`j-6 zWaY)~0GXuoa2QSfU?2N-&C;r{pl}cKsdLLI(^=f?haIv5Qi2LvA(G(gj9$D0sA3eD zoSK`d?rcGJU(|z|n@DiOr|;_x6qM}_nwa)u#fuU591lJ2mDk=Mj`zfg*7way=Szoo znaACihw!_xaw8AH+h)A&9&+H|2@cm^{vJyZzyui9H-pUr_7U9{&AaNI1$`6yc&b73 zx^Ko(C!_@Q$ktxf7dl>{U1g=a7_^L~y7N8_px49F%R)qe#S++GCMQsA7tZ%)asZ=X zo7>=RhD3v*T<5Ry50yLgel#0h52w&YJ#1CaK7Stwu-}7i^Jf-fh?pB({1IRqvKDl_ zjDhaQfDaf3`hwZzJX?)BarTrinEmAX3ue(x2Yrxs@E^L7ASF7_VOfz$m>~k3e!g&D z(C?PCN9?<7|nHJ^!(AKBlhjTl5SIC!IwN@xo7m7->%z@jKXN-S8~kwO+n2+ z_aZt-rj=9TA@~OcEx4Iqsn-6hkJjG_Jy)2 zN6VetND8TIl<|RTUTK^XHDS4M|ADfyStK6e{GIiL0pD>36@J<(U6p`D)pL2P$L4_}zycizH^5aU6kZVhvu4`UMZPfDMIjDeW2&K|9xm*-(h$3kY8X_3{_W3Vb2dsr=?S;rsuEvZ?=!vfkpJUnn~ny@vk}l%@VxlqLHc zW&Qp_*?$!r{zZx#qwRQw0{>5xmH97}Rs9FbBIlh-{f)9;V*d$c$8*0F?u+;@t^fbR zxtvAlJdGKJv75QyT5(dqxCy!(wE#7X?W$8W-^l|E0Uo9l(VL8y`= z*c;{lL|L{T1e;N0$~vR-Vi9iOLlPIkh876dh@&k38w-f`VRQ&0k{hXndvi65Hg<3HcfXhQprme5wXAv8QMRB=iuG>joPG$$Q6fqR-Ri|D#8qz@+!Z{!v29_jvY8&Z&ZEhQU)?&P+U|H3$oO2JM4rB^gbRw!`7Uw$Nq0M$^o6mx$^s z{)=Mv$7mgD#ABuc z>xlH&Q5@Os^0=XL8nj2$nq!n0m=ROn@lOcuRmbfH9N`-e6`L4TNFqU4nkfy{#a#7? z$f9OY(~-B4aGhn97~oiNq-ebP%Bjq&i=Bm6|Lh=Itzn#ji!be53p{x1I2DwBT&54Y zlUH-6f%5#>*Mp+eaYX;|C#Z}odwYS0-y{bXKAvK)U&ixCR3#!ysl)P#0r0O#N}>QQ z`7}bicS*EcAsS4|PiO#q$rwJ*i4ej|Q1##=Y1H61E}|#Li5(E2d>w&V>z20JwRz$1 z+9jj#bv;x0+ovu*AL5phaz@e5TUVlG6z^ISpC&kz#ik$Xmq^lF8kQ@$7>2M=x<;Dw zL=)>4BXo6V;})fTUocyB%;7Ge++A0x+s!kz#K=KqT~y)fiWjZlKBWjtYsps!hMQFv zJ%{}h`9bx=M94M6a=^OGt~C1h*!Cou{ee;JE%n=v2mOOkXD)CZwucMbLq!|-;)~kX zth{<*3b)StbH}0}gBN9=Me&0e-=L<=CHUEV4(F;}_YMN6$eW0BzULjPjfSMI-A z)=;$56Il6+Wo6x(6pMl({0Eo1(gJs`uS3mX4F?Ogdco7)-| zuDPaCT1tr_HPm#8Dc96ENQxLj%|uW`%}P~5P%}Z*Jl81~;kX>F;iAzRYA9OsSgI|j z=7Uy>o1Uu+Y1jP=?)Uw$*Z$#o)?RzP-~RS~_wznjFROvIce|IpLz-|SPjZh|_p9-Y zw#t^~m961oG3%nwc+xlQ|K+`|y0y97gD&5_OY%X_oAd_MHjO{$sYBI%ftknikM*U# z(7n=UA=WhvfNcYbE1a#B2+po93(%OW`|B$F+x2R7S5yp%CQLO(rmde?6VhP?Alh-v z0!V4QYLgAEeWF}mn31X_pUO%X+Is=mJH9xX;tJ9u*wF5;x9N)wJZ4!@eB2%UrQqr` zwcg*Q3imRYH|f2cRbM=5tL~I`5}5|2e0(?iM*ha|ITXE0@%fxDe=tqsmu2SO+wV`^ z-9#K}I<(bDZS|C)Sl^XPA=Kt@Zrx$p0c?ABJa76|_U~aCtGQ-1suFiGPDnD>8Q&|Y1$%5>Sug|rs z`UJS)({AOd+aR?1_fLN7wMyetp6f$SYK#ko;qK6QqATga!FJHV%z>m#1Pd}pKeePh z(pXbRjOT`w>7N+zzb_SO@&UO^Qz9OJOmYvAii7}fhhufeF>JqW36FH`i)BA`a z>dU_lN}8{95}KY9(%g+DvW*FE`&u@zd9p*3&>kFzYj&E|`^Pjfj0efu9<;r}pIU=) z)CEbc()Z2Kc2vz0u)(KvJZ8dL%CVd#zcr$~ibS;Cd7q6(bBPn>3Kj%fRv*k)V;&8v zq9scd6j!02mhybeTNEp*vqrH+XfbQW{phPMO7CJ6tcmSbuYBVRfQi14d|(Y!9HtqZ zRS!FtyVd6SkFqI=l*{8;+rFkH#oGYd&=sUtVKIIH5O-(t=b4H-t8cm$Q z#&75*3l8IfF^-mW22Tj~)+;tpcDSFKUdjGf3yw|oOwMd})*(TV-c9O)C{aIKu=+0x zvV6*J6Q24{MKnteoxpY%!z@X9DMZNiB?Y&`J<^9cjkXnX(#7a+ZqGD9?gARVHCQ@~ z%=##sC7&h9&RjjPyLoCWjz03A$i0s9T3!A+K}@LxHJ;ku4tZh8*uA(a2sQnbmgkI! zh0Br?Mg;5rz}Ujz%AUZU*7Fbh3^vmvNa3+~V`sGik^1*wFl#+6OAp9ZXmeQfInIq|YdzV>H7 zop^Ed@%ew=g*;`)Po8P7*OV-K3(rRlhNiB1n=XTMIa+Uv^l%Mw4x%b`Z(fSQ$k*m_ z3s_91N!8$OqY*dz9RB{~&;4-Mc$%p4eA|a3Xe(}qhaUAagqJb<+b@uo(Da7XPRpAQ zbz_&3f{&8DBevNQ*QFSUoybPrKjEDvlh;9uQIi>}1m=7wtRuOxVT8#mKV+>Pm}^kR zOee$8fO}8GhcAUch0GsCfDJ{lo3-j8K&fDse5LbRp+*6HrM~07VDr1Hh#adR!3uZ< z{?c4GKXemUCp2#)tzc|3@Hme}$bQ{9g-KsquGwyI$`Tj0HG4}m_05I3dM4>6?gWxu z3=rUxf%h49VO~+W1!1yEE&E#80Cfg`@QjVMPH7fAP>4&MR>J{Nr?XuX8K$4WDjXvm$ccBpCFJOIDPWiJ&WJ}Mo| zv!5^|Zf~tmD%^ZFwg%4rh%YiPEN;*zxT|LmziwVJ6ZS}K%lORleOU)kUn2`)e(q)XJu1GpKXEoh zz|Rt#wN(2K{MI&+KfO~1Ym~sVK2xWGvt(V!|8kw8WTJEvI^ohLyTJY6Ekp^Ytb{m$ zzYsizQ`SXLQcx;RPbi8&#}udar<8C?jnWC6aP1gQp;)41pcKuVFxZhbvVTp%PbD;z zJZJOOCoEJ{k`OAYAF|h!aLNqh3BgnKGsF0{1XF@3_ZTPOZP+pR%#MQ+e|E_~L6d7- d3{H*x_y>T1(~`rCis~HsWh6)HOT@R{e*iTGZzuo& literal 0 HcmV?d00001 diff --git a/IntelFsp2WrapperPkg/Contributions.txt b/IntelFsp2WrapperPkg/Contributions.txt new file mode 100644 index 0000000000..f87cbd73c6 --- /dev/null +++ b/IntelFsp2WrapperPkg/Contributions.txt @@ -0,0 +1,218 @@ + +====================== += Code Contributions = +====================== + +To make a contribution to a TianoCore project, follow these steps. +1. Create a change description in the format specified below to + use in the source control commit log. +2. Your commit message must include your "Signed-off-by" signature, + and "Contributed-under" message. +3. Your "Contributed-under" message explicitly states that the + contribution is made under the terms of the specified + contribution agreement. Your "Contributed-under" message + must include the name of contribution agreement and version. + For example: Contributed-under: TianoCore Contribution Agreement 1.0 + The "TianoCore Contribution Agreement" is included below in + this document. +4. Submit your code to the TianoCore project using the process + that the project documents on its web page. If the process is + not documented, then submit the code on development email list + for the project. +5. It is preferred that contributions are submitted using the same + copyright license as the base project. When that is not possible, + then contributions using the following licenses can be accepted: + * BSD (2-clause): http://opensource.org/licenses/BSD-2-Clause + * BSD (3-clause): http://opensource.org/licenses/BSD-3-Clause + * MIT: http://opensource.org/licenses/MIT + * Python-2.0: http://opensource.org/licenses/Python-2.0 + * Zlib: http://opensource.org/licenses/Zlib + + Contributions of code put into the public domain can also be + accepted. + + Contributions using other licenses might be accepted, but further + review will be required. + +===================================================== += Change Description / Commit Message / Patch Email = +===================================================== + +Your change description should use the standard format for a +commit message, and must include your "Signed-off-by" signature +and the "Contributed-under" message. + +== Sample Change Description / Commit Message = + +=== Start of sample patch email message === + +From: Contributor Name +Subject: [PATCH] CodeModule: Brief-single-line-summary + +Full-commit-message + +Contributed-under: TianoCore Contribution Agreement 1.0 +Signed-off-by: Contributor Name +--- + +An extra message for the patch email which will not be considered part +of the commit message can be added here. + +Patch content inline or attached + +=== End of sample patch email message === + +=== Notes for sample patch email === + +* The first line of commit message is taken from the email's subject + line following [PATCH]. The remaining portion of the commit message + is the email's content until the '---' line. +* git format-patch is one way to create this format + +=== Definitions for sample patch email === + +* "CodeModule" is a short idenfier for the affected code. For + example MdePkg, or MdeModulePkg UsbBusDxe. +* "Brief-single-line-summary" is a short summary of the change. +* The entire first line should be less than ~70 characters. +* "Full-commit-message" a verbose multiple line comment describing + the change. Each line should be less than ~70 characters. +* "Contributed-under" explicitely states that the contribution is + made under the terms of the contribtion agreement. This + agreement is included below in this document. +* "Signed-off-by" is the contributor's signature identifying them + by their real/legal name and their email address. + +======================================== += TianoCore Contribution Agreement 1.0 = +======================================== + +INTEL CORPORATION ("INTEL") MAKES AVAILABLE SOFTWARE, DOCUMENTATION, +INFORMATION AND/OR OTHER MATERIALS FOR USE IN THE TIANOCORE OPEN SOURCE +PROJECT (COLLECTIVELY "CONTENT"). USE OF THE CONTENT IS GOVERNED BY THE +TERMS AND CONDITIONS OF THIS AGREEMENT BETWEEN YOU AND INTEL AND/OR THE +TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR +REFERENCED BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE OF THE +CONTENT IS GOVERNED BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS +OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED +BELOW. IF YOU DO NOT AGREE TO THE TERMS AND CONDITIONS OF THIS +AGREEMENT AND THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE +AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU MAY NOT +USE THE CONTENT. + +Unless otherwise indicated, all Content made available on the TianoCore +site is provided to you under the terms and conditions of the BSD +License ("BSD"). A copy of the BSD License is available at +http://opensource.org/licenses/bsd-license.php +or when applicable, in the associated License.txt file. + +Certain other content may be made available under other licenses as +indicated in or with such Content. (For example, in a License.txt file.) + +You accept and agree to the following terms and conditions for Your +present and future Contributions submitted to TianoCore site. Except +for the license granted to Intel hereunder, You reserve all right, +title, and interest in and to Your Contributions. + +== SECTION 1: Definitions == +* "You" or "Contributor" shall mean the copyright owner or legal + entity authorized by the copyright owner that is making a + Contribution hereunder. All other entities that control, are + controlled by, or are under common control with that entity are + considered to be a single Contributor. For the purposes of this + definition, "control" means (i) the power, direct or indirect, to + cause the direction or management of such entity, whether by + contract or otherwise, or (ii) ownership of fifty percent (50%) + or more of the outstanding shares, or (iii) beneficial ownership + of such entity. +* "Contribution" shall mean any original work of authorship, + including any modifications or additions to an existing work, + that is intentionally submitted by You to the TinaoCore site for + inclusion in, or documentation of, any of the Content. For the + purposes of this definition, "submitted" means any form of + electronic, verbal, or written communication sent to the + TianoCore site or its representatives, including but not limited + to communication on electronic mailing lists, source code + control systems, and issue tracking systems that are managed by, + or on behalf of, the TianoCore site for the purpose of + discussing and improving the Content, but excluding + communication that is conspicuously marked or otherwise + designated in writing by You as "Not a Contribution." + +== SECTION 2: License for Contributions == +* Contributor hereby agrees that redistribution and use of the + Contribution in source and binary forms, with or without + modification, are permitted provided that the following + conditions are met: +** Redistributions of source code must retain the Contributor's + copyright notice, this list of conditions and the following + disclaimer. +** Redistributions in binary form must reproduce the Contributor's + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. +* Disclaimer. None of the names of Contributor, Intel, or the names + of their respective contributors may be used to endorse or + promote products derived from this software without specific + prior written permission. +* Contributor grants a license (with the right to sublicense) under + claims of Contributor's patents that Contributor can license that + are infringed by the Contribution (as delivered by Contributor) to + make, use, distribute, sell, offer for sale, and import the + Contribution and derivative works thereof solely to the minimum + extent necessary for licensee to exercise the granted copyright + license; this patent license applies solely to those portions of + the Contribution that are unmodified. No hardware per se is + licensed. +* EXCEPT AS EXPRESSLY SET FORTH IN SECTION 3 BELOW, THE + CONTRIBUTION IS PROVIDED BY THE CONTRIBUTOR "AS IS" AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + CONTRIBUTOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THE + CONTRIBUTION, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + DAMAGE. + +== SECTION 3: Representations == +* You represent that You are legally entitled to grant the above + license. If your employer(s) has rights to intellectual property + that You create that includes Your Contributions, You represent + that You have received permission to make Contributions on behalf + of that employer, that Your employer has waived such rights for + Your Contributions. +* You represent that each of Your Contributions is Your original + creation (see Section 4 for submissions on behalf of others). + You represent that Your Contribution submissions include complete + details of any third-party license or other restriction + (including, but not limited to, related patents and trademarks) + of which You are personally aware and which are associated with + any part of Your Contributions. + +== SECTION 4: Third Party Contributions == +* Should You wish to submit work that is not Your original creation, + You may submit it to TianoCore site separately from any + Contribution, identifying the complete details of its source + and of any license or other restriction (including, but not + limited to, related patents, trademarks, and license agreements) + of which You are personally aware, and conspicuously marking the + work as "Submitted on behalf of a third-party: [named here]". + +== SECTION 5: Miscellaneous == +* Applicable Laws. Any claims arising under or relating to this + Agreement shall be governed by the internal substantive laws of + the State of Delaware or federal courts located in Delaware, + without regard to principles of conflict of laws. +* Language. This Agreement is in the English language only, which + language shall be controlling in all respects, and all versions + of this Agreement in any other language shall be for accommodation + only and shall not be binding. All communications and notices made + or given pursuant to this Agreement, and all documentation and + support to be provided, unless otherwise noted, shall be in the + English language. + diff --git a/IntelFsp2WrapperPkg/FspWrapperNotifyDxe/FspWrapperNotifyDxe.c b/IntelFsp2WrapperPkg/FspWrapperNotifyDxe/FspWrapperNotifyDxe.c new file mode 100644 index 0000000000..30c06b88bf --- /dev/null +++ b/IntelFsp2WrapperPkg/FspWrapperNotifyDxe/FspWrapperNotifyDxe.c @@ -0,0 +1,250 @@ +/** @file + This driver will register two callbacks to call fsp's notifies. + + Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +typedef +EFI_STATUS +(EFIAPI * ADD_PERFORMANCE_RECORDS)( + IN CONST VOID *HobStart + ); + +struct _ADD_PERFORMANCE_RECORD_PROTOCOL { + ADD_PERFORMANCE_RECORDS AddPerformanceRecords; +}; + +typedef struct _ADD_PERFORMANCE_RECORD_PROTOCOL ADD_PERFORMANCE_RECORD_PROTOCOL; + +extern EFI_GUID gAddPerfRecordProtocolGuid; +extern EFI_GUID gFspHobGuid; +extern EFI_GUID gFspApiPerformanceGuid; + +EFI_EVENT mExitBootServicesEvent = NULL; + +/** + Relocate this image under 4G memory. + + @param ImageHandle Handle of driver image. + @param SystemTable Pointer to system table. + + @retval EFI_SUCCESS Image successfully relocated. + @retval EFI_ABORTED Failed to relocate image. + +**/ +EFI_STATUS +RelocateImageUnder4GIfNeeded ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +/** + PciEnumerationComplete Protocol notification event handler. + + @param[in] Event Event whose notification function is being invoked. + @param[in] Context Pointer to the notification function's context. +**/ +VOID +EFIAPI +OnPciEnumerationComplete ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + NOTIFY_PHASE_PARAMS NotifyPhaseParams; + EFI_STATUS Status; + VOID *Interface; + + // + // Try to locate it because gEfiPciEnumerationCompleteProtocolGuid will trigger it once when registration. + // Just return if it is not found. + // + Status = gBS->LocateProtocol ( + &gEfiPciEnumerationCompleteProtocolGuid, + NULL, + &Interface + ); + if (EFI_ERROR (Status)) { + return ; + } + + NotifyPhaseParams.Phase = EnumInitPhaseAfterPciEnumeration; + PERF_START_EX(&gFspApiPerformanceGuid, "EventRec", NULL, 0, 0x6000); + Status = CallFspNotifyPhase (&NotifyPhaseParams); + PERF_END_EX(&gFspApiPerformanceGuid, "EventRec", NULL, 0, 0x607F); + if (Status != EFI_SUCCESS) { + DEBUG((DEBUG_ERROR, "FSP NotifyPhase AfterPciEnumeration failed, status: 0x%x\n", Status)); + } else { + DEBUG((DEBUG_INFO, "FSP NotifyPhase AfterPciEnumeration Success.\n")); + } +} + +/** + Notification function of EVT_GROUP_READY_TO_BOOT event group. + + This is a notification function registered on EVT_GROUP_READY_TO_BOOT event group. + When the Boot Manager is about to load and execute a boot option, it reclaims variable + storage if free size is below the threshold. + + @param[in] Event Event whose notification function is being invoked. + @param[in] Context Pointer to the notification function's context. + +**/ +VOID +EFIAPI +OnReadyToBoot ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + NOTIFY_PHASE_PARAMS NotifyPhaseParams; + EFI_STATUS Status; + ADD_PERFORMANCE_RECORD_PROTOCOL *AddPerfRecordInterface; + EFI_PEI_HOB_POINTERS Hob; + VOID **FspHobListPtr; + + gBS->CloseEvent (Event); + + NotifyPhaseParams.Phase = EnumInitPhaseReadyToBoot; + PERF_START_EX(&gFspApiPerformanceGuid, "EventRec", NULL, 0, 0x4000); + Status = CallFspNotifyPhase (&NotifyPhaseParams); + PERF_END_EX(&gFspApiPerformanceGuid, "EventRec", NULL, 0, 0x407F); + if (Status != EFI_SUCCESS) { + DEBUG((DEBUG_ERROR, "FSP NotifyPhase ReadyToBoot failed, status: 0x%x\n", Status)); + } else { + DEBUG((DEBUG_INFO, "FSP NotifyPhase ReadyToBoot Success.\n")); + } + + Status = gBS->LocateProtocol ( + &gAddPerfRecordProtocolGuid, + NULL, + (VOID**) &AddPerfRecordInterface + ); + if (EFI_ERROR (Status)) { + DEBUG((DEBUG_INFO, "gAddPerfRecordProtocolGuid - Locate protocol failed\n")); + return; + } else { + Hob.Raw = GetHobList (); + if (Hob.Raw != NULL) { + Hob.Raw = GetNextGuidHob (&gFspHobGuid, Hob.Raw); + FspHobListPtr = GET_GUID_HOB_DATA(Hob.Raw); + AddPerfRecordInterface->AddPerformanceRecords((VOID *)(UINTN)(((UINT32)(UINTN)*FspHobListPtr) & 0xFFFFFFFF)); + } + } +} + +/** + This stage is notified just before the firmware/Preboot environment transfers + management of all system resources to the OS or next level execution environment. + + @param Event Event whose notification function is being invoked. + @param Context Pointer to the notification function's context, which is + always zero in current implementation. + +**/ +VOID +EFIAPI +OnEndOfFirmware ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + NOTIFY_PHASE_PARAMS NotifyPhaseParams; + EFI_STATUS Status; + + gBS->CloseEvent (Event); + + NotifyPhaseParams.Phase = EnumInitPhaseEndOfFirmware; + PERF_START_EX(&gFspApiPerformanceGuid, "EventRec", NULL, 0, 0x2000); + Status = CallFspNotifyPhase (&NotifyPhaseParams); + PERF_END_EX(&gFspApiPerformanceGuid, "EventRec", NULL, 0, 0x207F); + if (Status != EFI_SUCCESS) { + DEBUG((DEBUG_ERROR, "FSP NotifyPhase EndOfFirmware failed, status: 0x%x\n", Status)); + } else { + DEBUG((DEBUG_INFO, "FSP NotifyPhase EndOfFirmware Success.\n")); + } +} + +/** + Main entry for the FSP DXE module. + + This routine registers two callbacks to call fsp's notifies. + + @param[in] ImageHandle The firmware allocated handle for the EFI image. + @param[in] SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The entry point is executed successfully. + @retval other Some error occurs when executing this entry point. + +**/ +EFI_STATUS +EFIAPI +FspWrapperNotifyDxeEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + EFI_EVENT ReadyToBootEvent; + VOID *Registration; + EFI_EVENT ProtocolNotifyEvent; + + // + // Load this driver's image to memory + // + Status = RelocateImageUnder4GIfNeeded (ImageHandle, SystemTable); + if (EFI_ERROR (Status)) { + return EFI_SUCCESS; + } + + ProtocolNotifyEvent = EfiCreateProtocolNotifyEvent ( + &gEfiPciEnumerationCompleteProtocolGuid, + TPL_CALLBACK, + OnPciEnumerationComplete, + NULL, + &Registration + ); + ASSERT (ProtocolNotifyEvent != NULL); + + Status = EfiCreateEventReadyToBootEx ( + TPL_CALLBACK, + OnReadyToBoot, + NULL, + &ReadyToBootEvent + ); + ASSERT_EFI_ERROR (Status); + + Status = gBS->CreateEventEx ( + EVT_NOTIFY_SIGNAL, + TPL_NOTIFY, + OnEndOfFirmware, + NULL, + &gEfiEventExitBootServicesGuid, + &mExitBootServicesEvent + ); + ASSERT_EFI_ERROR (Status); + + return EFI_SUCCESS; +} + diff --git a/IntelFsp2WrapperPkg/FspWrapperNotifyDxe/FspWrapperNotifyDxe.inf b/IntelFsp2WrapperPkg/FspWrapperNotifyDxe/FspWrapperNotifyDxe.inf new file mode 100644 index 0000000000..9d50922547 --- /dev/null +++ b/IntelFsp2WrapperPkg/FspWrapperNotifyDxe/FspWrapperNotifyDxe.inf @@ -0,0 +1,66 @@ +## @file +# FSP DXE Module +# +# This driver will register two callbacks to call fsp's notifies. +# +# Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = FspWrapperNotifyDxe + FILE_GUID = AD61999A-507E-47E6-BA28-79CC609FA1A4 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = FspWrapperNotifyDxeEntryPoint + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources] + FspWrapperNotifyDxe.c + LoadBelow4G.c + +[Packages] + MdePkg/MdePkg.dec + IntelFsp2Pkg/IntelFsp2Pkg.dec + IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec + +[LibraryClasses] + UefiDriverEntryPoint + UefiBootServicesTableLib + DebugLib + BaseMemoryLib + UefiLib + FspWrapperApiLib + PeCoffLib + CacheMaintenanceLib + DxeServicesLib + PerformanceLib + HobLib + +[Protocols] + gEfiPciEnumerationCompleteProtocolGuid ## CONSUMES + gAddPerfRecordProtocolGuid ## CONSUMES + +[Guids] + gFspApiPerformanceGuid ## CONSUMES ## GUID + gEfiEventExitBootServicesGuid ## CONSUMES ## Event + gFspHobGuid ## CONSUMES ## HOB + +[Pcd] + gFspWrapperTokenSpaceGuid.PcdFspsBaseAddress ## CONSUMES + +[Depex] + TRUE diff --git a/IntelFsp2WrapperPkg/FspWrapperNotifyDxe/LoadBelow4G.c b/IntelFsp2WrapperPkg/FspWrapperNotifyDxe/LoadBelow4G.c new file mode 100644 index 0000000000..c073703a1b --- /dev/null +++ b/IntelFsp2WrapperPkg/FspWrapperNotifyDxe/LoadBelow4G.c @@ -0,0 +1,152 @@ +/** @file + +Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.
+ +This program and the accompanying materials +are licensed and made available under the terms and conditions +of the BSD License which accompanies this distribution. The +full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** + Relocate this image under 4G memory. + + @param ImageHandle Handle of driver image. + @param SystemTable Pointer to system table. + + @retval EFI_SUCCESS Image successfully relocated. + @retval EFI_ABORTED Failed to relocate image. + +**/ +EFI_STATUS +RelocateImageUnder4GIfNeeded ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + UINT8 *Buffer; + UINTN BufferSize; + EFI_HANDLE NewImageHandle; + UINTN Pages; + EFI_PHYSICAL_ADDRESS FfsBuffer; + PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; + VOID *Interface; + + // + // If it is already <4G, no need do relocate + // + if ((UINTN)RelocateImageUnder4GIfNeeded < 0xFFFFFFFF) { + return EFI_SUCCESS; + } + + // + // If locate gEfiCallerIdGuid success, it means 2nd entry. + // + Status = gBS->LocateProtocol (&gEfiCallerIdGuid, NULL, &Interface); + if (!EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "FspNotifyDxe - 2nd entry\n")); + return EFI_SUCCESS; + } + + DEBUG ((DEBUG_INFO, "FspNotifyDxe - 1st entry\n")); + + // + // Here we install a dummy handle + // + NewImageHandle = NULL; + Status = gBS->InstallProtocolInterface ( + &NewImageHandle, + &gEfiCallerIdGuid, + EFI_NATIVE_INTERFACE, + NULL + ); + ASSERT_EFI_ERROR (Status); + + // + // Reload image itself to <4G mem + // + Status = GetSectionFromAnyFv ( + &gEfiCallerIdGuid, + EFI_SECTION_PE32, + 0, + (VOID **) &Buffer, + &BufferSize + ); + ASSERT_EFI_ERROR (Status); + ImageContext.Handle = Buffer; + ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory; + // + // Get information about the image being loaded + // + Status = PeCoffLoaderGetImageInfo (&ImageContext); + ASSERT_EFI_ERROR (Status); + if (ImageContext.SectionAlignment > EFI_PAGE_SIZE) { + Pages = EFI_SIZE_TO_PAGES ((UINTN) (ImageContext.ImageSize + ImageContext.SectionAlignment)); + } else { + Pages = EFI_SIZE_TO_PAGES ((UINTN) ImageContext.ImageSize); + } + FfsBuffer = 0xFFFFFFFF; + Status = gBS->AllocatePages ( + AllocateMaxAddress, + EfiBootServicesCode, + Pages, + &FfsBuffer + ); + ASSERT_EFI_ERROR (Status); + ImageContext.ImageAddress = (PHYSICAL_ADDRESS)(UINTN)FfsBuffer; + // + // Align buffer on section boundry + // + ImageContext.ImageAddress += ImageContext.SectionAlignment - 1; + ImageContext.ImageAddress &= ~((EFI_PHYSICAL_ADDRESS)(ImageContext.SectionAlignment - 1)); + // + // Load the image to our new buffer + // + Status = PeCoffLoaderLoadImage (&ImageContext); + ASSERT_EFI_ERROR (Status); + + // + // Relocate the image in our new buffer + // + Status = PeCoffLoaderRelocateImage (&ImageContext); + ASSERT_EFI_ERROR (Status); + + // + // Free the buffer allocated by ReadSection since the image has been relocated in the new buffer + // + gBS->FreePool (Buffer); + + // + // Flush the instruction cache so the image data is written before we execute it + // + InvalidateInstructionCacheRange ((VOID *)(UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.ImageSize); + + DEBUG ((DEBUG_INFO, "Loading driver at 0x%08x EntryPoint=0x%08x\n", (UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.EntryPoint)); + Status = ((EFI_IMAGE_ENTRY_POINT)(UINTN)(ImageContext.EntryPoint)) (NewImageHandle, gST); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Error: Image at 0x%08x start failed: %r\n", ImageContext.ImageAddress, Status)); + gBS->FreePages (FfsBuffer, Pages); + } + + // + // return error to unload >4G copy, if we already relocate itself to <4G. + // + return EFI_ALREADY_STARTED; +} diff --git a/IntelFsp2WrapperPkg/FspmWrapperPeim/FspmWrapperPeim.c b/IntelFsp2WrapperPkg/FspmWrapperPeim/FspmWrapperPeim.c new file mode 100644 index 0000000000..b1c605c80b --- /dev/null +++ b/IntelFsp2WrapperPkg/FspmWrapperPeim/FspmWrapperPeim.c @@ -0,0 +1,161 @@ +/** @file + This will be invoked only once. It will call FspMemoryInit API, + register TemporaryRamDonePpi to call TempRamExit API, and register MemoryDiscoveredPpi + notify to call FspSiliconInit API. + + Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +extern EFI_GUID gFspHobGuid; + +/** + Call FspMemoryInit API. + + @return Status returned by FspMemoryInit API. +**/ +EFI_STATUS +PeiFspMemoryInit ( + VOID + ) +{ + FSP_INFO_HEADER *FspmHeaderPtr; + EFI_STATUS Status; + UINT64 TimeStampCounterStart; + VOID *FspHobListPtr; + VOID *HobData; + FSPM_UPD_COMMON *FspmUpdDataPtr; + UINTN *SourceData; + + DEBUG ((DEBUG_INFO, "PeiFspMemoryInit enter\n")); + + FspHobListPtr = NULL; + + // + // Copy default FSP-M UPD data from Flash + // + FspmHeaderPtr = (FSP_INFO_HEADER *)FspFindFspHeader (PcdGet32 (PcdFspmBaseAddress)); + FspmUpdDataPtr = (FSPM_UPD_COMMON *)AllocateZeroPool ((UINTN)FspmHeaderPtr->CfgRegionSize); + ASSERT (FspmUpdDataPtr != NULL); + SourceData = (UINTN *)((UINTN)FspmHeaderPtr->ImageBase + (UINTN)FspmHeaderPtr->CfgRegionOffset); + CopyMem (FspmUpdDataPtr, SourceData, (UINTN)FspmHeaderPtr->CfgRegionSize); + + DEBUG ((DEBUG_INFO, "FspWrapperPlatformInitPreMem enter\n")); + UpdateFspmUpdData ((VOID *)FspmUpdDataPtr); + DEBUG ((DEBUG_INFO, " NvsBufferPtr - 0x%x\n", FspmUpdDataPtr->FspmArchUpd.NvsBufferPtr)); + DEBUG ((DEBUG_INFO, " StackBase - 0x%x\n", FspmUpdDataPtr->FspmArchUpd.StackBase)); + DEBUG ((DEBUG_INFO, " StackSize - 0x%x\n", FspmUpdDataPtr->FspmArchUpd.StackSize)); + DEBUG ((DEBUG_INFO, " BootLoaderTolumSize - 0x%x\n", FspmUpdDataPtr->FspmArchUpd.BootLoaderTolumSize)); + DEBUG ((DEBUG_INFO, " BootMode - 0x%x\n", FspmUpdDataPtr->FspmArchUpd.BootMode)); + DEBUG ((DEBUG_INFO, " HobListPtr - 0x%x\n", &FspHobListPtr)); + + TimeStampCounterStart = AsmReadTsc (); + Status = CallFspMemoryInit (FspmUpdDataPtr, &FspHobListPtr); + // Create hobs after memory initialization and not in temp RAM. Hence passing the recorded timestamp here + PERF_START_EX(&gFspApiPerformanceGuid, "EventRec", NULL, TimeStampCounterStart, 0xD000); + PERF_END_EX(&gFspApiPerformanceGuid, "EventRec", NULL, 0, 0xD07F); + DEBUG ((DEBUG_INFO, "Total time spent executing FspMemoryInitApi: %d millisecond\n", DivU64x32 (GetTimeInNanoSecond (AsmReadTsc () - TimeStampCounterStart), 1000000))); + if (EFI_ERROR(Status)) { + DEBUG ((DEBUG_ERROR, "ERROR - Failed to execute FspMemoryInitApi(), Status = %r\n", Status)); + } + DEBUG((DEBUG_INFO, "FspMemoryInit status: 0x%x\n", Status)); + ASSERT_EFI_ERROR (Status); + + + Status = TestFspMemoryInitApiOutput (FspmUpdDataPtr, &FspHobListPtr); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "ERROR - TestFspMemoryInitApiOutput () fail, Status = %r\n", Status)); + } + + DEBUG ((DEBUG_INFO, " FspHobListPtr (returned) - 0x%x\n", FspHobListPtr)); + ASSERT (FspHobListPtr != NULL); + + PostFspmHobProcess (FspHobListPtr); + + // + // FspHobList is not complete at this moment. + // Save FspHobList pointer to hob, so that it can be got later + // + HobData = BuildGuidHob ( + &gFspHobGuid, + sizeof (VOID *) + ); + ASSERT (HobData != NULL); + CopyMem (HobData, &FspHobListPtr, sizeof (FspHobListPtr)); + + return Status; +} + +/** + Do FSP initialization. + + @return FSP initialization status. +**/ +EFI_STATUS +EFIAPI +FspmWrapperInit ( + VOID + ) +{ + EFI_STATUS Status; + + Status = PeiFspMemoryInit (); + ASSERT_EFI_ERROR (Status); + + return Status; +} + +/** + This is the entrypoint of PEIM + + @param[in] FileHandle Handle of the file being invoked. + @param[in] PeiServices Describes the list of possible PEI Services. + + @retval EFI_SUCCESS if it completed successfully. +**/ +EFI_STATUS +EFIAPI +FspmWrapperPeimEntryPoint ( + IN EFI_PEI_FILE_HANDLE FileHandle, + IN CONST EFI_PEI_SERVICES **PeiServices + ) +{ + DEBUG((DEBUG_INFO, "FspmWrapperPeimEntryPoint\n")); + + FspmWrapperInit (); + + return EFI_SUCCESS; +} diff --git a/IntelFsp2WrapperPkg/FspmWrapperPeim/FspmWrapperPeim.inf b/IntelFsp2WrapperPkg/FspmWrapperPeim/FspmWrapperPeim.inf new file mode 100644 index 0000000000..df735e1065 --- /dev/null +++ b/IntelFsp2WrapperPkg/FspmWrapperPeim/FspmWrapperPeim.inf @@ -0,0 +1,77 @@ +## @file +# FSP-M wrapper PEI Module +# +# This PEIM initialize FSP. +# This will be invoked only once. It will call FspMemoryInit API, +# register TemporaryRamDonePpi to call TempRamExit API, and register MemoryDiscoveredPpi +# notify to call FspSiliconInit API. +# +# Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +[Defines] + INF_VERSION = 0x00010017 + BASE_NAME = FspmWrapperPeim + FILE_GUID = 9FAAD0FF-0E0C-4885-A738-BAB4E4FA1E66 + VERSION_STRING = 1.0 + MODULE_TYPE = PEIM + ENTRY_POINT = FspmWrapperPeimEntryPoint + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 +# + +[LibraryClasses] + PeimEntryPoint + PeiServicesLib + PeiServicesTablePointerLib + BaseLib + BaseMemoryLib + MemoryAllocationLib + DebugLib + HobLib + FspWrapperPlatformLib + FspWrapperHobProcessLib + DebugAgentLib + UefiCpuLib + PeCoffGetEntryPointLib + PeCoffExtraActionLib + PerformanceLib + TimerLib + FspWrapperApiLib + FspWrapperApiTestLib + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + UefiCpuPkg/UefiCpuPkg.dec + IntelFsp2Pkg/IntelFsp2Pkg.dec + IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec + +[Pcd] + gFspWrapperTokenSpaceGuid.PcdFspmBaseAddress ## CONSUMES + +[Sources] + FspmWrapperPeim.c + +[Ppis] + gTopOfTemporaryRamPpiGuid ## PRODUCES + gEfiEndOfPeiSignalPpiGuid ## PRODUCES + gEfiPeiMemoryDiscoveredPpiGuid ## PRODUCES + +[Guids] + gFspHobGuid ## PRODUCES ## HOB + gFspApiPerformanceGuid ## CONSUMES ## GUID + +[Depex] + gEfiPeiMasterBootModePpiGuid diff --git a/IntelFsp2WrapperPkg/FspsWrapperPeim/FspsWrapperPeim.c b/IntelFsp2WrapperPkg/FspsWrapperPeim/FspsWrapperPeim.c new file mode 100644 index 0000000000..9bc720fe2d --- /dev/null +++ b/IntelFsp2WrapperPkg/FspsWrapperPeim/FspsWrapperPeim.c @@ -0,0 +1,313 @@ +/** @file + This will be invoked only once. It will call FspMemoryInit API, + register TemporaryRamDonePpi to call TempRamExit API, and register MemoryDiscoveredPpi + notify to call FspSiliconInit API. + + Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +extern EFI_PEI_NOTIFY_DESCRIPTOR mS3EndOfPeiNotifyDesc; +extern EFI_GUID gFspHobGuid; + +/** +This function handles S3 resume task at the end of PEI + +@param[in] PeiServices Pointer to PEI Services Table. +@param[in] NotifyDesc Pointer to the descriptor for the Notification event that +caused this function to execute. +@param[in] Ppi Pointer to the PPI data associated with this function. + +@retval EFI_STATUS Always return EFI_SUCCESS +**/ +EFI_STATUS +EFIAPI +S3EndOfPeiNotify( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc, + IN VOID *Ppi + ); + +EFI_PEI_NOTIFY_DESCRIPTOR mS3EndOfPeiNotifyDesc = { + (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gEfiEndOfPeiSignalPpiGuid, + S3EndOfPeiNotify +}; + +/** +This function handles S3 resume task at the end of PEI + +@param[in] PeiServices Pointer to PEI Services Table. +@param[in] NotifyDesc Pointer to the descriptor for the Notification event that +caused this function to execute. +@param[in] Ppi Pointer to the PPI data associated with this function. + +@retval EFI_STATUS Always return EFI_SUCCESS +**/ +EFI_STATUS +EFIAPI +S3EndOfPeiNotify( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc, + IN VOID *Ppi + ) +{ + NOTIFY_PHASE_PARAMS NotifyPhaseParams; + EFI_STATUS Status; + + DEBUG((DEBUG_INFO, "S3EndOfPeiNotify enter\n")); + + NotifyPhaseParams.Phase = EnumInitPhaseAfterPciEnumeration; + Status = CallFspNotifyPhase (&NotifyPhaseParams); + DEBUG((DEBUG_INFO, "FSP S3NotifyPhase AfterPciEnumeration status: 0x%x\n", Status)); + + NotifyPhaseParams.Phase = EnumInitPhaseReadyToBoot; + Status = CallFspNotifyPhase (&NotifyPhaseParams); + DEBUG((DEBUG_INFO, "FSP S3NotifyPhase ReadyToBoot status: 0x%x\n", Status)); + + NotifyPhaseParams.Phase = EnumInitPhaseEndOfFirmware; + Status = CallFspNotifyPhase (&NotifyPhaseParams); + DEBUG((DEBUG_INFO, "FSP S3NotifyPhase EndOfFirmware status: 0x%x\n", Status)); + + return EFI_SUCCESS; +} + +/** +Return Hob list produced by FSP. + +@param[in] PeiServices The pointer to the PEI Services Table. +@param[in] This The pointer to this instance of this PPI. +@param[out] FspHobList The pointer to Hob list produced by FSP. + +@return EFI_SUCCESS FReturn Hob list produced by FSP successfully. +**/ +EFI_STATUS +EFIAPI +FspSiliconInitDoneGetFspHobList ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN FSP_SILICON_INIT_DONE_PPI *This, + OUT VOID **FspHobList + ); + +FSP_SILICON_INIT_DONE_PPI mFspSiliconInitDonePpi = { + FspSiliconInitDoneGetFspHobList +}; + +EFI_PEI_PPI_DESCRIPTOR mPeiFspSiliconInitDonePpi = { + EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST, + &gFspSiliconInitDonePpiGuid, + &mFspSiliconInitDonePpi +}; + +/** +Return Hob list produced by FSP. + +@param[in] PeiServices The pointer to the PEI Services Table. +@param[in] This The pointer to this instance of this PPI. +@param[out] FspHobList The pointer to Hob list produced by FSP. + +@return EFI_SUCCESS FReturn Hob list produced by FSP successfully. +**/ +EFI_STATUS +EFIAPI +FspSiliconInitDoneGetFspHobList ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN FSP_SILICON_INIT_DONE_PPI *This, + OUT VOID **FspHobList + ) +{ + EFI_HOB_GUID_TYPE *GuidHob; + + GuidHob = GetFirstGuidHob (&gFspHobGuid); + if (GuidHob != NULL) { + *FspHobList = *(VOID **)GET_GUID_HOB_DATA(GuidHob); + return EFI_SUCCESS; + } else { + return EFI_NOT_FOUND; + } +} + +/** + This function is called after PEI core discover memory and finish migration. + + @param[in] PeiServices Pointer to PEI Services Table. + @param[in] NotifyDesc Pointer to the descriptor for the Notification event that + caused this function to execute. + @param[in] Ppi Pointer to the PPI data associated with this function. + + @retval EFI_STATUS Always return EFI_SUCCESS +**/ +EFI_STATUS +EFIAPI +PeiMemoryDiscoveredNotify ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc, + IN VOID *Ppi + ); + +EFI_PEI_NOTIFY_DESCRIPTOR mPeiMemoryDiscoveredNotifyDesc = { + (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gEfiPeiMemoryDiscoveredPpiGuid, + PeiMemoryDiscoveredNotify +}; + +/** +This function is called after PEI core discover memory and finish migration. + +@param[in] PeiServices Pointer to PEI Services Table. +@param[in] NotifyDesc Pointer to the descriptor for the Notification event that +caused this function to execute. +@param[in] Ppi Pointer to the PPI data associated with this function. + +@retval EFI_STATUS Always return EFI_SUCCESS +**/ +EFI_STATUS +EFIAPI +PeiMemoryDiscoveredNotify ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc, + IN VOID *Ppi + ) +{ + FSP_INFO_HEADER *FspsHeaderPtr; + UINT64 TimeStampCounterStart; + EFI_STATUS Status; + VOID *FspHobListPtr; + EFI_HOB_GUID_TYPE *GuidHob; + FSPS_UPD_COMMON *FspsUpdDataPtr; + UINTN *SourceData; + + + DEBUG ((DEBUG_INFO, "PeiMemoryDiscoveredNotify enter\n")); + + // + // Copy default FSP-S UPD data from Flash + // + FspsHeaderPtr = (FSP_INFO_HEADER *)FspFindFspHeader (PcdGet32 (PcdFspsBaseAddress)); + FspsUpdDataPtr = (FSPS_UPD_COMMON *)AllocateZeroPool ((UINTN)FspsHeaderPtr->CfgRegionSize); + ASSERT (FspsUpdDataPtr != NULL); + SourceData = (UINTN *)((UINTN)FspsHeaderPtr->ImageBase + (UINTN)FspsHeaderPtr->CfgRegionOffset); + CopyMem (FspsUpdDataPtr, SourceData, (UINTN)FspsHeaderPtr->CfgRegionSize); + + UpdateFspsUpdData ((VOID *)FspsUpdDataPtr); + + TimeStampCounterStart = AsmReadTsc (); + PERF_START_EX(&gFspApiPerformanceGuid, "EventRec", NULL, 0, 0x9000); + Status = CallFspSiliconInit ((VOID *)FspsUpdDataPtr); + PERF_END_EX(&gFspApiPerformanceGuid, "EventRec", NULL, 0, 0x907F); + DEBUG ((DEBUG_INFO, "Total time spent executing FspSiliconInitApi: %d millisecond\n", DivU64x32 (GetTimeInNanoSecond (AsmReadTsc () - TimeStampCounterStart), 1000000))); + if (EFI_ERROR(Status)) { + DEBUG ((DEBUG_ERROR, "ERROR - Failed to execute FspSiliconInitApi(), Status = %r\n", Status)); + } + DEBUG((DEBUG_INFO, "FspSiliconInit status: 0x%x\n", Status)); + ASSERT_EFI_ERROR (Status); + + Status = TestFspSiliconInitApiOutput ((VOID *)NULL); + if (RETURN_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "ERROR - TestFspSiliconInitApiOutput () fail, Status = %r\n", Status)); + } + + // + // Now FspHobList complete, process it + // + GuidHob = GetFirstGuidHob (&gFspHobGuid); + ASSERT (GuidHob != NULL); + FspHobListPtr = *(VOID **)GET_GUID_HOB_DATA (GuidHob); + DEBUG ((DEBUG_INFO, "FspHobListPtr - 0x%x\n", FspHobListPtr)); + PostFspsHobProcess (FspHobListPtr); + + // + // Install FspSiliconInitDonePpi so that any other driver can consume this info. + // + Status = PeiServicesInstallPpi (&mPeiFspSiliconInitDonePpi); + ASSERT_EFI_ERROR(Status); + + return Status; +} + +/** + Do FSP initialization. + + @return FSP initialization status. +**/ +EFI_STATUS +FspsWrapperInit ( + VOID + ) +{ + EFI_STATUS Status; + EFI_BOOT_MODE BootMode; + + // + // Register MemoryDiscovered Nofity to run FspSiliconInit + // + Status = PeiServicesNotifyPpi (&mPeiMemoryDiscoveredNotifyDesc); + ASSERT_EFI_ERROR (Status); + + // + // Register EndOfPei Notify for S3 to run FSP NotifyPhase + // + PeiServicesGetBootMode (&BootMode); + if (BootMode == BOOT_ON_S3_RESUME) { + Status = PeiServicesNotifyPpi (&mS3EndOfPeiNotifyDesc); + ASSERT_EFI_ERROR (Status); + } + + return EFI_SUCCESS; +} + +/** + This is the entrypoint of PEIM + + @param[in] FileHandle Handle of the file being invoked. + @param[in] PeiServices Describes the list of possible PEI Services. + + @retval EFI_SUCCESS if it completed successfully. +**/ +EFI_STATUS +EFIAPI +FspsWrapperPeimEntryPoint ( + IN EFI_PEI_FILE_HANDLE FileHandle, + IN CONST EFI_PEI_SERVICES **PeiServices + ) +{ + + DEBUG ((DEBUG_INFO, "FspsWrapperPeimEntryPoint\n")); + + FspsWrapperInit (); + + return EFI_SUCCESS; +} diff --git a/IntelFsp2WrapperPkg/FspsWrapperPeim/FspsWrapperPeim.inf b/IntelFsp2WrapperPkg/FspsWrapperPeim/FspsWrapperPeim.inf new file mode 100644 index 0000000000..05914f3849 --- /dev/null +++ b/IntelFsp2WrapperPkg/FspsWrapperPeim/FspsWrapperPeim.inf @@ -0,0 +1,79 @@ +## @file +# FSP-S wrapper PEI Module +# +# This PEIM initialize FSP. +# This will be invoked only once. It will call FspMemoryInit API, +# register TemporaryRamDonePpi to call TempRamExit API, and register MemoryDiscoveredPpi +# notify to call FspSiliconInit API. +# +# Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +[Defines] + INF_VERSION = 0x00010017 + BASE_NAME = FspsWrapperPeim + FILE_GUID = 0D244DF9-6CE3-4133-A1CF-53200AB663AC + VERSION_STRING = 1.0 + MODULE_TYPE = PEIM + ENTRY_POINT = FspsWrapperPeimEntryPoint + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 +# + +[LibraryClasses] + PeimEntryPoint + PeiServicesLib + PeiServicesTablePointerLib + BaseLib + BaseMemoryLib + TimerLib + DebugLib + HobLib + MemoryAllocationLib + FspWrapperPlatformLib + FspWrapperHobProcessLib + DebugAgentLib + UefiCpuLib + PeCoffGetEntryPointLib + PeCoffExtraActionLib + PerformanceLib + FspWrapperApiLib + FspWrapperApiTestLib + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + UefiCpuPkg/UefiCpuPkg.dec + IntelFsp2Pkg/IntelFsp2Pkg.dec + IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec + +[Ppis] + gTopOfTemporaryRamPpiGuid ## PRODUCES + gFspSiliconInitDonePpiGuid ## PRODUCES + gEfiEndOfPeiSignalPpiGuid ## PRODUCES + gEfiTemporaryRamDonePpiGuid ## PRODUCES + gEfiPeiMemoryDiscoveredPpiGuid ## PRODUCES + +[Pcd] + gFspWrapperTokenSpaceGuid.PcdFspsBaseAddress ## CONSUMES + +[Guids] + gFspHobGuid ## CONSUMES ## HOB + gFspApiPerformanceGuid ## CONSUMES ## GUID + +[Sources] + FspsWrapperPeim.c + +[Depex] + gEfiPeiMemoryDiscoveredPpiGuid diff --git a/IntelFsp2WrapperPkg/Include/Library/FspWrapperApiLib.h b/IntelFsp2WrapperPkg/Include/Library/FspWrapperApiLib.h new file mode 100644 index 0000000000..807fb03d32 --- /dev/null +++ b/IntelFsp2WrapperPkg/Include/Library/FspWrapperApiLib.h @@ -0,0 +1,87 @@ +/** @file + Provide FSP wrapper API related function. + + Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef __FSP_WRAPPER_API_LIB_H__ +#define __FSP_WRAPPER_API_LIB_H__ + +#include + +/** + Find FSP header pointer. + + @param[in] FlashFvFspBase Flash address of FSP FV. + + @return FSP header pointer. +**/ +FSP_INFO_HEADER * +EFIAPI +FspFindFspHeader ( + IN EFI_PHYSICAL_ADDRESS FlashFvFspBase + ); + +/** + Call FSP API - FspNotifyPhase. + + @param[in] NotifyPhaseParams Address pointer to the NOTIFY_PHASE_PARAMS structure. + + @return EFI status returned by FspNotifyPhase API. +**/ +EFI_STATUS +EFIAPI +CallFspNotifyPhase ( + IN NOTIFY_PHASE_PARAMS *NotifyPhaseParams + ); + +/** + Call FSP API - FspMemoryInit. + + @param[in] FspmUpdDataPtr Pointer to the FSPM_UPD data sructure. + @param[out] HobListPtr Pointer to receive the address of the HOB list. + + @return EFI status returned by FspMemoryInit API. +**/ +EFI_STATUS +EFIAPI +CallFspMemoryInit ( + IN VOID *FspmUpdDataPtr, + OUT VOID **HobListPtr + ); + +/** + Call FSP API - TempRamExit. + + @param[in] TempRamExitParam Address pointer to the TempRamExit parameters structure. + + @return EFI status returned by TempRamExit API. +**/ +EFI_STATUS +EFIAPI +CallTempRamExit ( + IN VOID *TempRamExitParam + ); + +/** + Call FSP API - FspSiliconInit. + + @param[in] FspsUpdDataPtr Pointer to the FSPS_UPD data structure. + + @return EFI status returned by FspSiliconInit API. +**/ +EFI_STATUS +EFIAPI +CallFspSiliconInit ( + IN VOID *FspsUpdDataPtr + ); + +#endif diff --git a/IntelFsp2WrapperPkg/Include/Library/FspWrapperApiTestLib.h b/IntelFsp2WrapperPkg/Include/Library/FspWrapperApiTestLib.h new file mode 100644 index 0000000000..a8f54afd72 --- /dev/null +++ b/IntelFsp2WrapperPkg/Include/Library/FspWrapperApiTestLib.h @@ -0,0 +1,61 @@ +/** @file + Provide FSP wrapper API test related function. + + Copyright (c) 2016, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef __FSP_WRAPPER_API_TEST_LIB_H__ +#define __FSP_WRAPPER_API_TEST_LIB_H__ + +#include + +/** + Test the output of FSP API - FspMemoryInit. + + @param[in] FspmUpdDataPtr Address pointer to the FSP_MEMORY_INIT_PARAMS structure. + @param[in] HobListPtr Address of the HobList pointer. + + @return test result on output of FspMemoryInit API. +**/ +EFI_STATUS +EFIAPI +TestFspMemoryInitApiOutput ( + IN VOID *FspmUpdDataPtr, + IN VOID **HobListPtr + ); + +/** + Test the output of FSP API - TempRamExit. + + @param[in] TempRamExitParam Address pointer to the TempRamExit parameters structure. + + @return test result on output of TempRamExit API. +**/ +EFI_STATUS +EFIAPI +TestFspTempRamExitApiOutput ( + IN VOID *TempRamExitParam + ); + +/** + Test the output of FSP API - FspSiliconInit. + + @param[in] FspsUpdDataPtr Address pointer to the Silicon Init parameters structure. + + @return test result on output of FspSiliconInit API. +**/ +EFI_STATUS +EFIAPI +TestFspSiliconInitApiOutput ( + IN VOID *FspsUpdDataPtr + ); + +#endif diff --git a/IntelFsp2WrapperPkg/Include/Library/FspWrapperHobProcessLib.h b/IntelFsp2WrapperPkg/Include/Library/FspWrapperHobProcessLib.h new file mode 100644 index 0000000000..8b1e7efdd5 --- /dev/null +++ b/IntelFsp2WrapperPkg/Include/Library/FspWrapperHobProcessLib.h @@ -0,0 +1,44 @@ +/** @file + Provide FSP wrapper hob process related function. + + Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef __FSP_WRAPPER_HOB_PROCESS_LIB_H__ +#define __FSP_WRAPPER_HOB_PROCESS_LIB_H__ + +/** + Post FSP-M HOB process for Memory Resource Descriptor. + + @param[in] FspHobList Pointer to the HOB data structure produced by FSP. + + @return If platform process the FSP hob list successfully. +**/ +EFI_STATUS +EFIAPI +PostFspmHobProcess ( + IN VOID *FspHobList + ); + +/** + Post FSP-S HOB process (not Memory Resource Descriptor). + + @param[in] FspHobList Pointer to the HOB data structure produced by FSP. + + @return If platform process the FSP hob list successfully. +**/ +EFI_STATUS +EFIAPI +PostFspsHobProcess ( + IN VOID *FspHobList + ); + +#endif diff --git a/IntelFsp2WrapperPkg/Include/Library/FspWrapperPlatformLib.h b/IntelFsp2WrapperPkg/Include/Library/FspWrapperPlatformLib.h new file mode 100644 index 0000000000..30dc8df5da --- /dev/null +++ b/IntelFsp2WrapperPkg/Include/Library/FspWrapperPlatformLib.h @@ -0,0 +1,73 @@ +/** @file + Provide FSP wrapper platform related function. + + Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef __FSP_WRAPPER_PLATFORM_LIB_H__ +#define __FSP_WRAPPER_PLATFORM_LIB_H__ + +/** + This function overrides the default configurations in the FSP-M UPD data region. + + @param[in,out] FspUpdRgnPtr A pointer to the UPD data region data strcture. + +**/ +VOID +EFIAPI +UpdateFspmUpdData ( + IN OUT VOID *FspUpdRgnPtr + ); + +/** + This function overrides the default configurations in the FSP-S UPD data region. + + @param[in,out] FspUpdRgnPtr A pointer to the UPD data region data strcture. + +**/ +VOID +EFIAPI +UpdateFspsUpdData ( + IN OUT VOID *FspUpdRgnPtr + ); + +/** + Update TempRamExit parameter. + + @note At this point, memory is ready, PeiServices are available to use. + + @return TempRamExit parameter. +**/ +VOID * +EFIAPI +UpdateTempRamExitParam ( + VOID + ); + +/** + Get S3 PEI memory information. + + @note At this point, memory is ready, and PeiServices are available to use. + Platform can get some data from SMRAM directly. + + @param[out] S3PeiMemSize PEI memory size to be installed in S3 phase. + @param[out] S3PeiMemBase PEI memory base to be installed in S3 phase. + + @return If S3 PEI memory information is got successfully. +**/ +EFI_STATUS +EFIAPI +GetS3MemoryInfo ( + OUT UINT64 *S3PeiMemSize, + OUT EFI_PHYSICAL_ADDRESS *S3PeiMemBase + ); + +#endif diff --git a/IntelFsp2WrapperPkg/Include/Ppi/FspSiliconInitDone.h b/IntelFsp2WrapperPkg/Include/Ppi/FspSiliconInitDone.h new file mode 100644 index 0000000000..4f3d8ad82f --- /dev/null +++ b/IntelFsp2WrapperPkg/Include/Ppi/FspSiliconInitDone.h @@ -0,0 +1,43 @@ +/** @file + Provides the services to return FSP hob list. + + Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef _FSP_SILICON_INIT_DONE_H_ +#define _FSP_SILICON_INIT_DONE_H_ + +typedef struct _FSP_SILICON_INIT_DONE_PPI FSP_SILICON_INIT_DONE_PPI; + +/** + Return Hob list produced by FSP. + + @param[in] PeiServices The pointer to the PEI Services Table. + @param[in] This The pointer to this instance of this PPI. + @param[out] FspHobList The pointer to Hob list produced by FSP. + + @return EFI_SUCCESS FReturn Hob list produced by FSP successfully. +**/ +typedef +EFI_STATUS +(EFIAPI *FSP_SILICON_INIT_DONE_GET_FSP_HOB_LIST)( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN FSP_SILICON_INIT_DONE_PPI *This, + OUT VOID **FspHobList + ); + +struct _FSP_SILICON_INIT_DONE_PPI { + FSP_SILICON_INIT_DONE_GET_FSP_HOB_LIST GetFspHobList; +}; + +extern EFI_GUID gFspSiliconInitDonePpiGuid; + +#endif diff --git a/IntelFsp2WrapperPkg/Include/Ppi/TopOfTemporaryRam.h b/IntelFsp2WrapperPkg/Include/Ppi/TopOfTemporaryRam.h new file mode 100644 index 0000000000..c25c4fa802 --- /dev/null +++ b/IntelFsp2WrapperPkg/Include/Ppi/TopOfTemporaryRam.h @@ -0,0 +1,20 @@ +/** @file + Provides the pointer to top of temporary ram. + + Copyright (c) 2014, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef _TOP_OF_TEMPORARY_RAM_H_ +#define _TOP_OF_TEMPORARY_RAM_H_ + +extern EFI_GUID gTopOfTemporaryRamPpiGuid; + +#endif diff --git a/IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec b/IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec new file mode 100644 index 0000000000..b76e611150 --- /dev/null +++ b/IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec @@ -0,0 +1,77 @@ +## @file +# Provides drivers and definitions to support fsp in EDKII bios. +# +# Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+# This program and the accompanying materials are licensed and made available under +# the terms and conditions of the BSD License that accompanies this distribution. +# The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +[Defines] + DEC_SPECIFICATION = 0x00010005 + PACKAGE_NAME = IntelFsp2WrapperPkg + PACKAGE_GUID = FAFE06D4-7245-42D7-9FD2-E5D5E36AB0A0 + PACKAGE_VERSION = 0.1 + +[Includes] + Include + +[LibraryClasses] + ## @libraryclass Provide FSP API related function. + FspWrapperApiLib|Include/Library/FspWrapperApiLib.h + FspWrapperApiTestLib|Include/Library/FspWrapperApiTestLib.h + + ## @libraryclass Provide FSP hob process related function. + FspWrapperHobProcessLib|Include/Library/FspWrapperHobProcessLib.h + + ## @libraryclass Provide FSP platform related function. + FspWrapperPlatformLib|Include/Library/FspWrapperPlatformLib.h + +[Guids] + # + # GUID defined in package + # + gFspWrapperTokenSpaceGuid = { 0xa34cf082, 0xf50, 0x4f0d, { 0x89, 0x8a, 0x3d, 0x39, 0x30, 0x2b, 0xc5, 0x1e } } + gFspApiPerformanceGuid = { 0xc9122295, 0x56ed, 0x4d4e, { 0x06, 0xa6, 0x50, 0x8d, 0x89, 0x4d, 0x3e, 0x40 } } + gFspHobGuid = { 0x6d86fb36, 0xba90, 0x472c, { 0xb5, 0x83, 0x3f, 0xbe, 0xd3, 0xfb, 0x20, 0x9a } } + +[Ppis] + gFspSiliconInitDonePpiGuid = { 0x4eb6e09c, 0xd256, 0x4e1e, { 0xb5, 0x0a, 0x87, 0x4b, 0xd2, 0x84, 0xb3, 0xde } } + gTopOfTemporaryRamPpiGuid = { 0x2f3962b2, 0x57c5, 0x44ec, { 0x9e, 0xfc, 0xa6, 0x9f, 0xd3, 0x02, 0x03, 0x2b } } + +[Protocols] + gAddPerfRecordProtocolGuid = { 0xc4a58d6d, 0x3677, 0x49cb, { 0xa0, 0x0a, 0x94, 0x70, 0x76, 0x5f, 0xb5, 0x5e } } + +################################################################################ +# +# PCD Declarations section - list of all PCDs Declared by this Package +# Only this package should be providing the +# declaration, other packages should not. +# +################################################################################ +[PcdsFixedAtBuild, PcdsPatchableInModule] + ## Provides the memory mapped base address of the BIOS CodeCache Flash Device. + gFspWrapperTokenSpaceGuid.PcdFlashCodeCacheAddress|0xFFE00000|UINT32|0x10000001 + ## Provides the size of the BIOS Flash Device. + gFspWrapperTokenSpaceGuid.PcdFlashCodeCacheSize|0x00200000|UINT32|0x10000002 + + ## Indicates the base address of the first Microcode Patch in the Microcode Region + gFspWrapperTokenSpaceGuid.PcdCpuMicrocodePatchAddress|0x0|UINT64|0x10000005 + gFspWrapperTokenSpaceGuid.PcdCpuMicrocodePatchRegionSize|0x0|UINT64|0x10000006 + ## Indicates the offset of the Cpu Microcode. + gFspWrapperTokenSpaceGuid.PcdFlashMicrocodeOffset|0x90|UINT32|0x10000007 + + ## Indicate the PEI memory size platform want to report + gFspWrapperTokenSpaceGuid.PcdPeiMinMemSize|0x1800000|UINT32|0x40000004 + ## Indicate the PEI memory size platform want to report + gFspWrapperTokenSpaceGuid.PcdPeiRecoveryMinMemSize|0x3000000|UINT32|0x40000005 + + ## This is the base address of FSP-T/M/S + gFspWrapperTokenSpaceGuid.PcdFsptBaseAddress|0x00000000|UINT32|0x00000300 + gFspWrapperTokenSpaceGuid.PcdFspmBaseAddress|0x00000000|UINT32|0x00000301 + gFspWrapperTokenSpaceGuid.PcdFspsBaseAddress|0x00000000|UINT32|0x00000302 diff --git a/IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dsc b/IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dsc new file mode 100644 index 0000000000..70541c8d20 --- /dev/null +++ b/IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dsc @@ -0,0 +1,87 @@ +## @file +# Provides drivers and definitions to support fsp in EDKII bios. +# +# Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+# This program and the accompanying materials are licensed and made available under +# the terms and conditions of the BSD License that accompanies this distribution. +# The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +[Defines] + PLATFORM_NAME = IntelFsp2WrapperPkg + PLATFORM_GUID = 34813E26-C930-427D-8993-80530549EADA + PLATFORM_VERSION = 0.1 + DSC_SPECIFICATION = 0x00010005 + OUTPUT_DIRECTORY = Build/IntelFsp2WrapperPkg + SUPPORTED_ARCHITECTURES = IA32|X64 + BUILD_TARGETS = DEBUG|RELEASE|NOOPT + SKUID_IDENTIFIER = DEFAULT + +[LibraryClasses] + BaseLib|MdePkg/Library/BaseLib/BaseLib.inf + BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf + PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf + PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf + DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf + DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf + PciCf8Lib|MdePkg/Library/BasePciCf8Lib/BasePciCf8Lib.inf + IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf + PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf + PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf + PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf + CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf + + PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf + SerialPortLib|MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.inf + ReportStatusCodeLib|MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.inf + TimerLib|MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplate.inf + + # MdeModulePkg + DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf + + # UefiCpuPkg + UefiCpuLib|UefiCpuPkg/Library/BaseUefiCpuLib/BaseUefiCpuLib.inf + LocalApicLib|UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.inf + + # FSP Wrapper Lib + FspWrapperApiLib|IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/BaseFspWrapperApiLib.inf + FspWrapperApiTestLib|IntelFsp2WrapperPkg/Library/BaseFspWrapperApiTestLibNull/BaseFspWrapperApiTestLibNull.inf + + # FSP platform sample + FspWrapperPlatformLib|IntelFsp2WrapperPkg/Library/BaseFspWrapperPlatformLibSample/BaseFspWrapperPlatformLibSample.inf + PlatformSecLib|IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/SecFspWrapperPlatformSecLibSample.inf + FspWrapperHobProcessLib|IntelFsp2WrapperPkg/Library/PeiFspWrapperHobProcessLibSample/PeiFspWrapperHobProcessLibSample.inf + +[LibraryClasses.common.PEIM,LibraryClasses.common.PEI_CORE] + PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf + PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf + PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf + MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf + HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf + +[LibraryClasses.common.DXE_DRIVER] + UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf + UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf + UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf + DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf + UefiLib|MdePkg/Library/UefiLib/UefiLib.inf + MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf + DevicePathLib|MdePkg/Library/UefiDevicePathLibDevicePathProtocol/UefiDevicePathLibDevicePathProtocol.inf + HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf + +[Components.Ia32] + IntelFsp2WrapperPkg/FspmWrapperPeim/FspmWrapperPeim.inf + IntelFsp2WrapperPkg/FspsWrapperPeim/FspsWrapperPeim.inf + +[Components.IA32, Components.X64] + IntelFsp2WrapperPkg/FspWrapperNotifyDxe/FspWrapperNotifyDxe.inf + +[PcdsFixedAtBuild.common] + gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x1f + gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80080046 + gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x07 diff --git a/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/BaseFspWrapperApiLib.inf b/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/BaseFspWrapperApiLib.inf new file mode 100644 index 0000000000..b1a9f38f4e --- /dev/null +++ b/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/BaseFspWrapperApiLib.inf @@ -0,0 +1,71 @@ +## @file +# Provide FSP API related function. +# +# Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +################################################################################ +# +# Defines Section - statements that will be processed to create a Makefile. +# +################################################################################ +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = BaseFspWrapperApiLib + FILE_GUID = F42C789F-4D66-49AF-8C73-1AADC00437AC + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = FspWrapperApiLib + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +################################################################################ +# +# Sources Section - list of files that are required for the build to succeed. +# +################################################################################ + +[Sources] + FspWrapperApiLib.c + +[Sources.IA32] + IA32/DispatchExecute.c + +[Sources.X64] + X64/DispatchExecute.c + X64/Thunk64To32.asm + X64/Thunk64To32.S + +################################################################################ +# +# Package Dependency Section - list of Package files that are required for +# this module. +# +################################################################################ + +[Packages] + MdePkg/MdePkg.dec + IntelFsp2Pkg/IntelFsp2Pkg.dec + IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec + +[LibraryClasses] + BaseLib + +[Guids] + gFspHeaderFileGuid ## CONSUMES ## GUID + +[Pcd] + gFspWrapperTokenSpaceGuid.PcdFspmBaseAddress ## CONSUMES + gFspWrapperTokenSpaceGuid.PcdFspsBaseAddress ## CONSUMES diff --git a/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/FspWrapperApiLib.c b/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/FspWrapperApiLib.c new file mode 100644 index 0000000000..8cf136fe1a --- /dev/null +++ b/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/FspWrapperApiLib.c @@ -0,0 +1,203 @@ +/** @file + Provide FSP API related function. + + Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include + +#include +#include +#include + +/** + Wrapper for a thunk to transition from long mode to compatibility mode to execute 32-bit code and then transit back to + long mode. + + @param[in] Function The 32bit code entry to be executed. + @param[in] Param1 The first parameter to pass to 32bit code. + @param[in] Param2 The second parameter to pass to 32bit code. + + @return EFI_STATUS. +**/ +EFI_STATUS +Execute32BitCode ( + IN UINT64 Function, + IN UINT64 Param1, + IN UINT64 Param2 + ); + +/** + Find FSP header pointer. + + @param[in] FlashFvFspBase Flash address of FSP FV. + + @return FSP header pointer. +**/ +FSP_INFO_HEADER * +EFIAPI +FspFindFspHeader ( + IN EFI_PHYSICAL_ADDRESS FlashFvFspBase + ) +{ + UINT8 *CheckPointer; + + CheckPointer = (UINT8 *) (UINTN) FlashFvFspBase; + + if (((EFI_FIRMWARE_VOLUME_HEADER *)CheckPointer)->Signature != EFI_FVH_SIGNATURE) { + return NULL; + } + + if (((EFI_FIRMWARE_VOLUME_HEADER *)CheckPointer)->ExtHeaderOffset != 0) { + CheckPointer = CheckPointer + ((EFI_FIRMWARE_VOLUME_HEADER *)CheckPointer)->ExtHeaderOffset; + CheckPointer = CheckPointer + ((EFI_FIRMWARE_VOLUME_EXT_HEADER *)CheckPointer)->ExtHeaderSize; + CheckPointer = (UINT8 *) ALIGN_POINTER (CheckPointer, 8); + } else { + CheckPointer = CheckPointer + ((EFI_FIRMWARE_VOLUME_HEADER *)CheckPointer)->HeaderLength; + } + + + CheckPointer = CheckPointer + sizeof (EFI_FFS_FILE_HEADER); + + if (((EFI_RAW_SECTION *)CheckPointer)->Type != EFI_SECTION_RAW) { + return NULL; + } + + CheckPointer = CheckPointer + sizeof (EFI_RAW_SECTION); + + return (FSP_INFO_HEADER *)CheckPointer; +} + +/** + Call FSP API - FspNotifyPhase. + + @param[in] NotifyPhaseParams Address pointer to the NOTIFY_PHASE_PARAMS structure. + + @return EFI status returned by FspNotifyPhase API. +**/ +EFI_STATUS +EFIAPI +CallFspNotifyPhase ( + IN NOTIFY_PHASE_PARAMS *NotifyPhaseParams + ) +{ + FSP_INFO_HEADER *FspHeader; + FSP_NOTIFY_PHASE NotifyPhaseApi; + EFI_STATUS Status; + BOOLEAN InterruptState; + + FspHeader = (FSP_INFO_HEADER *)FspFindFspHeader (PcdGet32 (PcdFspsBaseAddress)); + if (FspHeader == NULL) { + return EFI_DEVICE_ERROR; + } + + NotifyPhaseApi = (FSP_NOTIFY_PHASE)(UINTN)(FspHeader->ImageBase + FspHeader->NotifyPhaseEntryOffset); + InterruptState = SaveAndDisableInterrupts (); + Status = Execute32BitCode ((UINTN)NotifyPhaseApi, (UINTN)NotifyPhaseParams, (UINTN)NULL); + SetInterruptState (InterruptState); + + return Status; +} + +/** + Call FSP API - FspMemoryInit. + + @param[in] FspmUpdDataPtr Address pointer to the FSP_MEMORY_INIT_PARAMS structure. + @param[out] HobListPtr Address of the HobList pointer. + + @return EFI status returned by FspMemoryInit API. +**/ +EFI_STATUS +EFIAPI +CallFspMemoryInit ( + IN VOID *FspmUpdDataPtr, + OUT VOID **HobListPtr + ) +{ + FSP_INFO_HEADER *FspHeader; + FSP_MEMORY_INIT FspMemoryInitApi; + EFI_STATUS Status; + BOOLEAN InterruptState; + + FspHeader = (FSP_INFO_HEADER *)FspFindFspHeader (PcdGet32 (PcdFspmBaseAddress)); + if (FspHeader == NULL) { + return EFI_DEVICE_ERROR; + } + + FspMemoryInitApi = (FSP_MEMORY_INIT)(UINTN)(FspHeader->ImageBase + FspHeader->FspMemoryInitEntryOffset); + InterruptState = SaveAndDisableInterrupts (); + Status = Execute32BitCode ((UINTN)FspMemoryInitApi, (UINTN)FspmUpdDataPtr, (UINTN)HobListPtr); + SetInterruptState (InterruptState); + + return Status; +} + +/** + Call FSP API - TempRamExit. + + @param[in] TempRamExitParam Address pointer to the TempRamExit parameters structure. + + @return EFI status returned by TempRamExit API. +**/ +EFI_STATUS +EFIAPI +CallTempRamExit ( + IN VOID *TempRamExitParam + ) +{ + FSP_INFO_HEADER *FspHeader; + FSP_TEMP_RAM_EXIT TempRamExitApi; + EFI_STATUS Status; + BOOLEAN InterruptState; + + FspHeader = (FSP_INFO_HEADER *)FspFindFspHeader (PcdGet32 (PcdFspmBaseAddress)); + if (FspHeader == NULL) { + return EFI_DEVICE_ERROR; + } + + TempRamExitApi = (FSP_TEMP_RAM_EXIT)(UINTN)(FspHeader->ImageBase + FspHeader->TempRamExitEntryOffset); + InterruptState = SaveAndDisableInterrupts (); + Status = Execute32BitCode ((UINTN)TempRamExitApi, (UINTN)TempRamExitParam, (UINTN)NULL); + SetInterruptState (InterruptState); + + return Status; +} + +/** + Call FSP API - FspSiliconInit. + + @param[in] FspsUpdDataPtr Address pointer to the Silicon Init parameters structure. + + @return EFI status returned by FspSiliconInit API. +**/ +EFI_STATUS +EFIAPI +CallFspSiliconInit ( + IN VOID *FspsUpdDataPtr + ) +{ + FSP_INFO_HEADER *FspHeader; + FSP_SILICON_INIT FspSiliconInitApi; + EFI_STATUS Status; + BOOLEAN InterruptState; + + FspHeader = (FSP_INFO_HEADER *)FspFindFspHeader (PcdGet32 (PcdFspsBaseAddress)); + if (FspHeader == NULL) { + return EFI_DEVICE_ERROR; + } + + FspSiliconInitApi = (FSP_SILICON_INIT)(UINTN)(FspHeader->ImageBase + FspHeader->FspSiliconInitEntryOffset); + InterruptState = SaveAndDisableInterrupts (); + Status = Execute32BitCode ((UINTN)FspSiliconInitApi, (UINTN)FspsUpdDataPtr, (UINTN)NULL); + SetInterruptState (InterruptState); + + return Status; +} diff --git a/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/IA32/DispatchExecute.c b/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/IA32/DispatchExecute.c new file mode 100644 index 0000000000..72b1762f4c --- /dev/null +++ b/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/IA32/DispatchExecute.c @@ -0,0 +1,58 @@ +/** @file + Execute 32-bit code in Protected Mode. + + Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include + +/** + FSP API functions. + + @param[in] Param1 The first parameter to pass to 32bit code. + @param[in] Param2 The second parameter to pass to 32bit code. + + @return EFI_STATUS. +**/ +typedef +EFI_STATUS +(EFIAPI *FSP_FUNCTION) ( + IN VOID *Param1, + IN VOID *Param2 + ); + +/** + Wrapper for a thunk to transition from long mode to compatibility mode to execute 32-bit code and then transit back to + long mode. + + @param[in] Function The 32bit code entry to be executed. + @param[in] Param1 The first parameter to pass to 32bit code. + @param[in] Param2 The second parameter to pass to 32bit code. + + @return EFI_STATUS. +**/ +EFI_STATUS +Execute32BitCode ( + IN UINT64 Function, + IN UINT64 Param1, + IN UINT64 Param2 + ) +{ + FSP_FUNCTION EntryFunc; + EFI_STATUS Status; + + EntryFunc = (FSP_FUNCTION) (UINTN) (Function); + Status = EntryFunc ((VOID *)(UINTN)Param1, (VOID *)(UINTN)Param2); + + return Status; +} + diff --git a/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/X64/DispatchExecute.c b/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/X64/DispatchExecute.c new file mode 100644 index 0000000000..061d381c1b --- /dev/null +++ b/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/X64/DispatchExecute.c @@ -0,0 +1,108 @@ +/** @file + Execute 32-bit code in Long Mode. + Provide a thunk function to transition from long mode to compatibility mode to execute 32-bit code and then transit + back to long mode. + + Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include +#include + +#pragma pack(1) +typedef union { + struct { + UINT32 LimitLow : 16; + UINT32 BaseLow : 16; + UINT32 BaseMid : 8; + UINT32 Type : 4; + UINT32 System : 1; + UINT32 Dpl : 2; + UINT32 Present : 1; + UINT32 LimitHigh : 4; + UINT32 Software : 1; + UINT32 Reserved : 1; + UINT32 DefaultSize : 1; + UINT32 Granularity : 1; + UINT32 BaseHigh : 8; + } Bits; + UINT64 Uint64; +} IA32_GDT; +#pragma pack() + +GLOBAL_REMOVE_IF_UNREFERENCED IA32_GDT mGdtEntries[] = { + {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 0x0: reserve */ + {{0xFFFF, 0, 0, 0xB, 1, 0, 1, 0xF, 0, 0, 1, 1, 0}}, /* 0x8: compatibility mode */ + {{0xFFFF, 0, 0, 0xB, 1, 0, 1, 0xF, 0, 1, 0, 1, 0}}, /* 0x10: for long mode */ + {{0xFFFF, 0, 0, 0x3, 1, 0, 1, 0xF, 0, 0, 1, 1, 0}}, /* 0x18: data */ + {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 0x20: reserve */ +}; + +// +// IA32 Gdt register +// +GLOBAL_REMOVE_IF_UNREFERENCED IA32_DESCRIPTOR mGdt = { + sizeof (mGdtEntries) - 1, + (UINTN) mGdtEntries + }; + +/** + Assembly function to transition from long mode to compatibility mode to execute 32-bit code and then transit back to + long mode. + + @param[in] Function The 32bit code entry to be executed. + @param[in] Param1 The first parameter to pass to 32bit code + @param[in] Param2 The second parameter to pass to 32bit code + @param[in] InternalGdtr The GDT and GDT descriptor used by this library + + @return status. +**/ +UINT32 +AsmExecute32BitCode ( + IN UINT64 Function, + IN UINT64 Param1, + IN UINT64 Param2, + IN IA32_DESCRIPTOR *InternalGdtr + ); + +/** + Wrapper for a thunk to transition from long mode to compatibility mode to execute 32-bit code and then transit back to + long mode. + + @param[in] Function The 32bit code entry to be executed. + @param[in] Param1 The first parameter to pass to 32bit code. + @param[in] Param2 The second parameter to pass to 32bit code. + + @return EFI_STATUS. +**/ +EFI_STATUS +Execute32BitCode ( + IN UINT64 Function, + IN UINT64 Param1, + IN UINT64 Param2 + ) +{ + EFI_STATUS Status; + IA32_DESCRIPTOR Idtr; + + // + // Idtr might be changed inside of FSP. 32bit FSP only knows the <4G address. + // If IDTR.Base is >4G, FSP can not handle. So we need save/restore IDTR here for X64 only. + // Interrupt is already disabled here, so it is safety to update IDTR. + // + AsmReadIdtr (&Idtr); + Status = AsmExecute32BitCode (Function, Param1, Param2, &mGdt); + AsmWriteIdtr (&Idtr); + + return Status; +} + diff --git a/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/X64/Thunk64To32.S b/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/X64/Thunk64To32.S new file mode 100644 index 0000000000..b6b5c1aca8 --- /dev/null +++ b/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/X64/Thunk64To32.S @@ -0,0 +1,230 @@ +# +# Copyright (c) 2014, Intel Corporation. All rights reserved.
+# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +# +# Module Name: +# +# Thunk64To32.asm +# +# Abstract: +# +# This is the assembly code to transition from long mode to compatibility mode to execute 32-bit code and then +# transit back to long mode. +# +#------------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Procedure: AsmExecute32BitCode +# +# Input: None +# +# Output: None +# +# Prototype: UINT32 +# AsmExecute32BitCode ( +# IN UINT64 Function, +# IN UINT64 Param1, +# IN UINT64 Param2, +# IN IA32_DESCRIPTOR *InternalGdtr +# ); +# +# +# Description: A thunk function to execute 32-bit code in long mode. +# +#---------------------------------------------------------------------------- + +ASM_GLOBAL ASM_PFX(AsmExecute32BitCode) +ASM_PFX(AsmExecute32BitCode): + # + # save IFLAG and disable it + # + pushfq + cli + + # + # save orignal GDTR and CS + # + movl %ds, %eax + push %rax + movl %cs, %eax + push %rax + subq $0x10, %rsp + sgdt (%rsp) + # + # load internal GDT + # + lgdt (%r9) + # + # Save general purpose register and rflag register + # + pushfq + push %rdi + push %rsi + push %rbp + push %rbx + + # + # save CR3 + # + movq %cr3, %rax + movq %rax, %rbp + + # + # Prepare the CS and return address for the transition from 32-bit to 64-bit mode + # + movq $0x10, %rax # load long mode selector + shl $32, %rax + lea ReloadCS(%rip), %r9 #Assume the ReloadCS is under 4G + orq %r9, %rax + push %rax + # + # Save parameters for 32-bit function call + # + movq %r8, %rax + shl $32, %rax + orq %rdx, %rax + push %rax + # + # save the 32-bit function entry and the return address into stack which will be + # retrieve in compatibility mode. + # + lea ReturnBack(%rip), %rax #Assume the ReloadCS is under 4G + shl $32, %rax + orq %rcx, %rax + push %rax + + # + # let rax save DS + # + movq $0x18, %rax + + # + # Change to Compatible Segment + # + movq $8, %rcx # load compatible mode selector + shl $32, %rcx + lea Compatible(%rip), %rdx # assume address < 4G + orq %rdx, %rcx + push %rcx + .byte 0xcb # retf + +Compatible: + # reload DS/ES/SS to make sure they are correct referred to current GDT + movw %ax, %ds + movw %ax, %es + movw %ax, %ss + + # + # Disable paging + # + movq %cr0, %rcx + btc $31, %ecx + movq %rcx, %cr0 + # + # Clear EFER.LME + # + movl $0xC0000080, %ecx + rdmsr + btc $8, %eax + wrmsr + +# Now we are in protected mode + # + # Call 32-bit function. Assume the function entry address and parameter value is less than 4G + # + pop %rax # Here is the function entry + # + # Now the parameter is at the bottom of the stack, then call in to IA32 function. + # + jmp *%rax +ReturnBack: + movl %eax, %ebx # save return status + pop %rcx # drop param1 + pop %rcx # drop param2 + + # + # restore CR4 + # + movq %cr4, %rax + bts $5, %eax + movq %rax, %cr4 + + # + # restore CR3 + # + movl %ebp, %eax + movq %rax, %cr3 + + # + # Set EFER.LME to re-enable ia32-e + # + movl $0xC0000080, %ecx + rdmsr + bts $8, %eax + wrmsr + # + # Enable paging + # + movq %cr0, %rax + bts $31, %eax + mov %rax, %cr0 +# Now we are in compatible mode + + # + # Reload cs register + # + .byte 0xcb # retf +ReloadCS: + # + # Now we're in Long Mode + # + # + # Restore C register and eax hold the return status from 32-bit function. + # Note: Do not touch rax from now which hold the return value from IA32 function + # + movl %ebx, %eax # put return status to EAX + pop %rbx + pop %rbp + pop %rsi + pop %rdi + popfq + # + # Switch to orignal GDT and CS. here rsp is pointer to the orignal GDT descriptor. + # + lgdt (%rsp) + # + # drop GDT descriptor in stack + # + addq $0x10, %rsp + # + # switch to orignal CS and GDTR + # + pop %r9 # get CS + shl $32, %r9 # rcx[32..47] <- Cs + lea ReturnToLongMode(%rip), %rcx + orq %r9, %rcx + push %rcx + .byte 0xcb # retf +ReturnToLongMode: + # + # Reload original DS/ES/SS + # + pop %rcx + movl %ecx, %ds + movl %ecx, %es + movl %ecx, %ss + + # + # Restore IFLAG + # + popfq + + ret + diff --git a/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/X64/Thunk64To32.asm b/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/X64/Thunk64To32.asm new file mode 100644 index 0000000000..70e7b5f408 --- /dev/null +++ b/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/X64/Thunk64To32.asm @@ -0,0 +1,230 @@ +; +; Copyright (c) 2014, Intel Corporation. All rights reserved.
+; This program and the accompanying materials +; are licensed and made available under the terms and conditions of the BSD License +; which accompanies this distribution. The full text of the license may be found at +; http://opensource.org/licenses/bsd-license.php. +; +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +; +; +; Module Name: +; +; Thunk64To32.asm +; +; Abstract: +; +; This is the assembly code to transition from long mode to compatibility mode to execute 32-bit code and then +; transit back to long mode. +; +;------------------------------------------------------------------------------- + .code +;---------------------------------------------------------------------------- +; Procedure: AsmExecute32BitCode +; +; Input: None +; +; Output: None +; +; Prototype: UINT32 +; AsmExecute32BitCode ( +; IN UINT64 Function, +; IN UINT64 Param1, +; IN UINT64 Param2, +; IN IA32_DESCRIPTOR *InternalGdtr +; ); +; +; +; Description: A thunk function to execute 32-bit code in long mode. +; +;---------------------------------------------------------------------------- +AsmExecute32BitCode PROC + ; + ; save IFLAG and disable it + ; + pushfq + cli + + ; + ; save orignal GDTR and CS + ; + mov rax, ds + push rax + mov rax, cs + push rax + sub rsp, 10h + sgdt fword ptr [rsp] + ; + ; load internal GDT + ; + lgdt fword ptr [r9] + ; + ; Save general purpose register and rflag register + ; + pushfq + push rdi + push rsi + push rbp + push rbx + + ; + ; save CR3 + ; + mov rax, cr3 + mov rbp, rax + + ; + ; Prepare the CS and return address for the transition from 32-bit to 64-bit mode + ; + mov rax, 10h ; load long mode selector + shl rax, 32 + mov r9, OFFSET ReloadCS ;Assume the ReloadCS is under 4G + or rax, r9 + push rax + ; + ; Save parameters for 32-bit function call + ; + mov rax, r8 + shl rax, 32 + or rax, rdx + push rax + ; + ; save the 32-bit function entry and the return address into stack which will be + ; retrieve in compatibility mode. + ; + mov rax, OFFSET ReturnBack ;Assume the ReloadCS is under 4G + shl rax, 32 + or rax, rcx + push rax + + ; + ; let rax save DS + ; + mov rax, 018h + + ; + ; Change to Compatible Segment + ; + mov rcx, 08h ; load compatible mode selector + shl rcx, 32 + mov rdx, OFFSET Compatible ; assume address < 4G + or rcx, rdx + push rcx + retf + +Compatible: + ; reload DS/ES/SS to make sure they are correct referred to current GDT + mov ds, ax + mov es, ax + mov ss, ax + + ; + ; Disable paging + ; + mov rcx, cr0 + btc ecx, 31 + mov cr0, rcx + ; + ; Clear EFER.LME + ; + mov ecx, 0C0000080h + rdmsr + btc eax, 8 + wrmsr + +; Now we are in protected mode + ; + ; Call 32-bit function. Assume the function entry address and parameter value is less than 4G + ; + pop rax ; Here is the function entry + ; + ; Now the parameter is at the bottom of the stack, then call in to IA32 function. + ; + jmp rax +ReturnBack: + mov ebx, eax ; save return status + pop rcx ; drop param1 + pop rcx ; drop param2 + + ; + ; restore CR4 + ; + mov rax, cr4 + bts eax, 5 + mov cr4, rax + + ; + ; restore CR3 + ; + mov eax, ebp + mov cr3, rax + + ; + ; Set EFER.LME to re-enable ia32-e + ; + mov ecx, 0C0000080h + rdmsr + bts eax, 8 + wrmsr + ; + ; Enable paging + ; + mov rax, cr0 + bts eax, 31 + mov cr0, rax +; Now we are in compatible mode + + ; + ; Reload cs register + ; + retf +ReloadCS: + ; + ; Now we're in Long Mode + ; + ; + ; Restore C register and eax hold the return status from 32-bit function. + ; Note: Do not touch rax from now which hold the return value from IA32 function + ; + mov eax, ebx ; put return status to EAX + pop rbx + pop rbp + pop rsi + pop rdi + popfq + ; + ; Switch to orignal GDT and CS. here rsp is pointer to the orignal GDT descriptor. + ; + lgdt fword ptr[rsp] + ; + ; drop GDT descriptor in stack + ; + add rsp, 10h + ; + ; switch to orignal CS and GDTR + ; + pop r9 ; get CS + shl r9, 32 ; rcx[32..47] <- Cs + mov rcx, OFFSET @F + or rcx, r9 + push rcx + retf +@@: + ; + ; Reload original DS/ES/SS + ; + pop rcx + mov ds, rcx + mov es, rcx + mov ss, rcx + + ; + ; Restore IFLAG + ; + popfq + + ret +AsmExecute32BitCode ENDP + + END diff --git a/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiTestLibNull/BaseFspWrapperApiTestLibNull.inf b/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiTestLibNull/BaseFspWrapperApiTestLibNull.inf new file mode 100644 index 0000000000..6e82863328 --- /dev/null +++ b/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiTestLibNull/BaseFspWrapperApiTestLibNull.inf @@ -0,0 +1,53 @@ +### @file +# Provide FSP wrapper API test related function. +# +# Copyright (C) 2016, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +[Defines] + INF_VERSION = 0x00010017 + BASE_NAME = BaseFspWrapperApiTestLibNull + FILE_GUID = E7E96F88-017B-417C-8DC8-B84C2B877020 + VERSION_STRING = 1.0 + MODULE_TYPE = PEIM + LIBRARY_CLASS = FspWrapperApiTestLib + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 +# + +################################################################################ +# +# Sources Section - list of files that are required for the build to succeed. +# +################################################################################ + +[Sources] + FspWrapperApiTestNull.c + +################################################################################ +# +# Package Dependency Section - list of Package files that are required for +# this module. +# +################################################################################ + +[Packages] + MdePkg/MdePkg.dec + IntelFsp2Pkg/IntelFsp2Pkg.dec + IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec + +[LibraryClasses] + DebugLib + +[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 index 0000000000..6e40cd0644 --- /dev/null +++ b/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiTestLibNull/FspWrapperApiTestNull.c @@ -0,0 +1,65 @@ +/** @file + Provide FSP wrapper API test related function. + + Copyright (c) 2016, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include + +/** + Test the output of FSP API - FspMemoryInit. + + @param[in] FspmUpdDataPtr Address pointer to the FSP_MEMORY_INIT_PARAMS structure. + @param[in] HobListPtr Address of the HobList pointer. + + @return test result on output of FspMemoryInit API. +**/ +EFI_STATUS +EFIAPI +TestFspMemoryInitApiOutput ( + IN VOID *FspmUpdDataPtr, + IN VOID **HobListPtr + ) +{ + return RETURN_UNSUPPORTED; +} + +/** + Test the output of FSP API - TempRamExit. + + @param[in] TempRamExitParam Address pointer to the TempRamExit parameters structure. + + @return test result on output of TempRamExit API. +**/ +EFI_STATUS +EFIAPI +TestFspTempRamExitApiOutput ( + IN VOID *TempRamExitParam + ) +{ + return RETURN_UNSUPPORTED; +} + +/** + Test the output of FSP API - FspSiliconInit. + + @param[in] FspsUpdDataPtr Address pointer to the Silicon Init parameters structure. + + @return test result on output of FspSiliconInit API. +**/ +EFI_STATUS +EFIAPI +TestFspSiliconInitApiOutput ( + IN VOID *FspsUpdDataPtr + ) +{ + return RETURN_UNSUPPORTED; +} diff --git a/IntelFsp2WrapperPkg/Library/BaseFspWrapperPlatformLibSample/BaseFspWrapperPlatformLibSample.inf b/IntelFsp2WrapperPkg/Library/BaseFspWrapperPlatformLibSample/BaseFspWrapperPlatformLibSample.inf new file mode 100644 index 0000000000..f9581e8456 --- /dev/null +++ b/IntelFsp2WrapperPkg/Library/BaseFspWrapperPlatformLibSample/BaseFspWrapperPlatformLibSample.inf @@ -0,0 +1,60 @@ +## @file +# Sample to provide FSP wrapper platform related function. +# +# Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +################################################################################ +# +# Defines Section - statements that will be processed to create a Makefile. +# +################################################################################ +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = BaseFspWrapperPlatformLibSample + FILE_GUID = 12F38E73-B34D-4559-99E5-AE2DCD002156 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = FspWrapperPlatformLib + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +################################################################################ +# +# Sources Section - list of files that are required for the build to succeed. +# +################################################################################ + +[Sources] + FspWrapperPlatformLibSample.c + + +################################################################################ +# +# Package Dependency Section - list of Package files that are required for +# this module. +# +################################################################################ + +[Packages] + MdePkg/MdePkg.dec + IntelFsp2Pkg/IntelFsp2Pkg.dec + IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec + +[LibraryClasses] + +[Pcd] + gIntelFsp2PkgTokenSpaceGuid.PcdTemporaryRamBase ## CONSUMES + gIntelFsp2PkgTokenSpaceGuid.PcdTemporaryRamSize ## CONSUMES diff --git a/IntelFsp2WrapperPkg/Library/BaseFspWrapperPlatformLibSample/FspWrapperPlatformLibSample.c b/IntelFsp2WrapperPkg/Library/BaseFspWrapperPlatformLibSample/FspWrapperPlatformLibSample.c new file mode 100644 index 0000000000..9c1a84f12c --- /dev/null +++ b/IntelFsp2WrapperPkg/Library/BaseFspWrapperPlatformLibSample/FspWrapperPlatformLibSample.c @@ -0,0 +1,83 @@ +/** @file + Sample to provide FSP wrapper related function. + + Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include + +/** + This function overrides the default configurations in the FSP-M UPD data region. + + @note At this point, memory is NOT ready, PeiServices are available to use. + + @param[in,out] FspUpdRgnPtr A pointer to the UPD data region data strcture. + +**/ +VOID +EFIAPI +UpdateFspmUpdData ( + IN OUT VOID *FspUpdRgnPtr + ) +{ +} + +/** + This function overrides the default configurations in the FSP-S UPD data region. + + @param[in,out] FspUpdRgnPtr A pointer to the UPD data region data strcture. + +**/ +VOID +EFIAPI +UpdateFspsUpdData ( + IN OUT VOID *FspUpdRgnPtr + ) +{ +} + +/** + Update TempRamExit parameter. + + @note At this point, memory is ready, PeiServices are available to use. + + @return TempRamExit parameter. +**/ +VOID * +EFIAPI +UpdateTempRamExitParam ( + VOID + ) +{ + return NULL; +} + +/** + Get S3 PEI memory information. + + @note At this point, memory is ready, and PeiServices are available to use. + Platform can get some data from SMRAM directly. + + @param[out] S3PeiMemSize PEI memory size to be installed in S3 phase. + @param[out] S3PeiMemBase PEI memory base to be installed in S3 phase. + + @return If S3 PEI memory information is got successfully. +**/ +EFI_STATUS +EFIAPI +GetS3MemoryInfo ( + OUT UINT64 *S3PeiMemSize, + OUT EFI_PHYSICAL_ADDRESS *S3PeiMemBase + ) +{ + return EFI_UNSUPPORTED; +} \ No newline at end of file diff --git a/IntelFsp2WrapperPkg/Library/PeiFspWrapperApiTestLib/FspWrapperApiTest.c b/IntelFsp2WrapperPkg/Library/PeiFspWrapperApiTestLib/FspWrapperApiTest.c new file mode 100644 index 0000000000..b1280615cd --- /dev/null +++ b/IntelFsp2WrapperPkg/Library/PeiFspWrapperApiTestLib/FspWrapperApiTest.c @@ -0,0 +1,88 @@ +/** @file + Provide FSP wrapper API test related function. + + Copyright (c) 2016, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include +#include +#include +#include + +/** + Test the output of FSP API - FspMemoryInit. + + @param[in] FspmUpdDataPtr Address pointer to the FSP_MEMORY_INIT_PARAMS structure. + @param[in] HobListPtr Address of the HobList pointer. + + @return test result on output of FspMemoryInit API. +**/ +EFI_STATUS +EFIAPI +TestFspMemoryInitApiOutput ( + IN VOID *FspmUpdDataPtr, + IN VOID **HobListPtr + ) +{ + DEBUG_CODE_BEGIN (); + EFI_PEI_HOB_POINTERS Hob; + + Hob.Raw = (UINT8 *)(*(HobListPtr)); + while (TRUE) { + if (END_OF_HOB_LIST(Hob) == TRUE) { + DEBUG((DEBUG_INFO, "gFspBootLoaderTolumHobGuid not Found\n")); + break; + } + if ((CompareGuid (&Hob.ResourceDescriptor->Owner, &gFspBootLoaderTolumHobGuid))) { + DEBUG ((DEBUG_INFO, "gFspBootLoaderTolumHobGuid Found\n")); + DEBUG ((DEBUG_INFO, "Fill Boot Loader reserved memory range with 0x5A for testing purpose\n")); + SetMem ((VOID *)(UINTN)Hob.ResourceDescriptor->PhysicalStart, (UINTN)Hob.ResourceDescriptor->ResourceLength, 0x5A); + break; + } + Hob.Raw = GET_NEXT_HOB (Hob); + } + DEBUG_CODE_END (); + + return RETURN_SUCCESS; +} + +/** + Test the output of FSP API - TempRamExit. + + @param[in] TempRamExitParam Address pointer to the TempRamExit parameters structure. + + @return test result on output of TempRamExit API. +**/ +EFI_STATUS +EFIAPI +TestFspTempRamExitApiOutput ( + IN VOID *TempRamExitParam + ) +{ + return RETURN_SUCCESS; +} + +/** + Test the output of FSP API - FspSiliconInit. + + @param[in] FspsUpdDataPtr Address pointer to the Silicon Init parameters structure. + + @return test result on output of FspSiliconInit API. +**/ +EFI_STATUS +EFIAPI +TestFspSiliconInitApiOutput ( + IN VOID *FspsUpdDataPtr + ) +{ + return RETURN_SUCCESS; +} diff --git a/IntelFsp2WrapperPkg/Library/PeiFspWrapperApiTestLib/PeiFspWrapperApiTestLib.inf b/IntelFsp2WrapperPkg/Library/PeiFspWrapperApiTestLib/PeiFspWrapperApiTestLib.inf new file mode 100644 index 0000000000..fbbcf30035 --- /dev/null +++ b/IntelFsp2WrapperPkg/Library/PeiFspWrapperApiTestLib/PeiFspWrapperApiTestLib.inf @@ -0,0 +1,56 @@ +### @file +# Provide FSP-M wrapper API test related function. +# +# Copyright (C) 2016, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +[Defines] + INF_VERSION = 0x00010017 + BASE_NAME = PeiFspWrapperApiTestLib + FILE_GUID = 87DC266A-C8F7-4A66-A0CB-018A6F5305B4 + VERSION_STRING = 1.0 + MODULE_TYPE = PEIM + LIBRARY_CLASS = FspWrapperApiTestLib + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 +# + +################################################################################ +# +# Sources Section - list of files that are required for the build to succeed. +# +################################################################################ + +[Sources] + FspWrapperApiTest.c + +################################################################################ +# +# Package Dependency Section - list of Package files that are required for +# this module. +# +################################################################################ + +[Packages] + MdePkg/MdePkg.dec + IntelFsp2Pkg/IntelFsp2Pkg.dec + IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec + +[LibraryClasses] + BaseMemoryLib + DebugLib + HobLib + +[Guids] + 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 index 0000000000..8765bba5fd --- /dev/null +++ b/IntelFsp2WrapperPkg/Library/PeiFspWrapperHobProcessLibSample/FspWrapperHobProcessLibSample.c @@ -0,0 +1,390 @@ +/** @file + Sample to provide FSP wrapper hob process related function. + + Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +// +// Additional pages are used by DXE memory manager. +// It should be consistent between RetrieveRequiredMemorySize() and GetPeiMemSize() +// +#define PEI_ADDITIONAL_MEMORY_SIZE (16 * EFI_PAGE_SIZE) + +/** + Get the mem size in memory type infromation table. + + @param[in] PeiServices PEI Services table. + + @return the mem size in memory type infromation table. +**/ +UINT64 +GetMemorySizeInMemoryTypeInformation ( + IN EFI_PEI_SERVICES **PeiServices + ) +{ + EFI_STATUS Status; + EFI_PEI_HOB_POINTERS Hob; + EFI_MEMORY_TYPE_INFORMATION *MemoryData; + UINT8 Index; + UINTN TempPageNum; + + MemoryData = NULL; + Status = (*PeiServices)->GetHobList ((CONST EFI_PEI_SERVICES**)PeiServices, (VOID **) &Hob.Raw); + ASSERT_EFI_ERROR (Status); + while (!END_OF_HOB_LIST (Hob)) { + if (Hob.Header->HobType == EFI_HOB_TYPE_GUID_EXTENSION && + CompareGuid (&Hob.Guid->Name, &gEfiMemoryTypeInformationGuid)) { + MemoryData = (EFI_MEMORY_TYPE_INFORMATION *) (Hob.Raw + sizeof (EFI_HOB_GENERIC_HEADER) + sizeof (EFI_GUID)); + break; + } + + Hob.Raw = GET_NEXT_HOB (Hob); + } + + if (MemoryData == NULL) { + return 0; + } + + TempPageNum = 0; + for (Index = 0; MemoryData[Index].Type != EfiMaxMemoryType; Index++) { + // + // Accumulate default memory size requirements + // + TempPageNum += MemoryData[Index].NumberOfPages; + } + + return TempPageNum * EFI_PAGE_SIZE; +} + +/** + Get the mem size need to be reserved in PEI phase. + + @param[in] PeiServices PEI Services table. + + @return the mem size need to be reserved in PEI phase. +**/ +UINT64 +RetrieveRequiredMemorySize ( + IN EFI_PEI_SERVICES **PeiServices + ) +{ + UINT64 Size; + + Size = GetMemorySizeInMemoryTypeInformation (PeiServices); + return Size + PEI_ADDITIONAL_MEMORY_SIZE; +} + +/** + Get the mem size need to be consumed and reserved in PEI phase. + + @param[in] PeiServices PEI Services table. + @param[in] BootMode Current boot mode. + + @return the mem size need to be consumed and reserved in PEI phase. +**/ +UINT64 +GetPeiMemSize ( + IN EFI_PEI_SERVICES **PeiServices, + IN UINT32 BootMode + ) +{ + UINT64 Size; + UINT64 MinSize; + + if (BootMode == BOOT_IN_RECOVERY_MODE) { + return PcdGet32 (PcdPeiRecoveryMinMemSize); + } + + Size = GetMemorySizeInMemoryTypeInformation (PeiServices); + + if (BootMode == BOOT_ON_FLASH_UPDATE) { + // + // Maybe more size when in CapsuleUpdate phase ? + // + MinSize = PcdGet32 (PcdPeiMinMemSize); + } else { + MinSize = PcdGet32 (PcdPeiMinMemSize); + } + + return MinSize + Size + PEI_ADDITIONAL_MEMORY_SIZE; +} + +/** + Post FSP-M HOB process for Memory Resource Descriptor. + + @param[in] FspHobList Pointer to the HOB data structure produced by FSP. + + @return If platform process the FSP hob list successfully. +**/ +EFI_STATUS +EFIAPI +PostFspmHobProcess ( + IN VOID *FspHobList + ) +{ + EFI_PEI_HOB_POINTERS Hob; + UINT64 LowMemorySize; + UINT64 FspMemorySize; + EFI_PHYSICAL_ADDRESS FspMemoryBase; + UINT64 PeiMemSize; + EFI_PHYSICAL_ADDRESS PeiMemBase; + UINT64 S3PeiMemSize; + EFI_PHYSICAL_ADDRESS S3PeiMemBase; + BOOLEAN FoundFspMemHob; + EFI_STATUS Status; + EFI_BOOT_MODE BootMode; + EFI_PEI_CAPSULE_PPI *Capsule; + VOID *CapsuleBuffer; + UINTN CapsuleBufferLength; + UINT64 RequiredMemSize; + EFI_PEI_SERVICES **PeiServices; + + PeiServices = (EFI_PEI_SERVICES **)GetPeiServicesTablePointer (); + + PeiServicesGetBootMode (&BootMode); + + PeiMemBase = 0; + LowMemorySize = 0; + FspMemorySize = 0; + FspMemoryBase = 0; + FoundFspMemHob = FALSE; + + // + // Parse the hob list from fsp + // Report all the resource hob except the memory between 1M and 4G + // + Hob.Raw = (UINT8 *)(UINTN)FspHobList; + DEBUG((DEBUG_INFO, "FspHobList - 0x%x\n", FspHobList)); + + while ((Hob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, Hob.Raw)) != NULL) { + DEBUG((DEBUG_INFO, "\nResourceType: 0x%x\n", Hob.ResourceDescriptor->ResourceType)); + if ((Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) || + (Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_MEMORY_RESERVED)) { + DEBUG((DEBUG_INFO, "ResourceAttribute: 0x%x\n", Hob.ResourceDescriptor->ResourceAttribute)); + DEBUG((DEBUG_INFO, "PhysicalStart: 0x%x\n", Hob.ResourceDescriptor->PhysicalStart)); + DEBUG((DEBUG_INFO, "ResourceLength: 0x%x\n", Hob.ResourceDescriptor->ResourceLength)); + DEBUG((DEBUG_INFO, "Owner: %g\n\n", &Hob.ResourceDescriptor->Owner)); + } + + if ((Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) // Found the low memory length below 4G + && (Hob.ResourceDescriptor->PhysicalStart >= BASE_1MB) + && (Hob.ResourceDescriptor->PhysicalStart + Hob.ResourceDescriptor->ResourceLength <= BASE_4GB)) { + LowMemorySize += Hob.ResourceDescriptor->ResourceLength; + Hob.Raw = GET_NEXT_HOB (Hob); + continue; + } + + if ((Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_MEMORY_RESERVED) // Found the low memory length below 4G + && (Hob.ResourceDescriptor->PhysicalStart >= BASE_1MB) + && (Hob.ResourceDescriptor->PhysicalStart + Hob.ResourceDescriptor->ResourceLength <= BASE_4GB) + && (CompareGuid (&Hob.ResourceDescriptor->Owner, &gFspReservedMemoryResourceHobGuid))) { + FoundFspMemHob = TRUE; + FspMemoryBase = Hob.ResourceDescriptor->PhysicalStart; + FspMemorySize = Hob.ResourceDescriptor->ResourceLength; + DEBUG((DEBUG_INFO, "Find fsp mem hob, base 0x%x, len 0x%x\n", FspMemoryBase, FspMemorySize)); + } + + // + // Report the resource hob + // + BuildResourceDescriptorHob ( + Hob.ResourceDescriptor->ResourceType, + Hob.ResourceDescriptor->ResourceAttribute, + Hob.ResourceDescriptor->PhysicalStart, + Hob.ResourceDescriptor->ResourceLength + ); + + Hob.Raw = GET_NEXT_HOB (Hob); + } + + if (!FoundFspMemHob) { + DEBUG((DEBUG_INFO, "Didn't find the fsp used memory information.\n")); + //ASSERT(FALSE); + } + + DEBUG((DEBUG_INFO, "LowMemorySize: 0x%x.\n", LowMemorySize)); + DEBUG((DEBUG_INFO, "FspMemoryBase: 0x%x.\n", FspMemoryBase)); + DEBUG((DEBUG_INFO, "FspMemorySize: 0x%x.\n", FspMemorySize)); + + if (BootMode == BOOT_ON_S3_RESUME) { + BuildResourceDescriptorHob ( + EFI_RESOURCE_SYSTEM_MEMORY, + ( + EFI_RESOURCE_ATTRIBUTE_PRESENT | + EFI_RESOURCE_ATTRIBUTE_INITIALIZED | + // EFI_RESOURCE_ATTRIBUTE_TESTED | + EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE | + EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE | + EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE | + EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE + ), + BASE_1MB, + LowMemorySize + ); + + S3PeiMemBase = 0; + S3PeiMemSize = 0; + Status = GetS3MemoryInfo (&S3PeiMemSize, &S3PeiMemBase); + ASSERT_EFI_ERROR (Status); + DEBUG((DEBUG_INFO, "S3 memory %Xh - %Xh bytes\n", S3PeiMemBase, S3PeiMemSize)); + + // + // Make sure Stack and PeiMemory are not overlap + // + + Status = PeiServicesInstallPeiMemory ( + S3PeiMemBase, + S3PeiMemSize + ); + ASSERT_EFI_ERROR (Status); + } else { + PeiMemSize = GetPeiMemSize (PeiServices, BootMode); + DEBUG((DEBUG_INFO, "PEI memory size = %Xh bytes\n", PeiMemSize)); + + // + // Capsule mode + // + Capsule = NULL; + CapsuleBuffer = NULL; + CapsuleBufferLength = 0; + if (BootMode == BOOT_ON_FLASH_UPDATE) { + Status = PeiServicesLocatePpi ( + &gEfiPeiCapsulePpiGuid, + 0, + NULL, + (VOID **) &Capsule + ); + ASSERT_EFI_ERROR (Status); + + if (Status == EFI_SUCCESS) { + // + // Make sure Stack and CapsuleBuffer are not overlap + // + CapsuleBuffer = (VOID *)(UINTN)BASE_1MB; + CapsuleBufferLength = (UINTN)(LowMemorySize - PeiMemSize); + // + // Call the Capsule PPI Coalesce function to coalesce the capsule data. + // + Status = Capsule->Coalesce (PeiServices, &CapsuleBuffer, &CapsuleBufferLength); + } + } + + RequiredMemSize = RetrieveRequiredMemorySize (PeiServices); + DEBUG((DEBUG_INFO, "Required memory size = %Xh bytes\n", RequiredMemSize)); + + // + // Report the main memory + // + BuildResourceDescriptorHob ( + EFI_RESOURCE_SYSTEM_MEMORY, + ( + EFI_RESOURCE_ATTRIBUTE_PRESENT | + EFI_RESOURCE_ATTRIBUTE_INITIALIZED | + EFI_RESOURCE_ATTRIBUTE_TESTED | + EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE | + EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE | + EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE | + EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE + ), + BASE_1MB, + LowMemorySize + ); + + // + // Make sure Stack and CapsuleBuffer are not overlap + // + + // + // Install efi memory + // + PeiMemBase = BASE_1MB + LowMemorySize - PeiMemSize; + Status = PeiServicesInstallPeiMemory ( + PeiMemBase, + PeiMemSize - RequiredMemSize + ); + ASSERT_EFI_ERROR (Status); + + if (Capsule != NULL) { + Status = Capsule->CreateState (PeiServices, CapsuleBuffer, CapsuleBufferLength); + } + } + + return EFI_SUCCESS; +} + +/** + Process FSP HOB list + + @param[in] FspHobList Pointer to the HOB data structure produced by FSP. + +**/ +VOID +ProcessFspHobList ( + IN VOID *FspHobList + ) +{ + EFI_PEI_HOB_POINTERS FspHob; + + FspHob.Raw = FspHobList; + + // + // Add all the HOBs from FSP binary to FSP wrapper + // + while (!END_OF_HOB_LIST (FspHob)) { + if (FspHob.Header->HobType == EFI_HOB_TYPE_GUID_EXTENSION) { + // + // Skip FSP binary creates PcdDataBaseHobGuid + // + if (!CompareGuid(&FspHob.Guid->Name, &gPcdDataBaseHobGuid)) { + BuildGuidDataHob ( + &FspHob.Guid->Name, + GET_GUID_HOB_DATA(FspHob), + GET_GUID_HOB_DATA_SIZE(FspHob) + ); + } + } + FspHob.Raw = GET_NEXT_HOB (FspHob); + } +} + +/** + Post FSP-S HOB process (not Memory Resource Descriptor). + + @param[in] FspHobList Pointer to the HOB data structure produced by FSP. + + @return If platform process the FSP hob list successfully. +**/ +EFI_STATUS +EFIAPI +PostFspsHobProcess ( + IN VOID *FspHobList + ) +{ + ProcessFspHobList (FspHobList); + + return EFI_SUCCESS; +} \ No newline at end of file diff --git a/IntelFsp2WrapperPkg/Library/PeiFspWrapperHobProcessLibSample/PeiFspWrapperHobProcessLibSample.inf b/IntelFsp2WrapperPkg/Library/PeiFspWrapperHobProcessLibSample/PeiFspWrapperHobProcessLibSample.inf new file mode 100644 index 0000000000..6fa91b664f --- /dev/null +++ b/IntelFsp2WrapperPkg/Library/PeiFspWrapperHobProcessLibSample/PeiFspWrapperHobProcessLibSample.inf @@ -0,0 +1,76 @@ +## @file +# Sample to provide FSP wrapper hob process related function. +# +# Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +################################################################################ +# +# Defines Section - statements that will be processed to create a Makefile. +# +################################################################################ +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = PeiFspWrapperHobProcessLibSample + FILE_GUID = 864693E2-EDE8-4DF8-8871-38C0BAA157EB + MODULE_TYPE = SEC + VERSION_STRING = 1.0 + LIBRARY_CLASS = FspWrapperHobProcessLib + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +################################################################################ +# +# Sources Section - list of files that are required for the build to succeed. +# +################################################################################ + +[Sources] + FspWrapperHobProcessLibSample.c + + +################################################################################ +# +# Package Dependency Section - list of Package files that are required for +# this module. +# +################################################################################ + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + IntelFsp2Pkg/IntelFsp2Pkg.dec + IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + HobLib + DebugLib + FspWrapperPlatformLib + PeiServicesLib + PeiServicesTablePointerLib + +[Pcd] + gFspWrapperTokenSpaceGuid.PcdPeiMinMemSize ## CONSUMES + gFspWrapperTokenSpaceGuid.PcdPeiRecoveryMinMemSize ## CONSUMES + +[Guids] + gFspReservedMemoryResourceHobGuid ## CONSUMES ## HOB + gEfiMemoryTypeInformationGuid ## CONSUMES ## GUID + gPcdDataBaseHobGuid ## CONSUMES ## HOB + +[Ppis] + gEfiPeiCapsulePpiGuid ## CONSUMES diff --git a/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/FspWrapperPlatformSecLibSample.c b/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/FspWrapperPlatformSecLibSample.c new file mode 100644 index 0000000000..19379c20c6 --- /dev/null +++ b/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/FspWrapperPlatformSecLibSample.c @@ -0,0 +1,133 @@ +/** @file + Sample to provide FSP wrapper platform sec related function. + + Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include + +#include +#include + +#include + +/** + This interface conveys state information out of the Security (SEC) phase into PEI. + + @param[in] PeiServices Pointer to the PEI Services Table. + @param[in,out] StructureSize Pointer to the variable describing size of the input buffer. + @param[out] PlatformInformationRecord Pointer to the EFI_SEC_PLATFORM_INFORMATION_RECORD. + + @retval EFI_SUCCESS The data was successfully returned. + @retval EFI_BUFFER_TOO_SMALL The buffer was too small. + +**/ +EFI_STATUS +EFIAPI +SecPlatformInformation ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN OUT UINT64 *StructureSize, + OUT EFI_SEC_PLATFORM_INFORMATION_RECORD *PlatformInformationRecord + ); + +/** + This interface conveys performance information out of the Security (SEC) phase into PEI. + + This service is published by the SEC phase. The SEC phase handoff has an optional + EFI_PEI_PPI_DESCRIPTOR list as its final argument when control is passed from SEC into the + PEI Foundation. As such, if the platform supports collecting performance data in SEC, + this information is encapsulated into the data structure abstracted by this service. + This information is collected for the boot-strap processor (BSP) on IA-32. + + @param[in] PeiServices The pointer to the PEI Services Table. + @param[in] This The pointer to this instance of the PEI_SEC_PERFORMANCE_PPI. + @param[out] Performance The pointer to performance data collected in SEC phase. + + @retval EFI_SUCCESS The data was successfully returned. + +**/ +EFI_STATUS +EFIAPI +SecGetPerformance ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN PEI_SEC_PERFORMANCE_PPI *This, + OUT FIRMWARE_SEC_PERFORMANCE *Performance + ); + +PEI_SEC_PERFORMANCE_PPI mSecPerformancePpi = { + SecGetPerformance +}; + +EFI_PEI_PPI_DESCRIPTOR mPeiSecPlatformPpi[] = { + { + EFI_PEI_PPI_DESCRIPTOR_PPI, + &gTopOfTemporaryRamPpiGuid, + NULL // To be patched later. + }, + { + EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST, + &gPeiSecPerformancePpiGuid, + &mSecPerformancePpi + }, +}; + +/** + A developer supplied function to perform platform specific operations. + + It's a developer supplied function to perform any operations appropriate to a + given platform. It's invoked just before passing control to PEI core by SEC + core. Platform developer may modify the SecCoreData passed to PEI Core. + It returns a platform specific PPI list that platform wishes to pass to PEI core. + The Generic SEC core module will merge this list to join the final list passed to + PEI core. + + @param[in,out] SecCoreData The same parameter as passing to PEI core. It + could be overridden by this function. + + @return The platform specific PPI list to be passed to PEI core or + NULL if there is no need of such platform specific PPI list. + +**/ +EFI_PEI_PPI_DESCRIPTOR * +EFIAPI +SecPlatformMain ( + IN OUT EFI_SEC_PEI_HAND_OFF *SecCoreData + ) +{ + EFI_PEI_PPI_DESCRIPTOR *PpiList; + + DEBUG((DEBUG_INFO, "SecPlatformMain\n")); + + DEBUG((DEBUG_INFO, "BootFirmwareVolumeBase - 0x%x\n", SecCoreData->BootFirmwareVolumeBase)); + DEBUG((DEBUG_INFO, "BootFirmwareVolumeSize - 0x%x\n", SecCoreData->BootFirmwareVolumeSize)); + DEBUG((DEBUG_INFO, "TemporaryRamBase - 0x%x\n", SecCoreData->TemporaryRamBase)); + DEBUG((DEBUG_INFO, "TemporaryRamSize - 0x%x\n", SecCoreData->TemporaryRamSize)); + DEBUG((DEBUG_INFO, "PeiTemporaryRamBase - 0x%x\n", SecCoreData->PeiTemporaryRamBase)); + DEBUG((DEBUG_INFO, "PeiTemporaryRamSize - 0x%x\n", SecCoreData->PeiTemporaryRamSize)); + DEBUG((DEBUG_INFO, "StackBase - 0x%x\n", SecCoreData->StackBase)); + DEBUG((DEBUG_INFO, "StackSize - 0x%x\n", SecCoreData->StackSize)); + + InitializeApicTimer (0, (UINT32) -1, TRUE, 5); + + // + // Use middle of Heap as temp buffer, it will be copied by caller. + // Do not use Stack, because it will cause wrong calculation on stack by PeiCore + // + PpiList = (VOID *)((UINTN)SecCoreData->PeiTemporaryRamBase + (UINTN)SecCoreData->PeiTemporaryRamSize/2); + CopyMem (PpiList, mPeiSecPlatformPpi, sizeof(mPeiSecPlatformPpi)); + + // + // Patch TopOfTemporaryRamPpi + // + PpiList[0].Ppi = (VOID *)((UINTN)SecCoreData->TemporaryRamBase + SecCoreData->TemporaryRamSize); + + return PpiList; +} diff --git a/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/Fsp.h b/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/Fsp.h new file mode 100644 index 0000000000..c625a884d3 --- /dev/null +++ b/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/Fsp.h @@ -0,0 +1,51 @@ +/** @file + Fsp related definitions + + Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef __FSP_H__ +#define __FSP_H__ + +// +// Fv Header +// +#define FVH_FV_LENGTH_OFFSET 0x20 +#define FVH_SIGINATURE_OFFSET 0x28 +#define FVH_SIGINATURE_VALID_VALUE 0x4856465F // valid signature:_FVH +#define FVH_HEADER_LENGTH_OFFSET 0x30 +#define FVH_EXTHEADER_OFFSET_OFFSET 0x34 +#define FVH_EXTHEADER_SIZE_OFFSET 0x10 + +// +// Ffs Header +// +#define FSP_HEADER_SIGNATURE_OFFSET 0x1C +#define FSP_HEADER_SIGNATURE 0x48505346 ; valid signature:FSPH +#define FSP_HEADER_GUID_DWORD1 0x912740BE +#define FSP_HEADER_GUID_DWORD2 0x47342284 +#define FSP_HEADER_GUID_DWORD3 0xB08471B9 +#define FSP_HEADER_GUID_DWORD4 0x0C3F3527 +#define FFS_HEADER_SIZE_VALUE 0x18 + +// +// Section Header +// +#define SECTION_HEADER_TYPE_OFFSET 0x03 +#define RAW_SECTION_HEADER_SIZE_VALUE 0x04 + +// +// Fsp Header +// +#define FSP_HEADER_IMAGEBASE_OFFSET 0x1C +#define FSP_HEADER_TEMPRAMINIT_OFFSET 0x30 + +#endif diff --git a/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/PeiCoreEntry.S b/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/PeiCoreEntry.S new file mode 100644 index 0000000000..c35f02b77e --- /dev/null +++ b/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/PeiCoreEntry.S @@ -0,0 +1,130 @@ +#------------------------------------------------------------------------------ +# +# Copyright (c) 2014, Intel Corporation. All rights reserved.
+# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +# Module Name: +# +# PeiCoreEntry.S +# +# Abstract: +# +# Find and call SecStartup +# +#------------------------------------------------------------------------------ + +ASM_GLOBAL ASM_PFX(CallPeiCoreEntryPoint) +ASM_PFX(CallPeiCoreEntryPoint): + # + # Obtain the hob list pointer + # + movl 0x4(%esp), %eax + # + # Obtain the stack information + # ECX: start of range + # EDX: end of range + # + movl 0x8(%esp), %ecx + movl 0xC(%esp), %edx + + # + # Platform init + # + pushal + pushl %edx + pushl %ecx + pushl %eax + call ASM_PFX(PlatformInit) + popl %eax + popl %eax + popl %eax + popal + + # + # Set stack top pointer + # + movl %edx, %esp + + # + # Push the hob list pointer + # + pushl %eax + + # + # Save the value + # ECX: start of range + # EDX: end of range + # + movl %esp, %ebp + pushl %ecx + pushl %edx + + # + # Push processor count to stack first, then BIST status (AP then BSP) + # + movl $1, %eax + cpuid + shr $16, %ebx + andl $0x000000FF, %ebx + cmp $1, %bl + jae PushProcessorCount + + # + # Some processors report 0 logical processors. Effectively 0 = 1. + # So we fix up the processor count + # + inc %ebx + +PushProcessorCount: + pushl %ebx + + # + # We need to implement a long-term solution for BIST capture. For now, we just copy BSP BIST + # for all processor threads + # + xorl %ecx, %ecx + movb %bl, %cl +PushBist: + movd %mm0, %eax + pushl %eax + loop PushBist + + # Save Time-Stamp Counter + movd %mm5, %eax + pushl %eax + + movd %mm6, %eax + pushl %eax + + # + # Pass entry point of the PEI core + # + movl $0xFFFFFFE0, %edi + pushl %ds:(%edi) + + # + # Pass BFV into the PEI Core + # + movl $0xFFFFFFFC, %edi + pushl %ds:(%edi) + + # + # Pass stack size into the PEI Core + # + movl -4(%ebp), %ecx + movl -8(%ebp), %edx + pushl %ecx # RamBase + + subl %ecx, %edx + pushl %edx # RamSize + + # + # Pass Control into the PEI Core + # + call ASM_PFX(SecStartup) diff --git a/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/PeiCoreEntry.asm b/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/PeiCoreEntry.asm new file mode 100644 index 0000000000..cd1c7b8c5d --- /dev/null +++ b/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/PeiCoreEntry.asm @@ -0,0 +1,140 @@ +;------------------------------------------------------------------------------ +; +; Copyright (c) 2014, Intel Corporation. All rights reserved.
+; This program and the accompanying materials +; are licensed and made available under the terms and conditions of the BSD License +; which accompanies this distribution. The full text of the license may be found at +; http://opensource.org/licenses/bsd-license.php. +; +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +; +; Module Name: +; +; PeiCoreEntry.asm +; +; Abstract: +; +; Find and call SecStartup +; +;------------------------------------------------------------------------------ + +.686p +.xmm +.model flat, c +.code + +EXTRN SecStartup:NEAR +EXTRN PlatformInit:NEAR + +CallPeiCoreEntryPoint PROC PUBLIC + ; + ; Obtain the hob list pointer + ; + mov eax, [esp+4] + ; + ; Obtain the stack information + ; ECX: start of range + ; EDX: end of range + ; + mov ecx, [esp+8] + mov edx, [esp+0Ch] + + ; + ; Platform init + ; + pushad + push edx + push ecx + push eax + call PlatformInit + pop eax + pop eax + pop eax + popad + + ; + ; Set stack top pointer + ; + mov esp, edx + + ; + ; Push the hob list pointer + ; + push eax + + ; + ; Save the value + ; ECX: start of range + ; EDX: end of range + ; + mov ebp, esp + push ecx + push edx + + ; + ; Push processor count to stack first, then BIST status (AP then BSP) + ; + mov eax, 1 + cpuid + shr ebx, 16 + and ebx, 0000000FFh + cmp bl, 1 + jae PushProcessorCount + + ; + ; Some processors report 0 logical processors. Effectively 0 = 1. + ; So we fix up the processor count + ; + inc ebx + +PushProcessorCount: + push ebx + + ; + ; We need to implement a long-term solution for BIST capture. For now, we just copy BSP BIST + ; for all processor threads + ; + xor ecx, ecx + mov cl, bl +PushBist: + movd eax, mm0 + push eax + loop PushBist + + ; Save Time-Stamp Counter + movd eax, mm5 + push eax + + movd eax, mm6 + push eax + + ; + ; Pass entry point of the PEI core + ; + mov edi, 0FFFFFFE0h + push DWORD PTR ds:[edi] + + ; + ; Pass BFV into the PEI Core + ; + mov edi, 0FFFFFFFCh + push DWORD PTR ds:[edi] + + ; + ; Pass stack size into the PEI Core + ; + mov ecx, [ebp - 4] + mov edx, [ebp - 8] + push ecx ; RamBase + + sub edx, ecx + push edx ; RamSize + + ; + ; Pass Control into the PEI Core + ; + call SecStartup +CallPeiCoreEntryPoint ENDP + +END diff --git a/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/SecEntry.S b/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/SecEntry.S new file mode 100644 index 0000000000..aff77f6f1b --- /dev/null +++ b/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/SecEntry.S @@ -0,0 +1,336 @@ +#------------------------------------------------------------------------------ +# +# Copyright (c) 2014, Intel Corporation. All rights reserved.
+# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +# Module Name: +# +# SecEntry.S +# +# Abstract: +# +# This is the code that goes from real-mode to protected mode. +# It consumes the reset vector, calls TempRamInit API from FSP binary. +# +#------------------------------------------------------------------------------ + +#include "Fsp.h" + +ASM_GLOBAL ASM_PFX(_gPcd_FixedAtBuild_PcdFsptBaseAddress) + +ASM_GLOBAL ASM_PFX(_TEXT_REALMODE) +ASM_PFX(_TEXT_REALMODE): +#---------------------------------------------------------------------------- +# +# Procedure: _ModuleEntryPoint +# +# Input: None +# +# Output: None +# +# Destroys: Assume all registers +# +# Description: +# +# Transition to non-paged flat-model protected mode from a +# hard-coded GDT that provides exactly two descriptors. +# This is a bare bones transition to protected mode only +# used for a while in PEI and possibly DXE. +# +# After enabling protected mode, a far jump is executed to +# transfer to PEI using the newly loaded GDT. +# +# Return: None +# +# MMX Usage: +# MM0 = BIST State +# MM5 = Save time-stamp counter value high32bit +# MM6 = Save time-stamp counter value low32bit. +# +#---------------------------------------------------------------------------- + +.align 4 +ASM_GLOBAL ASM_PFX(_ModuleEntryPoint) +ASM_PFX(_ModuleEntryPoint): + fninit # clear any pending Floating point exceptions + # + # Store the BIST value in mm0 + # + movd %eax, %mm0 + + # + # Save time-stamp counter value + # rdtsc load 64bit time-stamp counter to EDX:EAX + # + rdtsc + movd %edx, %mm5 + movd %ecx, %mm6 + + # + # Load the GDT table in GdtDesc + # + movl $GdtDesc, %esi + .byte 0x66 + lgdt %cs:(%si) + + # + # Transition to 16 bit protected mode + # + movl %cr0, %eax # Get control register 0 + orl $0x00000003, %eax # Set PE bit (bit #0) & MP bit (bit #1) + movl %eax, %cr0 # Activate protected mode + + movl %cr4, %eax # Get control register 4 + orl $0x00000600, %eax # Set OSFXSR bit (bit #9) & OSXMMEXCPT bit (bit #10) + movl %eax, %cr4 + + # + # Now we're in 16 bit protected mode + # Set up the selectors for 32 bit protected mode entry + # + movw SYS_DATA_SEL, %ax + movw %ax, %ds + movw %ax, %es + movw %ax, %fs + movw %ax, %gs + movw %ax, %ss + + # + # Transition to Flat 32 bit protected mode + # The jump to a far pointer causes the transition to 32 bit mode + # + movl ASM_PFX(ProtectedModeEntryLinearAddress), %esi + jmp *%cs:(%si) + +ASM_GLOBAL ASM_PFX(_TEXT_PROTECTED_MODE) +ASM_PFX(_TEXT_PROTECTED_MODE): + +#---------------------------------------------------------------------------- +# +# Procedure: ProtectedModeEntryPoint +# +# Input: None +# +# Output: None +# +# Destroys: Assume all registers +# +# Description: +# +# This function handles: +# Call two basic APIs from FSP binary +# Initializes stack with some early data (BIST, PEI entry, etc) +# +# Return: None +# +#---------------------------------------------------------------------------- + +.align 4 +ASM_GLOBAL ASM_PFX(ProtectedModeEntryPoint) +ASM_PFX(ProtectedModeEntryPoint): + + # Find the fsp info header + movl ASM_PFX(_gPcd_FixedAtBuild_PcdFsptBaseAddress), %edi + + movl FVH_SIGINATURE_OFFSET(%edi), %eax + cmp $FVH_SIGINATURE_VALID_VALUE, %eax + jnz FspHeaderNotFound + + xorl %eax, %eax + movw FVH_EXTHEADER_OFFSET_OFFSET(%edi), %ax + cmp %ax, 0 + jnz FspFvExtHeaderExist + + xorl %eax, %eax + movw FVH_HEADER_LENGTH_OFFSET(%edi), %ax # Bypass Fv Header + addl %eax, %edi + jmp FspCheckFfsHeader + +FspFvExtHeaderExist: + addl %eax, %edi + movl FVH_EXTHEADER_SIZE_OFFSET(%edi), %eax # Bypass Ext Fv Header + addl %eax, %edi + + # Round up to 8 byte alignment + movl %edi, %eax + andb $0x07, %al + jz FspCheckFfsHeader + + and $0xFFFFFFF8, %edi + add $0x08, %edi + +FspCheckFfsHeader: + # Check the ffs guid + movl (%edi), %eax + cmp $FSP_HEADER_GUID_DWORD1, %eax + jnz FspHeaderNotFound + + movl 0x4(%edi), %eax + cmp $FSP_HEADER_GUID_DWORD2, %eax + jnz FspHeaderNotFound + + movl 0x08(%edi), %eax + cmp $FSP_HEADER_GUID_DWORD3, %eax + jnz FspHeaderNotFound + + movl 0x0c(%edi), %eax + cmp $FSP_HEADER_GUID_DWORD4, %eax + jnz FspHeaderNotFound + + add $FFS_HEADER_SIZE_VALUE, %edi # Bypass the ffs header + + # Check the section type as raw section + movb SECTION_HEADER_TYPE_OFFSET(%edi), %al + cmp $0x19, %al + jnz FspHeaderNotFound + + addl $RAW_SECTION_HEADER_SIZE_VALUE, %edi # Bypass the section header + jmp FspHeaderFound + +FspHeaderNotFound: + jmp . + +FspHeaderFound: + # Get the fsp TempRamInit Api address + movl FSP_HEADER_IMAGEBASE_OFFSET(%edi), %eax + addl FSP_HEADER_TEMPRAMINIT_OFFSET(%edi), %eax + + # Setup the hardcode stack + movl $TempRamInitStack, %esp + + # Call the fsp TempRamInit Api + jmp *%eax + +TempRamInitDone: + cmp $0x8000000E, %eax #Check if EFI_NOT_FOUND returned. Error code for Microcode Update not found. + je CallSecFspInit #If microcode not found, don't hang, but continue. + + cmp $0x0, %eax + jnz FspApiFailed + + # ECX: start of range + # EDX: end of range +CallSecFspInit: + xorl %eax, %eax + movl %edx, %esp + + # Align the stack at DWORD + addl $3, %esp + andl $0xFFFFFFFC, %esp + + pushl %edx + pushl %ecx + pushl %eax # zero - no hob list yet + call ASM_PFX(CallPeiCoreEntryPoint) + +FspApiFailed: + jmp . + +.align 0x10 +TempRamInitStack: + .long TempRamInitDone + .long ASM_PFX(FsptUpdDataPtr) + +# +# ROM-based Global-Descriptor Table for the Tiano PEI Phase +# +.align 16 + +# +# GDT[0]: 0x00: Null entry, never used. +# +.equ NULL_SEL, . - GDT_BASE # Selector [0] +GDT_BASE: +BootGdtTable: .long 0 + .long 0 +# +# Linear data segment descriptor +# +.equ LINEAR_SEL, . - GDT_BASE # Selector [0x8] + .word 0xFFFF # limit 0xFFFFF + .word 0 # base 0 + .byte 0 + .byte 0x92 # present, ring 0, data, expand-up, writable + .byte 0xCF # page-granular, 32-bit + .byte 0 +# +# Linear code segment descriptor +# +.equ LINEAR_CODE_SEL, . - GDT_BASE # Selector [0x10] + .word 0xFFFF # limit 0xFFFFF + .word 0 # base 0 + .byte 0 + .byte 0x9B # present, ring 0, data, expand-up, not-writable + .byte 0xCF # page-granular, 32-bit + .byte 0 +# +# System data segment descriptor +# +.equ SYS_DATA_SEL, . - GDT_BASE # Selector [0x18] + .word 0xFFFF # limit 0xFFFFF + .word 0 # base 0 + .byte 0 + .byte 0x93 # present, ring 0, data, expand-up, not-writable + .byte 0xCF # page-granular, 32-bit + .byte 0 + +# +# System code segment descriptor +# +.equ SYS_CODE_SEL, . - GDT_BASE # Selector [0x20] + .word 0xFFFF # limit 0xFFFFF + .word 0 # base 0 + .byte 0 + .byte 0x9A # present, ring 0, data, expand-up, writable + .byte 0xCF # page-granular, 32-bit + .byte 0 +# +# Spare segment descriptor +# +.equ SYS16_CODE_SEL, . - GDT_BASE # Selector [0x28] + .word 0xFFFF # limit 0xFFFFF + .word 0 # base 0 + .byte 0x0E # Changed from F000 to E000. + .byte 0x9B # present, ring 0, code, expand-up, writable + .byte 0x00 # byte-granular, 16-bit + .byte 0 +# +# Spare segment descriptor +# +.equ SYS16_DATA_SEL, . - GDT_BASE # Selector [0x30] + .word 0xFFFF # limit 0xFFFF + .word 0 # base 0 + .byte 0 + .byte 0x93 # present, ring 0, data, expand-up, not-writable + .byte 0x00 # byte-granular, 16-bit + .byte 0 + +# +# Spare segment descriptor +# +.equ SPARE5_SEL, . - GDT_BASE # Selector [0x38] + .word 0 # limit 0 + .word 0 # base 0 + .byte 0 + .byte 0 # present, ring 0, data, expand-up, writable + .byte 0 # page-granular, 32-bit + .byte 0 +.equ GDT_SIZE, . - BootGdtTable # Size, in bytes + +# +# GDT Descriptor +# +GdtDesc: # GDT descriptor + .word GDT_SIZE - 1 # GDT limit + .long BootGdtTable # GDT base address + +ASM_PFX(ProtectedModeEntryLinearAddress): +ProtectedModeEntryLinearOffset: + .long ASM_PFX(ProtectedModeEntryPoint) # Offset of our 32 bit code + .word LINEAR_CODE_SEL diff --git a/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/SecEntry.asm b/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/SecEntry.asm new file mode 100644 index 0000000000..ab8d46e9eb --- /dev/null +++ b/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/SecEntry.asm @@ -0,0 +1,353 @@ +;------------------------------------------------------------------------------ +; +; Copyright (c) 2014, Intel Corporation. All rights reserved.
+; This program and the accompanying materials +; are licensed and made available under the terms and conditions of the BSD License +; which accompanies this distribution. The full text of the license may be found at +; http://opensource.org/licenses/bsd-license.php. +; +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +; +; Module Name: +; +; SecEntry.asm +; +; Abstract: +; +; This is the code that goes from real-mode to protected mode. +; It consumes the reset vector, calls TempRamInit API from FSP binary. +; +;------------------------------------------------------------------------------ + +#include "Fsp.h" + +.686p +.xmm +.model small, c + +EXTRN CallPeiCoreEntryPoint:NEAR +EXTRN FsptUpdDataPtr:FAR + +; Pcds +EXTRN PcdGet32 (PcdFsptBaseAddress):DWORD + +_TEXT_REALMODE SEGMENT PARA PUBLIC USE16 'CODE' + ASSUME CS:_TEXT_REALMODE, DS:_TEXT_REALMODE + +;---------------------------------------------------------------------------- +; +; Procedure: _ModuleEntryPoint +; +; Input: None +; +; Output: None +; +; Destroys: Assume all registers +; +; Description: +; +; Transition to non-paged flat-model protected mode from a +; hard-coded GDT that provides exactly two descriptors. +; This is a bare bones transition to protected mode only +; used for a while in PEI and possibly DXE. +; +; After enabling protected mode, a far jump is executed to +; transfer to PEI using the newly loaded GDT. +; +; Return: None +; +; MMX Usage: +; MM0 = BIST State +; MM5 = Save time-stamp counter value high32bit +; MM6 = Save time-stamp counter value low32bit. +; +;---------------------------------------------------------------------------- + +align 4 +_ModuleEntryPoint PROC NEAR C PUBLIC + fninit ; clear any pending Floating point exceptions + ; + ; Store the BIST value in mm0 + ; + movd mm0, eax + + ; + ; Save time-stamp counter value + ; rdtsc load 64bit time-stamp counter to EDX:EAX + ; + rdtsc + movd mm5, edx + movd mm6, eax + + ; + ; Load the GDT table in GdtDesc + ; + mov esi, OFFSET GdtDesc + DB 66h + lgdt fword ptr cs:[si] + + ; + ; Transition to 16 bit protected mode + ; + mov eax, cr0 ; Get control register 0 + or eax, 00000003h ; Set PE bit (bit #0) & MP bit (bit #1) + mov cr0, eax ; Activate protected mode + + mov eax, cr4 ; Get control register 4 + or eax, 00000600h ; Set OSFXSR bit (bit #9) & OSXMMEXCPT bit (bit #10) + mov cr4, eax + + ; + ; Now we're in 16 bit protected mode + ; Set up the selectors for 32 bit protected mode entry + ; + mov ax, SYS_DATA_SEL + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + mov ss, ax + + ; + ; Transition to Flat 32 bit protected mode + ; The jump to a far pointer causes the transition to 32 bit mode + ; + mov esi, offset ProtectedModeEntryLinearAddress + jmp fword ptr cs:[si] + +_ModuleEntryPoint ENDP +_TEXT_REALMODE ENDS + +_TEXT_PROTECTED_MODE SEGMENT PARA PUBLIC USE32 'CODE' + ASSUME CS:_TEXT_PROTECTED_MODE, DS:_TEXT_PROTECTED_MODE + +;---------------------------------------------------------------------------- +; +; Procedure: ProtectedModeEntryPoint +; +; Input: None +; +; Output: None +; +; Destroys: Assume all registers +; +; Description: +; +; This function handles: +; Call two basic APIs from FSP binary +; Initializes stack with some early data (BIST, PEI entry, etc) +; +; Return: None +; +;---------------------------------------------------------------------------- + +align 4 +ProtectedModeEntryPoint PROC NEAR PUBLIC + + ; Find the fsp info header + mov edi, PcdGet32 (PcdFsptBaseAddress) + + mov eax, dword ptr [edi + FVH_SIGINATURE_OFFSET] + cmp eax, FVH_SIGINATURE_VALID_VALUE + jnz FspHeaderNotFound + + xor eax, eax + mov ax, word ptr [edi + FVH_EXTHEADER_OFFSET_OFFSET] + cmp ax, 0 + jnz FspFvExtHeaderExist + + xor eax, eax + mov ax, word ptr [edi + FVH_HEADER_LENGTH_OFFSET] ; Bypass Fv Header + add edi, eax + jmp FspCheckFfsHeader + +FspFvExtHeaderExist: + add edi, eax + mov eax, dword ptr [edi + FVH_EXTHEADER_SIZE_OFFSET] ; Bypass Ext Fv Header + add edi, eax + + ; Round up to 8 byte alignment + mov eax, edi + and al, 07h + jz FspCheckFfsHeader + + and edi, 0FFFFFFF8h + add edi, 08h + +FspCheckFfsHeader: + ; Check the ffs guid + mov eax, dword ptr [edi] + cmp eax, FSP_HEADER_GUID_DWORD1 + jnz FspHeaderNotFound + + mov eax, dword ptr [edi + 4] + cmp eax, FSP_HEADER_GUID_DWORD2 + jnz FspHeaderNotFound + + mov eax, dword ptr [edi + 8] + cmp eax, FSP_HEADER_GUID_DWORD3 + jnz FspHeaderNotFound + + mov eax, dword ptr [edi + 0Ch] + cmp eax, FSP_HEADER_GUID_DWORD4 + jnz FspHeaderNotFound + + add edi, FFS_HEADER_SIZE_VALUE ; Bypass the ffs header + + ; Check the section type as raw section + mov al, byte ptr [edi + SECTION_HEADER_TYPE_OFFSET] + cmp al, 019h + jnz FspHeaderNotFound + + add edi, RAW_SECTION_HEADER_SIZE_VALUE ; Bypass the section header + jmp FspHeaderFound + +FspHeaderNotFound: + jmp $ + +FspHeaderFound: + ; Get the fsp TempRamInit Api address + mov eax, dword ptr [edi + FSP_HEADER_IMAGEBASE_OFFSET] + add eax, dword ptr [edi + FSP_HEADER_TEMPRAMINIT_OFFSET] + + ; Setup the hardcode stack + mov esp, OFFSET TempRamInitStack + + ; Call the fsp TempRamInit Api + jmp eax + +TempRamInitDone: + cmp eax, 8000000Eh ;Check if EFI_NOT_FOUND returned. Error code for Microcode Update not found. + je CallSecFspInit ;If microcode not found, don't hang, but continue. + + cmp eax, 0 ;Check if EFI_SUCCESS retuned. + jnz FspApiFailed + + ; ECX: start of range + ; EDX: end of range +CallSecFspInit: + xor eax, eax + mov esp, edx + + ; Align the stack at DWORD + add esp, 3 + and esp, 0FFFFFFFCh + + push edx + push ecx + push eax ; zero - no hob list yet + call CallPeiCoreEntryPoint + +FspApiFailed: + jmp $ + +align 10h +TempRamInitStack: + DD OFFSET TempRamInitDone + DD OFFSET FsptUpdDataPtr ; TempRamInitParams + +ProtectedModeEntryPoint ENDP + +; +; ROM-based Global-Descriptor Table for the Tiano PEI Phase +; +align 16 +PUBLIC BootGdtTable + +; +; GDT[0]: 0x00: Null entry, never used. +; +NULL_SEL EQU $ - GDT_BASE ; Selector [0] +GDT_BASE: +BootGdtTable DD 0 + DD 0 +; +; Linear data segment descriptor +; +LINEAR_SEL EQU $ - GDT_BASE ; Selector [0x8] + DW 0FFFFh ; limit 0xFFFFF + DW 0 ; base 0 + DB 0 + DB 092h ; present, ring 0, data, expand-up, writable + DB 0CFh ; page-granular, 32-bit + DB 0 +; +; Linear code segment descriptor +; +LINEAR_CODE_SEL EQU $ - GDT_BASE ; Selector [0x10] + DW 0FFFFh ; limit 0xFFFFF + DW 0 ; base 0 + DB 0 + DB 09Bh ; present, ring 0, data, expand-up, not-writable + DB 0CFh ; page-granular, 32-bit + DB 0 +; +; System data segment descriptor +; +SYS_DATA_SEL EQU $ - GDT_BASE ; Selector [0x18] + DW 0FFFFh ; limit 0xFFFFF + DW 0 ; base 0 + DB 0 + DB 093h ; present, ring 0, data, expand-up, not-writable + DB 0CFh ; page-granular, 32-bit + DB 0 + +; +; System code segment descriptor +; +SYS_CODE_SEL EQU $ - GDT_BASE ; Selector [0x20] + DW 0FFFFh ; limit 0xFFFFF + DW 0 ; base 0 + DB 0 + DB 09Ah ; present, ring 0, data, expand-up, writable + DB 0CFh ; page-granular, 32-bit + DB 0 +; +; Spare segment descriptor +; +SYS16_CODE_SEL EQU $ - GDT_BASE ; Selector [0x28] + DW 0FFFFh ; limit 0xFFFFF + DW 0 ; base 0 + DB 0Eh ; Changed from F000 to E000. + DB 09Bh ; present, ring 0, code, expand-up, writable + DB 00h ; byte-granular, 16-bit + DB 0 +; +; Spare segment descriptor +; +SYS16_DATA_SEL EQU $ - GDT_BASE ; Selector [0x30] + DW 0FFFFh ; limit 0xFFFF + DW 0 ; base 0 + DB 0 + DB 093h ; present, ring 0, data, expand-up, not-writable + DB 00h ; byte-granular, 16-bit + DB 0 + +; +; Spare segment descriptor +; +SPARE5_SEL EQU $ - GDT_BASE ; Selector [0x38] + DW 0 ; limit 0 + DW 0 ; base 0 + DB 0 + DB 0 ; present, ring 0, data, expand-up, writable + DB 0 ; page-granular, 32-bit + DB 0 +GDT_SIZE EQU $ - BootGdtTable ; Size, in bytes + +; +; GDT Descriptor +; +GdtDesc: ; GDT descriptor + DW GDT_SIZE - 1 ; GDT limit + DD OFFSET BootGdtTable ; GDT base address + + +ProtectedModeEntryLinearAddress LABEL FWORD +ProtectedModeEntryLinearOffset LABEL DWORD + DD OFFSET ProtectedModeEntryPoint ; Offset of our 32 bit code + DW LINEAR_CODE_SEL + +_TEXT_PROTECTED_MODE ENDS +END diff --git a/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/Stack.S b/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/Stack.S new file mode 100644 index 0000000000..ae4293589d --- /dev/null +++ b/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/Stack.S @@ -0,0 +1,77 @@ +#------------------------------------------------------------------------------ +# +# Copyright (c) 2014, Intel Corporation. All rights reserved.
+# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +# Abstract: +# +# Switch the stack from temporary memory to permenent memory. +# +#------------------------------------------------------------------------------ + + +#------------------------------------------------------------------------------ +# VOID +# EFIAPI +# SecSwitchStack ( +# UINT32 TemporaryMemoryBase, +# UINT32 PermanentMemoryBase +# )# +#------------------------------------------------------------------------------ +ASM_GLOBAL ASM_PFX (SecSwitchStack) +ASM_PFX(SecSwitchStack): + # + # Save standard registers so they can be used to change stack + # + pushl %eax + pushl %ebx + pushl %ecx + pushl %edx + + # + # !!CAUTION!! this function address's is pushed into stack after + # migration of whole temporary memory, so need save it to permanent + # memory at first! + # + movl 20(%esp), %ebx # Save the first parameter + movl 24(%esp), %ecx # Save the second parameter + + # + # Save this function's return address into permanent memory at first. + # Then, Fixup the esp point to permanent memory + # + movl %esp, %eax + subl %ebx, %eax + addl %ecx, %eax + movl 0(%esp), %edx # copy pushed register's value to permanent memory + movl %edx, 0(%eax) + movl 4(%esp), %edx + movl %edx, 4(%eax) + movl 8(%esp), %edx + movl %edx, 8(%eax) + movl 12(%esp), %edx + movl %edx, 12(%eax) + movl 16(%esp), %edx # Update this function's return address into permanent memory + movl %edx, 16(%eax) + movl %eax, %esp # From now, esp is pointed to permanent memory + + # + # Fixup the ebp point to permanent memory + # + movl %ebp, %eax + subl %ebx, %eax + addl %ecx, %eax + movl %eax, %ebp # From now, ebp is pointed to permanent memory + + popl %edx + popl %ecx + popl %ebx + popl %eax + ret + diff --git a/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/Stack.asm b/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/Stack.asm new file mode 100644 index 0000000000..116b738fc7 --- /dev/null +++ b/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/Stack.asm @@ -0,0 +1,82 @@ +;------------------------------------------------------------------------------ +; +; Copyright (c) 2014, Intel Corporation. All rights reserved.
+; This program and the accompanying materials +; are licensed and made available under the terms and conditions of the BSD License +; which accompanies this distribution. The full text of the license may be found at +; http://opensource.org/licenses/bsd-license.php. +; +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +; +; Abstract: +; +; Switch the stack from temporary memory to permenent memory. +; +;------------------------------------------------------------------------------ + + .586p + .model flat,C + .code + +;------------------------------------------------------------------------------ +; VOID +; EFIAPI +; SecSwitchStack ( +; UINT32 TemporaryMemoryBase, +; UINT32 PermanentMemoryBase +; ); +;------------------------------------------------------------------------------ +SecSwitchStack PROC + ; + ; Save three register: eax, ebx, ecx + ; + push eax + push ebx + push ecx + push edx + + ; + ; !!CAUTION!! this function address's is pushed into stack after + ; migration of whole temporary memory, so need save it to permanent + ; memory at first! + ; + + mov ebx, [esp + 20] ; Save the first parameter + mov ecx, [esp + 24] ; Save the second parameter + + ; + ; Save this function's return address into permanent memory at first. + ; Then, Fixup the esp point to permanent memory + ; + mov eax, esp + sub eax, ebx + add eax, ecx + mov edx, dword ptr [esp] ; copy pushed register's value to permanent memory + mov dword ptr [eax], edx + mov edx, dword ptr [esp + 4] + mov dword ptr [eax + 4], edx + mov edx, dword ptr [esp + 8] + mov dword ptr [eax + 8], edx + mov edx, dword ptr [esp + 12] + mov dword ptr [eax + 12], edx + mov edx, dword ptr [esp + 16] ; Update this function's return address into permanent memory + mov dword ptr [eax + 16], edx + mov esp, eax ; From now, esp is pointed to permanent memory + + ; + ; Fixup the ebp point to permanent memory + ; + mov eax, ebp + sub eax, ebx + add eax, ecx + mov ebp, eax ; From now, ebp is pointed to permanent memory + + pop edx + pop ecx + pop ebx + pop eax + ret +SecSwitchStack ENDP + + END diff --git a/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/PlatformInit.c b/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/PlatformInit.c new file mode 100644 index 0000000000..ba75e0f835 --- /dev/null +++ b/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/PlatformInit.c @@ -0,0 +1,45 @@ +/** @file + Sample to provide platform init function. + + Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + + +#include +#include +#include + +/** + Platform initialization. + + @param[in] FspHobList HobList produced by FSP. + @param[in] StartOfRange Start of temporary RAM. + @param[in] EndOfRange End of temporary RAM. +**/ +VOID +EFIAPI +PlatformInit ( + IN VOID *FspHobList, + IN VOID *StartOfRange, + IN VOID *EndOfRange + ) +{ + // + // Platform initialization + // Enable Serial port here + // + SerialPortInitialize (); + + DEBUG ((DEBUG_INFO, "PrintPeiCoreEntryPointParam in PlatformInit\n")); + DEBUG ((DEBUG_INFO, "FspHobList - 0x%x\n", FspHobList)); + DEBUG ((DEBUG_INFO, "StartOfRange - 0x%x\n", StartOfRange)); + DEBUG ((DEBUG_INFO, "EndOfRange - 0x%x\n", EndOfRange)); +} diff --git a/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/SecFspWrapperPlatformSecLibSample.inf b/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/SecFspWrapperPlatformSecLibSample.inf new file mode 100644 index 0000000000..10df778df3 --- /dev/null +++ b/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/SecFspWrapperPlatformSecLibSample.inf @@ -0,0 +1,89 @@ +## @file +# Sample to provide FSP wrapper platform sec related function. +# +# Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +################################################################################ +# +# Defines Section - statements that will be processed to create a Makefile. +# +################################################################################ +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = SecFspWrapperPlatformSecLibSample + FILE_GUID = 8F1AC44A-CE7E-4E29-95BB-92E321BB1573 + MODULE_TYPE = SEC + VERSION_STRING = 1.0 + LIBRARY_CLASS = FspWrapperPlatformSecLib + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +################################################################################ +# +# Sources Section - list of files that are required for the build to succeed. +# +################################################################################ + +[Sources] + FspWrapperPlatformSecLibSample.c + SecRamInitData.c + SecPlatformInformation.c + SecGetPerformance.c + SecTempRamDone.c + PlatformInit.c + +[Sources.IA32] + Ia32/SecEntry.asm + Ia32/PeiCoreEntry.asm + Ia32/Stack.asm + Ia32/Fsp.h + Ia32/SecEntry.S + Ia32/PeiCoreEntry.S + Ia32/Stack.S + +################################################################################ +# +# Package Dependency Section - list of Package files that are required for +# this module. +# +################################################################################ + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + UefiCpuPkg/UefiCpuPkg.dec + IntelFsp2Pkg/IntelFsp2Pkg.dec + IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec + +[LibraryClasses] + LocalApicLib + SerialPortLib + +[Ppis] + gEfiSecPlatformInformationPpiGuid ## CONSUMES + gPeiSecPerformancePpiGuid ## CONSUMES + gTopOfTemporaryRamPpiGuid ## PRODUCES + +[Pcd] + gFspWrapperTokenSpaceGuid.PcdFsptBaseAddress ## CONSUMES + gFspWrapperTokenSpaceGuid.PcdFspmBaseAddress ## CONSUMES + +[FixedPcd] + gFspWrapperTokenSpaceGuid.PcdCpuMicrocodePatchAddress ## CONSUMES + gFspWrapperTokenSpaceGuid.PcdCpuMicrocodePatchRegionSize ## CONSUMES + gFspWrapperTokenSpaceGuid.PcdFlashMicrocodeOffset ## CONSUMES + gFspWrapperTokenSpaceGuid.PcdFlashCodeCacheAddress ## CONSUMES + gFspWrapperTokenSpaceGuid.PcdFlashCodeCacheSize ## CONSUMES diff --git a/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/SecGetPerformance.c b/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/SecGetPerformance.c new file mode 100644 index 0000000000..e2d6b3da57 --- /dev/null +++ b/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/SecGetPerformance.c @@ -0,0 +1,90 @@ +/** @file + Sample to provide SecGetPerformance function. + + Copyright (c) 2014, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include + +#include +#include + +#include +#include +#include + +/** + This interface conveys performance information out of the Security (SEC) phase into PEI. + + This service is published by the SEC phase. The SEC phase handoff has an optional + EFI_PEI_PPI_DESCRIPTOR list as its final argument when control is passed from SEC into the + PEI Foundation. As such, if the platform supports collecting performance data in SEC, + this information is encapsulated into the data structure abstracted by this service. + This information is collected for the boot-strap processor (BSP) on IA-32. + + @param[in] PeiServices The pointer to the PEI Services Table. + @param[in] This The pointer to this instance of the PEI_SEC_PERFORMANCE_PPI. + @param[out] Performance The pointer to performance data collected in SEC phase. + + @retval EFI_SUCCESS The data was successfully returned. + +**/ +EFI_STATUS +EFIAPI +SecGetPerformance ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN PEI_SEC_PERFORMANCE_PPI *This, + OUT FIRMWARE_SEC_PERFORMANCE *Performance + ) +{ + UINT32 Size; + UINT32 Count; + UINT32 TopOfTemporaryRam; + UINT64 Ticker; + VOID *TopOfTemporaryRamPpi; + EFI_STATUS Status; + + DEBUG ((DEBUG_INFO, "SecGetPerformance\n")); + + Status = (*PeiServices)->LocatePpi ( + PeiServices, + &gTopOfTemporaryRamPpiGuid, + 0, + NULL, + (VOID **) &TopOfTemporaryRamPpi + ); + if (EFI_ERROR (Status)) { + return EFI_NOT_FOUND; + } + + // + // |--------------| <- TopOfTemporaryRam + // |Number of BSPs| + // |--------------| + // | BIST | + // |--------------| + // | .... | + // |--------------| + // | TSC[63:32] | + // |--------------| + // | TSC[31:00] | + // |--------------| + // + TopOfTemporaryRam = (UINT32)(UINTN)TopOfTemporaryRamPpi - sizeof(UINT32); + TopOfTemporaryRam -= sizeof(UINT32) * 2; + Count = *(UINT32 *) (UINTN) (TopOfTemporaryRam - sizeof (UINT32)); + Size = Count * sizeof (UINT64); + + Ticker = *(UINT64 *) (UINTN) (TopOfTemporaryRam - sizeof (UINT32) - Size - sizeof (UINT32) * 2); + Performance->ResetEnd = GetTimeInNanoSecond (Ticker); + + return EFI_SUCCESS; +} diff --git a/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/SecPlatformInformation.c b/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/SecPlatformInformation.c new file mode 100644 index 0000000000..b879080dfa --- /dev/null +++ b/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/SecPlatformInformation.c @@ -0,0 +1,84 @@ +/** @file + Sample to provide SecPlatformInformation function. + + Copyright (c) 2014, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include + +#include +#include + +#include +#include + +/** + This interface conveys state information out of the Security (SEC) phase into PEI. + + @param[in] PeiServices Pointer to the PEI Services Table. + @param[in,out] StructureSize Pointer to the variable describing size of the input buffer. + @param[out] PlatformInformationRecord Pointer to the EFI_SEC_PLATFORM_INFORMATION_RECORD. + + @retval EFI_SUCCESS The data was successfully returned. + @retval EFI_BUFFER_TOO_SMALL The buffer was too small. + +**/ +EFI_STATUS +EFIAPI +SecPlatformInformation ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN OUT UINT64 *StructureSize, + OUT EFI_SEC_PLATFORM_INFORMATION_RECORD *PlatformInformationRecord + ) +{ + UINT32 *Bist; + UINT32 Size; + UINT32 Count; + UINT32 TopOfTemporaryRam; + VOID *TopOfTemporaryRamPpi; + EFI_STATUS Status; + + DEBUG ((DEBUG_INFO, "SecPlatformInformation\n")); + + Status = (*PeiServices)->LocatePpi ( + PeiServices, + &gTopOfTemporaryRamPpiGuid, + 0, + NULL, + (VOID **) &TopOfTemporaryRamPpi + ); + if (EFI_ERROR (Status)) { + return EFI_NOT_FOUND; + } + + // + // The entries of BIST information, together with the number of them, + // reside in the bottom of stack, left untouched by normal stack operation. + // This routine copies the BIST information to the buffer pointed by + // PlatformInformationRecord for output. + // + TopOfTemporaryRam = (UINT32)(UINTN)TopOfTemporaryRamPpi - sizeof (UINT32); + TopOfTemporaryRam -= sizeof(UINT32) * 2; + Count = *((UINT32 *)(UINTN) (TopOfTemporaryRam - sizeof (UINT32))); + Size = Count * sizeof (IA32_HANDOFF_STATUS); + + if ((*StructureSize) < (UINT64) Size) { + *StructureSize = Size; + return EFI_BUFFER_TOO_SMALL; + } + + *StructureSize = Size; + Bist = (UINT32 *) (TopOfTemporaryRam - sizeof (UINT32) - Size); + + CopyMem (PlatformInformationRecord, Bist, Size); + + return EFI_SUCCESS; +} diff --git a/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/SecRamInitData.c b/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/SecRamInitData.c new file mode 100644 index 0000000000..e2fbc4510f --- /dev/null +++ b/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/SecRamInitData.c @@ -0,0 +1,45 @@ +/** @file + Sample to provide TempRamInitParams data. + + Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include + +typedef struct { + UINT32 MicrocodeRegionBase; + UINT32 MicrocodeRegionSize; + UINT32 CodeRegionBase; + UINT32 CodeRegionSize; +} FSPT_CORE_UPD; + +typedef struct { + FSP_UPD_HEADER FspUpdHeader; + FSPT_CORE_UPD FsptCoreUpd; +} FSPT_UPD_CORE_DATA; + +GLOBAL_REMOVE_IF_UNREFERENCED CONST FSPT_UPD_CORE_DATA FsptUpdDataPtr = { + { + 0x4450555F54505346, + 0x00, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + } + }, + { + ((UINT32)FixedPcdGet64 (PcdCpuMicrocodePatchAddress) + FixedPcdGet32 (PcdFlashMicrocodeOffset)), + ((UINT32)FixedPcdGet64 (PcdCpuMicrocodePatchRegionSize) - FixedPcdGet32 (PcdFlashMicrocodeOffset)), + FixedPcdGet32 (PcdFlashCodeCacheAddress), + FixedPcdGet32 (PcdFlashCodeCacheSize), + } +}; + diff --git a/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/SecTempRamDone.c b/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/SecTempRamDone.c new file mode 100644 index 0000000000..76d2f42086 --- /dev/null +++ b/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/SecTempRamDone.c @@ -0,0 +1,52 @@ +/** @file + Sample to provide SecTemporaryRamDone function. + + Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include + +#include + +#include +#include +#include +#include +#include +#include + +/** +This interface disables temporary memory in SEC Phase. +**/ +VOID +EFIAPI +SecPlatformDisableTemporaryMemory ( + VOID + ) +{ + EFI_STATUS Status; + VOID *TempRamExitParam; + FSP_INFO_HEADER *FspHeader; + + FspHeader = FspFindFspHeader (PcdGet32(PcdFspmBaseAddress)); + if (FspHeader == NULL) { + return ; + } + + DEBUG((DEBUG_INFO, "SecPlatformDisableTemporaryMemory enter\n")); + + TempRamExitParam = GetTempRamExitParam (); + Status = CallTempRamExit (FspHeader, TempRamExitParam); + DEBUG((DEBUG_INFO, "TempRamExit status: 0x%x\n", Status)); + ASSERT_EFI_ERROR(Status); + + return ; +} -- 2.39.2