diff options
author | Guo Mang <mang.guo@intel.com> | 2017-04-27 11:14:40 +0800 |
---|---|---|
committer | Guo Mang <mang.guo@intel.com> | 2017-04-27 11:14:40 +0800 |
commit | 517785fc9a17f2445ae49b3f4e6a8c61fed8aea1 (patch) | |
tree | b420f3443ecc7221d1f890f5980763146667df9e /Core/IntelFsp2Pkg | |
parent | af874ef836cedf1034bc51eb65a99e9ea4fdc904 (diff) | |
download | edk2-platforms-517785fc9a17f2445ae49b3f4e6a8c61fed8aea1.tar.xz |
IntelFsp2Pkg: Move to new location
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Guo Mang <mang.guo@intel.com>
Diffstat (limited to 'Core/IntelFsp2Pkg')
72 files changed, 11189 insertions, 0 deletions
diff --git a/Core/IntelFsp2Pkg/Contributions.txt b/Core/IntelFsp2Pkg/Contributions.txt new file mode 100644 index 0000000000..f87cbd73c6 --- /dev/null +++ b/Core/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 <contributor@example.com>
+Subject: [PATCH] CodeModule: Brief-single-line-summary
+
+Full-commit-message
+
+Contributed-under: TianoCore Contribution Agreement 1.0
+Signed-off-by: Contributor Name <contributor@example.com>
+---
+
+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/Core/IntelFsp2Pkg/FspNotifyPhase/FspNotifyPhasePeim.c b/Core/IntelFsp2Pkg/FspNotifyPhase/FspNotifyPhasePeim.c new file mode 100644 index 0000000000..41131d5854 --- /dev/null +++ b/Core/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"));
+ FspSiliconInitDone2 (EFI_SUCCESS);
+
+ //
+ // 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/Core/IntelFsp2Pkg/FspNotifyPhase/FspNotifyPhasePeim.h b/Core/IntelFsp2Pkg/FspNotifyPhase/FspNotifyPhasePeim.h new file mode 100644 index 0000000000..6e2ae591ec --- /dev/null +++ b/Core/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 <Library/PeiServicesLib.h>
+#include <Ppi/DxeIpl.h>
+#include <Library/DebugLib.h>
+#include <Library/FspPlatformLib.h>
+#include <Library/FspCommonLib.h>
+#include <Library/FspSwitchStackLib.h>
+#endif
diff --git a/Core/IntelFsp2Pkg/FspNotifyPhase/FspNotifyPhasePeim.inf b/Core/IntelFsp2Pkg/FspNotifyPhase/FspNotifyPhasePeim.inf new file mode 100644 index 0000000000..75f7ae5fb7 --- /dev/null +++ b/Core/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/Core/IntelFsp2Pkg/FspSecCore/FspSecCoreM.inf b/Core/IntelFsp2Pkg/FspSecCore/FspSecCoreM.inf new file mode 100644 index 0000000000..611fab215a --- /dev/null +++ b/Core/IntelFsp2Pkg/FspSecCore/FspSecCoreM.inf @@ -0,0 +1,74 @@ +## @file
+# Sec Core for FSP
+#
+# Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[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/Core/IntelFsp2Pkg/FspSecCore/FspSecCoreS.inf b/Core/IntelFsp2Pkg/FspSecCore/FspSecCoreS.inf new file mode 100644 index 0000000000..8e1bb4a592 --- /dev/null +++ b/Core/IntelFsp2Pkg/FspSecCore/FspSecCoreS.inf @@ -0,0 +1,68 @@ +## @file
+# Sec Core for FSP
+#
+# Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[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/Core/IntelFsp2Pkg/FspSecCore/FspSecCoreT.inf b/Core/IntelFsp2Pkg/FspSecCore/FspSecCoreT.inf new file mode 100644 index 0000000000..cf6a1918a3 --- /dev/null +++ b/Core/IntelFsp2Pkg/FspSecCore/FspSecCoreT.inf @@ -0,0 +1,66 @@ +## @file
+# Sec Core for FSP
+#
+# Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[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/Core/IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryCommon.nasm b/Core/IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryCommon.nasm new file mode 100644 index 0000000000..c48a95694c --- /dev/null +++ b/Core/IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryCommon.nasm @@ -0,0 +1,76 @@ +;; @file
+; Provide FSP API entry points.
+;
+; Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+; This program and the accompanying materials
+; are licensed and made available under the terms and conditions of the BSD License
+; which accompanies this distribution. The full text of the license may be found at
+; http://opensource.org/licenses/bsd-license.php.
+;
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+;;
+
+ 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/Core/IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryM.nasm b/Core/IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryM.nasm new file mode 100644 index 0000000000..9744e1682d --- /dev/null +++ b/Core/IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryM.nasm @@ -0,0 +1,202 @@ +;; @file
+; Provide FSP API entry points.
+;
+; Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+; This program and the accompanying materials
+; are licensed and made available under the terms and conditions of the BSD License
+; which accompanies this distribution. The full text of the license may be found at
+; http://opensource.org/licenses/bsd-license.php.
+;
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+;;
+
+ 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/Core/IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryS.nasm b/Core/IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryS.nasm new file mode 100644 index 0000000000..cdc1149d6c --- /dev/null +++ b/Core/IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryS.nasm @@ -0,0 +1,62 @@ +;; @file
+; Provide FSP API entry points.
+;
+; Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+; This program and the accompanying materials
+; are licensed and made available under the terms and conditions of the BSD License
+; which accompanies this distribution. The full text of the license may be found at
+; http://opensource.org/licenses/bsd-license.php.
+;
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+;;
+
+ 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/Core/IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryT.nasm b/Core/IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryT.nasm new file mode 100644 index 0000000000..6e860238fd --- /dev/null +++ b/Core/IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryT.nasm @@ -0,0 +1,477 @@ +;; @file
+; Provide FSP API entry points.
+;
+; Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+; This program and the accompanying materials
+; are licensed and made available under the terms and conditions of the BSD License
+; which accompanies this distribution. The full text of the license may be found at
+; http://opensource.org/licenses/bsd-license.php.
+;
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+;;
+
+ 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
+
+ ; skip loading Microcode if the MicrocodeCodeSize is zero
+ ; and report error if size is less than 2k
+ mov eax, dword [esp + LoadMicrocodeParams.MicrocodeCodeSize]
+ cmp eax, 0
+ jz Exit2
+ cmp eax, 0800h
+ jl ParamError
+
+ 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/Core/IntelFsp2Pkg/FspSecCore/Ia32/FspHelper.nasm b/Core/IntelFsp2Pkg/FspSecCore/Ia32/FspHelper.nasm new file mode 100644 index 0000000000..ad631943e3 --- /dev/null +++ b/Core/IntelFsp2Pkg/FspSecCore/Ia32/FspHelper.nasm @@ -0,0 +1,41 @@ +;; @file
+; Provide FSP helper function.
+;
+; Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
+; This program and the accompanying materials
+; are licensed and made available under the terms and conditions of the BSD License
+; which accompanies this distribution. The full text of the license may be found at
+; http://opensource.org/licenses/bsd-license.php.
+;
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+;;
+
+ SECTION .text
+
+global ASM_PFX(FspInfoHeaderRelativeOff)
+ASM_PFX(FspInfoHeaderRelativeOff):
+ DD 0x12345678 ; This value must be patched by the build script
+
+global ASM_PFX(AsmGetFspBaseAddress)
+ASM_PFX(AsmGetFspBaseAddress):
+ call ASM_PFX(AsmGetFspInfoHeader)
+ add eax, 0x1C
+ mov eax, dword [eax]
+ ret
+
+global ASM_PFX(AsmGetFspInfoHeader)
+ASM_PFX(AsmGetFspInfoHeader):
+ call ASM_PFX(NextInstruction)
+ASM_PFX(NextInstruction):
+ pop eax
+ sub eax, ASM_PFX(NextInstruction)
+ add eax, ASM_PFX(AsmGetFspInfoHeader)
+ sub eax, dword [eax - ASM_PFX(AsmGetFspInfoHeader) + ASM_PFX(FspInfoHeaderRelativeOff)]
+ ret
+
+global ASM_PFX(AsmGetFspInfoHeaderNoStack)
+ASM_PFX(AsmGetFspInfoHeaderNoStack):
+ mov eax, ASM_PFX(AsmGetFspInfoHeader)
+ sub eax, dword [ASM_PFX(FspInfoHeaderRelativeOff)]
+ jmp edi
diff --git a/Core/IntelFsp2Pkg/FspSecCore/Ia32/InitializeFpu.nasm b/Core/IntelFsp2Pkg/FspSecCore/Ia32/InitializeFpu.nasm new file mode 100644 index 0000000000..cc87e893d5 --- /dev/null +++ b/Core/IntelFsp2Pkg/FspSecCore/Ia32/InitializeFpu.nasm @@ -0,0 +1,78 @@ +;------------------------------------------------------------------------------
+;
+; Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+; This program and the accompanying materials
+; are licensed and made available under the terms and conditions of the BSD License
+; which accompanies this distribution. The full text of the license may be found at
+; http://opensource.org/licenses/bsd-license.php.
+;
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+;
+; 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/Core/IntelFsp2Pkg/FspSecCore/Ia32/MicrocodeLoadNasm.inc b/Core/IntelFsp2Pkg/FspSecCore/Ia32/MicrocodeLoadNasm.inc new file mode 100644 index 0000000000..1663a85d11 --- /dev/null +++ b/Core/IntelFsp2Pkg/FspSecCore/Ia32/MicrocodeLoadNasm.inc @@ -0,0 +1,16 @@ +;; @file
+;
+;@copyright
+; Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
+; This program and the accompanying materials
+; are licensed and made available under the terms and conditions of the BSD License
+; which accompanies this distribution. The full text of the license may be found at
+; http://opensource.org/licenses/bsd-license.php.
+;
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+;;
+
+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/Core/IntelFsp2Pkg/FspSecCore/Ia32/SaveRestoreSseNasm.inc b/Core/IntelFsp2Pkg/FspSecCore/Ia32/SaveRestoreSseNasm.inc new file mode 100644 index 0000000000..ae0a93dc94 --- /dev/null +++ b/Core/IntelFsp2Pkg/FspSecCore/Ia32/SaveRestoreSseNasm.inc @@ -0,0 +1,187 @@ +;------------------------------------------------------------------------------
+;
+; Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+; This program and the accompanying materials
+; are licensed and made available under the terms and conditions of the BSD License
+; which accompanies this distribution. The full text of the license may be found at
+; http://opensource.org/licenses/bsd-license.php.
+;
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+;
+; 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/Core/IntelFsp2Pkg/FspSecCore/Ia32/Stack.nasm b/Core/IntelFsp2Pkg/FspSecCore/Ia32/Stack.nasm new file mode 100644 index 0000000000..338e700751 --- /dev/null +++ b/Core/IntelFsp2Pkg/FspSecCore/Ia32/Stack.nasm @@ -0,0 +1,78 @@ +;------------------------------------------------------------------------------
+;
+; Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+; This program and the accompanying materials
+; are licensed and made available under the terms and conditions of the BSD License
+; which accompanies this distribution. The full text of the license may be found at
+; http://opensource.org/licenses/bsd-license.php.
+;
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+;
+; 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/Core/IntelFsp2Pkg/FspSecCore/SecFsp.c b/Core/IntelFsp2Pkg/FspSecCore/SecFsp.c new file mode 100644 index 0000000000..96f8fb7554 --- /dev/null +++ b/Core/IntelFsp2Pkg/FspSecCore/SecFsp.c @@ -0,0 +1,214 @@ +/** @file
+
+ Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "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 = PcdGet32(PcdTemporaryRamBase) + PcdGet32(PcdTemporaryRamSize);
+ 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;
+
+ 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/Core/IntelFsp2Pkg/FspSecCore/SecFsp.h b/Core/IntelFsp2Pkg/FspSecCore/SecFsp.h new file mode 100644 index 0000000000..f199b12e4d --- /dev/null +++ b/Core/IntelFsp2Pkg/FspSecCore/SecFsp.h @@ -0,0 +1,99 @@ +/** @file
+
+ Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _SEC_FSP_H_
+#define _SEC_FSP_H_
+
+#include <PiPei.h>
+#include <FspEas.h>
+#include <Library/PcdLib.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/SerialPortLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/FspCommonLib.h>
+#include <Library/FspSecPlatformLib.h>
+
+#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/Core/IntelFsp2Pkg/FspSecCore/SecFspApiChk.c b/Core/IntelFsp2Pkg/FspSecCore/SecFspApiChk.c new file mode 100644 index 0000000000..bace5eca43 --- /dev/null +++ b/Core/IntelFsp2Pkg/FspSecCore/SecFspApiChk.c @@ -0,0 +1,97 @@ +/** @file
+
+ Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "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/Core/IntelFsp2Pkg/FspSecCore/SecMain.c b/Core/IntelFsp2Pkg/FspSecCore/SecMain.c new file mode 100644 index 0000000000..0432dee6ea --- /dev/null +++ b/Core/IntelFsp2Pkg/FspSecCore/SecMain.c @@ -0,0 +1,227 @@ +/** @file
+
+ Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "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 temporary 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
+ // immediately, also we need fixup the stack change caused by new call into
+ // permanent memory.
+ //
+ SecSwitchStack (
+ (UINT32) (UINTN) OldStack,
+ (UINT32) (UINTN) NewStack
+ );
+
+ return EFI_SUCCESS;
+}
diff --git a/Core/IntelFsp2Pkg/FspSecCore/SecMain.h b/Core/IntelFsp2Pkg/FspSecCore/SecMain.h new file mode 100644 index 0000000000..291bc5ca5c --- /dev/null +++ b/Core/IntelFsp2Pkg/FspSecCore/SecMain.h @@ -0,0 +1,140 @@ +/** @file
+
+ Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _SEC_CORE_H_
+#define _SEC_CORE_H_
+
+
+#include <PiPei.h>
+#include <Ppi/TemporaryRamSupport.h>
+
+#include <Library/BaseLib.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PciCf8Lib.h>
+#include <Library/SerialPortLib.h>
+#include <Library/FspSwitchStackLib.h>
+#include <Library/FspCommonLib.h>
+#include <FspEas.h>
+
+#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 temporary 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/Core/IntelFsp2Pkg/FspSecCore/Vtf0/Bin/ResetVec.ia32.raw b/Core/IntelFsp2Pkg/FspSecCore/Vtf0/Bin/ResetVec.ia32.raw Binary files differnew file mode 100644 index 0000000000..2dc9f178d3 --- /dev/null +++ b/Core/IntelFsp2Pkg/FspSecCore/Vtf0/Bin/ResetVec.ia32.raw diff --git a/Core/IntelFsp2Pkg/FspSecCore/Vtf0/Build.py b/Core/IntelFsp2Pkg/FspSecCore/Vtf0/Build.py new file mode 100644 index 0000000000..3018391445 --- /dev/null +++ b/Core/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.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+
+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/Core/IntelFsp2Pkg/FspSecCore/Vtf0/Ia16/ResetVec.asm16 b/Core/IntelFsp2Pkg/FspSecCore/Vtf0/Ia16/ResetVec.asm16 new file mode 100644 index 0000000000..585876fa86 --- /dev/null +++ b/Core/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.<BR>
+; This program and the accompanying materials
+; are licensed and made available under the terms and conditions of the BSD License
+; which accompanies this distribution. The full text of the license may be found at
+; http://opensource.org/licenses/bsd-license.php.
+;
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+;
+;;
+
+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/Core/IntelFsp2Pkg/FspSecCore/Vtf0/ResetVectorCode.asm b/Core/IntelFsp2Pkg/FspSecCore/Vtf0/ResetVectorCode.asm new file mode 100644 index 0000000000..72b252491f --- /dev/null +++ b/Core/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.<BR>
+; This program and the accompanying materials
+; are licensed and made available under the terms and conditions of the BSD License
+; which accompanies this distribution. The full text of the license may be found at
+; http://opensource.org/licenses/bsd-license.php
+;
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+;
+;------------------------------------------------------------------------------
+
+
+%include "Ia16/ResetVec.asm16"
diff --git a/Core/IntelFsp2Pkg/FspSecCore/Vtf0/Tools/FixupForRawSection.py b/Core/IntelFsp2Pkg/FspSecCore/Vtf0/Tools/FixupForRawSection.py new file mode 100644 index 0000000000..8e7c20b401 --- /dev/null +++ b/Core/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.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+
+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/Core/IntelFsp2Pkg/Include/FspEas.h b/Core/IntelFsp2Pkg/Include/FspEas.h new file mode 100644 index 0000000000..00098a3926 --- /dev/null +++ b/Core/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.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _FSP_EAS_H_
+#define _FSP_EAS_H_
+
+#include <Uefi/UefiBaseType.h>
+#include <Guid/GuidHobFspEas.h>
+#include <Guid/FspHeaderFile.h>
+#include <FspEas/FspApi.h>
+
+#endif
diff --git a/Core/IntelFsp2Pkg/Include/FspEas/FspApi.h b/Core/IntelFsp2Pkg/Include/FspEas/FspApi.h new file mode 100644 index 0000000000..a2e4813baa --- /dev/null +++ b/Core/IntelFsp2Pkg/Include/FspEas/FspApi.h @@ -0,0 +1,288 @@ +/** @file
+ Intel FSP API definition from Intel Firmware Support Package External
+ Architecture Specification v2.0.
+
+ Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _FSP_API_H_
+#define _FSP_API_H_
+
+///
+/// FSP Reset Status code
+/// These are defined in FSP EAS v2.0 section 11.2.2 - OEM Status Code
+/// @{
+#define FSP_STATUS_RESET_REQUIRED_COLD 0x40000001
+#define FSP_STATUS_RESET_REQUIRED_WARM 0x40000002
+#define FSP_STATUS_RESET_REQUIRED_3 0x40000003
+#define FSP_STATUS_RESET_REQUIRED_4 0x40000004
+#define FSP_STATUS_RESET_REQUIRED_5 0x40000005
+#define FSP_STATUS_RESET_REQUIRED_6 0x40000006
+#define FSP_STATUS_RESET_REQUIRED_7 0x40000007
+#define FSP_STATUS_RESET_REQUIRED_8 0x40000008
+/// @}
+
+#pragma pack(1)
+///
+/// FSP_UPD_HEADER Configuration.
+///
+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;
+
+///
+/// FSPM_ARCH_UPD Configuration.
+///
+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;
+
+///
+/// FSPT_UPD_COMMON Configuration.
+///
+typedef struct {
+ ///
+ /// FSP_UPD_HEADER Configuration.
+ ///
+ FSP_UPD_HEADER FspUpdHeader;
+} FSPT_UPD_COMMON;
+
+///
+/// FSPM_UPD_COMMON Configuration.
+///
+typedef struct {
+ ///
+ /// FSP_UPD_HEADER Configuration.
+ ///
+ FSP_UPD_HEADER FspUpdHeader;
+ ///
+ /// FSPM_ARCH_UPD Configuration.
+ ///
+ FSPM_ARCH_UPD FspmArchUpd;
+} FSPM_UPD_COMMON;
+
+///
+/// FSPS_UPD_COMMON Configuration.
+///
+typedef struct {
+ ///
+ /// FSP_UPD_HEADER Configuration.
+ ///
+ FSP_UPD_HEADER FspUpdHeader;
+} FSPS_UPD_COMMON;
+
+///
+/// Enumeration of FSP_INIT_PHASE for NOTIFY_PHASE.
+///
+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;
+
+///
+/// Definition of NOTIFY_PHASE_PARAMS.
+///
+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/Core/IntelFsp2Pkg/Include/FspGlobalData.h b/Core/IntelFsp2Pkg/Include/FspGlobalData.h new file mode 100644 index 0000000000..7de26606a7 --- /dev/null +++ b/Core/IntelFsp2Pkg/Include/FspGlobalData.h @@ -0,0 +1,67 @@ +/** @file
+
+ Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _FSP_GLOBAL_DATA_H_
+#define _FSP_GLOBAL_DATA_H_
+
+#include <FspEas.h>
+
+#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;
+} 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')
+#define FSP_PERFORMANCE_DATA_TIMER_MASK 0xFFFFFFFFFFFFFF
+
+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/Core/IntelFsp2Pkg/Include/FspMeasurePointId.h b/Core/IntelFsp2Pkg/Include/FspMeasurePointId.h new file mode 100644 index 0000000000..ee103df795 --- /dev/null +++ b/Core/IntelFsp2Pkg/Include/FspMeasurePointId.h @@ -0,0 +1,62 @@ +/** @file
+
+ Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#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/Core/IntelFsp2Pkg/Include/FspStatusCode.h b/Core/IntelFsp2Pkg/Include/FspStatusCode.h new file mode 100644 index 0000000000..c9a316e6e7 --- /dev/null +++ b/Core/IntelFsp2Pkg/Include/FspStatusCode.h @@ -0,0 +1,46 @@ +/** @file
+ Intel FSP status code definition
+
+ Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#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/Core/IntelFsp2Pkg/Include/Guid/FspHeaderFile.h b/Core/IntelFsp2Pkg/Include/Guid/FspHeaderFile.h new file mode 100644 index 0000000000..96cac00124 --- /dev/null +++ b/Core/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.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __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/Core/IntelFsp2Pkg/Include/Guid/GuidHobFspEas.h b/Core/IntelFsp2Pkg/Include/Guid/GuidHobFspEas.h new file mode 100644 index 0000000000..83c7f0068f --- /dev/null +++ b/Core/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.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __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/Core/IntelFsp2Pkg/Include/Library/CacheAsRamLib.h b/Core/IntelFsp2Pkg/Include/Library/CacheAsRamLib.h new file mode 100644 index 0000000000..6f3d068b67 --- /dev/null +++ b/Core/IntelFsp2Pkg/Include/Library/CacheAsRamLib.h @@ -0,0 +1,30 @@ +/** @file
+
+ Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _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/Core/IntelFsp2Pkg/Include/Library/CacheLib.h b/Core/IntelFsp2Pkg/Include/Library/CacheLib.h new file mode 100644 index 0000000000..909ae928f1 --- /dev/null +++ b/Core/IntelFsp2Pkg/Include/Library/CacheLib.h @@ -0,0 +1,62 @@ +/** @file
+
+ Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _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/Core/IntelFsp2Pkg/Include/Library/DebugDeviceLib.h b/Core/IntelFsp2Pkg/Include/Library/DebugDeviceLib.h new file mode 100644 index 0000000000..5c35eda579 --- /dev/null +++ b/Core/IntelFsp2Pkg/Include/Library/DebugDeviceLib.h @@ -0,0 +1,29 @@ +/** @file
+
+ Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __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/Core/IntelFsp2Pkg/Include/Library/FspCommonLib.h b/Core/IntelFsp2Pkg/Include/Library/FspCommonLib.h new file mode 100644 index 0000000000..5f7a14b9b2 --- /dev/null +++ b/Core/IntelFsp2Pkg/Include/Library/FspCommonLib.h @@ -0,0 +1,303 @@ +/** @file
+
+ Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _FSP_COMMON_LIB_H_
+#define _FSP_COMMON_LIB_H_
+
+#include <FspGlobalData.h>
+#include <FspMeasurePointId.h>
+
+/**
+ 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 CfgRegion data pointer.
+
+ @return CfgRegion data pointer.
+**/
+VOID *
+EFIAPI
+GetFspCfgRegionDataPointer (
+ 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 updates the return status of the FSP API with requested reset type and returns to Boot Loader.
+
+ @param[in] FspResetType Reset type that needs to returned as API return status
+
+**/
+VOID
+EFIAPI
+FspApiReturnStatusReset (
+ IN UINT32 FspResetType
+ );
+#endif
diff --git a/Core/IntelFsp2Pkg/Include/Library/FspPlatformLib.h b/Core/IntelFsp2Pkg/Include/Library/FspPlatformLib.h new file mode 100644 index 0000000000..1f39601269 --- /dev/null +++ b/Core/IntelFsp2Pkg/Include/Library/FspPlatformLib.h @@ -0,0 +1,131 @@ +/** @file
+
+ Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#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
+ );
+
+
+/**
+ 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
+ );
+
+/**
+ This function transfer control back to BootLoader after FspSiliconInit.
+
+ @param[in] Status return status for the FspSiliconInit.
+**/
+VOID
+EFIAPI
+FspSiliconInitDone2 (
+ IN EFI_STATUS Status
+ );
+
+/**
+ This function returns control to BootLoader after MemoryInitApi.
+
+ @param[in] Status return status for the MemoryInitApi.
+ @param[in,out] HobListPtr The address of HobList pointer.
+**/
+VOID
+EFIAPI
+FspMemoryInitDone2 (
+ IN EFI_STATUS Status,
+ IN OUT VOID **HobListPtr
+ );
+
+/**
+ This function returns control to BootLoader after TempRamExitApi.
+
+ @param[in] Status return status for the TempRamExitApi.
+**/
+VOID
+EFIAPI
+FspTempRamExitDone2 (
+ IN EFI_STATUS Status
+ );
+
+#endif
diff --git a/Core/IntelFsp2Pkg/Include/Library/FspSecPlatformLib.h b/Core/IntelFsp2Pkg/Include/Library/FspSecPlatformLib.h new file mode 100644 index 0000000000..cf2b0ffa2e --- /dev/null +++ b/Core/IntelFsp2Pkg/Include/Library/FspSecPlatformLib.h @@ -0,0 +1,88 @@ +/** @file
+
+ Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#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/Core/IntelFsp2Pkg/Include/Library/FspSwitchStackLib.h b/Core/IntelFsp2Pkg/Include/Library/FspSwitchStackLib.h new file mode 100644 index 0000000000..fee44a3147 --- /dev/null +++ b/Core/IntelFsp2Pkg/Include/Library/FspSwitchStackLib.h @@ -0,0 +1,45 @@ +/** @file
+
+ Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _FSP_SWITCH_STACK_LIB_H_
+#define _FSP_SWITCH_STACK_LIB_H_
+
+/**
+
+ This function 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/Core/IntelFsp2Pkg/IntelFsp2Pkg.dec b/Core/IntelFsp2Pkg/IntelFsp2Pkg.dec new file mode 100644 index 0000000000..52024af4fb --- /dev/null +++ b/Core/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.<BR>
+# 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/Core/IntelFsp2Pkg/IntelFsp2Pkg.dsc b/Core/IntelFsp2Pkg/IntelFsp2Pkg.dsc new file mode 100644 index 0000000000..1469d35ede --- /dev/null +++ b/Core/IntelFsp2Pkg/IntelFsp2Pkg.dsc @@ -0,0 +1,82 @@ +## @file
+# Provides driver and definitions to build fsp.
+#
+# Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>
+# This program and the accompanying materials are licensed and made available under
+# the terms and conditions of the BSD License 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/Library/BaseDebugDeviceLibNull/BaseDebugDeviceLibNull.inf
+ IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/SecFspSecPlatformLibNull.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
+
+[BuildOptions]
+ *_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES
diff --git a/Core/IntelFsp2Pkg/Library/BaseCacheAsRamLibNull/BaseCacheAsRamLibNull.inf b/Core/IntelFsp2Pkg/Library/BaseCacheAsRamLibNull/BaseCacheAsRamLibNull.inf new file mode 100644 index 0000000000..bdb6744f37 --- /dev/null +++ b/Core/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.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = 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/Core/IntelFsp2Pkg/Library/BaseCacheAsRamLibNull/DisableCacheAsRamNull.c b/Core/IntelFsp2Pkg/Library/BaseCacheAsRamLibNull/DisableCacheAsRamNull.c new file mode 100644 index 0000000000..9b45163c34 --- /dev/null +++ b/Core/IntelFsp2Pkg/Library/BaseCacheAsRamLibNull/DisableCacheAsRamNull.c @@ -0,0 +1,41 @@ +/** @file
+
+ Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/CacheAsRamLib.h>
+
+/**
+ 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/Core/IntelFsp2Pkg/Library/BaseCacheLib/BaseCacheLib.inf b/Core/IntelFsp2Pkg/Library/BaseCacheLib/BaseCacheLib.inf new file mode 100644 index 0000000000..7b026b1dfc --- /dev/null +++ b/Core/IntelFsp2Pkg/Library/BaseCacheLib/BaseCacheLib.inf @@ -0,0 +1,34 @@ +## @file
+# Instance of BaseCache.
+#
+# Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[defines]
+ 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/Core/IntelFsp2Pkg/Library/BaseCacheLib/CacheLib.c b/Core/IntelFsp2Pkg/Library/BaseCacheLib/CacheLib.c new file mode 100644 index 0000000000..b38dce32a8 --- /dev/null +++ b/Core/IntelFsp2Pkg/Library/BaseCacheLib/CacheLib.c @@ -0,0 +1,703 @@ +/** @file
+
+ Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/CacheLib.h>
+#include <Library/CacheAsRamLib.h>
+#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/Core/IntelFsp2Pkg/Library/BaseCacheLib/CacheLibInternal.h b/Core/IntelFsp2Pkg/Library/BaseCacheLib/CacheLibInternal.h new file mode 100644 index 0000000000..fbbf551dde --- /dev/null +++ b/Core/IntelFsp2Pkg/Library/BaseCacheLib/CacheLibInternal.h @@ -0,0 +1,59 @@ +/** @file
+
+ Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _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/Core/IntelFsp2Pkg/Library/BaseDebugDeviceLibNull/BaseDebugDeviceLibNull.inf b/Core/IntelFsp2Pkg/Library/BaseDebugDeviceLibNull/BaseDebugDeviceLibNull.inf new file mode 100644 index 0000000000..5e4c572973 --- /dev/null +++ b/Core/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.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = 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/Core/IntelFsp2Pkg/Library/BaseDebugDeviceLibNull/DebugDeviceLibNull.c b/Core/IntelFsp2Pkg/Library/BaseDebugDeviceLibNull/DebugDeviceLibNull.c new file mode 100644 index 0000000000..95c100472c --- /dev/null +++ b/Core/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.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Base.h>
+
+/**
+ Returns the debug print device enable state.
+
+ @return Debug print device enable state.
+
+**/
+UINT8
+EFIAPI
+GetDebugPrintDeviceEnable (
+ VOID
+ )
+{
+ return 1;
+}
diff --git a/Core/IntelFsp2Pkg/Library/BaseFspCommonLib/BaseFspCommonLib.inf b/Core/IntelFsp2Pkg/Library/BaseFspCommonLib/BaseFspCommonLib.inf new file mode 100644 index 0000000000..df8803a036 --- /dev/null +++ b/Core/IntelFsp2Pkg/Library/BaseFspCommonLib/BaseFspCommonLib.inf @@ -0,0 +1,40 @@ +## @file
+# Instance of FspCommonLib
+# Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[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
+ FspSwitchStackLib
+
+[Pcd]
+ gIntelFsp2PkgTokenSpaceGuid.PcdGlobalDataPointerAddress ## CONSUMES
+
+[FixedPcd]
+ gIntelFsp2PkgTokenSpaceGuid.PcdFspMaxPatchEntry ## CONSUMES
+ gIntelFsp2PkgTokenSpaceGuid.PcdFspMaxPerfEntry ## CONSUMES
+ gIntelFsp2PkgTokenSpaceGuid.PcdTemporaryRamBase ## CONSUMES
+ gIntelFsp2PkgTokenSpaceGuid.PcdTemporaryRamSize ## CONSUMES
diff --git a/Core/IntelFsp2Pkg/Library/BaseFspCommonLib/FspCommonLib.c b/Core/IntelFsp2Pkg/Library/BaseFspCommonLib/FspCommonLib.c new file mode 100644 index 0000000000..2f2981c990 --- /dev/null +++ b/Core/IntelFsp2Pkg/Library/BaseFspCommonLib/FspCommonLib.c @@ -0,0 +1,532 @@ +/** @file
+
+ Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <PiPei.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+#include <FspGlobalData.h>
+#include <FspEas.h>
+#include <Library/FspSwitchStackLib.h>
+
+#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 FspMemoryInit UPD data pointer.
+
+ @param[in] MemoryInitUpdPtr FspMemoryInit UPD data pointer.
+**/
+VOID
+EFIAPI
+SetFspMemoryInitUpdDataPointer (
+ IN VOID *MemoryInitUpdPtr
+ )
+{
+ FSP_GLOBAL_DATA *FspData;
+
+ //
+ // Get the FSP Global Data Pointer
+ //
+ FspData = GetFspGlobalDataPointer ();
+
+ //
+ // Set the FspMemoryInit UPD pointer.
+ //
+ FspData->MemoryInitUpdPtr = MemoryInitUpdPtr;
+}
+
+/**
+ This function gets the FspMemoryInit UPD data pointer.
+
+ @return FspMemoryInit UPD data pointer.
+**/
+VOID *
+EFIAPI
+GetFspMemoryInitUpdDataPointer (
+ VOID
+ )
+{
+ FSP_GLOBAL_DATA *FspData;
+
+ FspData = GetFspGlobalDataPointer ();
+ return FspData->MemoryInitUpdPtr;
+}
+
+
+/**
+ This function sets the FspSiliconInit UPD data pointer.
+
+ @param[in] SiliconInitUpdPtr FspSiliconInit UPD data pointer.
+**/
+VOID
+EFIAPI
+SetFspSiliconInitUpdDataPointer (
+ IN VOID *SiliconInitUpdPtr
+ )
+{
+ FSP_GLOBAL_DATA *FspData;
+
+ //
+ // Get the FSP Global Data Pointer
+ //
+ FspData = GetFspGlobalDataPointer ();
+
+ //
+ // Set the FspSiliconInit UPD data pointer.
+ //
+ FspData->SiliconInitUpdPtr = SiliconInitUpdPtr;
+}
+
+/**
+ This function gets the FspSiliconInit UPD data pointer.
+
+ @return FspSiliconInit 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 CfgRegion data pointer.
+
+ @return CfgRegion data pointer.
+**/
+VOID *
+EFIAPI
+GetFspCfgRegionDataPointer (
+ 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 updates the return status of the FSP API with requested reset type and returns to Boot Loader.
+
+ @param[in] FspResetType Reset type that needs to returned as API return status
+
+**/
+VOID
+EFIAPI
+FspApiReturnStatusReset (
+ IN UINT32 FspResetType
+ )
+{
+ volatile BOOLEAN LoopUntilReset;
+
+ LoopUntilReset = TRUE;
+ DEBUG ((DEBUG_INFO, "FSP returning control to Bootloader with reset required return status %x\n",FspResetType));
+ ///
+ /// Below code is not an infinite loop.The control will go back to API calling function in BootLoader each time BootLoader
+ /// calls the FSP API without honoring the reset request by FSP
+ ///
+ do {
+ SetFspApiReturnStatus ((EFI_STATUS)FspResetType);
+ Pei2LoaderSwitchStack ();
+ DEBUG ((DEBUG_ERROR, "!!!ERROR: FSP has requested BootLoader for reset. But BootLoader has not honored the reset\n"));
+ DEBUG ((DEBUG_ERROR, "!!!ERROR: Please add support in BootLoader to honor the reset request from FSP\n"));
+ } while (LoopUntilReset);
+}
diff --git a/Core/IntelFsp2Pkg/Library/BaseFspDebugLibSerialPort/BaseFspDebugLibSerialPort.inf b/Core/IntelFsp2Pkg/Library/BaseFspDebugLibSerialPort/BaseFspDebugLibSerialPort.inf new file mode 100644 index 0000000000..49adfd8c82 --- /dev/null +++ b/Core/IntelFsp2Pkg/Library/BaseFspDebugLibSerialPort/BaseFspDebugLibSerialPort.inf @@ -0,0 +1,50 @@ +## @file
+# Instance of BaseFspDebugLib
+#
+# Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[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.nasm
+
+[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/Core/IntelFsp2Pkg/Library/BaseFspDebugLibSerialPort/DebugLib.c b/Core/IntelFsp2Pkg/Library/BaseFspDebugLibSerialPort/DebugLib.c new file mode 100644 index 0000000000..73bb08e357 --- /dev/null +++ b/Core/IntelFsp2Pkg/Library/BaseFspDebugLibSerialPort/DebugLib.c @@ -0,0 +1,328 @@ +/** @file
+
+ Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Base.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+#include <Library/PrintLib.h>
+#include <Library/PcdLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/SerialPortLib.h>
+#include <Library/DebugDeviceLib.h>
+#include <Library/DebugPrintErrorLevelLib.h>
+
+//
+// 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 <FileName>(<LineNumber>): <Description>\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 <FileName> string of "(NULL) Filename" is printed.
+ If Description is NULL, then a <Description> 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 <FileName>(<LineNumber>): <Description>\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 <FileName> string of "(NULL) Filename" is printed.
+ If Description is NULL, then a <Description> 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/Core/IntelFsp2Pkg/Library/BaseFspDebugLibSerialPort/Ia32/FspDebug.nasm b/Core/IntelFsp2Pkg/Library/BaseFspDebugLibSerialPort/Ia32/FspDebug.nasm new file mode 100644 index 0000000000..fd20b0d5ac --- /dev/null +++ b/Core/IntelFsp2Pkg/Library/BaseFspDebugLibSerialPort/Ia32/FspDebug.nasm @@ -0,0 +1,31 @@ +;------------------------------------------------------------------------------
+;
+; Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+; This program and the accompanying materials
+; are licensed and made available under the terms and conditions of the BSD License
+; which accompanies this distribution. The full text of the license may be found at
+; http://opensource.org/licenses/bsd-license.php.
+;
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+;
+; Abstract:
+;
+; FSP Debug functions
+;
+;------------------------------------------------------------------------------
+
+ SECTION .text
+
+;------------------------------------------------------------------------------
+; UINT32 *
+; EFIAPI
+; GetStackFramePointer (
+; VOID
+; );
+;------------------------------------------------------------------------------
+global ASM_PFX(GetStackFramePointer)
+ASM_PFX(GetStackFramePointer):
+ mov eax, ebp
+ ret
+
diff --git a/Core/IntelFsp2Pkg/Library/BaseFspPlatformLib/BaseFspPlatformLib.inf b/Core/IntelFsp2Pkg/Library/BaseFspPlatformLib/BaseFspPlatformLib.inf new file mode 100644 index 0000000000..907482daed --- /dev/null +++ b/Core/IntelFsp2Pkg/Library/BaseFspPlatformLib/BaseFspPlatformLib.inf @@ -0,0 +1,54 @@ +## @file
+# Instance of FspPlatformLib
+#
+# Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[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
+ gEfiEventReadyToBootGuid ## CONSUMES ## Event
+
+[Protocols]
+ gEfiPciEnumerationCompleteProtocolGuid ## CONSUMES
+
+[FixedPcd]
+ gIntelFsp2PkgTokenSpaceGuid.PcdFspMaxPatchEntry ## CONSUMES
+ gIntelFsp2PkgTokenSpaceGuid.PcdFspMaxPerfEntry ## CONSUMES
diff --git a/Core/IntelFsp2Pkg/Library/BaseFspPlatformLib/FspPlatformMemory.c b/Core/IntelFsp2Pkg/Library/BaseFspPlatformLib/FspPlatformMemory.c new file mode 100644 index 0000000000..edb8d67223 --- /dev/null +++ b/Core/IntelFsp2Pkg/Library/BaseFspPlatformLib/FspPlatformMemory.c @@ -0,0 +1,122 @@ +/** @file
+
+ Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <PiPei.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+#include <Library/HobLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/FspCommonLib.h>
+#include <FspGlobalData.h>
+#include <FspEas.h>
+
+/**
+ 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);
+ }
+}
diff --git a/Core/IntelFsp2Pkg/Library/BaseFspPlatformLib/FspPlatformNotify.c b/Core/IntelFsp2Pkg/Library/BaseFspPlatformLib/FspPlatformNotify.c new file mode 100644 index 0000000000..ac1fc1ac0b --- /dev/null +++ b/Core/IntelFsp2Pkg/Library/BaseFspPlatformLib/FspPlatformNotify.c @@ -0,0 +1,397 @@ +/** @file
+
+ Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <PiPei.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/PeiServicesTablePointerLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PcdLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/FspSwitchStackLib.h>
+#include <Library/FspCommonLib.h>
+#include <Guid/EventGroup.h>
+#include <FspEas.h>
+#include <FspStatusCode.h>
+#include <Protocol/PciEnumerationComplete.h>
+#include <Library/ReportStatusCodeLib.h>
+#include <Library/PerformanceLib.h>
+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.
+
+ @param[in] Status return status for the FspSiliconInit.
+
+**/
+VOID
+EFIAPI
+FspSiliconInitDone2 (
+ IN EFI_STATUS Status
+ )
+{
+ //
+ // Convert to FSP EAS defined API return codes
+ //
+ switch (Status) {
+ case EFI_SUCCESS:
+ case EFI_INVALID_PARAMETER:
+ case EFI_UNSUPPORTED:
+ case EFI_DEVICE_ERROR:
+ break;
+ default:
+ DEBUG ((DEBUG_INFO | DEBUG_INIT, "FspSiliconInitApi() Invalid Error - [Status: 0x%08X]\n", Status));
+ Status = EFI_DEVICE_ERROR; // Force to known error.
+ break;
+ }
+ //
+ // 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() - [Status: 0x%08X] - End\n", Status));
+ PERF_END_EX (&gFspPerformanceDataGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_SILICON_INIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
+ REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
+ do {
+ SetFspApiReturnStatus (Status);
+ Pei2LoaderSwitchStack ();
+ if (Status != EFI_SUCCESS) {
+ DEBUG ((DEBUG_ERROR, "!!!ERROR: FspSiliconInitApi() - [Status: 0x%08X] - Error encountered during previous API and cannot proceed further\n", Status));
+ }
+ } while (Status != EFI_SUCCESS);
+}
+
+/**
+ This function returns control to BootLoader after MemoryInitApi.
+
+ @param[in] Status return status for the MemoryInitApi.
+ @param[in,out] HobListPtr The address of HobList pointer, if NULL, will get value from GetFspApiParameter2 ()
+**/
+VOID
+EFIAPI
+FspMemoryInitDone2 (
+ IN EFI_STATUS Status,
+ IN OUT VOID **HobListPtr
+ )
+{
+ FSP_GLOBAL_DATA *FspData;
+ //
+ // Calling use FspMemoryInit API
+ // Update HOB and return the control directly
+ //
+ if (HobListPtr == NULL) {
+ HobListPtr = (VOID **)GetFspApiParameter2 ();
+ }
+ if (HobListPtr != NULL) {
+ *HobListPtr = (VOID *) GetHobList ();
+ }
+ //
+ // Convert to FSP EAS defined API return codes
+ //
+ switch (Status) {
+ case EFI_SUCCESS:
+ case EFI_INVALID_PARAMETER:
+ case EFI_UNSUPPORTED:
+ case EFI_DEVICE_ERROR:
+ case EFI_OUT_OF_RESOURCES:
+ break;
+ default:
+ DEBUG ((DEBUG_INFO | DEBUG_INIT, "FspMemoryInitApi() Invalid Error [Status: 0x%08X]\n", Status));
+ Status = EFI_DEVICE_ERROR; // Force to known error.
+ break;
+ }
+ //
+ // This is the end of the FspMemoryInit API
+ // Give control back to the boot loader
+ //
+ DEBUG ((DEBUG_INFO | DEBUG_INIT, "FspMemoryInitApi() - [Status: 0x%08X] - End\n", Status));
+ SetFspMeasurePoint (FSP_PERF_ID_API_FSP_MEMORY_INIT_EXIT);
+ FspData = GetFspGlobalDataPointer ();
+ PERF_START_EX(&gFspPerformanceDataGuid, "EventRec", NULL, (FspData->PerfData[0] & FSP_PERFORMANCE_DATA_TIMER_MASK), FSP_STATUS_CODE_TEMP_RAM_INIT | FSP_STATUS_CODE_COMMON_CODE| FSP_STATUS_CODE_API_ENTRY);
+ PERF_END_EX(&gFspPerformanceDataGuid, "EventRec", NULL, (FspData->PerfData[1] & FSP_PERFORMANCE_DATA_TIMER_MASK), FSP_STATUS_CODE_TEMP_RAM_INIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
+ PERF_START_EX(&gFspPerformanceDataGuid, "EventRec", NULL, (FspData->PerfData[2] & FSP_PERFORMANCE_DATA_TIMER_MASK), FSP_STATUS_CODE_MEMORY_INIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);
+ PERF_END_EX(&gFspPerformanceDataGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_MEMORY_INIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
+ REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_MEMORY_INIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
+ do {
+ SetFspApiReturnStatus (Status);
+ Pei2LoaderSwitchStack ();
+ if (Status != EFI_SUCCESS) {
+ DEBUG ((DEBUG_ERROR, "!!!ERROR: FspMemoryInitApi() - [Status: 0x%08X] - Error encountered during previous API and cannot proceed further\n", Status));
+ }
+ } while (Status != EFI_SUCCESS);
+
+ //
+ // The TempRamExitApi is called
+ //
+ if (GetFspApiCallingIndex () == TempRamExitApiIndex) {
+ SetPhaseStatusCode (FSP_STATUS_CODE_TEMP_RAM_EXIT);
+ SetFspMeasurePoint (FSP_PERF_ID_API_TEMP_RAM_EXIT_ENTRY);
+ PERF_START_EX(&gFspPerformanceDataGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_TEMP_RAM_EXIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);
+ REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_TEMP_RAM_EXIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);
+ DEBUG ((DEBUG_INFO | DEBUG_INIT, "TempRamExitApi() - Begin\n"));
+ } else {
+ SetPhaseStatusCode (FSP_STATUS_CODE_SILICON_INIT);
+ SetFspMeasurePoint (FSP_PERF_ID_API_FSP_SILICON_INIT_ENTRY);
+ PERF_START_EX(&gFspPerformanceDataGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_SILICON_INIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);
+ REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_SILICON_INIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);
+ DEBUG ((DEBUG_INFO | DEBUG_INIT, "FspSiliconInitApi() - Begin\n"));
+ }
+}
+
+/**
+ This function returns control to BootLoader after TempRamExitApi.
+
+ @param[in] Status return status for the TempRamExitApi.
+
+**/
+VOID
+EFIAPI
+FspTempRamExitDone2 (
+ IN EFI_STATUS Status
+ )
+{
+ //
+ // Convert to FSP EAS defined API return codes
+ //
+ switch (Status) {
+ case EFI_SUCCESS:
+ case EFI_INVALID_PARAMETER:
+ case EFI_UNSUPPORTED:
+ case EFI_DEVICE_ERROR:
+ break;
+ default:
+ DEBUG ((DEBUG_INFO | DEBUG_INIT, "TempRamExitApi() Invalid Error - [Status: 0x%08X]\n", Status));
+ Status = EFI_DEVICE_ERROR; // Force to known error.
+ break;
+ }
+ //
+ // This is the end of the TempRamExit API
+ // Give control back to the boot loader
+ //
+ DEBUG ((DEBUG_INFO | DEBUG_INIT, "TempRamExitApi() - [Status: 0x%08X] - End\n", Status));
+ SetFspMeasurePoint (FSP_PERF_ID_API_TEMP_RAM_EXIT_EXIT);
+ PERF_END_EX(&gFspPerformanceDataGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_TEMP_RAM_EXIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
+ REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_TEMP_RAM_EXIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
+ do {
+ SetFspApiReturnStatus (Status);
+ Pei2LoaderSwitchStack ();
+ if (Status != EFI_SUCCESS) {
+ DEBUG ((DEBUG_ERROR, "!!!ERROR: TempRamExitApi() - [Status: 0x%08X] - Error encountered during previous API and cannot proceed further\n", Status));
+ }
+ } while (Status != EFI_SUCCESS);
+ SetPhaseStatusCode (FSP_STATUS_CODE_SILICON_INIT);
+ SetFspMeasurePoint (FSP_PERF_ID_API_FSP_SILICON_INIT_ENTRY);
+ PERF_START_EX(&gFspPerformanceDataGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_SILICON_INIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);
+ REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_SILICON_INIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);
+ DEBUG ((DEBUG_INFO | DEBUG_INIT, "SiliconInitApi() - Begin\n"));
+}
+
+/**
+ 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);
+ PERF_START_EX (&gFspPerformanceDataGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_POST_PCIE_ENUM_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);
+ 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);
+ PERF_START_EX(&gFspPerformanceDataGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_READY_TO_BOOT_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);
+ 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);
+ PERF_START_EX (&gFspPerformanceDataGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_END_OF_FIRMWARE_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);
+ 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++;
+ }
+ }
+
+ 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) {
+ PERF_END_EX(&gFspPerformanceDataGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_POST_PCIE_ENUM_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
+ 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) {
+ PERF_END_EX(&gFspPerformanceDataGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_READY_TO_BOOT_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
+ 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) {
+ PERF_END_EX(&gFspPerformanceDataGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_END_OF_FIRMWARE_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
+ REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_END_OF_FIRMWARE_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
+ }
+ do {
+ SetFspApiReturnStatus(Status);
+ Pei2LoaderSwitchStack();
+ if (Status != EFI_SUCCESS) {
+ DEBUG ((DEBUG_ERROR, "!!!ERROR: NotifyPhaseApi() [Phase: %08X] - Failed - [Status: 0x%08X]\n", NotificationValue, Status));
+ }
+ } while (Status != EFI_SUCCESS);
+ }
+
+ //
+ // 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.
+ //
+}
+
+/**
+ This function transfer control back to BootLoader after FspSiliconInit.
+
+**/
+VOID
+EFIAPI
+FspSiliconInitDone (
+ VOID
+ )
+{
+ FspSiliconInitDone2 (EFI_SUCCESS);
+}
+
+/**
+ This function returns control to BootLoader after MemoryInitApi.
+
+ @param[in,out] HobListPtr The address of HobList pointer.
+**/
+VOID
+EFIAPI
+FspMemoryInitDone (
+ IN OUT VOID **HobListPtr
+ )
+{
+ FspMemoryInitDone2 (EFI_SUCCESS, HobListPtr);
+}
+
+/**
+ This function returns control to BootLoader after TempRamExitApi.
+
+**/
+VOID
+EFIAPI
+FspTempRamExitDone (
+ VOID
+ )
+{
+ FspTempRamExitDone2 (EFI_SUCCESS);
+}
diff --git a/Core/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/BaseFspSwitchStackLib.inf b/Core/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/BaseFspSwitchStackLib.inf new file mode 100644 index 0000000000..b3c673a0ac --- /dev/null +++ b/Core/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/BaseFspSwitchStackLib.inf @@ -0,0 +1,42 @@ +## @file
+# Instance of BaseFspSwitchStackLib
+#
+# Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[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.nasm
+
+[Packages]
+ MdePkg/MdePkg.dec
+ IntelFsp2Pkg/IntelFsp2Pkg.dec
+
+[LibraryClasses]
+ BaseLib
+ IoLib
+
+[FixedPcd]
+ gIntelFsp2PkgTokenSpaceGuid.PcdFspMaxPatchEntry ## CONSUMES
+ gIntelFsp2PkgTokenSpaceGuid.PcdFspMaxPerfEntry ## CONSUMES
+
+
+
diff --git a/Core/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/FspSwitchStackLib.c b/Core/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/FspSwitchStackLib.c new file mode 100644 index 0000000000..42a57a27c0 --- /dev/null +++ b/Core/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/FspSwitchStackLib.c @@ -0,0 +1,42 @@ +/** @file
+
+ Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Base.h>
+#include <Library/BaseLib.h>
+#include <Library/FspCommonLib.h>
+
+/**
+
+ 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/Core/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/Ia32/Stack.nasm b/Core/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/Ia32/Stack.nasm new file mode 100644 index 0000000000..b0d843e9d3 --- /dev/null +++ b/Core/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/Ia32/Stack.nasm @@ -0,0 +1,74 @@ +;------------------------------------------------------------------------------
+;
+; Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+; This program and the accompanying materials
+; are licensed and made available under the terms and conditions of the BSD License
+; which accompanies this distribution. The full text of the license may be found at
+; http://opensource.org/licenses/bsd-license.php.
+;
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+;
+; Abstract:
+;
+; Switch the stack from temporary memory to permenent memory.
+;
+;------------------------------------------------------------------------------
+
+ SECTION .text
+
+extern ASM_PFX(SwapStack)
+
+;------------------------------------------------------------------------------
+; UINT32
+; EFIAPI
+; Pei2LoaderSwitchStack (
+; VOID
+; )
+;------------------------------------------------------------------------------
+global ASM_PFX(Pei2LoaderSwitchStack)
+ASM_PFX(Pei2LoaderSwitchStack):
+ xor eax, eax
+ jmp ASM_PFX(FspSwitchStack)
+
+;------------------------------------------------------------------------------
+; UINT32
+; EFIAPI
+; Loader2PeiSwitchStack (
+; VOID
+; )
+;------------------------------------------------------------------------------
+global ASM_PFX(Loader2PeiSwitchStack)
+ASM_PFX(Loader2PeiSwitchStack):
+ jmp ASM_PFX(FspSwitchStack)
+
+;------------------------------------------------------------------------------
+; UINT32
+; EFIAPI
+; FspSwitchStack (
+; VOID
+; )
+;------------------------------------------------------------------------------
+global ASM_PFX(FspSwitchStack)
+ASM_PFX(FspSwitchStack):
+ ; Save current contexts
+ push eax
+ pushfd
+ cli
+ pushad
+ sub esp, 8
+ sidt [esp]
+
+ ; Load new stack
+ push esp
+ call ASM_PFX(SwapStack)
+ mov esp, eax
+
+ ; Restore previous contexts
+ lidt [esp]
+ add esp, 8
+ popad
+ popfd
+ add esp, 4
+ ret
+
diff --git a/Core/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/Ia32/Flat32.nasm b/Core/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/Ia32/Flat32.nasm new file mode 100644 index 0000000000..122eb9eb33 --- /dev/null +++ b/Core/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/Ia32/Flat32.nasm @@ -0,0 +1,127 @@ +;; @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.<BR>
+; This program and the accompanying materials
+; are licensed and made available under the terms and conditions of the BSD License
+; which accompanies this distribution. The full text of the license may be found at
+; http://opensource.org/licenses/bsd-license.php.
+;
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+;;
+
+;
+; Define assembler characteristics
+;
+
+extern ASM_PFX(TempRamInitApi)
+
+SECTION .text
+
+%macro RET_ESI 0
+
+ movd esi, mm7 ; restore ESP from MM7
+ jmp esi
+
+%endmacro
+
+;
+; Perform early platform initialization
+;
+global ASM_PFX(SecPlatformInit)
+ASM_PFX(SecPlatformInit):
+
+ RET_ESI
+
+;
+; 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
+;
+;----------------------------------------------------------------------------
+global ASM_PFX(ProtectedModeEntryPoint)
+ASM_PFX(ProtectedModeEntryPoint):
+ ;
+ ; Dummy function. Consume 2 API to make sure they can be linked.
+ ;
+ mov eax, ASM_PFX(TempRamInitApi)
+
+ ; Should never return
+ jmp $
+
+;
+; ROM-based Global-Descriptor Table for the PEI Phase
+;
+align 16
+global ASM_PFX(BootGdtTable)
+
+;
+; GDT[0]: 0x00: Null entry, never used.
+;
+NULL_SEL equ $ - GDT_BASE ; Selector [0]
+GDT_BASE:
+ASM_PFX(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 $ - GDT_BASE ; Size, in bytes
+
+;
+; GDT Descriptor
+;
+GdtDesc: ; GDT descriptor
+ DW GDT_SIZE - 1 ; GDT limit
+ DD GDT_BASE ; GDT base address
+
+global ASM_PFX(ProtectedModeEntryLinearAddress)
+global ASM_PFX(ProtectedModeEntryLinearOffset)
+
+ASM_PFX(ProtectedModeEntryLinearAddress):
+ASM_PFX(ProtectedModeEntryLinearOffset):
+ DD ASM_PFX(ProtectedModeEntryPoint) ; Offset of our 32 bit code
+ DW LINEAR_CODE_SEL
+
diff --git a/Core/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/Ia32/SecCarInit.nasm b/Core/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/Ia32/SecCarInit.nasm new file mode 100644 index 0000000000..df2233cf6f --- /dev/null +++ b/Core/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/Ia32/SecCarInit.nasm @@ -0,0 +1,46 @@ +;; @file
+; SEC CAR function
+;
+; Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+; This program and the accompanying materials
+; are licensed and made available under the terms and conditions of the BSD License
+; which accompanies this distribution. The full text of the license may be found at
+; http://opensource.org/licenses/bsd-license.php.
+;
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+;;
+
+;
+; Define assembler characteristics
+;
+
+%macro RET_ESI 0
+
+ movd esi, mm7 ; move ReturnAddress from MM7 to ESI
+ jmp esi
+
+%endmacro
+
+SECTION .text
+
+;-----------------------------------------------------------------------------
+;
+; Section: SecCarInit
+;
+; Description: This function initializes the Cache for Data, Stack, and Code
+;
+;-----------------------------------------------------------------------------
+global ASM_PFX(SecCarInit)
+ASM_PFX(SecCarInit):
+
+ ;
+ ; Set up CAR
+ ;
+
+ xor eax, eax
+
+SecCarInitExit:
+
+ RET_ESI
+
diff --git a/Core/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/PlatformSecLibNull.c b/Core/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/PlatformSecLibNull.c new file mode 100644 index 0000000000..7bb95a9054 --- /dev/null +++ b/Core/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.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <PiPei.h>
+#include <Library/FspCommonLib.h>
+
+/**
+ 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/Core/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/SecFspSecPlatformLibNull.inf b/Core/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/SecFspSecPlatformLibNull.inf new file mode 100644 index 0000000000..e1cab05232 --- /dev/null +++ b/Core/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/SecFspSecPlatformLibNull.inf @@ -0,0 +1,56 @@ +## @file
+# NULL instance of Platform Sec Lib.
+#
+# Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+################################################################################
+#
+# 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.nasm
+ Ia32/SecCarInit.nasm
+
+################################################################################
+#
+# Package Dependency Section - list of Package files that are required for
+# this module.
+#
+################################################################################
+
+[Packages]
+ MdePkg/MdePkg.dec
+ IntelFsp2Pkg/IntelFsp2Pkg.dec
diff --git a/Core/IntelFsp2Pkg/License.txt b/Core/IntelFsp2Pkg/License.txt new file mode 100644 index 0000000000..87ae665edf --- /dev/null +++ b/Core/IntelFsp2Pkg/License.txt @@ -0,0 +1,25 @@ +Copyright (c) 2016, 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.
+
+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 HOLDER 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.
diff --git a/Core/IntelFsp2Pkg/Readme.md b/Core/IntelFsp2Pkg/Readme.md new file mode 100644 index 0000000000..719ce099e4 --- /dev/null +++ b/Core/IntelFsp2Pkg/Readme.md @@ -0,0 +1,7 @@ +# IntelFsp2Pkg
+
+This package provides the component to create an FSP binary.
+
+Source Repository: https://github.com/tianocore/edk2/tree/master/IntelFsp2Pkg
+
+A whitepaper to describe the IntelFsp2Pkg: https://firmware.intel.com/sites/default/files/A_Tour_Beyond_BIOS_Creating_the_Intel_Firmware_Support_Package_with_the_EFI_Developer_Kit_II_%28FSP2.0%29.pdf
diff --git a/Core/IntelFsp2Pkg/Tools/GenCfgOpt.py b/Core/IntelFsp2Pkg/Tools/GenCfgOpt.py new file mode 100644 index 0000000000..6dc1b10b34 --- /dev/null +++ b/Core/IntelFsp2Pkg/Tools/GenCfgOpt.py @@ -0,0 +1,1482 @@ +## @ GenCfgOpt.py
+#
+# Copyright (c) 2014 - 2017, Intel Corporation. All rights reserved.<BR>
+# This program and the accompanying materials are licensed and made available under
+# the terms and conditions of the BSD License 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.<BR>
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+"""
+
+__copyright_bsf__ = """/** @file
+
+ Boot Setting File for Platform Configuration.
+
+ Copyright (c) %4d, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ This file is automatically generated. Please do NOT modify !!!
+
+**/
+
+"""
+
+__copyright_h__ = """/** @file
+
+Copyright (c) %4d, Intel Corporation. All rights reserved.<BR>
+
+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._PcdsDict = {}
+ 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 ExpandPcds (self, Input):
+ Line = Input
+ Match = re.findall("(\w+\.\w+)", Input)
+ if Match:
+ for PcdName in Match:
+ if PcdName in self._PcdsDict:
+ Line = Line.replace(PcdName, self._PcdsDict[PcdName])
+ else:
+ if self.Debug:
+ print "WARN : %s is not defined" % PcdName
+ return Line
+
+ def EvaluateExpress (self, Expr):
+ ExpExpr = self.ExpandPcds(Expr)
+ ExpExpr = self.ExpandMacros(ExpExpr)
+ 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):
+ self._CfgItemList = []
+ self._CfgPageDict = {}
+ self._CfgBlkDict = {}
+ self._DscFile = DscFile
+ self._FvDir = FvDir
+
+ IsDefSect = False
+ IsPcdSect = False
+ IsUpdSect = False
+ IsVpdSect = 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:
+ IsDefSect = False
+ IsPcdSect = False
+ IsVpdSect = False
+ IsUpdSect = False
+ if Match.group(1).lower() == "Defines".lower():
+ IsDefSect = True
+ if Match.group(1).lower() == "PcdsFeatureFlag".lower():
+ IsPcdSect = True
+ 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'] = []
+ IsUpdSect = True
+ else:
+ if IsDefSect or IsPcdSect 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:
+ 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)
+ PackagesPath = os.getenv("PACKAGES_PATH")
+ if PackagesPath:
+ for PackagePath in PackagesPath.split(os.pathsep):
+ IncludeFilePathAbs = os.path.join(os.path.normpath(PackagePath), os.path.normpath(IncludeFilePath))
+ if os.path.exists(IncludeFilePathAbs):
+ IncludeDsc = open(IncludeFilePathAbs, "r")
+ break
+ else:
+ IncludeDsc = open(IncludeFilePath, "r")
+ if IncludeDsc == None:
+ 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))
+ elif IsPcdSect:
+ #gSiPkgTokenSpaceGuid.PcdTxtEnable|FALSE
+ #gSiPkgTokenSpaceGuid.PcdOverclockEnable|TRUE
+ Match = re.match("^\s*([\w\.]+)\s*\|\s*(\w+)", DscLine)
+ if Match:
+ self._PcdsDict[Match.group(1)] = Match.group(2)
+ if self.Debug:
+ print "INFO : PCD %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:{SerialDebugPortAddress0:1}
+ # or
+ # @Bsf FIELD:{SerialDebugPortAddress0:1b}
+ Match = re.match("^\s*#\s+(!BSF|@Bsf)\s+FIELD:{(.+):(\d+)([Bb])?}", DscLine)
+ if Match:
+ SubCfgDict = ConfigDict.copy()
+ if (Match.group(4) == None) or (Match.group(4) == 'B'):
+ UnitBitLen = 8
+ elif Match.group(4) == 'b':
+ UnitBitLen = 1
+ else:
+ print("ERROR: Invalide BSF FIELD length for line '%s'" % DscLine)
+ raise SystemExit
+ SubCfgDict['cname'] = Match.group(2)
+ SubCfgDict['bitlength'] = int (Match.group(3)) * UnitBitLen
+ if SubCfgDict['bitlength'] > 0:
+ LastItem = self._CfgItemList[-1]
+ if len(LastItem['subreg']) == 0:
+ SubOffset = 0
+ else:
+ SubOffset = LastItem['subreg'][-1]['bitoffset'] + LastItem['subreg'][-1]['bitlength']
+ SubCfgDict['bitoffset'] = SubOffset
+ LastItem['subreg'].append (SubCfgDict.copy())
+ ConfigDict['name'] = ''
+ return Error
+
+ def GetBsfBitFields (self, subitem, bytes):
+ start = subitem['bitoffset']
+ end = start + subitem['bitlength']
+ bitsvalue = ''.join('{0:08b}'.format(i) for i in bytes[::-1])
+ bitsvalue = bitsvalue[::-1]
+ bitslen = len(bitsvalue)
+ if start > bitslen or end > bitslen:
+ print "Invalid bits offset [%d,%d] for %s" % (start, end, subitem['name'])
+ raise SystemExit
+ return hex(int(bitsvalue[start:end][::-1], 2))
+
+ 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']:
+ valuestr = self.GetBsfBitFields(SubItem, bytearray)
+ SubItem['value'] = 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)
+ if Name.startswith("UnusedUpdSpace") and Length != 1:
+ IsArray = True
+ Type = "UINT8"
+ 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(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()\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 <FspEas.h>\n\n")
+ HeaderFd.write("#pragma pack(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()\n\n")
+ HeaderFd.write("#endif\n")
+ HeaderFd.close()
+
+ return 0
+
+ def WriteBsfStruct (self, BsfFd, Item):
+ LogExpr = CLogicalExpression()
+ 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()
+ if 'bitlength' in Item:
+ BsfFd.write(" %s%s%4d bits $_DEFAULT_ = %s\n" % (Line, ' ' * (64 - len(Line)), Item['bitlength'], DefaultValue))
+ else:
+ 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(':')
+ test = LogExpr.getNumber (OpVal)
+ if test is None:
+ raise Exception("Selection Index '%s' is not a number" % OpVal)
+ 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']
+ BitsOffset = NextOffset * 8
+ for SubItem in Item['subreg']:
+ BitsOffset += SubItem['bitlength']
+ if SubItem['name'] == '':
+ if 'bitlength' in SubItem:
+ BsfFd.write(" Skip %d bits\n" % (SubItem['bitlength']))
+ else:
+ BsfFd.write(" Skip %d bytes\n" % (SubItem['length']))
+ else:
+ Options = self.WriteBsfStruct(BsfFd, SubItem)
+ if len(Options) > 0:
+ OptionDict[SubItem['space']+'_'+SubItem['cname']] = Options
+
+ NextBitsOffset = (Item['offset'] + Item['length']) * 8
+ if NextBitsOffset > BitsOffset:
+ BitsGap = NextBitsOffset - BitsOffset
+ BitsRemain = BitsGap % 8
+ if BitsRemain:
+ BsfFd.write(" Skip %d bits\n" % BitsRemain)
+ BitsGap -= BitsRemain
+ BytesRemain = BitsGap / 8
+ if BytesRemain:
+ BsfFd.write(" Skip %d bytes\n" % BytesRemain)
+ NextOffset = Item['offset'] + Item['length']
+ 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.52"
+ print "Usage:"
+ print " GenCfgOpt UPDTXT PlatformDscFile BuildFvDir [-D Macros]"
+ print " GenCfgOpt HEADER PlatformDscFile BuildFvDir InputHFile [-D Macros]"
+ print " GenCfgOpt GENBSF PlatformDscFile BuildFvDir 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
+
+ OutFile = ''
+ if argc > 4:
+ if sys.argv[4][0] == '-':
+ Start = 4
+ else:
+ OutFile = sys.argv[4]
+ Start = 5
+ if argc > Start:
+ if GenCfgOpt.ParseMacros(sys.argv[Start:]) != 0:
+ print "ERROR: Macro parsing failed !"
+ return 3
+
+ GenCfgOpt.ParseBuildMode(sys.argv[3])
+ FvDir = sys.argv[3]
+ if not os.path.exists(FvDir):
+ os.makedirs(FvDir)
+
+ if GenCfgOpt.ParseDscFile(DscFile, FvDir) != 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/Core/IntelFsp2Pkg/Tools/PatchFv.py b/Core/IntelFsp2Pkg/Tools/PatchFv.py new file mode 100644 index 0000000000..fc2ee19bcd --- /dev/null +++ b/Core/IntelFsp2Pkg/Tools/PatchFv.py @@ -0,0 +1,947 @@ +## @ PatchFv.py
+#
+# Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>
+# This program and the accompanying materials are licensed and made available under
+# the terms and conditions of the BSD License 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/Core/IntelFsp2Pkg/Tools/SplitFspBin.py b/Core/IntelFsp2Pkg/Tools/SplitFspBin.py new file mode 100644 index 0000000000..e4c3aa6d0b --- /dev/null +++ b/Core/IntelFsp2Pkg/Tools/SplitFspBin.py @@ -0,0 +1,795 @@ +## @ FspTool.py
+#
+# Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
+# This program and the accompanying materials are licensed and made available under
+# the terms and conditions of the BSD License 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 2.0 image.
+It supports:
+ - Display FSP 2.0 information header
+ - Split FSP 2.0 image into individual FSP-T/M/S/O component
+ - Rebase FSP 2.0 components to a different base address
+ - Generate FSP mapping C header file
+"""
+
+CopyRightHeaderFile = """/*
+ *
+ * Automatically generated file; DO NOT EDIT.
+ * FSP mapping 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 __int__(self):
+ return self.get_value()
+
+ def set_value(self, val):
+ self.Data[0:3] = Val2Bytes(val, 3)
+
+ def get_value(self):
+ return Bytes2Val(self.Data[0:3])
+
+ value = property(get_value, set_value)
+
+class EFI_FIRMWARE_VOLUME_HEADER(Structure):
+ _fields_ = [
+ ('ZeroVector', ARRAY(c_uint8, 16)),
+ ('FileSystemGuid', ARRAY(c_uint8, 16)),
+ ('FvLength', c_uint64),
+ ('Signature', ARRAY(c_char, 4)),
+ ('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_uint8, 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_uint8, 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_COMMON_HEADER(Structure):
+ _fields_ = [
+ ('Signature', ARRAY(c_char, 4)),
+ ('HeaderLength', c_uint32)
+ ]
+
+class FSP_INFORMATION_HEADER(Structure):
+ _fields_ = [
+ ('Signature', ARRAY(c_char, 4)),
+ ('HeaderLength', c_uint32),
+ ('Reserved1', c_uint16),
+ ('SpecVersion', c_uint8),
+ ('HeaderRevision', c_uint8),
+ ('ImageRevision', c_uint32),
+ ('ImageId', ARRAY(c_char, 8)),
+ ('ImageSize', c_uint32),
+ ('ImageBase', c_uint32),
+ ('ImageAttribute', c_uint16),
+ ('ComponentAttribute', c_uint16),
+ ('CfgRegionOffset', c_uint32),
+ ('CfgRegionSize', c_uint32),
+ ('Reserved2', c_uint32),
+ ('TempRamInitEntryOffset', c_uint32),
+ ('Reserved3', c_uint32),
+ ('NotifyPhaseEntryOffset', c_uint32),
+ ('FspMemoryInitEntryOffset', c_uint32),
+ ('TempRamExitEntryOffset', c_uint32),
+ ('FspSiliconInitEntryOffset', c_uint32)
+ ]
+
+class FSP_PATCH_TABLE(Structure):
+ _fields_ = [
+ ('Signature', ARRAY(c_char, 4)),
+ ('HeaderLength', c_uint16),
+ ('HeaderRevision', c_uint8),
+ ('Reserved', c_uint8),
+ ('PatchEntryNum', c_uint32)
+ ]
+
+class EFI_IMAGE_DATA_DIRECTORY(Structure):
+ _fields_ = [
+ ('VirtualAddress', c_uint32),
+ ('Size', c_uint32)
+ ]
+
+class EFI_TE_IMAGE_HEADER(Structure):
+ _fields_ = [
+ ('Signature', ARRAY(c_char, 2)),
+ ('Machine', c_uint16),
+ ('NumberOfSections', c_uint8),
+ ('Subsystem', c_uint8),
+ ('StrippedSize', c_uint16),
+ ('AddressOfEntryPoint', c_uint32),
+ ('BaseOfCode', c_uint32),
+ ('ImageBase', c_uint64),
+ ('DataDirectoryBaseReloc', EFI_IMAGE_DATA_DIRECTORY),
+ ('DataDirectoryDebug', EFI_IMAGE_DATA_DIRECTORY)
+ ]
+
+class EFI_IMAGE_DOS_HEADER(Structure):
+ _fields_ = [
+ ('e_magic', c_uint16),
+ ('e_cblp', c_uint16),
+ ('e_cp', c_uint16),
+ ('e_crlc', c_uint16),
+ ('e_cparhdr', c_uint16),
+ ('e_minalloc', c_uint16),
+ ('e_maxalloc', c_uint16),
+ ('e_ss', c_uint16),
+ ('e_sp', c_uint16),
+ ('e_csum', c_uint16),
+ ('e_ip', c_uint16),
+ ('e_cs', c_uint16),
+ ('e_lfarlc', c_uint16),
+ ('e_ovno', c_uint16),
+ ('e_res', ARRAY(c_uint16, 4)),
+ ('e_oemid', c_uint16),
+ ('e_oeminfo', c_uint16),
+ ('e_res2', ARRAY(c_uint16, 10)),
+ ('e_lfanew', c_uint16)
+ ]
+
+class EFI_IMAGE_FILE_HEADER(Structure):
+ _fields_ = [
+ ('Machine', c_uint16),
+ ('NumberOfSections', c_uint16),
+ ('TimeDateStamp', c_uint32),
+ ('PointerToSymbolTable', c_uint32),
+ ('NumberOfSymbols', c_uint32),
+ ('SizeOfOptionalHeader', c_uint16),
+ ('Characteristics', c_uint16)
+ ]
+
+class PE_RELOC_BLOCK_HEADER(Structure):
+ _fields_ = [
+ ('PageRVA', c_uint32),
+ ('BlockSize', c_uint32)
+ ]
+
+class EFI_IMAGE_OPTIONAL_HEADER32(Structure):
+ _fields_ = [
+ ('Magic', c_uint16),
+ ('MajorLinkerVersion', c_uint8),
+ ('MinorLinkerVersion', c_uint8),
+ ('SizeOfCode', c_uint32),
+ ('SizeOfInitializedData', c_uint32),
+ ('SizeOfUninitializedData', c_uint32),
+ ('AddressOfEntryPoint', c_uint32),
+ ('BaseOfCode', c_uint32),
+ ('BaseOfData', c_uint32),
+ ('ImageBase', c_uint32),
+ ('SectionAlignment', c_uint32),
+ ('FileAlignment', c_uint32),
+ ('MajorOperatingSystemVersion', c_uint16),
+ ('MinorOperatingSystemVersion', c_uint16),
+ ('MajorImageVersion', c_uint16),
+ ('MinorImageVersion', c_uint16),
+ ('MajorSubsystemVersion', c_uint16),
+ ('MinorSubsystemVersion', c_uint16),
+ ('Win32VersionValue', c_uint32),
+ ('SizeOfImage', c_uint32),
+ ('SizeOfHeaders', c_uint32),
+ ('CheckSum' , c_uint32),
+ ('Subsystem', c_uint16),
+ ('DllCharacteristics', c_uint16),
+ ('SizeOfStackReserve', c_uint32),
+ ('SizeOfStackCommit' , c_uint32),
+ ('SizeOfHeapReserve', c_uint32),
+ ('SizeOfHeapCommit' , c_uint32),
+ ('LoaderFlags' , c_uint32),
+ ('NumberOfRvaAndSizes', c_uint32),
+ ('DataDirectory', ARRAY(EFI_IMAGE_DATA_DIRECTORY, 16))
+ ]
+
+class EFI_IMAGE_NT_HEADERS32(Structure):
+ _fields_ = [
+ ('Signature', c_uint32),
+ ('FileHeader', EFI_IMAGE_FILE_HEADER),
+ ('OptionalHeader', EFI_IMAGE_OPTIONAL_HEADER32)
+ ]
+
+
+class EFI_IMAGE_DIRECTORY_ENTRY:
+ EXPORT = 0
+ IMPORT = 1
+ RESOURCE = 2
+ EXCEPTION = 3
+ SECURITY = 4
+ BASERELOC = 5
+ DEBUG = 6
+ COPYRIGHT = 7
+ GLOBALPTR = 8
+ TLS = 9
+ LOAD_CONFIG = 10
+
+class EFI_FV_FILETYPE:
+ ALL = 0x00
+ RAW = 0x01
+ FREEFORM = 0x02
+ SECURITY_CORE = 0x03
+ PEI_CORE = 0x04
+ DXE_CORE = 0x05
+ PEIM = 0x06
+ DRIVER = 0x07
+ COMBINED_PEIM_DRIVER = 0x08
+ APPLICATION = 0x09
+ SMM = 0x0a
+ FIRMWARE_VOLUME_IMAGE = 0x0b
+ COMBINED_SMM_DXE = 0x0c
+ SMM_CORE = 0x0d
+ OEM_MIN = 0xc0
+ OEM_MAX = 0xdf
+ DEBUG_MIN = 0xe0
+ DEBUG_MAX = 0xef
+ FFS_MIN = 0xf0
+ FFS_MAX = 0xff
+ FFS_PAD = 0xf0
+
+class EFI_SECTION_TYPE:
+ """Enumeration of all valid firmware file section types."""
+ ALL = 0x00
+ COMPRESSION = 0x01
+ GUID_DEFINED = 0x02
+ DISPOSABLE = 0x03
+ PE32 = 0x10
+ PIC = 0x11
+ TE = 0x12
+ DXE_DEPEX = 0x13
+ VERSION = 0x14
+ USER_INTERFACE = 0x15
+ COMPATIBILITY16 = 0x16
+ FIRMWARE_VOLUME_IMAGE = 0x17
+ FREEFORM_SUBTYPE_GUID = 0x18
+ RAW = 0x19
+ PEI_DEPEX = 0x1b
+ SMM_DEPEX = 0x1c
+
+def AlignPtr (offset, alignment = 8):
+ return (offset + alignment - 1) & ~(alignment - 1)
+
+def Bytes2Val (bytes):
+ return reduce(lambda x,y: (x<<8)|y, bytes[::-1] )
+
+def Val2Bytes (value, blen):
+ return [(value>>(i*8) & 0xff) for i in range(blen)]
+
+def OutputStruct (obj, indent = 0, plen = 0):
+ if indent:
+ body = ''
+ else:
+ body = (' ' * indent + '<%s>:\n') % obj.__class__.__name__
+
+ if plen == 0:
+ plen = sizeof(obj)
+
+ max_key_len = 26
+ pstr = (' ' * (indent + 1) + '{0:<%d} = {1}\n') % max_key_len
+
+ for field in obj._fields_:
+ key = field[0]
+ val = getattr(obj, key)
+ rep = ''
+ if not isinstance(val, c_uint24) and isinstance(val, Structure):
+ body += pstr.format(key, val.__class__.__name__)
+ body += OutputStruct (val, indent + 1)
+ plen -= sizeof(val)
+ else:
+ if type(val) is str:
+ rep = "0x%X ('%s')" % (Bytes2Val(bytearray(val)), val)
+ elif type(val) in (int, long):
+ rep = '0x%X' % val
+ elif isinstance(val, c_uint24):
+ rep = '0x%X' % val.get_value()
+ elif 'c_ubyte_Array' in str(type(val)):
+ if sizeof(val) == 16:
+ rep = str(uuid.UUID(bytes = str(bytearray(val)))).upper()
+ else:
+ res = ['0x%02X'%i for i in bytearray(val)]
+ rep = '[%s]' % (','.join(res))
+ else:
+ rep = str(val)
+ plen -= sizeof(field[1])
+ body += pstr.format(key, rep)
+ if plen <= 0:
+ break
+ return body
+
+class Section:
+ def __init__(self, offset, secdata):
+ self.SecHdr = EFI_COMMON_SECTION_HEADER.from_buffer (secdata, 0)
+ self.SecData = secdata[0:int(self.SecHdr.Size)]
+ self.Offset = offset
+
+class FirmwareFile:
+ def __init__(self, offset, filedata):
+ self.FfsHdr = EFI_FFS_FILE_HEADER.from_buffer (filedata, 0)
+ self.FfsData = filedata[0:int(self.FfsHdr.Size)]
+ self.Offset = offset
+ self.SecList = []
+
+ def ParseFfs(self):
+ ffssize = len(self.FfsData)
+ offset = sizeof(self.FfsHdr)
+ if self.FfsHdr.Name != '\xff' * 16:
+ while offset < ffssize:
+ sechdr = EFI_COMMON_SECTION_HEADER.from_buffer (self.FfsData, offset)
+ sec = Section (offset, self.FfsData[offset:offset + int(sechdr.Size)])
+ self.SecList.append(sec)
+ offset += int(sechdr.Size)
+ offset = AlignPtr(offset, 4)
+
+class FirmwareVolume:
+ def __init__(self, offset, fvdata):
+ self.FvHdr = EFI_FIRMWARE_VOLUME_HEADER.from_buffer (fvdata, 0)
+ self.FvData = fvdata[0 : self.FvHdr.FvLength]
+ self.Offset = offset
+ if self.FvHdr.ExtHeaderOffset > 0:
+ self.FvExtHdr = EFI_FIRMWARE_VOLUME_EXT_HEADER.from_buffer (self.FvData, self.FvHdr.ExtHeaderOffset)
+ else:
+ self.FvExtHdr = None
+ self.FfsList = []
+
+ def ParseFv(self):
+ fvsize = len(self.FvData)
+ if self.FvExtHdr:
+ offset = self.FvHdr.ExtHeaderOffset + self.FvExtHdr.ExtHeaderSize
+ else:
+ offset = self.FvHdr.HeaderLength
+ offset = AlignPtr(offset)
+ while offset < fvsize:
+ ffshdr = EFI_FFS_FILE_HEADER.from_buffer (self.FvData, offset)
+ if (ffshdr.Name == '\xff' * 16) and (int(ffshdr.Size) == 0xFFFFFF):
+ offset = fvsize
+ else:
+ ffs = FirmwareFile (offset, self.FvData[offset:offset + int(ffshdr.Size)])
+ ffs.ParseFfs()
+ self.FfsList.append(ffs)
+ offset += int(ffshdr.Size)
+ offset = AlignPtr(offset)
+
+class FspImage:
+ def __init__(self, offset, fih, fihoff, patch):
+ self.Fih = fih
+ self.FihOffset = fihoff
+ self.Offset = offset
+ self.FvIdxList = []
+ self.Type = "XTMSXXXXOXXXXXXX"[(fih.ComponentAttribute >> 12) & 0x0F]
+ self.PatchList = patch
+ self.PatchList.append(fihoff + 0x1C)
+
+ def AppendFv(self, FvIdx):
+ self.FvIdxList.append(FvIdx)
+
+ def Patch(self, delta, fdbin):
+ count = 0
+ applied = 0
+ for idx, patch in enumerate(self.PatchList):
+ ptype = (patch>>24) & 0x0F
+ if ptype not in [0x00, 0x0F]:
+ raise Exception('ERROR: Invalid patch type %d !' % ptype)
+ if patch & 0x80000000:
+ patch = self.Fih.ImageSize - (0x1000000 - (patch & 0xFFFFFF))
+ else:
+ patch = patch & 0xFFFFFF
+ if (patch < self.Fih.ImageSize) and (patch + sizeof(c_uint32) <= self.Fih.ImageSize):
+ offset = patch + self.Offset
+ value = Bytes2Val(fdbin[offset:offset+sizeof(c_uint32)])
+ value += delta
+ fdbin[offset:offset+sizeof(c_uint32)] = Val2Bytes(value, sizeof(c_uint32))
+ applied += 1
+ count += 1
+ # Don't count the FSP base address patch entry appended at the end
+ if count != 0:
+ count -= 1
+ applied -= 1
+ return (count, applied)
+
+class FirmwareDevice:
+ def __init__(self, offset, fdfile):
+ self.FvList = []
+ self.FspList = []
+ self.FdFile = fdfile
+ self.Offset = 0
+ hfsp = open (self.FdFile, 'rb')
+ self.FdData = bytearray(hfsp.read())
+ hfsp.close()
+
+ def ParseFd(self):
+ offset = 0
+ fdsize = len(self.FdData)
+ self.FvList = []
+ while offset < fdsize:
+ fvh = EFI_FIRMWARE_VOLUME_HEADER.from_buffer (self.FdData, offset)
+ if '_FVH' != fvh.Signature:
+ raise Exception("ERROR: Invalid FV header !")
+ fv = FirmwareVolume (offset, self.FdData[offset:offset + fvh.FvLength])
+ fv.ParseFv ()
+ self.FvList.append(fv)
+ offset += fv.FvHdr.FvLength
+
+ def CheckFsp (self):
+ if len(self.FspList) == 0:
+ return
+
+ fih = None
+ for fsp in self.FspList:
+ if fsp.Fih.HeaderRevision < 3:
+ raise Exception("ERROR: FSP 1.x is not supported by this tool !")
+ if not fih:
+ fih = fsp.Fih
+ else:
+ newfih = fsp.Fih
+ if (newfih.ImageId != fih.ImageId) or (newfih.ImageRevision != fih.ImageRevision):
+ raise Exception("ERROR: Inconsistent FSP ImageId or ImageRevision detected !")
+
+ def ParseFsp(self):
+ flen = 0
+ for idx, fv in enumerate(self.FvList):
+ # Check if this FV contains FSP header
+ if flen == 0:
+ if len(fv.FfsList) == 0:
+ continue
+ ffs = fv.FfsList[0]
+ if len(ffs.SecList) == 0:
+ continue
+ sec = ffs.SecList[0]
+ if sec.SecHdr.Type != EFI_SECTION_TYPE.RAW:
+ continue
+ fihoffset = ffs.Offset + sec.Offset + sizeof(sec.SecHdr)
+ fspoffset = fv.Offset
+ offset = fspoffset + fihoffset
+ fih = FSP_INFORMATION_HEADER.from_buffer (self.FdData, offset)
+ if 'FSPH' != fih.Signature:
+ continue
+
+ offset += fih.HeaderLength
+ offset = AlignPtr(offset, 4)
+ plist = []
+ while True:
+ fch = FSP_COMMON_HEADER.from_buffer (self.FdData, offset)
+ if 'FSPP' != fch.Signature:
+ offset += fch.HeaderLength
+ offset = AlignPtr(offset, 4)
+ else:
+ fspp = FSP_PATCH_TABLE.from_buffer (self.FdData, offset)
+ offset += sizeof(fspp)
+ pdata = (c_uint32 * fspp.PatchEntryNum).from_buffer(self.FdData, offset)
+ plist = list(pdata)
+ break
+
+ fsp = FspImage (fspoffset, fih, fihoffset, plist)
+ fsp.AppendFv (idx)
+ self.FspList.append(fsp)
+ flen = fsp.Fih.ImageSize - fv.FvHdr.FvLength
+ else:
+ fsp.AppendFv (idx)
+ flen -= fv.FvHdr.FvLength
+ if flen < 0:
+ raise Exception("ERROR: Incorrect FV size in image !")
+ self.CheckFsp ()
+
+class PeTeImage:
+ def __init__(self, offset, data):
+ self.Offset = offset
+ tehdr = EFI_TE_IMAGE_HEADER.from_buffer (data, 0)
+ if tehdr.Signature == 'VZ': # TE image
+ self.TeHdr = tehdr
+ elif tehdr.Signature == 'MZ': # PE32 image
+ self.TeHdr = None
+ self.DosHdr = EFI_IMAGE_DOS_HEADER.from_buffer (data, 0)
+ self.PeHdr = EFI_IMAGE_NT_HEADERS32.from_buffer (data, self.DosHdr.e_lfanew)
+ if self.PeHdr.Signature != 0x4550:
+ raise Exception("ERROR: Invalid PE32 header !")
+ if self.PeHdr.FileHeader.SizeOfOptionalHeader < EFI_IMAGE_OPTIONAL_HEADER32.DataDirectory.offset:
+ raise Exception("ERROR: Unsupported PE32 image !")
+ if self.PeHdr.OptionalHeader.NumberOfRvaAndSizes <= EFI_IMAGE_DIRECTORY_ENTRY.BASERELOC:
+ raise Exception("ERROR: No relocation information available !")
+ self.Offset = offset
+ self.Data = data
+ self.RelocList = []
+
+ def IsTeImage(self):
+ return self.TeHdr is not None
+
+ def ParseReloc(self):
+ if self.IsTeImage():
+ rsize = self.TeHdr.DataDirectoryBaseReloc.Size
+ roffset = sizeof(self.TeHdr) - self.TeHdr.StrippedSize + self.TeHdr.DataDirectoryBaseReloc.VirtualAddress
+ else:
+ rsize = self.PeHdr.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY.BASERELOC].Size
+ roffset = self.PeHdr.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY.BASERELOC].VirtualAddress
+
+ alignment = 4
+ offset = roffset
+ while offset < roffset + rsize:
+ offset = AlignPtr(offset, 4)
+ blkhdr = PE_RELOC_BLOCK_HEADER.from_buffer(self.Data, offset)
+ offset += sizeof(blkhdr)
+ # Read relocation type,offset pairs
+ rlen = blkhdr.BlockSize - sizeof(PE_RELOC_BLOCK_HEADER)
+ rnum = rlen/sizeof(c_uint16)
+ rdata = (c_uint16 * rnum).from_buffer(self.Data, offset)
+ for each in rdata:
+ roff = each & 0xfff
+ rtype = each >> 12
+ if rtype == 0: # IMAGE_REL_BASED.ABSOLUTE:
+ continue
+ if rtype != 3: # IMAGE_REL_BASED_HIGHLOW
+ raise Exception("ERROR: Unsupported relocation type %d!" % rtype)
+ # Calculate the offset of the relocation
+ aoff = blkhdr.PageRVA + roff
+ if self.IsTeImage():
+ aoff += sizeof(self.TeHdr) - self.TeHdr.StrippedSize
+ self.RelocList.append((rtype, aoff))
+ offset += sizeof(rdata)
+
+ def Rebase(self, delta, fdbin):
+ count = 0
+ if delta == 0:
+ return count
+
+ for (rtype, roff) in self.RelocList:
+ if rtype == 0x03: # HIGHLOW
+ offset = roff + self.Offset
+ value = Bytes2Val(fdbin[offset:offset+sizeof(c_uint32)])
+ value += delta
+ fdbin[offset:offset+sizeof(c_uint32)] = Val2Bytes(value, sizeof(c_uint32))
+ count += 1
+ else:
+ raise Exception('ERROR: Unknown relocation type %d !' % rtype)
+
+ if self.IsTeImage():
+ offset = self.Offset + EFI_TE_IMAGE_HEADER.ImageBase.offset
+ size = EFI_TE_IMAGE_HEADER.ImageBase.size
+ else:
+ offset = self.Offset + self.DosHdr.e_lfanew
+ offset += EFI_IMAGE_NT_HEADERS32.OptionalHeader.offset
+ offset += EFI_IMAGE_OPTIONAL_HEADER32.ImageBase.offset
+ size = EFI_IMAGE_OPTIONAL_HEADER32.ImageBase.size
+
+ value = Bytes2Val(fdbin[offset:offset+size]) + delta
+ fdbin[offset:offset+size] = Val2Bytes(value, size)
+
+ return count
+
+def ShowFspInfo (fspfile):
+ fd = FirmwareDevice(0, fspfile)
+ fd.ParseFd ()
+ fd.ParseFsp ()
+
+ print ("\nFound the following %d Firmware Volumes in FSP binary:" % (len(fd.FvList)))
+ for idx, fv in enumerate(fd.FvList):
+ name = fv.FvExtHdr.FvName
+ if not name:
+ name = '\xff' * 16
+ else:
+ name = str(bytearray(name))
+ guid = uuid.UUID(bytes = name)
+ print ("FV%d:" % idx)
+ print (" GUID : %s" % str(guid).upper())
+ print (" Offset : 0x%08X" % fv.Offset)
+ print (" Length : 0x%08X" % fv.FvHdr.FvLength)
+ print ("\n")
+
+ for fsp in fd.FspList:
+ fvlist = map(lambda x : 'FV%d' % x, fsp.FvIdxList)
+ print ("FSP_%s contains %s" % (fsp.Type, ','.join(fvlist)))
+ print ("%s" % (OutputStruct(fsp.Fih, 0, fsp.Fih.HeaderLength)))
+
+def GenFspHdr (fspfile, outdir, hfile):
+ fd = FirmwareDevice(0, fspfile)
+ fd.ParseFd ()
+ fd.ParseFsp ()
+
+ if not hfile:
+ hfile = os.path.splitext(os.path.basename(fspfile))[0] + '.h'
+ fspname, ext = os.path.splitext(os.path.basename(hfile))
+ filename = os.path.join(outdir, fspname + ext)
+ hfsp = open(filename, 'w')
+ hfsp.write ('%s\n\n' % CopyRightHeaderFile)
+
+ firstfv = True
+ for fsp in fd.FspList:
+ fih = fsp.Fih
+ if firstfv:
+ hfsp.write("#define FSP_IMAGE_ID 0x%016X /* '%s' */\n" % (Bytes2Val(bytearray(fih.ImageId)), fih.ImageId))
+ hfsp.write("#define FSP_IMAGE_REV 0x%08X \n\n" % fih.ImageRevision)
+ firstfv = False
+ fv = fd.FvList[fsp.FvIdxList[0]]
+ hfsp.write ('#define FSP%s_BASE 0x%08X\n' % (fsp.Type, fih.ImageBase))
+ hfsp.write ('#define FSP%s_OFFSET 0x%08X\n' % (fsp.Type, fv.Offset))
+ hfsp.write ('#define FSP%s_LENGTH 0x%08X\n\n' % (fsp.Type, fih.ImageSize))
+
+ hfsp.close()
+
+def SplitFspBin (fspfile, outdir, nametemplate):
+ fd = FirmwareDevice(0, fspfile)
+ fd.ParseFd ()
+ fd.ParseFsp ()
+
+ for fsp in fd.FspList:
+ ftype = fsp.Type
+ if not nametemplate:
+ nametemplate = fspfile
+ fspname, ext = os.path.splitext(os.path.basename(nametemplate))
+ filename = os.path.join(outdir, fspname + '_' + fsp.Type + ext)
+ hfsp = open(filename, 'wb')
+ print ("Ceate FSP component file '%s'" % filename)
+ for fvidx in fsp.FvIdxList:
+ fv = fd.FvList[fvidx]
+ hfsp.write(fv.FvData)
+ hfsp.close()
+
+def RebaseFspBin (FspBinary, FspComponent, FspBase, OutputDir, OutputFile):
+ fd = FirmwareDevice(0, FspBinary)
+ fd.ParseFd ()
+ fd.ParseFsp ()
+
+ numcomp = len(FspComponent)
+ baselist = FspBase
+ if numcomp != len(baselist):
+ print "ERROR: Required number of base does not match number of FSP component !"
+ return
+
+ newfspbin = fd.FdData[:]
+
+ for idx, fspcomp in enumerate(FspComponent):
+
+ found = False
+ for fsp in fd.FspList:
+ ftype = fsp.Type.lower()
+ if ftype == fspcomp:
+ found = True
+ break
+
+ if not found:
+ print "ERROR: Could not find FSP_%c component to rebase !" % fspcomp.upper()
+ return
+
+ fspbase = baselist[idx]
+ if fspbase.startswith('0x'):
+ newbase = int(fspbase, 16)
+ else:
+ newbase = int(fspbase)
+ oldbase = fsp.Fih.ImageBase
+ delta = newbase - oldbase
+ print "Rebase FSP-%c from 0x%08X to 0x%08X:" % (ftype.upper(),oldbase,newbase)
+
+ imglist = []
+ for fvidx in fsp.FvIdxList:
+ fv = fd.FvList[fvidx]
+ for ffs in fv.FfsList:
+ for sec in ffs.SecList:
+ if sec.SecHdr.Type in [EFI_SECTION_TYPE.TE, EFI_SECTION_TYPE.PE32]: # TE or PE32
+ offset = fd.Offset + fv.Offset + ffs.Offset + sec.Offset + sizeof(sec.SecHdr)
+ imglist.append ((offset, len(sec.SecData) - sizeof(sec.SecHdr)))
+
+ fcount = 0
+ pcount = 0
+ for (offset, length) in imglist:
+ img = PeTeImage(offset, fd.FdData[offset:offset + length])
+ img.ParseReloc()
+ pcount += img.Rebase(delta, newfspbin)
+ fcount += 1
+
+ print " Patched %d entries in %d TE/PE32 images." % (pcount, fcount)
+
+ (count, applied) = fsp.Patch(delta, newfspbin)
+ print " Patched %d entries using FSP patch table." % applied
+ if count != applied:
+ print " %d invalid entries are ignored !" % (count - applied)
+
+ if OutputFile == '':
+ filename = os.path.basename(FspBinary)
+ base, ext = os.path.splitext(filename)
+ OutputFile = base + "_%08X" % newbase + ext
+
+ fspname, ext = os.path.splitext(os.path.basename(OutputFile))
+ filename = os.path.join(OutputDir, fspname + ext)
+ fd = open(filename, "wb")
+ fd.write(newfspbin)
+ fd.close()
+
+def main ():
+ parser = argparse.ArgumentParser()
+ subparsers = parser.add_subparsers(title='commands')
+
+ parser_rebase = subparsers.add_parser('rebase', help='rebase a FSP into a new base address')
+ parser_rebase.set_defaults(which='rebase')
+ parser_rebase.add_argument('-f', '--fspbin' , dest='FspBinary', type=str, help='FSP binary file path', required = True)
+ parser_rebase.add_argument('-c', '--fspcomp', choices=['t','m','s','o'], nargs='+', dest='FspComponent', type=str, help='FSP component to rebase', default = "['t']", required = True)
+ parser_rebase.add_argument('-b', '--newbase', dest='FspBase', nargs='+', type=str, help='Rebased FSP binary file name', default = '', required = True)
+ parser_rebase.add_argument('-o', '--outdir' , dest='OutputDir', type=str, help='Output directory path', default = '.')
+ parser_rebase.add_argument('-n', '--outfile', dest='OutputFile', type=str, help='Rebased FSP binary file name', default = '')
+
+ 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_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_info = subparsers.add_parser('info', help='display FSP information')
+ parser_info.set_defaults(which='info')
+ parser_info.add_argument('-f', '--fspbin' , dest='FspBinary', type=str, help='FSP binary file path', required = True)
+
+ args = parser.parse_args()
+ if args.which in ['rebase', 'split', 'genhdr', 'info']:
+ if not os.path.exists(args.FspBinary):
+ raise Exception ("ERROR: Could not locate FSP binary file '%s' !" % args.FspBinary)
+ if hasattr(args, 'OutputDir') and not os.path.exists(args.OutputDir):
+ raise Exception ("ERROR: Invalid output directory '%s' !" % args.OutputDir)
+
+ if args.which == 'rebase':
+ RebaseFspBin (args.FspBinary, args.FspComponent, args.FspBase, args.OutputDir, args.OutputFile)
+ elif args.which == 'split':
+ SplitFspBin (args.FspBinary, args.OutputDir, args.NameTemplate)
+ elif args.which == 'genhdr':
+ GenFspHdr (args.FspBinary, args.OutputDir, args.HFileName)
+ elif args.which == 'info':
+ ShowFspInfo (args.FspBinary)
+ else:
+ pass
+
+ return 0
+
+if __name__ == '__main__':
+ sys.exit(main())
diff --git a/Core/IntelFsp2Pkg/Tools/UserManuals/GenCfgOptUserManual.md b/Core/IntelFsp2Pkg/Tools/UserManuals/GenCfgOptUserManual.md new file mode 100644 index 0000000000..938c18416d --- /dev/null +++ b/Core/IntelFsp2Pkg/Tools/UserManuals/GenCfgOptUserManual.md @@ -0,0 +1,353 @@ +#Name
+**GenCfgOpt.py** The python script that generates UPD text (**.txt**) files for
+the compiler, header files for the UPD regions, and generates a Boot Settings
+File (**BSF**), all from an EDK II Platform Description (**DSC**) file.
+
+#Synopsis
+```
+GenCfgOpt UPDTXT PlatformDscFile BuildFvDir [TxtOutFile] [-D Macros]
+GenCfgOpt HEADER PlatformDscFile BuildFvDir [InputHFile] [-D Macros]
+GenCfgOpt GENBSF PlatformDscFile BuildFvDir BsfOutFile [-D Macros]
+```
+
+#Description
+**GenCfgOpt.py** is a script that generates configuration options from an
+**EDK II Platform Description (DSC)** file. It has three functions.
+
+ 1. It produces a **.txt** file that is used by the compiler that summarizes
+ the UPD section in the DSC file.
+ 2. It generates header files for the UPD regions.
+ 3. It generates a **Boot Settings File (BSF)** that can be used by the
+ **Binary Configuration Tool (BCT)** to provide a graphical user
+ interface for manipulating settings in the UPD regions.
+
+The **GenCfgOpt.py** script generates important files that are vital parts of
+your build process. The **UPDTXT** and **HEADER** use cases must be done before
+the **'build'** command; the **GENBSF** use case may be done at any time.
+
+The following sections explain the three use cases.
+
+## 1. GenCfgOpt.py UPDTXT
+The **UPDTXT** option creates a text file with all the UPD entries, offsets,
+size in bytes, and values. **GenCfgOpt** reads this information from the
+**[PcdsDynamicVpd.Upd]** section of the project's DSC file. The DSC file allows
+you to specify offsets and sizes for each entry, opening up the possibility of
+introducing gaps between entries. **GenCfgOpt** fills in these gaps with UPD
+entries that have the generic names **UnusedUpdSpaceN** where N begins with 0
+and increments. The command signature for **UPDTXT** is:
+
+```
+GenCfgOpt UPDTXT PlatformDscFile BuildFvDir [TxtOutFile] [-D Macros]
+```
+
+**PlatformDscFile** must be the location of the DSC file for the platform you're
+building. **BuildFvDir** is the location where the binary will be stored. The
+optional **TxtOutFile** is a name and location for the output of **GenCfgOpt**.
+The default name and location is the ```<UPD_TOOL_GUID>.txt``` in the directory
+specified by **BuildFvDir**. The macro ```UPD_TOOL_GUID``` must be defined in
+the DSC file or in the optional Macros arguments. Each optional macro argument
+must follow the form ```?D <MACRO_NAME>=<VALUE>```.
+
+**GenCfgOpt** checks to see if the UPD txt file has already been created and
+will only re-create it if the DSC was modified after it was created.
+
+## 2. GenCfgOpt.py HEADER
+The **HEADER** option creates header files in the build folder. Both header
+files define the ```_UPD_DATA_REGION``` data structures in FspUpd.h, FsptUpd.h,
+FspmUpd.h and FspsUpd.h. In these header files any undefined elements of
+structures will be added as **ReservedUpdSpaceN** beginning with N=0. The
+command signature for **HEADER** is
+
+```GenCfgOpt HEADER PlatformDscFile BuildFvDir [InputHFile] [-D Macros]```
+
+**PlatformDscFile** and **BuildFvDir** are described in the previous section.
+The optional **InputHFile** is a header file that may contain data definitions
+that are used by variables in the UPD regions. This header file must contain
+the special keywords ```!EXPORT EXTERNAL_BOOTLOADER_STRUCT_BEGIN``` and
+```!EXPORT EXTERNAL_BOOTLOADER_STRUCT_END``` in comments. Everything between
+these two keywords will be included in the generated header file.
+The mechanism to specify whether a variable appears as **ReservedUpdSpaceN** in
+the FspUpd.h header file is in special commands that appear in the comments of
+the DSC file. The special commands begin with ```!HDR```, for header. The
+following table summarizes the two command options.
+
+### HEADER
+Use the **HEADER** command to hide specific variables in the public header file.
+In your project DSC file, use ```!HDR HEADER:{OFF}``` at the beginning of the
+section you wish to hide and ```!HDR HEADER:{ON}``` at the end.
+
+### STRUCT
+The **STRUCT** command allows you to specify a specific data type for a
+variable. You can specify a pointer to a data struct, for example. You define
+the data structure in the **InputHFile** between
+```!EXPORT EXTERNAL_BOOTLOADER_STRUCT_BEGIN``` and
+```!EXPORT EXTERNAL_BOOTLOADER_STRUCT_END```.
+
+#####Example:
+```!HDR STRUCT:{MY_DATA_STRUCT*}```
+
+You then define ```MY_DATA_STRUCT``` in **InputHFile**.
+
+### EMBED
+The **EMBED** command allows you to put one or more UPD data into a specify data
+structure. You can utilize it as a group of UPD for example. You must specify a
+start and an end for the specify data structure.
+
+#####Example:
+```
+ !HDR EMBED:{MY_DATA_STRUCT:MyDataStructure:START}
+ gTokenSpaceGuid.Upd1 | 0x0020 | 0x01 | 0x00
+ gTokenSpaceGuid.Upd2 | 0x0021 | 0x01 | 0x00
+ !HDR EMBED:{MY_DATA_STRUCT:MyDataStructure:END}
+ gTokenSpaceGuid.UpdN | 0x0022 | 0x01 | 0x00
+```
+
+#####Result:
+```
+ typedef struct {
+ /** Offset 0x0020
+ **/
+ UINT8 Upd1;
+ /** Offset 0x0021
+ **/
+ UINT8 Upd2;
+ /** Offset 0x0022
+ **/
+ UINT8 UpdN;
+ } MY_DATA_STRUCT;
+
+ typedef struct _UPD_DATA_REGION {
+ ...
+ /** Offset 0x0020
+ **/
+ MY_DATA_STRUCT MyDataStruct;
+ ...
+ } UPD_DATA_REGION;
+```
+
+## 3. GenCfgOpt .py GENBSF
+The **GENBSF** option generates a BSF from the UPD entries in a package's DSC
+file. It does this by parsing special commands found in the comments of the DSC
+file. They roughly match the keywords that define the different sections of the
+BSF.
+
+The command signature for **GENBSF** is
+
+```GenCfgOpt GENBSF PlatformDscFile BuildFvDir BsfOutFile [-D Macros]```
+
+In this case, the **BsfOutFile** parameter is required; it should be the
+relative path to where the BSF should be stored.
+
+Every BSF command in the DSC file begins with **!BSF** or **@Bsf**. The
+following table summarizes the options that come after **!BSF** or **@Bsf**:
+
+# BSF Commands Description
+###PAGES
+**PAGES** maps abbreviations to friendly-text descriptions of the pages in a BSF.
+
+#####Example:
+```!BSF PAGES:{PG1:?Page 1?, PG2:?Page 2?}``` or
+
+```@Bsf PAGES:{PG1:?Page 1?, PG2:?Page 2?}```
+
+###PAGE
+This marks the beginning of a page. Use the abbreviation specified in **PAGES**
+command.
+
+#####Example:
+```!BSF PAGE:{PG1}``` or
+
+```@Bsf PAGE:{PG1}```
+
+All the entries that come after this command are assumed to be on that page,
+until the next **PAGE** command
+
+###FIND
+FIND maps to the BSF **Find** command. It will be placed in the **StructDef**
+region of the BSF and should come at the beginning of the UPD sections of the
+DSC, immediately before the signatures that mark the beginning of these
+sections. The content should be the plain-text equivalent of the signature. The
+signature is usually 8 characters.
+
+#####Example:
+```!BSF FIND:{PROJSIG1}``` or
+
+```@Bsf FIND:{PROJSIG1}```
+
+###BLOCK
+The BLOCK command maps to the **BeginInfoBlock** section of the BSF. There are
+two elements: a version number and a plain-text description.
+
+#####Example:
+```!BSF BLOCK:{NAME:"My platform name", VER:"0.1"}``` or
+
+```@Bsf BLOCK:{NAME:"My platform name", VER:"0.1"}```
+
+###NAME
+**NAME** gives a plain-text for a variable. This is the text label that will
+appear next to the control in **BCT**.
+
+#####Example:
+```!BSF NAME:{Variable 0}``` or
+
+```@Bsf NAME:{Variable 0}```
+
+If the **!BSF NAME** or **@Bsf NAME** command does not appear before an entry
+in the UPD region of the DSC file, then that entry will not appear in the BSF.
+
+###TYPE
+The **TYPE** command is used either by itself or with the **NAME** command. It
+is usually used by itself when defining an **EditNum** field for the BSF. You
+specify the type of data in the second parameter and the range of valid values
+in the third.
+
+#####Example:
+```!BSF TYPE:{EditNum, HEX, (0x00,0xFF)}``` or
+
+```@Bsf TYPE:{EditNum, HEX, (0x00,0xFF)}```
+
+**TYPE** appears on the same line as the **NAME** command when using a combo-box.
+
+#####Example:
+```!BSF NAME:{Variable 1} TYPE:{Combo}``` or
+```@Bsf NAME:{Variable 1} TYPE:{Combo}```
+
+There is a special **None** type that puts the variable in the **StructDef**
+region of the BSF, but doesn?t put it in any **Page** section. This makes the
+variable visible to BCT, but not to the end user.
+
+###HELP
+The **HELP** command defines what will appear in the help text for each control
+in BCT.
+
+#####Example:
+```!BSF HELP:{Enable/disable LAN controller.}``` or
+
+```@Bsf HELP:{Enable/disable LAN controller.}```
+
+###OPTION
+The **OPTION** command allows you to custom-define combo boxes and map integer
+or hex values to friendly-text options.
+
+#####Example:
+```!BSF OPTION:{0:IDE, 1:AHCI, 2:RAID}```
+
+```!BSF OPTION:{0x00:0 MB, 0x01:32 MB, 0x02:64 MB}```
+
+or
+
+```@Bsf OPTION:{0:IDE, 1:AHCI, 2:RAID}```
+
+```@Bsf OPTION:{0x00:0 MB, 0x01:32 MB, 0x02:64 MB}```
+
+###FIELD
+The **FIELD** command can be used to define a section of a consolidated PCD
+such that the PCD will be displayed in several fields via BCT interface instead
+of one long entry.
+
+#####Example:
+```!BSF FIELD:{PcdDRAMSpeed:1}``` or
+
+```@Bsf FIELD:{PcdDRAMSpeed:1}```
+
+###ORDER
+The **ORDER** command can be used to adjust the display order for the BSF items.
+By default the order value for a BSF item is assigned to be the UPD item
+```(Offset * 256)```. It can be overridden by declaring **ORDER** command using
+format ORDER: ```{HexMajor.HexMinor}```. In this case the order value will be
+```(HexMajor*256+HexMinor)```. The item order value will be used as the sort key
+during the BSF item display.
+
+#####Example:
+```!BSF ORDER:{0x0040.01}``` or
+
+```@Bsf ORDER:{0x0040.01}```
+
+For **OPTION** and **HELP** commands, it allows to split the contents into
+multiple lines by adding multiple **OPTION** and **HELP** command lines. The
+lines except for the very first line need to start with **+** in the content to
+tell the tool to append this string to the previous one.
+
+For example, the statement
+
+```!BSF OPTION:{0x00:0 MB, 0x01:32 MB, 0x02:64 MB}```
+
+is equivalent to:
+
+```!BSF OPTION:{0x00:0 MB, 0x01:32 MB,}```
+
+```!BSF OPTION:{+ 0x02:64 MB}```
+
+or
+
+```@Bsf OPTION:{0x00:0 MB, 0x01:32 MB, 0x02:64 MB}```
+
+is equivalent to:
+
+```@Bsf OPTION:{0x00:0 MB, 0x01:32 MB,}```
+
+```@Bsf OPTION:{+ 0x02:64 MB}```
+
+The **NAME**, **OPTION**, **TYPE**, and **HELP** commands can all appear on the
+same line following the **!BSF** or **@Bsf** keyword or they may appear on
+separate lines to improve readability.
+
+There are four alternative ways to replace current BSF commands.
+### 1. ```# @Prompt```
+An alternative way replacing **NAME** gives a plain-text for a
+variable. This is the text label that will appear next to the control in BCT.
+
+#####Example:
+```# @Prompt Variable 0```
+
+The above example can replace the two methods as below.
+
+```!BSF NAME:{Variable 0}``` or
+
+```@Bsf NAME:{Variable 0}```
+
+If the ```# @Prompt``` command does not appear before an entry in the UPD region
+of the DSC file, then that entry will not appear in the BSF.
+
+### 2. ```##```
+An alternative way replacing **HELP** command defines what will appear in the
+help text for each control in BCT.
+
+#####Example:
+```## Enable/disable LAN controller.```
+
+The above example can replace the two methods as below.
+
+```!BSF HELP:{Enable/disable LAN controller.}``` or
+
+```@Bsf HELP:{Enable/disable LAN controller.}```
+
+### 3. ```# @ValidList```
+An alternative way replacing **OPTION** command allows you to custom-define
+combo boxes and map integer or hex values to friendly-text options.
+
+#####Example:
+``` # @ValidList 0x80000003 | 0, 1, 2 | IDE, AHCI, RAID
+ Error Code | Options | Descriptions
+```
+
+The above example can replace the two methods as below.
+
+```!BSF OPTION:{0:IDE, 1:AHCI, 2:RAID}``` or
+
+```@Bsf OPTION:{0:IDE, 1:AHCI, 2:RAID}```
+
+### 4. ```# @ValidRange```
+An alternative way replace **EditNum** field for the BSF.
+
+#####Example:
+```# @ValidRange 0x80000001 | 0x0 ? 0xFF
+ Error Code | Range
+```
+
+The above example can replace the two methods as below.
+
+```!BSF TYPE:{EditNum, HEX, (0x00,0xFF)}``` or
+
+```@Bsf TYPE:{EditNum, HEX, (0x00,0xFF)}```
+
diff --git a/Core/IntelFsp2Pkg/Tools/UserManuals/PatchFvUserManual.md b/Core/IntelFsp2Pkg/Tools/UserManuals/PatchFvUserManual.md new file mode 100644 index 0000000000..becaf96b21 --- /dev/null +++ b/Core/IntelFsp2Pkg/Tools/UserManuals/PatchFvUserManual.md @@ -0,0 +1,123 @@ +#Name
+**_PatchFv.py_** - The python script that patches the firmware volumes (**FV**)
+with in the flash device (**FD**) file post FSP build.
+
+#Synopsis
+
+```
+PatchFv FvBuildDir [FvFileBaseNames:]FdFileBaseNameToPatch ["Offset, Value"]+
+ | ["Offset, Value, @Comment"]+
+ | ["Offset, Value, $Command"]+
+ | ["Offset, Value, $Command, @Comment"]+
+```
+
+#Description
+The **_PatchFv.py_** tool allows the developer to fix up FD images to follow the
+Intel FSP Architecture specification. It also makes the FD image relocatable.
+The tool is written in Python and uses Python 2.7 or later to run.
+Consider using the tool in a build script.
+
+#FvBuildDir (Argument 1)
+This is the first argument that **_PatchFv.py_** requires. It is the build
+directory for all firmware volumes created during the FSP build. The path must
+be either an absolute path or a relevant path, relevant to the top level of the
+FSP tree.
+
+####Example usage:
+```
+ Build\YouPlatformFspPkg\%BD_TARGET%_%VS_VERSION%%VS_X86%\FV
+```
+
+The example used contains Windows batch script %VARIABLES%.
+
+#FvFileBaseNames (Argument 2: 0ptional Part 1)
+The firmware volume file base names (**_FvFileBaseNames_**) are the independent
+Fv?s that are to be patched within the FD. (0 or more in the form
+**FVFILEBASENAME:**) The colon **:** is used for delimiting the single
+argument and must be appended to the end of each (**_FvFileBaseNames_**).
+
+####Example usage:
+```
+STAGE1:STAGE2:MANIFEST:YOURPLATFORM
+```
+
+In the example **STAGE1** is **STAGE1.Fv** in **YOURPLATFORM.fd**.
+
+# FdFileNameToPatch (Argument 2: Mandatory Part 2)
+
+Firmware device file name to patch (**_FdFileNameToPatch_**) is the base name of
+the FD file that is to be patched. (1 only, in the form **YOURPLATFORM**)
+
+####Example usage:
+```
+STAGE1:STAGE2:MANIFEST:YOURPLATFORM
+```
+
+In the example **YOURPLATFORM** is from **_YOURPLATFORM.fd_**
+
+#"Offset, Value[, Command][, Comment]" (Argument 3)
+The **_Offset_** can be a positive or negative number and represents where the
+**_Value_** to be patched is located within the FD. The **_Value_** is what
+will be written at the given **_Offset_** in the FD. Constants may be used for
+both offsets and values. Also, this argument handles expressions for both
+offsets and values using these operators:
+
+```
+ = - * & | ~ ( ) [ ] { } < >
+```
+
+The entire argument includes the quote marks like in the example argument below:
+
+```
+0xFFFFFFC0, SomeCore:__EntryPoint - [0x000000F0],@SomeCore Entry
+```
+
+###Constants:
+ Hexadecimal (use **0x** as prefix) | Decimal
+
+####Examples:
+
+| **Positive Hex** | **Negative Hex** | **Positive Decimal** | **Negative Decimal** |
+| ---------------: | ---------------: | -------------------: | -------------------: |
+| 0x000000BC | 0xFFFFFFA2 | 188 | -94 |
+
+```
+ModuleName:FunctionName | ModuleName:GlobalVariableName
+ModuleGuid:Offset
+```
+
+###Operators:
+
+```
+
+ + Addition
+ - Subtraction
+ * Multiplication
+ & Logical and
+ | Logical or
+ ~ Complement
+ ( ) Evaluation control
+ [ ] Get a DWord value at the specified offset expression from [expr]
+ { } Convert an offset {expr} into an absolute address (FSP_BASE + expr)
+ < > Convert absolute address <expr> into an image offset (expr & FSP_SIZE)
+
+```
+
+###Special Commands:
+Special commands must use the **$** symbol as a prefix to the command itself.
+There is only one command available at this time.
+
+```
+$COPY ? Copy a binary block from source to destination.
+```
+
+####Example:
+
+```
+0x94, [PlatformInit:__gPcd_BinPatch_FvRecOffset] + 0x94, [0x98], $COPY, @Sync up 2nd FSP Header
+```
+
+###Comments:
+Comments are allowed in the **Offset, Value [, Comment]** argument. Comments
+must use the **@** symbol as a prefix. The comment will output to the build
+window upon successful completion of patching along with the offset and value data.
diff --git a/Core/IntelFsp2Pkg/Tools/UserManuals/SplitFspBinUserManual.md b/Core/IntelFsp2Pkg/Tools/UserManuals/SplitFspBinUserManual.md new file mode 100644 index 0000000000..064e0ac845 --- /dev/null +++ b/Core/IntelFsp2Pkg/Tools/UserManuals/SplitFspBinUserManual.md @@ -0,0 +1,69 @@ +# SplitFspBin.py is a python script to support some operations on Intel FSP 2.0 image.
+
+It supports:
+
+- Split Intel FSP 2.0 image into individual FSP-T/M/S/O component
+
+- Rebase Intel FSP 2.0 components to different base addresses
+
+- Generate Intel FSP 2.0 C header file
+
+- Display Intel FSP 2.0 information header for each FSP component
+
+## Split Intel FSP 2.0 image
+
+To split individual FSP component in Intel FSP 2.0 image, the following
+command can be used:
+
+ **python SplitFspBin.py split [-h] -f FSPBINARY [-o OUTPUTDIR] [-n NAMETEMPLATE]**
+
+For example:
+
+ `python SplitFspBin.py split -f FSP.bin`
+
+ It will create FSP_T.bin, FSP_M.bin and FSP_S.bin in current directory.
+
+## Rebase Intel FSP 2.0 components
+
+To rebase one or multiple FSP components in Intel FSP 2.0 image, the following
+command can be used:
+
+ **python SplitFspBin.py rebase [-h] -f FSPBINARY -c {t,m,s,o} [{t,m,s,o} ...] -b FSPBASE [FSPBASE ...] [-o OUTPUTDIR] [-n OUTPUTFILE]**
+
+For example:
+
+ `python SplitFspBin.py rebase -f FSP.bin –c t –b 0xFFF00000 –n FSP_new.bin`
+
+ It will rebase FSP-T component inside FSP.bin to new base 0xFFF00000 and save the
+ rebased Intel FSP 2.0 image into file FSP_new.bin.
+
+ `python SplitFspBin.py rebase -f FSP.bin –c t m –b 0xFFF00000 0xFEF80000 –n FSP_new.bin`
+
+ It will rebase FSP-T and FSP-M components inside FSP.bin to new base 0xFFF00000
+ and 0xFEF80000 respectively, and save the rebased Intel FSP 2.0 image into file
+ FSP_new.bin file.
+
+## Generate Intel FSP 2.0 C header file
+
+To generate Intel FSP 2.0 C header file, the following command can be used:
+
+ **Python SplitFspBin.py genhdr [-h] -f FSPBINARY [-o OUTPUTDIR] [-n HFILENAME]**
+
+For example:
+
+ `python SplitFspBin.py genhdr -f FSP.bin –n FSP.h`
+
+ It will create the C header file FSP.h containing the image ID, revision, offset
+ and size for each individual FSP component.
+
+## Display Intel FSP 2.0 information header
+
+To display Intel FSP 2.0 information headers, the following command can be used:
+
+ **Python SplitFspBin.py info [-h] -f FSPBINARY**
+
+For example:
+
+ `python SplitFspBin.py info -f FSP.bin`
+
+ It will print out the FSP information header for each FSP component.
|