diff options
author | Jiewen Yao <jiewen.yao@intel.com> | 2016-05-13 13:00:53 +0800 |
---|---|---|
committer | Jiewen Yao <jiewen.yao@intel.com> | 2016-05-13 13:00:53 +0800 |
commit | cf1d454983fb4fd3b580a92bd242310467a5eaef (patch) | |
tree | c289db5c4533b6f6d824f2aad6f9fc1e00648bf6 /IntelFsp2Pkg | |
parent | c9802c45647d84e71b4620fdfff0c4bd88cf5acb (diff) | |
download | edk2-platforms-cf1d454983fb4fd3b580a92bd242310467a5eaef.tar.xz |
Add IntelFsp2Pkg and IntelFsp2WrapperPkg.
Add FSP2.0 support.
This series of patch is to support FSP2.0 specification at
https://firmware.intel.com/sites/default/files/FSP_EAS_v2.0_Draft%20External.pdf
Some major updates include:
1) One FSP binary is separated to multiple components:
FSP-T, FSP-M, FSP-S, and optional FSP-O.
Each component has its own configuration data region.
2) All FSP-APIs use same UPD format - FSP_UPD_HEADER.
3) Add EnumInitPhaseEndOfFirmware notifyphase.
4) FSP1.1/FSP1.0 compatibility is NOT maintained.
5) We also add rename Fsp* to FspWrapper* in IntelFsp2WrapperPkg,
to indicate that it is for FspWrapper only.
IntelFspPkg and IntelFspWrapperPkg will be deprecated.
The new Intel platform will follow FSP2.0 and use IntelFsp2Pkg
and IntelFsp2WrapperPkg.
The old platform can still use IntelFspPkg and IntelFspWrapperPkg
for compatibility consideration.
Cc: Giri P Mudusuru <giri.p.mudusuru@intel.com>
Cc: Maurice Ma <maurice.ma@intel.com>
Cc: Ravi P Rangarajan <ravi.p.rangarajan@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
Reviewed-by: Giri P Mudusuru <giri.p.mudusuru@intel.com>
Reviewed-by: Maurice Ma <maurice.ma@intel.com>
Reviewed-by: Ravi P Rangarajan <ravi.p.rangarajan@intel.com>
Diffstat (limited to 'IntelFsp2Pkg')
74 files changed, 10347 insertions, 0 deletions
diff --git a/IntelFsp2Pkg/Contributions.txt b/IntelFsp2Pkg/Contributions.txt new file mode 100644 index 0000000000..f87cbd73c6 --- /dev/null +++ b/IntelFsp2Pkg/Contributions.txt @@ -0,0 +1,218 @@ +
+======================
+= Code Contributions =
+======================
+
+To make a contribution to a TianoCore project, follow these steps.
+1. Create a change description in the format specified below to
+ use in the source control commit log.
+2. Your commit message must include your "Signed-off-by" signature,
+ and "Contributed-under" message.
+3. Your "Contributed-under" message explicitly states that the
+ contribution is made under the terms of the specified
+ contribution agreement. Your "Contributed-under" message
+ must include the name of contribution agreement and version.
+ For example: Contributed-under: TianoCore Contribution Agreement 1.0
+ The "TianoCore Contribution Agreement" is included below in
+ this document.
+4. Submit your code to the TianoCore project using the process
+ that the project documents on its web page. If the process is
+ not documented, then submit the code on development email list
+ for the project.
+5. It is preferred that contributions are submitted using the same
+ copyright license as the base project. When that is not possible,
+ then contributions using the following licenses can be accepted:
+ * BSD (2-clause): http://opensource.org/licenses/BSD-2-Clause
+ * BSD (3-clause): http://opensource.org/licenses/BSD-3-Clause
+ * MIT: http://opensource.org/licenses/MIT
+ * Python-2.0: http://opensource.org/licenses/Python-2.0
+ * Zlib: http://opensource.org/licenses/Zlib
+
+ Contributions of code put into the public domain can also be
+ accepted.
+
+ Contributions using other licenses might be accepted, but further
+ review will be required.
+
+=====================================================
+= Change Description / Commit Message / Patch Email =
+=====================================================
+
+Your change description should use the standard format for a
+commit message, and must include your "Signed-off-by" signature
+and the "Contributed-under" message.
+
+== Sample Change Description / Commit Message =
+
+=== Start of sample patch email message ===
+
+From: Contributor Name <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/IntelFsp2Pkg/FspNotifyPhase/FspNotifyPhasePeim.c b/IntelFsp2Pkg/FspNotifyPhase/FspNotifyPhasePeim.c new file mode 100644 index 0000000000..6acdeb3b60 --- /dev/null +++ b/IntelFsp2Pkg/FspNotifyPhase/FspNotifyPhasePeim.c @@ -0,0 +1,142 @@ +/** @file
+ Source file for FSP notify phase PEI module
+
+ Copyright (c) 2016, Intel Corporation. All rights reserved.
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+
+#include "FspNotifyPhasePeim.h"
+
+/**
+
+ This function waits for FSP notify.
+
+ @param This Entry point for DXE IPL PPI.
+ @param PeiServices General purpose services available to every PEIM.
+ @param HobList Address to the Pei HOB list.
+
+ @return EFI_SUCCESS This function never returns.
+
+**/
+EFI_STATUS
+EFIAPI
+WaitForNotify (
+ IN CONST EFI_DXE_IPL_PPI *This,
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_HOB_POINTERS HobList
+ );
+
+CONST EFI_DXE_IPL_PPI mDxeIplPpi = {
+ WaitForNotify
+};
+
+CONST EFI_PEI_PPI_DESCRIPTOR mInstallDxeIplPpi = {
+ EFI_PEI_PPI_DESCRIPTOR_PPI,
+ &gEfiDxeIplPpiGuid,
+ (VOID *) &mDxeIplPpi
+};
+
+CONST EFI_PEI_PPI_DESCRIPTOR gEndOfPeiSignalPpi = {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gEfiEndOfPeiSignalPpiGuid,
+ NULL
+};
+
+/**
+
+ This function waits for FSP notify.
+
+ @param This Entry point for DXE IPL PPI.
+ @param PeiServices General purpose services available to every PEIM.
+ @param HobList Address to the Pei HOB list.
+
+ @return EFI_SUCCESS This function never returns.
+
+**/
+EFI_STATUS
+EFIAPI
+WaitForNotify (
+ IN CONST EFI_DXE_IPL_PPI *This,
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_HOB_POINTERS HobList
+ )
+{
+ EFI_STATUS Status;
+
+ DEBUG ((DEBUG_INFO | DEBUG_INIT, "FSP HOB is located at 0x%08X\n", HobList));
+
+ //
+ // End of PEI phase signal
+ //
+ Status = PeiServicesInstallPpi (&gEndOfPeiSignalPpi);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Give control back to BootLoader after FspSiliconInit
+ //
+ DEBUG ((DEBUG_INFO | DEBUG_INIT, "FSP is waiting for NOTIFY\n"));
+ FspSiliconInitDone ();
+
+ //
+ // BootLoader called FSP again through NotifyPhase
+ //
+ FspWaitForNotify ();
+
+ //
+ // Should not come here
+ //
+ while (TRUE) {
+ DEBUG ((DEBUG_ERROR, "No FSP API should be called after FSP is DONE!\n"));
+ SetFspApiReturnStatus (EFI_UNSUPPORTED);
+ Pei2LoaderSwitchStack ();
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ FSP notify phase PEI module entry point
+
+ @param[in] FileHandle Not used.
+ @param[in] PeiServices General purpose services available to every PEIM.
+
+ @retval EFI_SUCCESS The function completes successfully
+ @retval EFI_OUT_OF_RESOURCES Insufficient resources to create database
+**/
+EFI_STATUS
+FspNotifyPhasePeimEntryPoint (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ )
+{
+ EFI_STATUS Status;
+ VOID *OldDxeIplPpi;
+ EFI_PEI_PPI_DESCRIPTOR *OldDescriptor;
+
+ DEBUG ((DEBUG_INFO | DEBUG_INIT, "The entry of FspNotificationPeim\n"));
+
+ //
+ // Locate old DXE IPL PPI
+ //
+ Status = PeiServicesLocatePpi (
+ &gEfiDxeIplPpiGuid,
+ 0,
+ &OldDescriptor,
+ &OldDxeIplPpi
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Re-install the DXE IPL PPI to wait for notify
+ //
+ Status = PeiServicesReInstallPpi (OldDescriptor, &mInstallDxeIplPpi);
+ ASSERT_EFI_ERROR (Status);
+
+ return EFI_SUCCESS;
+}
diff --git a/IntelFsp2Pkg/FspNotifyPhase/FspNotifyPhasePeim.h b/IntelFsp2Pkg/FspNotifyPhase/FspNotifyPhasePeim.h new file mode 100644 index 0000000000..6e2ae591ec --- /dev/null +++ b/IntelFsp2Pkg/FspNotifyPhase/FspNotifyPhasePeim.h @@ -0,0 +1,23 @@ +/** @file
+ Header file for FSP notify phase PEI module
+
+ Copyright (c) 2016 Intel Corporation. All rights reserved.
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+
+#ifndef _FSP_NOTIFY_PHASE_PEIM_H_
+#define _FSP_NOTIFY_PHASE_PEIM_H_
+
+#include <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/IntelFsp2Pkg/FspNotifyPhase/FspNotifyPhasePeim.inf b/IntelFsp2Pkg/FspNotifyPhase/FspNotifyPhasePeim.inf new file mode 100644 index 0000000000..75f7ae5fb7 --- /dev/null +++ b/IntelFsp2Pkg/FspNotifyPhase/FspNotifyPhasePeim.inf @@ -0,0 +1,49 @@ +## @file
+# Component information file for the FSP notify phase PEI module.
+#
+#@copyright
+# Copyright (c) 2016 Intel Corporation. All rights reserved.
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = FspNotifyPhasePeim
+ FILE_GUID = 29CBB005-C972-49F3-960F-292E2202CECD
+ MODULE_TYPE = PEIM
+ VERSION_STRING = 1.0
+ ENTRY_POINT = FspNotifyPhasePeimEntryPoint
+
+[Sources]
+ FspNotifyPhasePeim.h
+ FspNotifyPhasePeim.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ IntelFsp2Pkg/IntelFsp2Pkg.dec
+
+[LibraryClasses]
+ PeimEntryPoint
+ DebugLib
+ FspPlatformLib
+ FspCommonLib
+ FspSwitchStackLib
+
+[Ppis]
+ gEfiDxeIplPpiGuid ## PRODUCES
+ gEfiEndOfPeiSignalPpiGuid ## PRODUCES
+
+[Protocols]
+ gEfiPciEnumerationCompleteProtocolGuid ## PRODUCES
+
+[Guids]
+ gEfiEventReadyToBootGuid ## PRODUCES ## Event
+
+[Depex]
+ gEfiDxeIplPpiGuid
diff --git a/IntelFsp2Pkg/FspSecCore/FspSecCoreM.inf b/IntelFsp2Pkg/FspSecCore/FspSecCoreM.inf new file mode 100644 index 0000000000..611fab215a --- /dev/null +++ b/IntelFsp2Pkg/FspSecCore/FspSecCoreM.inf @@ -0,0 +1,74 @@ +## @file
+# Sec Core for FSP
+#
+# Copyright (c) 2016, Intel Corporation. All rights reserved.<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/IntelFsp2Pkg/FspSecCore/FspSecCoreS.inf b/IntelFsp2Pkg/FspSecCore/FspSecCoreS.inf new file mode 100644 index 0000000000..8e1bb4a592 --- /dev/null +++ b/IntelFsp2Pkg/FspSecCore/FspSecCoreS.inf @@ -0,0 +1,68 @@ +## @file
+# Sec Core for FSP
+#
+# Copyright (c) 2016, Intel Corporation. All rights reserved.<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/IntelFsp2Pkg/FspSecCore/FspSecCoreT.inf b/IntelFsp2Pkg/FspSecCore/FspSecCoreT.inf new file mode 100644 index 0000000000..cf6a1918a3 --- /dev/null +++ b/IntelFsp2Pkg/FspSecCore/FspSecCoreT.inf @@ -0,0 +1,66 @@ +## @file
+# Sec Core for FSP
+#
+# Copyright (c) 2016, Intel Corporation. All rights reserved.<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/IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryCommon.nasm b/IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryCommon.nasm new file mode 100644 index 0000000000..c48a95694c --- /dev/null +++ b/IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryCommon.nasm @@ -0,0 +1,76 @@ +;; @file
+; Provide FSP API entry points.
+;
+; Copyright (c) 2016, Intel Corporation. All rights reserved.<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/IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryM.nasm b/IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryM.nasm new file mode 100644 index 0000000000..9744e1682d --- /dev/null +++ b/IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryM.nasm @@ -0,0 +1,202 @@ +;; @file
+; Provide FSP API entry points.
+;
+; Copyright (c) 2016, Intel Corporation. All rights reserved.<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/IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryS.nasm b/IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryS.nasm new file mode 100644 index 0000000000..cdc1149d6c --- /dev/null +++ b/IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryS.nasm @@ -0,0 +1,62 @@ +;; @file
+; Provide FSP API entry points.
+;
+; Copyright (c) 2016, Intel Corporation. All rights reserved.<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/IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryT.nasm b/IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryT.nasm new file mode 100644 index 0000000000..55ee85a06e --- /dev/null +++ b/IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryT.nasm @@ -0,0 +1,469 @@ +;; @file
+; Provide FSP API entry points.
+;
+; Copyright (c) 2016, Intel Corporation. All rights reserved.<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
+
+ mov esi, dword [esp + LoadMicrocodeParams.MicrocodeCodeAddr]
+ cmp esi, 0
+ jnz CheckMainHeader
+
+ParamError:
+ mov eax, 080000002h
+ jmp Exit2
+
+CheckMainHeader:
+ ; Get processor signature and platform ID from the installed processor
+ ; and save into registers for later use
+ ; ebx = processor signature
+ ; edx = platform ID
+ mov eax, 1
+ cpuid
+ mov ebx, eax
+ mov ecx, MSR_IA32_PLATFORM_ID
+ rdmsr
+ mov ecx, edx
+ shr ecx, 50-32 ; shift (50d-32d=18d=0x12) bits
+ and ecx, 7h ; platform id at bit[52..50]
+ mov edx, 1
+ shl edx, cl
+
+ ; Current register usage
+ ; esp -> stack with parameters
+ ; esi -> microcode update to check
+ ; ebx = processor signature
+ ; edx = platform ID
+
+ ; Check for valid microcode header
+ ; Minimal test checking for header version and loader version as 1
+ mov eax, dword 1
+ cmp dword [esi + MicrocodeHdr.MicrocodeHdrVersion], eax
+ jne AdvanceFixedSize
+ cmp dword [esi + MicrocodeHdr.MicrocodeHdrLoader], eax
+ jne AdvanceFixedSize
+
+ ; Check if signature and plaform ID match
+ cmp ebx, dword [esi + MicrocodeHdr.MicrocodeHdrProcessor]
+ jne LoadMicrocodeDefault1
+ test edx, dword [esi + MicrocodeHdr.MicrocodeHdrFlags ]
+ jnz LoadCheck ; Jif signature and platform ID match
+
+LoadMicrocodeDefault1:
+ ; Check if extended header exists
+ ; First check if MicrocodeHdrTotalSize and MicrocodeHdrDataSize are valid
+ xor eax, eax
+ cmp dword [esi + MicrocodeHdr.MicrocodeHdrTotalSize], eax
+ je NextMicrocode
+ cmp dword [esi + MicrocodeHdr.MicrocodeHdrDataSize], eax
+ je NextMicrocode
+
+ ; Then verify total size - sizeof header > data size
+ mov ecx, dword [esi + MicrocodeHdr.MicrocodeHdrTotalSize]
+ sub ecx, MicrocodeHdr.size
+ cmp ecx, dword [esi + MicrocodeHdr.MicrocodeHdrDataSize]
+ jng NextMicrocode ; Jif extended header does not exist
+
+ ; Set edi -> extended header
+ mov edi, esi
+ add edi, MicrocodeHdr.size
+ add edi, dword [esi + MicrocodeHdr.MicrocodeHdrDataSize]
+
+ ; Get count of extended structures
+ mov ecx, dword [edi + ExtSigHdr.ExtSigHdrCount]
+
+ ; Move pointer to first signature structure
+ add edi, ExtSigHdr.size
+
+CheckExtSig:
+ ; Check if extended signature and platform ID match
+ cmp dword [edi + ExtSig.ExtSigProcessor], ebx
+ jne LoadMicrocodeDefault2
+ test dword [edi + ExtSig.ExtSigFlags], edx
+ jnz LoadCheck ; Jif signature and platform ID match
+LoadMicrocodeDefault2:
+ ; Check if any more extended signatures exist
+ add edi, ExtSig.size
+ loop CheckExtSig
+
+NextMicrocode:
+ ; Advance just after end of this microcode
+ xor eax, eax
+ cmp dword [esi + MicrocodeHdr.MicrocodeHdrTotalSize], eax
+ je LoadMicrocodeDefault3
+ add esi, dword [esi + MicrocodeHdr.MicrocodeHdrTotalSize]
+ jmp CheckAddress
+LoadMicrocodeDefault3:
+ add esi, dword 2048
+ jmp CheckAddress
+
+AdvanceFixedSize:
+ ; Advance by 4X dwords
+ add esi, dword 1024
+
+CheckAddress:
+ ; Is valid Microcode start point ?
+ cmp dword [esi + MicrocodeHdr.MicrocodeHdrVersion], 0ffffffffh
+ jz Done
+
+ ; Is automatic size detection ?
+ mov eax, dword [esp + LoadMicrocodeParams.MicrocodeCodeSize]
+ cmp eax, 0ffffffffh
+ jz LoadMicrocodeDefault4
+
+ ; Address >= microcode region address + microcode region size?
+ add eax, dword [esp + LoadMicrocodeParams.MicrocodeCodeAddr]
+ cmp esi, eax
+ jae Done ;Jif address is outside of microcode region
+ jmp CheckMainHeader
+
+LoadMicrocodeDefault4:
+LoadCheck:
+ ; Get the revision of the current microcode update loaded
+ mov ecx, MSR_IA32_BIOS_SIGN_ID
+ xor eax, eax ; Clear EAX
+ xor edx, edx ; Clear EDX
+ wrmsr ; Load 0 to MSR at 8Bh
+
+ mov eax, 1
+ cpuid
+ mov ecx, MSR_IA32_BIOS_SIGN_ID
+ rdmsr ; Get current microcode signature
+
+ ; Verify this microcode update is not already loaded
+ cmp dword [esi + MicrocodeHdr.MicrocodeHdrRevision], edx
+ je Continue
+
+LoadMicrocode:
+ ; EAX contains the linear address of the start of the Update Data
+ ; EDX contains zero
+ ; ECX contains 79h (IA32_BIOS_UPDT_TRIG)
+ ; Start microcode load with wrmsr
+ mov eax, esi
+ add eax, MicrocodeHdr.size
+ xor edx, edx
+ mov ecx, MSR_IA32_BIOS_UPDT_TRIG
+ wrmsr
+ mov eax, 1
+ cpuid
+
+Continue:
+ jmp NextMicrocode
+
+Done:
+ mov eax, 1
+ cpuid
+ mov ecx, MSR_IA32_BIOS_SIGN_ID
+ rdmsr ; Get current microcode signature
+ xor eax, eax
+ cmp edx, 0
+ jnz Exit2
+ mov eax, 08000000Eh
+
+Exit2:
+ jmp ebp
+
+
+global ASM_PFX(EstablishStackFsp)
+ASM_PFX(EstablishStackFsp):
+ ;
+ ; Save parameter pointer in edx
+ ;
+ mov edx, dword [esp + 4]
+
+ ;
+ ; Enable FSP STACK
+ ;
+ mov esp, DWORD [ASM_PFX(PcdGet32 (PcdTemporaryRamBase))]
+ add esp, DWORD [ASM_PFX(PcdGet32 (PcdTemporaryRamSize))]
+
+ push DATA_LEN_OF_MCUD ; Size of the data region
+ push 4455434Dh ; Signature of the data region 'MCUD'
+ push dword [edx + 2Ch] ; Code size sizeof(FSPT_UPD_COMMON) + 12
+ push dword [edx + 28h] ; Code base sizeof(FSPT_UPD_COMMON) + 8
+ push dword [edx + 24h] ; Microcode size sizeof(FSPT_UPD_COMMON) + 4
+ push dword [edx + 20h] ; Microcode base sizeof(FSPT_UPD_COMMON) + 0
+
+ ;
+ ; Save API entry/exit timestamp into stack
+ ;
+ push DATA_LEN_OF_PER0 ; Size of the data region
+ push 30524550h ; Signature of the data region 'PER0'
+ rdtsc
+ push edx
+ push eax
+ LOAD_EDX
+ push edx
+ LOAD_EAX
+ push eax
+
+ ;
+ ; Terminator for the data on stack
+ ;
+ push 0
+
+ ;
+ ; Set ECX/EDX to the BootLoader temporary memory range
+ ;
+ mov ecx, [ASM_PFX(PcdGet32 (PcdTemporaryRamBase))]
+ mov edx, ecx
+ add edx, [ASM_PFX(PcdGet32 (PcdTemporaryRamSize))]
+ sub edx, [ASM_PFX(PcdGet32 (PcdFspReservedBufferSize))]
+
+ cmp ecx, edx ;If PcdFspReservedBufferSize >= PcdTemporaryRamSize, then error.
+ jb EstablishStackFspSuccess
+ mov eax, 80000003h ;EFI_UNSUPPORTED
+ jmp EstablishStackFspExit
+EstablishStackFspSuccess:
+ xor eax, eax
+
+EstablishStackFspExit:
+ RET_ESI
+
+;----------------------------------------------------------------------------
+; TempRamInit API
+;
+; This FSP API will load the microcode update, enable code caching for the
+; region specified by the boot loader and also setup a temporary stack to be
+; used till main memory is initialized.
+;
+;----------------------------------------------------------------------------
+global ASM_PFX(TempRamInitApi)
+ASM_PFX(TempRamInitApi):
+ ;
+ ; Ensure SSE is enabled
+ ;
+ ENABLE_SSE
+
+ ;
+ ; Save EBP, EBX, ESI, EDI & ESP in XMM7 & XMM6
+ ;
+ SAVE_REGS
+
+ ;
+ ; Save timestamp into XMM6
+ ;
+ rdtsc
+ SAVE_EAX
+ SAVE_EDX
+
+ ;
+ ; Check Parameter
+ ;
+ mov eax, dword [esp + 4]
+ cmp eax, 0
+ mov eax, 80000002h
+ jz TempRamInitExit
+
+ ;
+ ; Sec Platform Init
+ ;
+ CALL_MMX ASM_PFX(SecPlatformInit)
+ cmp eax, 0
+ jnz TempRamInitExit
+
+ ; Load microcode
+ LOAD_ESP
+ CALL_MMX ASM_PFX(LoadMicrocodeDefault)
+ SXMMN xmm6, 3, eax ;Save microcode return status in ECX-SLOT 3 in xmm6.
+ ;@note If return value eax is not 0, microcode did not load, but continue and attempt to boot.
+
+ ; Call Sec CAR Init
+ LOAD_ESP
+ CALL_MMX ASM_PFX(SecCarInit)
+ cmp eax, 0
+ jnz TempRamInitExit
+
+ LOAD_ESP
+ CALL_MMX ASM_PFX(EstablishStackFsp)
+ cmp eax, 0
+ jnz TempRamInitExit
+
+ LXMMN xmm6, eax, 3 ;Restore microcode status if no CAR init error from ECX-SLOT 3 in xmm6.
+
+TempRamInitExit:
+ mov bl, al ; save al data in bl
+ mov al, 07Fh ; API exit postcode 7f
+ out 080h, al
+ mov al, bl ; restore al data from bl
+
+ ;
+ ; Load EBP, EBX, ESI, EDI & ESP from XMM7 & XMM6
+ ;
+ LOAD_REGS
+ ret
+
+;----------------------------------------------------------------------------
+; Module Entrypoint API
+;----------------------------------------------------------------------------
+global ASM_PFX(_ModuleEntryPoint)
+ASM_PFX(_ModuleEntryPoint):
+ jmp $
diff --git a/IntelFsp2Pkg/FspSecCore/Ia32/FspHelper.nasm b/IntelFsp2Pkg/FspSecCore/Ia32/FspHelper.nasm new file mode 100644 index 0000000000..00e953b4f1 --- /dev/null +++ b/IntelFsp2Pkg/FspSecCore/Ia32/FspHelper.nasm @@ -0,0 +1,35 @@ +;; @file
+; Provide FSP helper function.
+;
+; Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<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):
+ ;
+ ; This value will be pached by the build script
+ ;
+ DD 0x12345678
+
+global ASM_PFX(AsmGetFspBaseAddress)
+ASM_PFX(AsmGetFspBaseAddress):
+ mov eax, ASM_PFX(AsmGetFspInfoHeader)
+ sub eax, dword [ASM_PFX(FspInfoHeaderRelativeOff)]
+ add eax, 0x1C
+ mov eax, dword [eax]
+ ret
+
+global ASM_PFX(AsmGetFspInfoHeader)
+ASM_PFX(AsmGetFspInfoHeader):
+ mov eax, ASM_PFX(AsmGetFspInfoHeader)
+ sub eax, dword [ASM_PFX(FspInfoHeaderRelativeOff)]
+ ret
diff --git a/IntelFsp2Pkg/FspSecCore/Ia32/InitializeFpu.nasm b/IntelFsp2Pkg/FspSecCore/Ia32/InitializeFpu.nasm new file mode 100644 index 0000000000..cc87e893d5 --- /dev/null +++ b/IntelFsp2Pkg/FspSecCore/Ia32/InitializeFpu.nasm @@ -0,0 +1,78 @@ +;------------------------------------------------------------------------------
+;
+; Copyright (c) 2015, Intel Corporation. All rights reserved.<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/IntelFsp2Pkg/FspSecCore/Ia32/MicrocodeLoadNasm.inc b/IntelFsp2Pkg/FspSecCore/Ia32/MicrocodeLoadNasm.inc new file mode 100644 index 0000000000..1663a85d11 --- /dev/null +++ b/IntelFsp2Pkg/FspSecCore/Ia32/MicrocodeLoadNasm.inc @@ -0,0 +1,16 @@ +;; @file
+;
+;@copyright
+; Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<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/IntelFsp2Pkg/FspSecCore/Ia32/SaveRestoreSseNasm.inc b/IntelFsp2Pkg/FspSecCore/Ia32/SaveRestoreSseNasm.inc new file mode 100644 index 0000000000..ae0a93dc94 --- /dev/null +++ b/IntelFsp2Pkg/FspSecCore/Ia32/SaveRestoreSseNasm.inc @@ -0,0 +1,187 @@ +;------------------------------------------------------------------------------
+;
+; Copyright (c) 2015, Intel Corporation. All rights reserved.<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/IntelFsp2Pkg/FspSecCore/Ia32/Stack.nasm b/IntelFsp2Pkg/FspSecCore/Ia32/Stack.nasm new file mode 100644 index 0000000000..338e700751 --- /dev/null +++ b/IntelFsp2Pkg/FspSecCore/Ia32/Stack.nasm @@ -0,0 +1,78 @@ +;------------------------------------------------------------------------------
+;
+; Copyright (c) 2015, Intel Corporation. All rights reserved.<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/IntelFsp2Pkg/FspSecCore/SecFsp.c b/IntelFsp2Pkg/FspSecCore/SecFsp.c new file mode 100644 index 0000000000..7259a55bbd --- /dev/null +++ b/IntelFsp2Pkg/FspSecCore/SecFsp.c @@ -0,0 +1,216 @@ +/** @file
+
+ Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<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 = FspPlatformData->CarBase + FspPlatformData->CarSize;
+ StackPtr = (UINT32 *)(TopOfCar - sizeof (UINT32));
+
+ if (*(StackPtr - 1) == FSP_MCUD_SIGNATURE) {
+ while (*StackPtr != 0) {
+ if (*(StackPtr - 1) == FSP_MCUD_SIGNATURE) {
+ //
+ // This following data was pushed onto stack after TempRamInit API
+ //
+ DwordSize = 4;
+ StackPtr = StackPtr - 1 - DwordSize;
+ CopyMem (&(FspPlatformData->MicrocodeRegionBase), StackPtr, (DwordSize << 2));
+ StackPtr--;
+ } else if (*(StackPtr - 1) == FSP_PER0_SIGNATURE) {
+ //
+ // This is the performance data for InitTempMemory API entry/exit
+ //
+ DwordSize = 4;
+ StackPtr = StackPtr - 1 - DwordSize;
+ CopyMem (FspData->PerfData, StackPtr, (DwordSize << 2));
+
+ ((UINT8 *)(&FspData->PerfData[0]))[7] = FSP_PERF_ID_API_TEMP_RAM_INIT_ENTRY;
+ ((UINT8 *)(&FspData->PerfData[1]))[7] = FSP_PERF_ID_API_TEMP_RAM_INIT_EXIT;
+
+ StackPtr--;
+ } else {
+ StackPtr -= (*StackPtr);
+ }
+ }
+ }
+}
+
+/**
+
+ Initialize the FSP global data region.
+ It needs to be done as soon as possible after the stack is setup.
+
+ @param[in,out] PeiFspData Pointer of the FSP global data.
+ @param[in] BootLoaderStack BootLoader stack.
+ @param[in] ApiIdx The index of the FSP API.
+
+**/
+VOID
+FspGlobalDataInit (
+ IN OUT FSP_GLOBAL_DATA *PeiFspData,
+ IN UINT32 BootLoaderStack,
+ IN UINT8 ApiIdx
+ )
+{
+ VOID *FspmUpdDataPtr;
+ CHAR8 ImageId[9];
+ UINTN Idx;
+
+ //
+ // Set FSP Global Data pointer
+ //
+ SetFspGlobalDataPointer (PeiFspData);
+ ZeroMem ((VOID *)PeiFspData, sizeof(FSP_GLOBAL_DATA));
+
+ PeiFspData->Signature = FSP_GLOBAL_DATA_SIGNATURE;
+ PeiFspData->Version = 0;
+ PeiFspData->CoreStack = BootLoaderStack;
+ PeiFspData->PerfIdx = 2;
+ PeiFspData->PerfSig = FSP_PERFORMANCE_DATA_SIGNATURE;
+ PeiFspData->PlatformData.CarBase = AsmReadMsr32 (0x200) & ~(0x6);
+ PeiFspData->PlatformData.CarSize = ~(AsmReadMsr32(0x201) & ~(0x800)) + 1;
+
+ SetFspMeasurePoint (FSP_PERF_ID_API_FSP_MEMORY_INIT_ENTRY);
+
+ //
+ // Get FSP Header offset
+ // It may have multiple FVs, so look into the last one for FSP header
+ //
+ PeiFspData->FspInfoHeader = (FSP_INFO_HEADER *)AsmGetFspInfoHeader();
+ SecGetPlatformData (PeiFspData);
+
+ //
+ // Set API calling mode
+ //
+ SetFspApiCallingIndex (ApiIdx);
+
+ //
+ // Set UPD pointer
+ //
+ FspmUpdDataPtr = (VOID *) GetFspApiParameter ();
+ if (FspmUpdDataPtr == NULL) {
+ FspmUpdDataPtr = (VOID *)(PeiFspData->FspInfoHeader->ImageBase + PeiFspData->FspInfoHeader->CfgRegionOffset);
+ }
+ SetFspUpdDataPointer (FspmUpdDataPtr);
+ SetFspMemoryInitUpdDataPointer (FspmUpdDataPtr);
+ SetFspSiliconInitUpdDataPointer (NULL);
+
+ //
+ // Initialize serial port
+ // It might have been done in ProcessLibraryConstructorList(), however,
+ // the FSP global data is not initialized at that time. So do it again
+ // for safe.
+ //
+ SerialPortInitialize ();
+
+ //
+ // Ensure the golbal data pointer is valid
+ //
+ ASSERT (GetFspGlobalDataPointer () == PeiFspData);
+
+ for (Idx = 0; Idx < 8; Idx++) {
+ ImageId[Idx] = PeiFspData->FspInfoHeader->ImageId[Idx];
+ }
+ ImageId[Idx] = 0;
+
+ DEBUG ((DEBUG_INFO | DEBUG_INIT, "\n============= FSP Spec v%d.%d Header Revision v%x (%a v%x.%x.%x.%x) =============\n", \
+ (PeiFspData->FspInfoHeader->SpecVersion >> 4) & 0xF, \
+ PeiFspData->FspInfoHeader->SpecVersion & 0xF, \
+ PeiFspData->FspInfoHeader->HeaderRevision, \
+ ImageId, \
+ (PeiFspData->FspInfoHeader->ImageRevision >> 24) & 0xFF, \
+ (PeiFspData->FspInfoHeader->ImageRevision >> 16) & 0xFF, \
+ (PeiFspData->FspInfoHeader->ImageRevision >> 8) & 0xFF, \
+ PeiFspData->FspInfoHeader->ImageRevision & 0xFF));
+}
+
+/**
+
+ Adjust the FSP data pointers after the stack is migrated to memory.
+
+ @param[in] OffsetGap The offset gap between the old stack and the new stack.
+
+**/
+VOID
+FspDataPointerFixUp (
+ IN UINT32 OffsetGap
+ )
+{
+ FSP_GLOBAL_DATA *NewFspData;
+
+ NewFspData = (FSP_GLOBAL_DATA *)((UINTN)GetFspGlobalDataPointer() + (UINTN)OffsetGap);
+ SetFspGlobalDataPointer (NewFspData);
+}
diff --git a/IntelFsp2Pkg/FspSecCore/SecFsp.h b/IntelFsp2Pkg/FspSecCore/SecFsp.h new file mode 100644 index 0000000000..f199b12e4d --- /dev/null +++ b/IntelFsp2Pkg/FspSecCore/SecFsp.h @@ -0,0 +1,99 @@ +/** @file
+
+ Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<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/IntelFsp2Pkg/FspSecCore/SecFspApiChk.c b/IntelFsp2Pkg/FspSecCore/SecFspApiChk.c new file mode 100644 index 0000000000..bace5eca43 --- /dev/null +++ b/IntelFsp2Pkg/FspSecCore/SecFspApiChk.c @@ -0,0 +1,97 @@ +/** @file
+
+ Copyright (c) 2016, Intel Corporation. All rights reserved.<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/IntelFsp2Pkg/FspSecCore/SecMain.c b/IntelFsp2Pkg/FspSecCore/SecMain.c new file mode 100644 index 0000000000..fa556bf058 --- /dev/null +++ b/IntelFsp2Pkg/FspSecCore/SecMain.c @@ -0,0 +1,227 @@ +/** @file
+
+ Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<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 tempory ram
+ @param[in] BootFirmwareVolume Base address of the Boot Firmware Volume.
+ @param[in] PeiCore PeiCore entry point.
+ @param[in] BootLoaderStack BootLoader stack.
+ @param[in] ApiIdx the index of API.
+
+ @return This function never returns.
+
+**/
+VOID
+EFIAPI
+SecStartup (
+ IN UINT32 SizeOfRam,
+ IN UINT32 TempRamBase,
+ IN VOID *BootFirmwareVolume,
+ IN PEI_CORE_ENTRY PeiCore,
+ IN UINT32 BootLoaderStack,
+ IN UINT32 ApiIdx
+ )
+{
+ EFI_SEC_PEI_HAND_OFF SecCoreData;
+ IA32_DESCRIPTOR IdtDescriptor;
+ SEC_IDT_TABLE IdtTableInStack;
+ UINT32 Index;
+ FSP_GLOBAL_DATA PeiFspData;
+ UINT64 ExceptionHandler;
+
+ //
+ // Process all libraries constructor function linked to SecCore.
+ //
+ ProcessLibraryConstructorList ();
+
+ //
+ // Initialize floating point operating environment
+ // to be compliant with UEFI spec.
+ //
+ InitializeFloatingPointUnits ();
+
+
+ // |-------------------|---->
+ // |Idt Table |
+ // |-------------------|
+ // |PeiService Pointer | PeiStackSize
+ // |-------------------|
+ // | |
+ // | Stack |
+ // |-------------------|---->
+ // | |
+ // | |
+ // | Heap | PeiTemporayRamSize
+ // | |
+ // | |
+ // |-------------------|----> TempRamBase
+ IdtTableInStack.PeiService = NULL;
+ ExceptionHandler = FspGetExceptionHandler(mIdtEntryTemplate);
+ for (Index = 0; Index < SEC_IDT_ENTRY_COUNT; Index ++) {
+ CopyMem ((VOID*)&IdtTableInStack.IdtTable[Index], (VOID*)&ExceptionHandler, sizeof (UINT64));
+ }
+
+ IdtDescriptor.Base = (UINTN) &IdtTableInStack.IdtTable;
+ IdtDescriptor.Limit = (UINT16)(sizeof (IdtTableInStack.IdtTable) - 1);
+
+ AsmWriteIdtr (&IdtDescriptor);
+
+ //
+ // Initialize the global FSP data region
+ //
+ FspGlobalDataInit (&PeiFspData, BootLoaderStack, (UINT8)ApiIdx);
+
+ //
+ // Update the base address and length of Pei temporary memory
+ //
+ SecCoreData.DataSize = sizeof (EFI_SEC_PEI_HAND_OFF);
+ SecCoreData.BootFirmwareVolumeBase = BootFirmwareVolume;
+ SecCoreData.BootFirmwareVolumeSize = (UINT32)((EFI_FIRMWARE_VOLUME_HEADER *)BootFirmwareVolume)->FvLength;
+
+ SecCoreData.TemporaryRamBase = (VOID*)(UINTN) TempRamBase;
+ SecCoreData.TemporaryRamSize = SizeOfRam;
+ SecCoreData.PeiTemporaryRamBase = SecCoreData.TemporaryRamBase;
+ SecCoreData.PeiTemporaryRamSize = SecCoreData.TemporaryRamSize * PcdGet8 (PcdFspHeapSizePercentage) / 100;
+ SecCoreData.StackBase = (VOID*)(UINTN)((UINTN)SecCoreData.TemporaryRamBase + SecCoreData.PeiTemporaryRamSize);
+ SecCoreData.StackSize = SecCoreData.TemporaryRamSize - SecCoreData.PeiTemporaryRamSize;
+
+ DEBUG ((DEBUG_INFO, "Fsp BootFirmwareVolumeBase - 0x%x\n", SecCoreData.BootFirmwareVolumeBase));
+ DEBUG ((DEBUG_INFO, "Fsp BootFirmwareVolumeSize - 0x%x\n", SecCoreData.BootFirmwareVolumeSize));
+ DEBUG ((DEBUG_INFO, "Fsp TemporaryRamBase - 0x%x\n", SecCoreData.TemporaryRamBase));
+ DEBUG ((DEBUG_INFO, "Fsp TemporaryRamSize - 0x%x\n", SecCoreData.TemporaryRamSize));
+ DEBUG ((DEBUG_INFO, "Fsp PeiTemporaryRamBase - 0x%x\n", SecCoreData.PeiTemporaryRamBase));
+ DEBUG ((DEBUG_INFO, "Fsp PeiTemporaryRamSize - 0x%x\n", SecCoreData.PeiTemporaryRamSize));
+ DEBUG ((DEBUG_INFO, "Fsp StackBase - 0x%x\n", SecCoreData.StackBase));
+ DEBUG ((DEBUG_INFO, "Fsp StackSize - 0x%x\n", SecCoreData.StackSize));
+
+ //
+ // Call PeiCore Entry
+ //
+ PeiCore (&SecCoreData, mPeiSecPlatformInformationPpi);
+
+ //
+ // Should never be here
+ //
+ CpuDeadLoop ();
+}
+
+/**
+ This service of the TEMPORARY_RAM_SUPPORT_PPI that migrates temporary RAM into
+ permanent memory.
+
+ @param[in] PeiServices Pointer to the PEI Services Table.
+ @param[in] TemporaryMemoryBase Source Address in temporary memory from which the SEC or PEIM will copy the
+ Temporary RAM contents.
+ @param[in] PermanentMemoryBase Destination Address in permanent memory into which the SEC or PEIM will copy the
+ Temporary RAM contents.
+ @param[in] CopySize Amount of memory to migrate from temporary to permanent memory.
+
+ @retval EFI_SUCCESS The data was successfully returned.
+ @retval EFI_INVALID_PARAMETER PermanentMemoryBase + CopySize > TemporaryMemoryBase when
+ TemporaryMemoryBase > PermanentMemoryBase.
+
+**/
+EFI_STATUS
+EFIAPI
+SecTemporaryRamSupport (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase,
+ IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase,
+ IN UINTN CopySize
+ )
+{
+ IA32_DESCRIPTOR IdtDescriptor;
+ VOID* OldHeap;
+ VOID* NewHeap;
+ VOID* OldStack;
+ VOID* NewStack;
+ UINTN HeapSize;
+ UINTN StackSize;
+
+ HeapSize = CopySize * PcdGet8 (PcdFspHeapSizePercentage) / 100 ;
+ StackSize = CopySize - HeapSize;
+
+ OldHeap = (VOID*)(UINTN)TemporaryMemoryBase;
+ NewHeap = (VOID*)((UINTN)PermanentMemoryBase + StackSize);
+
+ OldStack = (VOID*)((UINTN)TemporaryMemoryBase + HeapSize);
+ NewStack = (VOID*)(UINTN)PermanentMemoryBase;
+
+ //
+ // Migrate Heap
+ //
+ CopyMem (NewHeap, OldHeap, HeapSize);
+
+ //
+ // Migrate Stack
+ //
+ CopyMem (NewStack, OldStack, StackSize);
+
+
+ //
+ // We need *not* fix the return address because currently,
+ // The PeiCore is executed in flash.
+ //
+
+ //
+ // Rebase IDT table in permanent memory
+ //
+ AsmReadIdtr (&IdtDescriptor);
+ IdtDescriptor.Base = IdtDescriptor.Base - (UINTN)OldStack + (UINTN)NewStack;
+
+ AsmWriteIdtr (&IdtDescriptor);
+
+ //
+ // Fixed the FSP data pointer
+ //
+ FspDataPointerFixUp ((UINTN)NewStack - (UINTN)OldStack);
+
+ //
+ // SecSwitchStack function must be invoked after the memory migration
+ // immediatly, also we need fixup the stack change caused by new call into
+ // permenent memory.
+ //
+ SecSwitchStack (
+ (UINT32) (UINTN) OldStack,
+ (UINT32) (UINTN) NewStack
+ );
+
+ return EFI_SUCCESS;
+}
diff --git a/IntelFsp2Pkg/FspSecCore/SecMain.h b/IntelFsp2Pkg/FspSecCore/SecMain.h new file mode 100644 index 0000000000..33f73625ca --- /dev/null +++ b/IntelFsp2Pkg/FspSecCore/SecMain.h @@ -0,0 +1,140 @@ +/** @file
+
+ Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<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 tempory ram
+ @param[in] BootFirmwareVolume Base address of the Boot Firmware Volume.
+ @param[in] PeiCore PeiCore entry point.
+ @param[in] BootLoaderStack BootLoader stack.
+ @param[in] ApiIdx the index of API.
+
+ @return This function never returns.
+
+**/
+VOID
+EFIAPI
+SecStartup (
+ IN UINT32 SizeOfRam,
+ IN UINT32 TempRamBase,
+ IN VOID *BootFirmwareVolume,
+ IN PEI_CORE_ENTRY PeiCore,
+ IN UINT32 BootLoaderStack,
+ IN UINT32 ApiIdx
+ );
+
+/**
+ Autogenerated function that calls the library constructors for all of the module's
+ dependent libraries. This function must be called by the SEC Core once a stack has
+ been established.
+
+**/
+VOID
+EFIAPI
+ProcessLibraryConstructorList (
+ VOID
+ );
+
+#endif
diff --git a/IntelFsp2Pkg/FspSecCore/Vtf0/Bin/ResetVec.ia32.raw b/IntelFsp2Pkg/FspSecCore/Vtf0/Bin/ResetVec.ia32.raw Binary files differnew file mode 100644 index 0000000000..2dc9f178d3 --- /dev/null +++ b/IntelFsp2Pkg/FspSecCore/Vtf0/Bin/ResetVec.ia32.raw diff --git a/IntelFsp2Pkg/FspSecCore/Vtf0/Build.py b/IntelFsp2Pkg/FspSecCore/Vtf0/Build.py new file mode 100644 index 0000000000..3018391445 --- /dev/null +++ b/IntelFsp2Pkg/FspSecCore/Vtf0/Build.py @@ -0,0 +1,53 @@ +## @file
+# Automate the process of building the various reset vector types
+#
+# Copyright (c) 2014, Intel Corporation. All rights reserved.<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/IntelFsp2Pkg/FspSecCore/Vtf0/Ia16/ResetVec.asm16 b/IntelFsp2Pkg/FspSecCore/Vtf0/Ia16/ResetVec.asm16 new file mode 100644 index 0000000000..585876fa86 --- /dev/null +++ b/IntelFsp2Pkg/FspSecCore/Vtf0/Ia16/ResetVec.asm16 @@ -0,0 +1,103 @@ +;; @file
+; Reset Vector Data structure
+; This structure is located at 0xFFFFFFC0
+;
+; Copyright (c) 2014, Intel Corporation. All rights reserved.<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/IntelFsp2Pkg/FspSecCore/Vtf0/ResetVectorCode.asm b/IntelFsp2Pkg/FspSecCore/Vtf0/ResetVectorCode.asm new file mode 100644 index 0000000000..72b252491f --- /dev/null +++ b/IntelFsp2Pkg/FspSecCore/Vtf0/ResetVectorCode.asm @@ -0,0 +1,17 @@ +;------------------------------------------------------------------------------
+; @file
+; This file includes all other code files to assemble the reset vector code
+;
+; Copyright (c) 2014, Intel Corporation. All rights reserved.<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/IntelFsp2Pkg/FspSecCore/Vtf0/Tools/FixupForRawSection.py b/IntelFsp2Pkg/FspSecCore/Vtf0/Tools/FixupForRawSection.py new file mode 100644 index 0000000000..8e7c20b401 --- /dev/null +++ b/IntelFsp2Pkg/FspSecCore/Vtf0/Tools/FixupForRawSection.py @@ -0,0 +1,110 @@ +## @file
+# Apply fixup to VTF binary image for FFS Raw section
+#
+# Copyright (c) 2014, Intel Corporation. All rights reserved.<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/IntelFsp2Pkg/Include/FspDataTable.h b/IntelFsp2Pkg/Include/FspDataTable.h new file mode 100644 index 0000000000..3c79f34e47 --- /dev/null +++ b/IntelFsp2Pkg/Include/FspDataTable.h @@ -0,0 +1,32 @@ +/** @file
+ The header file of FSP data table
+
+ Copyright (c) 2016, Intel Corporation. All rights reserved.<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_DATA_TABLE_H_
+#define _FSP_DATA_TABLE_H_
+
+#pragma pack(1)
+
+#define FSP_DATA_SIGNATURE SIGNATURE_32 ('F', 'S', 'P', 'D')
+
+typedef struct {
+ UINT32 Signature;
+ UINT32 Length;
+ UINT32 FsptBase;
+ UINT32 FspmBase;
+ UINT32 FspsBase;
+} FSP_DATA_TABLE;
+
+#pragma pack()
+
+#endif
diff --git a/IntelFsp2Pkg/Include/FspEas.h b/IntelFsp2Pkg/Include/FspEas.h new file mode 100644 index 0000000000..79bb0b8e8e --- /dev/null +++ b/IntelFsp2Pkg/Include/FspEas.h @@ -0,0 +1,24 @@ +/** @file
+ Intel FSP definition from Intel Firmware Support Package External
+ Architecture Specification v2.0.
+
+ Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<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.h>
+#include <Guid/GuidHobFspEas.h>
+#include <Guid/FspHeaderFile.h>
+#include <FspEas/FspApi.h>
+
+#endif
diff --git a/IntelFsp2Pkg/Include/FspEas/FspApi.h b/IntelFsp2Pkg/Include/FspEas/FspApi.h new file mode 100644 index 0000000000..f7c71681c8 --- /dev/null +++ b/IntelFsp2Pkg/Include/FspEas/FspApi.h @@ -0,0 +1,241 @@ +/** @file
+ Intel FSP API definition from Intel Firmware Support Package External
+ Architecture Specification v2.0.
+
+ Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<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_
+
+#pragma pack(1)
+typedef struct {
+ ///
+ /// UPD Region Signature. This signature will be
+ /// "XXXXXX_T" for FSP-T
+ /// "XXXXXX_M" for FSP-M
+ /// "XXXXXX_S" for FSP-S
+ /// Where XXXXXX is an unique signature
+ ///
+ UINT64 Signature;
+ ///
+ /// Revision of the Data structure. For FSP v2.0 value is 1.
+ ///
+ UINT8 Revision;
+ UINT8 Reserved[23];
+} FSP_UPD_HEADER;
+
+typedef struct {
+ ///
+ /// Revision of the structure. For FSP v2.0 value is 1.
+ ///
+ UINT8 Revision;
+ UINT8 Reserved[3];
+ ///
+ /// Pointer to the non-volatile storage (NVS) data buffer.
+ /// If it is NULL it indicates the NVS data is not available.
+ ///
+ VOID *NvsBufferPtr;
+ ///
+ /// Pointer to the temporary stack base address to be
+ /// consumed inside FspMemoryInit() API.
+ ///
+ VOID *StackBase;
+ ///
+ /// Temporary stack size to be consumed inside
+ /// FspMemoryInit() API.
+ ///
+ UINT32 StackSize;
+ ///
+ /// Size of memory to be reserved by FSP below "top
+ /// of low usable memory" for bootloader usage.
+ ///
+ UINT32 BootLoaderTolumSize;
+ ///
+ /// Current boot mode.
+ ///
+ UINT32 BootMode;
+ UINT8 Reserved1[8];
+} FSPM_ARCH_UPD;
+
+typedef struct {
+ FSP_UPD_HEADER FspUpdHeader;
+} FSPT_UPD_COMMON;
+
+typedef struct {
+ FSP_UPD_HEADER FspUpdHeader;
+ FSPM_ARCH_UPD FspmArchUpd;
+} FSPM_UPD_COMMON;
+
+typedef struct {
+ FSP_UPD_HEADER FspUpdHeader;
+} FSPS_UPD_COMMON;
+
+typedef enum {
+ ///
+ /// This stage is notified when the bootloader completes the
+ /// PCI enumeration and the resource allocation for the
+ /// PCI devices is complete.
+ ///
+ EnumInitPhaseAfterPciEnumeration = 0x20,
+ ///
+ /// This stage is notified just before the bootloader hand-off
+ /// to the OS loader.
+ ///
+ EnumInitPhaseReadyToBoot = 0x40,
+ ///
+ /// This stage is notified just before the firmware/Preboot
+ /// environment transfers management of all system resources
+ /// to the OS or next level execution environment.
+ ///
+ EnumInitPhaseEndOfFirmware = 0xF0
+} FSP_INIT_PHASE;
+
+typedef struct {
+ ///
+ /// Notification phase used for NotifyPhase API
+ ///
+ FSP_INIT_PHASE Phase;
+} NOTIFY_PHASE_PARAMS;
+
+#pragma pack()
+
+/**
+ This FSP API is called soon after coming out of reset and before memory and stack is
+ available. This FSP API will load the microcode update, enable code caching for the
+ region specified by the boot loader and also setup a temporary stack to be used until
+ main memory is initialized.
+
+ A hardcoded stack can be set up with the following values, and the "esp" register
+ initialized to point to this hardcoded stack.
+ 1. The return address where the FSP will return control after setting up a temporary
+ stack.
+ 2. A pointer to the input parameter structure
+
+ However, since the stack is in ROM and not writeable, this FSP API cannot be called
+ using the "call" instruction, but needs to be jumped to.
+
+ @param[in] FsptUpdDataPtr Pointer to the FSPT_UPD data structure.
+
+ @retval EFI_SUCCESS Temporary RAM was initialized successfully.
+ @retval EFI_INVALID_PARAMETER Input parameters are invalid.
+ @retval EFI_UNSUPPORTED The FSP calling conditions were not met.
+ @retval EFI_DEVICE_ERROR Temp RAM initialization failed.
+
+ If this function is successful, the FSP initializes the ECX and EDX registers to point to
+ a temporary but writeable memory range available to the boot loader and returns with
+ FSP_SUCCESS in register EAX. Register ECX points to the start of this temporary
+ memory range and EDX points to the end of the range. Boot loader is free to use the
+ whole range described. Typically the boot loader can reload the ESP register to point
+ to the end of this returned range so that it can be used as a standard stack.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *FSP_TEMP_RAM_INIT) (
+ IN VOID *FsptUpdDataPtr
+ );
+
+/**
+ This FSP API is used to notify the FSP about the different phases in the boot process.
+ This allows the FSP to take appropriate actions as needed during different initialization
+ phases. The phases will be platform dependent and will be documented with the FSP
+ release. The current FSP supports two notify phases:
+ Post PCI enumeration
+ Ready To Boot
+
+ @param[in] NotifyPhaseParamPtr Address pointer to the NOTIFY_PHASE_PRAMS
+
+ @retval EFI_SUCCESS The notification was handled successfully.
+ @retval EFI_UNSUPPORTED The notification was not called in the proper order.
+ @retval EFI_INVALID_PARAMETER The notification code is invalid.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *FSP_NOTIFY_PHASE) (
+ IN NOTIFY_PHASE_PARAMS *NotifyPhaseParamPtr
+ );
+
+/**
+ This FSP API is called after TempRamInit and initializes the memory.
+ This FSP API accepts a pointer to a data structure that will be platform dependent
+ and defined for each FSP binary. This will be documented in Integration guide with
+ each FSP release.
+ After FspMemInit completes its execution, it passes the pointer to the HobList and
+ returns to the boot loader from where it was called. BootLoader is responsible to
+ migrate it's stack and data to Memory.
+ FspMemoryInit, TempRamExit and FspSiliconInit APIs provide an alternate method to
+ complete the silicon initialization and provides bootloader an opportunity to get
+ control after system memory is available and before the temporary RAM is torn down.
+
+ @param[in] FspmUpdDataPtr Pointer to the FSPM_UPD data sructure.
+ @param[out] HobListPtr Pointer to receive the address of the HOB list.
+
+ @retval EFI_SUCCESS FSP execution environment was initialized successfully.
+ @retval EFI_INVALID_PARAMETER Input parameters are invalid.
+ @retval EFI_UNSUPPORTED The FSP calling conditions were not met.
+ @retval EFI_DEVICE_ERROR FSP initialization failed.
+ @retval EFI_OUT_OF_RESOURCES Stack range requested by FSP is not met.
+ @retval FSP_STATUS_RESET_REQUIREDx A reset is reuired. These status codes will not be returned during S3.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *FSP_MEMORY_INIT) (
+ IN VOID *FspmUpdDataPtr,
+ OUT VOID **HobListPtr
+ );
+
+
+/**
+ This FSP API is called after FspMemoryInit API. This FSP API tears down the temporary
+ memory setup by TempRamInit API. This FSP API accepts a pointer to a data structure
+ that will be platform dependent and defined for each FSP binary. This will be
+ documented in Integration Guide.
+ FspMemoryInit, TempRamExit and FspSiliconInit APIs provide an alternate method to
+ complete the silicon initialization and provides bootloader an opportunity to get
+ control after system memory is available and before the temporary RAM is torn down.
+
+ @param[in] TempRamExitParamPtr Pointer to the Temp Ram Exit parameters structure.
+ This structure is normally defined in the Integration Guide.
+ And if it is not defined in the Integration Guide, pass NULL.
+
+ @retval EFI_SUCCESS FSP execution environment was initialized successfully.
+ @retval EFI_INVALID_PARAMETER Input parameters are invalid.
+ @retval EFI_UNSUPPORTED The FSP calling conditions were not met.
+ @retval EFI_DEVICE_ERROR FSP initialization failed.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *FSP_TEMP_RAM_EXIT) (
+ IN VOID *TempRamExitParamPtr
+ );
+
+
+/**
+ This FSP API is called after TempRamExit API.
+ FspMemoryInit, TempRamExit and FspSiliconInit APIs provide an alternate method to complete the
+ silicon initialization.
+
+ @param[in] FspsUpdDataPtr Pointer to the FSPS_UPD data structure.
+ If NULL, FSP will use the default parameters.
+
+ @retval EFI_SUCCESS FSP execution environment was initialized successfully.
+ @retval EFI_INVALID_PARAMETER Input parameters are invalid.
+ @retval EFI_UNSUPPORTED The FSP calling conditions were not met.
+ @retval EFI_DEVICE_ERROR FSP initialization failed.
+ @retval FSP_STATUS_RESET_REQUIREDx A reset is reuired. These status codes will not be returned during S3.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *FSP_SILICON_INIT) (
+ IN VOID *FspsUpdDataPtr
+ );
+
+#endif
diff --git a/IntelFsp2Pkg/Include/FspGlobalData.h b/IntelFsp2Pkg/Include/FspGlobalData.h new file mode 100644 index 0000000000..a484d16dcc --- /dev/null +++ b/IntelFsp2Pkg/Include/FspGlobalData.h @@ -0,0 +1,68 @@ +/** @file
+
+ Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<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;
+ UINT32 CarBase;
+ UINT32 CarSize;
+} FSP_PLAT_DATA;
+
+#define FSP_GLOBAL_DATA_SIGNATURE SIGNATURE_32 ('F', 'S', 'P', 'D')
+#define FSP_PERFORMANCE_DATA_SIGNATURE SIGNATURE_32 ('P', 'E', 'R', 'F')
+
+typedef struct {
+ UINT32 Signature;
+ UINT8 Version;
+ UINT8 Reserved1[3];
+ UINT32 CoreStack;
+ UINT32 StatusCode;
+ UINT32 Reserved2[8];
+ FSP_PLAT_DATA PlatformData;
+ FSP_INFO_HEADER *FspInfoHeader;
+ VOID *UpdDataPtr;
+ VOID *TempRamInitUpdPtr;
+ VOID *MemoryInitUpdPtr;
+ VOID *SiliconInitUpdPtr;
+ UINT8 ApiIdx;
+ UINT8 Reserved3[31];
+ UINT32 PerfSig;
+ UINT16 PerfLen;
+ UINT16 Reserved4;
+ UINT32 PerfIdx;
+ UINT64 PerfData[32];
+} FSP_GLOBAL_DATA;
+
+#pragma pack()
+
+#endif
diff --git a/IntelFsp2Pkg/Include/FspMeasurePointId.h b/IntelFsp2Pkg/Include/FspMeasurePointId.h new file mode 100644 index 0000000000..ee103df795 --- /dev/null +++ b/IntelFsp2Pkg/Include/FspMeasurePointId.h @@ -0,0 +1,62 @@ +/** @file
+
+ Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<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/IntelFsp2Pkg/Include/FspStatusCode.h b/IntelFsp2Pkg/Include/FspStatusCode.h new file mode 100644 index 0000000000..c9a316e6e7 --- /dev/null +++ b/IntelFsp2Pkg/Include/FspStatusCode.h @@ -0,0 +1,46 @@ +/** @file
+ Intel FSP status code definition
+
+ Copyright (c) 2016, Intel Corporation. All rights reserved.<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/IntelFsp2Pkg/Include/Guid/FspHeaderFile.h b/IntelFsp2Pkg/Include/Guid/FspHeaderFile.h new file mode 100644 index 0000000000..96cac00124 --- /dev/null +++ b/IntelFsp2Pkg/Include/Guid/FspHeaderFile.h @@ -0,0 +1,204 @@ +/** @file
+ Intel FSP Header File definition from Intel Firmware Support Package External
+ Architecture Specification v2.0.
+
+ Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<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/IntelFsp2Pkg/Include/Guid/GuidHobFspEas.h b/IntelFsp2Pkg/Include/Guid/GuidHobFspEas.h new file mode 100644 index 0000000000..83c7f0068f --- /dev/null +++ b/IntelFsp2Pkg/Include/Guid/GuidHobFspEas.h @@ -0,0 +1,23 @@ +/** @file
+ Intel FSP Hob Guid definition from Intel Firmware Support Package External
+ Architecture Specification v2.0.
+
+ Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<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/IntelFsp2Pkg/Include/Library/CacheAsRamLib.h b/IntelFsp2Pkg/Include/Library/CacheAsRamLib.h new file mode 100644 index 0000000000..6f3d068b67 --- /dev/null +++ b/IntelFsp2Pkg/Include/Library/CacheAsRamLib.h @@ -0,0 +1,30 @@ +/** @file
+
+ Copyright (c) 2014, Intel Corporation. All rights reserved.<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/IntelFsp2Pkg/Include/Library/CacheLib.h b/IntelFsp2Pkg/Include/Library/CacheLib.h new file mode 100644 index 0000000000..909ae928f1 --- /dev/null +++ b/IntelFsp2Pkg/Include/Library/CacheLib.h @@ -0,0 +1,62 @@ +/** @file
+
+ Copyright (c) 2014, Intel Corporation. All rights reserved.<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/IntelFsp2Pkg/Include/Library/DebugDeviceLib.h b/IntelFsp2Pkg/Include/Library/DebugDeviceLib.h new file mode 100644 index 0000000000..5c35eda579 --- /dev/null +++ b/IntelFsp2Pkg/Include/Library/DebugDeviceLib.h @@ -0,0 +1,29 @@ +/** @file
+
+ Copyright (c) 2014, Intel Corporation. All rights reserved.<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/IntelFsp2Pkg/Include/Library/FspCommonLib.h b/IntelFsp2Pkg/Include/Library/FspCommonLib.h new file mode 100644 index 0000000000..0bb0c53786 --- /dev/null +++ b/IntelFsp2Pkg/Include/Library/FspCommonLib.h @@ -0,0 +1,312 @@ +/** @file
+
+ Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<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 VPD data pointer.
+
+ @return VpdDataRgnPtr VPD data pointer.
+**/
+VOID *
+EFIAPI
+GetFspVpdDataPointer (
+ VOID
+ );
+
+/**
+ This function gets FSP API calling mode.
+
+ @retval API calling mode
+**/
+UINT8
+EFIAPI
+GetFspApiCallingIndex (
+ VOID
+ );
+
+/**
+ This function sets FSP API calling mode.
+
+ @param[in] Index API calling index
+**/
+VOID
+EFIAPI
+SetFspApiCallingIndex (
+ UINT8 Index
+ );
+
+/**
+ This function gets FSP Phase StatusCode.
+
+ @retval StatusCode
+**/
+UINT32
+EFIAPI
+GetPhaseStatusCode (
+ VOID
+ );
+
+
+/**
+ This function sets FSP Phase StatusCode.
+
+ @param[in] Mode Phase StatusCode
+**/
+VOID
+EFIAPI
+SetPhaseStatusCode (
+ UINT32 StatusCode
+ );
+
+/**
+ This function gets FSP CAR base.
+
+**/
+UINT32
+EFIAPI
+GetFspCarBase (
+ VOID
+ );
+
+/**
+ This function gets FSP CAR size.
+
+**/
+UINT32
+EFIAPI
+GetFspCarSize (
+ VOID
+ );
+
+#endif
diff --git a/IntelFsp2Pkg/Include/Library/FspPlatformLib.h b/IntelFsp2Pkg/Include/Library/FspPlatformLib.h new file mode 100644 index 0000000000..9247bd5221 --- /dev/null +++ b/IntelFsp2Pkg/Include/Library/FspPlatformLib.h @@ -0,0 +1,105 @@ +/** @file
+
+ Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<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
+ );
+
+/**
+ Migrate BootLoader data before destroying CAR.
+
+**/
+VOID
+EFIAPI
+FspMigrateTemporaryMemory (
+ VOID
+ );
+
+/**
+ Set a new stack frame for the continuation function.
+
+**/
+VOID
+EFIAPI
+FspSetNewStackFrame (
+ VOID
+ );
+
+/**
+ This function transfer control back to BootLoader after FspSiliconInit.
+
+**/
+VOID
+EFIAPI
+FspSiliconInitDone (
+ VOID
+ );
+
+/**
+ This function returns control to BootLoader after MemoryInitApi.
+
+ @param[in,out] HobListPtr The address of HobList pointer.
+**/
+VOID
+EFIAPI
+FspMemoryInitDone (
+ IN OUT VOID **HobListPtr
+ );
+
+/**
+ This function returns control to BootLoader after TempRamExitApi.
+
+**/
+VOID
+EFIAPI
+FspTempRamExitDone (
+ VOID
+ );
+
+/**
+ This function handle NotifyPhase API call from the BootLoader.
+ It gives control back to the BootLoader after it is handled. If the
+ Notification code is a ReadyToBoot event, this function will return
+ and FSP continues the remaining execution until it reaches the DxeIpl.
+
+**/
+VOID
+EFIAPI
+FspWaitForNotify (
+ VOID
+ );
+
+#endif
diff --git a/IntelFsp2Pkg/Include/Library/FspSecPlatformLib.h b/IntelFsp2Pkg/Include/Library/FspSecPlatformLib.h new file mode 100644 index 0000000000..cf2b0ffa2e --- /dev/null +++ b/IntelFsp2Pkg/Include/Library/FspSecPlatformLib.h @@ -0,0 +1,88 @@ +/** @file
+
+ Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<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/IntelFsp2Pkg/Include/Library/FspSwitchStackLib.h b/IntelFsp2Pkg/Include/Library/FspSwitchStackLib.h new file mode 100644 index 0000000000..e90b13e8da --- /dev/null +++ b/IntelFsp2Pkg/Include/Library/FspSwitchStackLib.h @@ -0,0 +1,45 @@ +/** @file
+
+ Copyright (c) 2014, Intel Corporation. All rights reserved.<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 funciton will switch the current stack to the previous saved stack.
+ Before calling the previous stack has to be set in FSP_GLOBAL_DATA.CoreStack.
+ EIP
+ FLAGS 16 bit FLAGS 16 bit
+ EDI
+ ESI
+ EBP
+ ESP
+ EBX
+ EDX
+ ECX
+ EAX
+ DWORD IDT base1
+ StackPointer: DWORD IDT base2
+
+ @return ReturnKey After switching to the saved stack,
+ this value will be saved in eax before returning.
+
+
+**/
+UINT32
+EFIAPI
+Pei2LoaderSwitchStack (
+ VOID
+ );
+
+#endif
diff --git a/IntelFsp2Pkg/IntelFsp2Pkg.dec b/IntelFsp2Pkg/IntelFsp2Pkg.dec new file mode 100644 index 0000000000..52024af4fb --- /dev/null +++ b/IntelFsp2Pkg/IntelFsp2Pkg.dec @@ -0,0 +1,80 @@ +## @file
+# Provides driver and definitions to build fsp in EDKII bios.
+#
+# Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<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/IntelFsp2Pkg/IntelFsp2Pkg.dsc b/IntelFsp2Pkg/IntelFsp2Pkg.dsc new file mode 100644 index 0000000000..3b50bbf629 --- /dev/null +++ b/IntelFsp2Pkg/IntelFsp2Pkg.dsc @@ -0,0 +1,77 @@ +## @file
+# Provides driver and definitions to build fsp.
+#
+# Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<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/FspSecCore/FspSecCoreT.inf
+ IntelFsp2Pkg/FspSecCore/FspSecCoreM.inf
+ IntelFsp2Pkg/FspSecCore/FspSecCoreS.inf
+ IntelFsp2Pkg/FspNotifyPhase/FspNotifyPhasePeim.inf
+
+[PcdsFixedAtBuild.common]
+ gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x1f
+ gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80080046
+ gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x07
diff --git a/IntelFsp2Pkg/Library/BaseCacheAsRamLibNull/BaseCacheAsRamLibNull.inf b/IntelFsp2Pkg/Library/BaseCacheAsRamLibNull/BaseCacheAsRamLibNull.inf new file mode 100644 index 0000000000..bdb6744f37 --- /dev/null +++ b/IntelFsp2Pkg/Library/BaseCacheAsRamLibNull/BaseCacheAsRamLibNull.inf @@ -0,0 +1,31 @@ +## @file
+# NULL instance of Base cache as RAM.
+#
+# Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.<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/IntelFsp2Pkg/Library/BaseCacheAsRamLibNull/DisableCacheAsRamNull.c b/IntelFsp2Pkg/Library/BaseCacheAsRamLibNull/DisableCacheAsRamNull.c new file mode 100644 index 0000000000..9b45163c34 --- /dev/null +++ b/IntelFsp2Pkg/Library/BaseCacheAsRamLibNull/DisableCacheAsRamNull.c @@ -0,0 +1,41 @@ +/** @file
+
+ Copyright (c) 2014, Intel Corporation. All rights reserved.<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/IntelFsp2Pkg/Library/BaseCacheLib/BaseCacheLib.inf b/IntelFsp2Pkg/Library/BaseCacheLib/BaseCacheLib.inf new file mode 100644 index 0000000000..7b026b1dfc --- /dev/null +++ b/IntelFsp2Pkg/Library/BaseCacheLib/BaseCacheLib.inf @@ -0,0 +1,34 @@ +## @file
+# Instance of BaseCache.
+#
+# Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.<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/IntelFsp2Pkg/Library/BaseCacheLib/CacheLib.c b/IntelFsp2Pkg/Library/BaseCacheLib/CacheLib.c new file mode 100644 index 0000000000..b38dce32a8 --- /dev/null +++ b/IntelFsp2Pkg/Library/BaseCacheLib/CacheLib.c @@ -0,0 +1,703 @@ +/** @file
+
+ Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.<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/IntelFsp2Pkg/Library/BaseCacheLib/CacheLibInternal.h b/IntelFsp2Pkg/Library/BaseCacheLib/CacheLibInternal.h new file mode 100644 index 0000000000..fbbf551dde --- /dev/null +++ b/IntelFsp2Pkg/Library/BaseCacheLib/CacheLibInternal.h @@ -0,0 +1,59 @@ +/** @file
+
+ Copyright (c) 2014, Intel Corporation. All rights reserved.<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/IntelFsp2Pkg/Library/BaseDebugDeviceLibNull/BaseDebugDeviceLibNull.inf b/IntelFsp2Pkg/Library/BaseDebugDeviceLibNull/BaseDebugDeviceLibNull.inf new file mode 100644 index 0000000000..5e4c572973 --- /dev/null +++ b/IntelFsp2Pkg/Library/BaseDebugDeviceLibNull/BaseDebugDeviceLibNull.inf @@ -0,0 +1,34 @@ +## @file
+# Debug device library instance that retrieves the current enabling state for
+# the platform debug output device.
+#
+# Copyright (c) 2014, Intel Corporation. All rights reserved.<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/IntelFsp2Pkg/Library/BaseDebugDeviceLibNull/DebugDeviceLibNull.c b/IntelFsp2Pkg/Library/BaseDebugDeviceLibNull/DebugDeviceLibNull.c new file mode 100644 index 0000000000..95c100472c --- /dev/null +++ b/IntelFsp2Pkg/Library/BaseDebugDeviceLibNull/DebugDeviceLibNull.c @@ -0,0 +1,31 @@ +/** @file
+ Debug device library instance that retrieves the current enabling state for
+ the platform debug output device.
+
+ Copyright (c) 2014, Intel Corporation. All rights reserved.<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/IntelFsp2Pkg/Library/BaseFspCommonLib/BaseFspCommonLib.inf b/IntelFsp2Pkg/Library/BaseFspCommonLib/BaseFspCommonLib.inf new file mode 100644 index 0000000000..0b0741b1c6 --- /dev/null +++ b/IntelFsp2Pkg/Library/BaseFspCommonLib/BaseFspCommonLib.inf @@ -0,0 +1,39 @@ +## @file
+# Instance of FspCommonLib
+# Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<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
+
+[Pcd]
+ gIntelFsp2PkgTokenSpaceGuid.PcdGlobalDataPointerAddress ## CONSUMES
+
+[FixedPcd]
+ gIntelFsp2PkgTokenSpaceGuid.PcdFspMaxPatchEntry ## CONSUMES
+ gIntelFsp2PkgTokenSpaceGuid.PcdFspMaxPerfEntry ## CONSUMES
+ gIntelFsp2PkgTokenSpaceGuid.PcdTemporaryRamBase ## CONSUMES
+ gIntelFsp2PkgTokenSpaceGuid.PcdTemporaryRamSize ## CONSUMES
diff --git a/IntelFsp2Pkg/Library/BaseFspCommonLib/FspCommonLib.c b/IntelFsp2Pkg/Library/BaseFspCommonLib/FspCommonLib.c new file mode 100644 index 0000000000..efd55f464c --- /dev/null +++ b/IntelFsp2Pkg/Library/BaseFspCommonLib/FspCommonLib.c @@ -0,0 +1,546 @@ +/** @file
+
+ Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<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 <FspDataTable.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 memory init UPD data pointer.
+
+ @param[in] MemoryInitUpdPtr memory init UPD data pointer.
+**/
+VOID
+EFIAPI
+SetFspMemoryInitUpdDataPointer (
+ IN VOID *MemoryInitUpdPtr
+ )
+{
+ FSP_GLOBAL_DATA *FspData;
+
+ //
+ // Get the Fsp Global Data Pointer
+ //
+ FspData = GetFspGlobalDataPointer ();
+
+ //
+ // Set the memory init UPD pointer.
+ //
+ FspData->MemoryInitUpdPtr = MemoryInitUpdPtr;
+}
+
+/**
+ This function gets the memory init UPD data pointer.
+
+ @return memory init UPD data pointer.
+**/
+VOID *
+EFIAPI
+GetFspMemoryInitUpdDataPointer (
+ VOID
+ )
+{
+ FSP_GLOBAL_DATA *FspData;
+
+ FspData = GetFspGlobalDataPointer ();
+ return FspData->MemoryInitUpdPtr;
+}
+
+
+/**
+ This function sets the silicon init UPD data pointer.
+
+ @param[in] SiliconInitUpdPtr silicon init UPD data pointer.
+**/
+VOID
+EFIAPI
+SetFspSiliconInitUpdDataPointer (
+ IN VOID *SiliconInitUpdPtr
+ )
+{
+ FSP_GLOBAL_DATA *FspData;
+
+ //
+ // Get the Fsp Global Data Pointer
+ //
+ FspData = GetFspGlobalDataPointer ();
+
+ //
+ // Set the silicon init UPD data pointer.
+ //
+ FspData->SiliconInitUpdPtr = SiliconInitUpdPtr;
+}
+
+/**
+ This function gets the silicon init UPD data pointer.
+
+ @return silicon init UPD data pointer.
+**/
+VOID *
+EFIAPI
+GetFspSiliconInitUpdDataPointer (
+ VOID
+ )
+{
+ FSP_GLOBAL_DATA *FspData;
+
+ FspData = GetFspGlobalDataPointer ();
+ return FspData->SiliconInitUpdPtr;
+}
+
+
+/**
+ Set FSP measurement point timestamp.
+
+ @param[in] Id Measurement point ID.
+
+ @return performance timestamp.
+**/
+UINT64
+EFIAPI
+SetFspMeasurePoint (
+ IN UINT8 Id
+ )
+{
+ FSP_GLOBAL_DATA *FspData;
+
+ //
+ // Bit [55: 0] will be the timestamp
+ // Bit [63:56] will be the ID
+ //
+ FspData = GetFspGlobalDataPointer ();
+ if (FspData->PerfIdx < sizeof(FspData->PerfData) / sizeof(FspData->PerfData[0])) {
+ FspData->PerfData[FspData->PerfIdx] = AsmReadTsc ();
+ ((UINT8 *)(&FspData->PerfData[FspData->PerfIdx]))[7] = Id;
+ }
+
+ return FspData->PerfData[(FspData->PerfIdx)++];
+}
+
+/**
+ This function gets the FSP info header pointer.
+
+ @retval FspInfoHeader FSP info header pointer
+**/
+FSP_INFO_HEADER *
+EFIAPI
+GetFspInfoHeader (
+ VOID
+ )
+{
+ return GetFspGlobalDataPointer()->FspInfoHeader;
+}
+
+/**
+ This function sets the FSP info header pointer.
+
+ @param[in] FspInfoHeader FSP info header pointer
+**/
+VOID
+EFIAPI
+SetFspInfoHeader (
+ FSP_INFO_HEADER *FspInfoHeader
+ )
+{
+ GetFspGlobalDataPointer()->FspInfoHeader = FspInfoHeader;
+}
+
+/**
+ This function gets the FSP info header pointer using the API stack context.
+
+ @retval FspInfoHeader FSP info header pointer using the API stack context
+**/
+FSP_INFO_HEADER *
+EFIAPI
+GetFspInfoHeaderFromApiContext (
+ VOID
+ )
+{
+ FSP_GLOBAL_DATA *FspData;
+
+ FspData = GetFspGlobalDataPointer ();
+ return (FSP_INFO_HEADER *)(*(UINT32 *)(UINTN)(FspData->CoreStack + CONTEXT_STACK_OFFSET(FspInfoHeader)));
+}
+
+/**
+ This function gets the VPD data pointer.
+
+ @return VpdDataRgnPtr VPD data pointer.
+**/
+VOID *
+EFIAPI
+GetFspVpdDataPointer (
+ VOID
+ )
+{
+ FSP_INFO_HEADER *FspInfoHeader;
+
+ FspInfoHeader = GetFspInfoHeader ();
+ return (VOID *)(FspInfoHeader->ImageBase + FspInfoHeader->CfgRegionOffset);
+}
+
+/**
+ This function gets FSP API calling index.
+
+ @retval API calling index
+**/
+UINT8
+EFIAPI
+GetFspApiCallingIndex (
+ VOID
+ )
+{
+ return GetFspGlobalDataPointer()->ApiIdx;
+}
+
+/**
+ This function sets FSP API calling mode.
+
+ @param[in] Index API calling index
+**/
+VOID
+EFIAPI
+SetFspApiCallingIndex (
+ UINT8 Index
+ )
+{
+ FSP_GLOBAL_DATA *FspData;
+
+ FspData = GetFspGlobalDataPointer ();
+ FspData->ApiIdx = Index;
+}
+
+/**
+ This function gets FSP Phase StatusCode.
+
+ @retval StatusCode
+**/
+UINT32
+EFIAPI
+GetPhaseStatusCode (
+ VOID
+ )
+{
+ return GetFspGlobalDataPointer()->StatusCode;
+}
+
+/**
+ This function sets FSP Phase StatusCode.
+
+ @param[in] Mode Phase StatusCode
+**/
+VOID
+EFIAPI
+SetPhaseStatusCode (
+ UINT32 StatusCode
+ )
+{
+ FSP_GLOBAL_DATA *FspData;
+
+ FspData = GetFspGlobalDataPointer ();
+ FspData->StatusCode = StatusCode;
+}
+
+/**
+ This function gets FSP CAR base.
+
+**/
+UINT32
+EFIAPI
+GetFspCarBase (
+ VOID
+ )
+{
+ FSP_GLOBAL_DATA *FspData;
+ UINT32 CarBase;
+
+ FspData = GetFspGlobalDataPointer ();
+ CarBase = FspData->PlatformData.CarBase;
+ if (CarBase == 0) {
+ CarBase = PcdGet32(PcdTemporaryRamBase);
+ }
+ return CarBase;
+}
+
+/**
+ This function gets FSP CAR size.
+
+**/
+UINT32
+EFIAPI
+GetFspCarSize (
+ VOID
+ )
+{
+ FSP_GLOBAL_DATA *FspData;
+ UINT32 CarSize;
+
+ FspData = GetFspGlobalDataPointer ();
+ CarSize = FspData->PlatformData.CarSize;
+ if (FspData->PlatformData.CarBase == 0) {
+ CarSize = PcdGet32(PcdTemporaryRamSize);
+ }
+ return CarSize;
+}
diff --git a/IntelFsp2Pkg/Library/BaseFspDebugLibSerialPort/BaseFspDebugLibSerialPort.inf b/IntelFsp2Pkg/Library/BaseFspDebugLibSerialPort/BaseFspDebugLibSerialPort.inf new file mode 100644 index 0000000000..a7f10d4262 --- /dev/null +++ b/IntelFsp2Pkg/Library/BaseFspDebugLibSerialPort/BaseFspDebugLibSerialPort.inf @@ -0,0 +1,51 @@ +## @file
+# Instance of BaseFspDebugLib
+#
+# Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.<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.asm | MSFT
+ Ia32/FspDebug.s | GCC
+
+[Packages]
+ MdePkg/MdePkg.dec
+ IntelFsp2Pkg/IntelFsp2Pkg.dec
+
+[LibraryClasses]
+ SerialPortLib
+ BaseMemoryLib
+ PcdLib
+ PrintLib
+ BaseLib
+ DebugDeviceLib
+ DebugPrintErrorLevelLib
+
+[Pcd]
+ gEfiMdePkgTokenSpaceGuid.PcdDebugClearMemoryValue ## CONSUMES
+ gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask ## CONSUMES
+ gEfiMdePkgTokenSpaceGuid.PcdFixedDebugPrintErrorLevel ## CONSUMES
+
diff --git a/IntelFsp2Pkg/Library/BaseFspDebugLibSerialPort/DebugLib.c b/IntelFsp2Pkg/Library/BaseFspDebugLibSerialPort/DebugLib.c new file mode 100644 index 0000000000..73bb08e357 --- /dev/null +++ b/IntelFsp2Pkg/Library/BaseFspDebugLibSerialPort/DebugLib.c @@ -0,0 +1,328 @@ +/** @file
+
+ Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.<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/IntelFsp2Pkg/Library/BaseFspDebugLibSerialPort/Ia32/FspDebug.asm b/IntelFsp2Pkg/Library/BaseFspDebugLibSerialPort/Ia32/FspDebug.asm new file mode 100644 index 0000000000..8ac18ec4ec --- /dev/null +++ b/IntelFsp2Pkg/Library/BaseFspDebugLibSerialPort/Ia32/FspDebug.asm @@ -0,0 +1,34 @@ +;------------------------------------------------------------------------------
+;
+; Copyright (c) 2014, Intel Corporation. All rights reserved.<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
+;
+;------------------------------------------------------------------------------
+
+ .386
+ .model flat,C
+ .code
+
+;------------------------------------------------------------------------------
+; UINT32 *
+; EFIAPI
+; GetStackFramePointer (
+; VOID
+; );
+;------------------------------------------------------------------------------
+GetStackFramePointer PROC PUBLIC
+ mov eax, ebp
+ ret
+GetStackFramePointer ENDP
+
+ END
diff --git a/IntelFsp2Pkg/Library/BaseFspDebugLibSerialPort/Ia32/FspDebug.s b/IntelFsp2Pkg/Library/BaseFspDebugLibSerialPort/Ia32/FspDebug.s new file mode 100644 index 0000000000..0f8475fa62 --- /dev/null +++ b/IntelFsp2Pkg/Library/BaseFspDebugLibSerialPort/Ia32/FspDebug.s @@ -0,0 +1,30 @@ +#------------------------------------------------------------------------------
+#
+# Copyright (c) 2014, Intel Corporation. All rights reserved.<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
+#
+#------------------------------------------------------------------------------
+
+#------------------------------------------------------------------------------
+# UINT32 *
+# EFIAPI
+# GetStackFramePointer (
+# VOID
+# )
+#------------------------------------------------------------------------------
+ASM_GLOBAL ASM_PFX(GetStackFramePointer)
+ASM_PFX(GetStackFramePointer):
+ mov %ebp, %eax
+ ret
+
+
diff --git a/IntelFsp2Pkg/Library/BaseFspPlatformLib/BaseFspPlatformLib.inf b/IntelFsp2Pkg/Library/BaseFspPlatformLib/BaseFspPlatformLib.inf new file mode 100644 index 0000000000..d04689ef88 --- /dev/null +++ b/IntelFsp2Pkg/Library/BaseFspPlatformLib/BaseFspPlatformLib.inf @@ -0,0 +1,50 @@ +## @file
+# Instance of FspPlatformLib
+#
+# Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<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
+
+[FixedPcd]
+ gIntelFsp2PkgTokenSpaceGuid.PcdFspMaxPatchEntry ## CONSUMES
+ gIntelFsp2PkgTokenSpaceGuid.PcdFspMaxPerfEntry ## CONSUMES
diff --git a/IntelFsp2Pkg/Library/BaseFspPlatformLib/FspPlatformMemory.c b/IntelFsp2Pkg/Library/BaseFspPlatformLib/FspPlatformMemory.c new file mode 100644 index 0000000000..d6684f3b06 --- /dev/null +++ b/IntelFsp2Pkg/Library/BaseFspPlatformLib/FspPlatformMemory.c @@ -0,0 +1,189 @@ +/** @file
+
+ Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<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);
+ }
+}
+
+/**
+ Migrate BootLoader data before destroying CAR.
+
+**/
+VOID
+EFIAPI
+FspMigrateTemporaryMemory (
+ VOID
+ )
+{
+ UINT32 BootLoaderTempRamStart;
+ UINT32 BootLoaderTempRamEnd;
+ UINT32 BootLoaderTempRamSize;
+ UINT32 OffsetGap;
+ UINT32 FspParamPtr;
+ VOID *BootLoaderTempRamHob;
+ UINT32 MemoryInitUpdPtr;
+ VOID *PlatformDataPtr;
+
+ //
+ // Get the temporary memory range used by the BootLoader
+ //
+ BootLoaderTempRamStart = GetFspCarBase ();
+ BootLoaderTempRamSize = GetFspCarSize () - PcdGet32(PcdFspTemporaryRamSize);
+
+ BootLoaderTempRamEnd = BootLoaderTempRamStart + BootLoaderTempRamSize;
+
+ //
+ // Build a Boot Loader Temporary Memory GUID HOB
+ //
+ BootLoaderTempRamHob = (VOID *)AllocatePages (EFI_SIZE_TO_PAGES (BootLoaderTempRamSize));
+ ASSERT(BootLoaderTempRamHob != NULL);
+
+ DEBUG ((DEBUG_INFO, "FSP_BOOT_LOADER_TEMPORARY_MEMORY_HOB\n"));
+ DEBUG ((DEBUG_INFO, "FspBootLoaderTemporaryMemory Base : %x\n", BootLoaderTempRamStart));
+ DEBUG ((DEBUG_INFO, "FspBootLoaderTemporaryMemory Size : %x\n", BootLoaderTempRamSize));
+
+ CopyMem (BootLoaderTempRamHob, (VOID *)BootLoaderTempRamStart, BootLoaderTempRamSize);
+ OffsetGap = (UINT32)BootLoaderTempRamHob - BootLoaderTempRamStart;
+
+ //
+ // Fix the FspMemoryinit Parameter Pointers to the new location.
+ //
+ FspParamPtr = GetFspApiParameter ();
+ if ((VOID *)FspParamPtr != NULL && FspParamPtr >= BootLoaderTempRamStart &&
+ FspParamPtr < BootLoaderTempRamEnd) {
+ SetFspApiParameter (FspParamPtr + OffsetGap);
+ }
+
+ //
+ // Update UPD pointer in FSP Global Data
+ //
+ MemoryInitUpdPtr = (UINT32)((UINT32 *)GetFspMemoryInitUpdDataPointer ());
+ if (MemoryInitUpdPtr >= BootLoaderTempRamStart && MemoryInitUpdPtr < BootLoaderTempRamEnd) {
+ SetFspMemoryInitUpdDataPointer ((VOID *)(MemoryInitUpdPtr + OffsetGap));
+ }
+
+ //
+ // Update Platform data pointer in FSP Global Data
+ //
+ PlatformDataPtr = GetFspPlatformDataPointer ();
+ if (((UINT32)PlatformDataPtr >= BootLoaderTempRamStart) &&
+ ((UINT32)PlatformDataPtr < BootLoaderTempRamEnd)) {
+ SetFspPlatformDataPointer ((UINT8 *)PlatformDataPtr + OffsetGap);
+ }
+}
diff --git a/IntelFsp2Pkg/Library/BaseFspPlatformLib/FspPlatformNotify.c b/IntelFsp2Pkg/Library/BaseFspPlatformLib/FspPlatformNotify.c new file mode 100644 index 0000000000..66b6cdb878 --- /dev/null +++ b/IntelFsp2Pkg/Library/BaseFspPlatformLib/FspPlatformNotify.c @@ -0,0 +1,279 @@ +/** @file
+
+ Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<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.
+
+**/
+VOID
+EFIAPI
+FspSiliconInitDone (
+ VOID
+ )
+{
+ //
+ // This is the end of the FspSiliconInit API
+ // Give control back to the boot loader
+ //
+ SetFspMeasurePoint (FSP_PERF_ID_API_FSP_SILICON_INIT_EXIT);
+ DEBUG ((DEBUG_INFO | DEBUG_INIT, "FspSiliconInitApi() - End\n"));
+
+ PERF_END_EX (&gFspPerformanceDataGuid, "EventRec", NULL, 0, 0x907F);
+
+ REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
+ SetFspApiReturnStatus (EFI_SUCCESS);
+
+ Pei2LoaderSwitchStack();
+
+ PERF_START_EX (&gFspPerformanceDataGuid, "EventRec", NULL, 0, 0x6000);
+}
+
+/**
+ This function returns control to BootLoader after MemoryInitApi.
+
+ @param[in,out] HobListPtr The address of HobList pointer.
+**/
+VOID
+EFIAPI
+FspMemoryInitDone (
+ IN OUT VOID **HobListPtr
+ )
+{
+ //
+ // Calling use FspMemoryInit API
+ // Update HOB and return the control directly
+ //
+ if (HobListPtr != NULL) {
+ *HobListPtr = (VOID *) GetHobList ();
+ }
+
+ //
+ // This is the end of the FspMemoryInit API
+ // Give control back to the boot loader
+ //
+ SetFspMeasurePoint (FSP_PERF_ID_API_FSP_MEMORY_INIT_EXIT);
+ DEBUG ((DEBUG_INFO | DEBUG_INIT, "FspMemoryInitApi() - End\n"));
+ REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_MEMORY_INIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
+ SetFspApiReturnStatus (EFI_SUCCESS);
+ Pei2LoaderSwitchStack ();
+
+ //
+ // The TempRamExitApi is called
+ //
+ if (GetFspApiCallingIndex () == TempRamExitApiIndex) {
+ SetPhaseStatusCode (FSP_STATUS_CODE_TEMP_RAM_EXIT);
+ REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_TEMP_RAM_EXIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);
+ SetFspMeasurePoint (FSP_PERF_ID_API_TEMP_RAM_EXIT_ENTRY);
+ DEBUG ((DEBUG_INFO | DEBUG_INIT, "TempRamExitApi() - Begin\n"));
+ } else {
+ SetFspMeasurePoint (FSP_PERF_ID_API_FSP_SILICON_INIT_ENTRY);
+ DEBUG ((DEBUG_INFO | DEBUG_INIT, "FspSiliconInitApi() - Begin\n"));
+ SetPhaseStatusCode (FSP_STATUS_CODE_SILICON_INIT);
+ REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_SILICON_INIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);
+ }
+}
+
+/**
+ This function returns control to BootLoader after TempRamExitApi.
+
+**/
+VOID
+EFIAPI
+FspTempRamExitDone (
+ VOID
+ )
+{
+
+ //
+ // This is the end of the TempRamExit API
+ // Give control back to the boot loader
+ //
+ SetFspMeasurePoint (FSP_PERF_ID_API_TEMP_RAM_EXIT_EXIT);
+ DEBUG ((DEBUG_INFO | DEBUG_INIT, "TempRamExitApi() - End\n"));
+ REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_TEMP_RAM_EXIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
+ SetFspApiReturnStatus (EFI_SUCCESS);
+ Pei2LoaderSwitchStack ();
+
+ SetPhaseStatusCode (FSP_STATUS_CODE_SILICON_INIT);
+ SetFspMeasurePoint (FSP_PERF_ID_API_FSP_SILICON_INIT_ENTRY);
+ DEBUG ((DEBUG_INFO | DEBUG_INIT, "SiliconInitApi() - Begin\n"));
+ REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_SILICON_INIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);
+}
+
+/**
+ This function handle NotifyPhase API call from the BootLoader.
+ It gives control back to the BootLoader after it is handled. If the
+ Notification code is a ReadyToBoot event, this function will return
+ and FSP continues the remaining execution until it reaches the DxeIpl.
+
+**/
+VOID
+FspWaitForNotify (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ UINT32 NotificationValue;
+ UINT32 NotificationCount;
+ UINT8 Count;
+
+ NotificationCount = 0;
+ while (NotificationCount < sizeof(mFspNotifySequence) / sizeof(UINT32)) {
+
+ Count = (UINT8)((NotificationCount << 1) & 0x07);
+ SetFspMeasurePoint (FSP_PERF_ID_API_NOTIFY_POST_PCI_ENTRY + Count);
+
+ if (NotificationCount == 0) {
+ SetPhaseStatusCode (FSP_STATUS_CODE_POST_PCIE_ENUM_NOTIFICATION);
+ REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_POST_PCIE_ENUM_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);
+ } else if (NotificationCount == 1) {
+ SetPhaseStatusCode (FSP_STATUS_CODE_READY_TO_BOOT_NOTIFICATION);
+ REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_READY_TO_BOOT_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);
+ } else if (NotificationCount == 2) {
+ SetPhaseStatusCode (FSP_STATUS_CODE_END_OF_FIRMWARE_NOTIFICATION);
+ REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_END_OF_FIRMWARE_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);
+ }
+
+ NotificationValue = ((NOTIFY_PHASE_PARAMS *)(UINTN)GetFspApiParameter ())->Phase;
+ DEBUG ((DEBUG_INFO | DEBUG_INIT, "NotifyPhaseApi() - Begin [Phase: %08X]\n", NotificationValue));
+ if (mFspNotifySequence[NotificationCount] != NotificationValue) {
+ //
+ // Notify code does not follow the predefined order
+ //
+ DEBUG ((DEBUG_INFO, "Unsupported FSP Notification Value\n"));
+ Status = EFI_UNSUPPORTED;
+ } else {
+ //
+ // Process Notification and Give control back to the boot loader framework caller
+ //
+ Status = FspNotificationHandler (NotificationValue);
+ if (!EFI_ERROR(Status)) {
+ NotificationCount++;
+ }
+ }
+
+ SetFspApiReturnStatus(Status);
+ DEBUG ((DEBUG_INFO | DEBUG_INIT, "NotifyPhaseApi() - End [Status: 0x%08X]\n", Status));
+
+ SetFspMeasurePoint (FSP_PERF_ID_API_NOTIFY_POST_PCI_EXIT + Count);
+
+ if ((NotificationCount - 1) == 0) {
+ REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_POST_PCIE_ENUM_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
+ } else if ((NotificationCount - 1) == 1) {
+ REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_READY_TO_BOOT_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
+ } else if ((NotificationCount - 1) == 2) {
+ REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_END_OF_FIRMWARE_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
+ }
+ Pei2LoaderSwitchStack();
+ }
+
+ //
+ // Control goes back to the PEI Core and it dispatches further PEIMs.
+ // DXEIPL is the final one to transfer control back to the boot loader.
+ //
+}
+
diff --git a/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/BaseFspSwitchStackLib.inf b/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/BaseFspSwitchStackLib.inf new file mode 100644 index 0000000000..bbeeb744ff --- /dev/null +++ b/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/BaseFspSwitchStackLib.inf @@ -0,0 +1,43 @@ +## @file
+# Instance of BaseFspSwitchStackLib
+#
+# Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.<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.asm | MSFT
+ Ia32/Stack.s | GCC
+
+[Packages]
+ MdePkg/MdePkg.dec
+ IntelFsp2Pkg/IntelFsp2Pkg.dec
+
+[LibraryClasses]
+ BaseLib
+ IoLib
+
+[FixedPcd]
+ gIntelFsp2PkgTokenSpaceGuid.PcdFspMaxPatchEntry ## CONSUMES
+ gIntelFsp2PkgTokenSpaceGuid.PcdFspMaxPerfEntry ## CONSUMES
+
+
+
diff --git a/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/FspSwitchStackLib.c b/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/FspSwitchStackLib.c new file mode 100644 index 0000000000..42a57a27c0 --- /dev/null +++ b/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/FspSwitchStackLib.c @@ -0,0 +1,42 @@ +/** @file
+
+ Copyright (c) 2014, Intel Corporation. All rights reserved.<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/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/Ia32/Stack.asm b/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/Ia32/Stack.asm new file mode 100644 index 0000000000..1efab52059 --- /dev/null +++ b/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/Ia32/Stack.asm @@ -0,0 +1,77 @@ +;------------------------------------------------------------------------------
+;
+; Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.<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.
+;
+;------------------------------------------------------------------------------
+
+ .586p
+ .model flat,C
+ .code
+
+;------------------------------------------------------------------------------
+; UINT32
+; EFIAPI
+; Pei2LoaderSwitchStack (
+; VOID
+; )
+;------------------------------------------------------------------------------
+EXTERNDEF C MeasurePoint:PROC
+Pei2LoaderSwitchStack PROC C PUBLIC
+ xor eax, eax
+ jmp FspSwitchStack
+Pei2LoaderSwitchStack ENDP
+
+;------------------------------------------------------------------------------
+; UINT32
+; EFIAPI
+; Loader2PeiSwitchStack (
+; VOID
+; )
+;------------------------------------------------------------------------------
+Loader2PeiSwitchStack PROC C PUBLIC
+ jmp FspSwitchStack
+Loader2PeiSwitchStack ENDP
+
+;------------------------------------------------------------------------------
+; UINT32
+; EFIAPI
+; FspSwitchStack (
+; VOID
+; )
+;------------------------------------------------------------------------------
+EXTERNDEF C SwapStack:PROC
+FspSwitchStack PROC C PUBLIC
+ ; Save current contexts
+ push eax
+ pushfd
+ cli
+ pushad
+ sub esp, 8
+ sidt fword ptr [esp]
+
+ ; Load new stack
+ push esp
+ call SwapStack
+ mov esp, eax
+
+ ; Restore previous contexts
+ lidt fword ptr [esp]
+ add esp, 8
+ popad
+ popfd
+ add esp, 4
+ ret
+FspSwitchStack ENDP
+
+ END
diff --git a/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/Ia32/Stack.s b/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/Ia32/Stack.s new file mode 100644 index 0000000000..a21a5b6c61 --- /dev/null +++ b/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/Ia32/Stack.s @@ -0,0 +1,78 @@ +#------------------------------------------------------------------------------
+#
+# Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.<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.
+#
+#------------------------------------------------------------------------------
+
+
+#------------------------------------------------------------------------------
+# UINT32
+# EFIAPI
+# Pei2LoaderSwitchStack (
+# VOID
+# )
+#------------------------------------------------------------------------------
+ASM_GLOBAL ASM_PFX(Pei2LoaderSwitchStack)
+ASM_PFX(Pei2LoaderSwitchStack):
+ xorl %eax, %eax
+ jmp ASM_PFX(FspSwitchStack)
+
+#------------------------------------------------------------------------------
+# UINT32
+# EFIAPI
+# Loader2PeiSwitchStack (
+# VOID
+# )
+#------------------------------------------------------------------------------
+ASM_GLOBAL ASM_PFX(Loader2PeiSwitchStack)
+ASM_PFX(Loader2PeiSwitchStack):
+ jmp ASM_PFX(FspSwitchStack)
+
+#------------------------------------------------------------------------------
+# UINT32
+# EFIAPI
+# FspSwitchStack (
+# VOID
+# )
+#------------------------------------------------------------------------------
+ASM_GLOBAL ASM_PFX(FspSwitchStack)
+ASM_PFX(FspSwitchStack):
+ #
+ #Save current contexts
+ #
+ push %eax
+ pushf
+ cli
+ pusha
+ sub $0x08, %esp
+ sidt (%esp)
+
+ #
+ # Load new stack
+ #
+ push %esp
+ call ASM_PFX(SwapStack)
+ movl %eax, %esp
+
+ #
+ # Restore previous contexts
+ #
+ lidt (%esp)
+ add $0x08,%esp
+ popa
+ popf
+ add $0x04,%esp
+ ret
+
+
diff --git a/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/Ia32/Flat32.asm b/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/Ia32/Flat32.asm new file mode 100644 index 0000000000..9f144fc4ca --- /dev/null +++ b/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/Ia32/Flat32.asm @@ -0,0 +1,131 @@ +;; @file
+; This is the code that goes from real-mode to protected mode.
+; It consumes the reset vector, configures the stack.
+;
+; Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<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
+;
+.586p
+.xmm
+.model flat, c
+
+EXTRN TempRamInitApi:NEAR
+
+.code
+
+RET_ESI MACRO
+
+ movd esi, mm7 ; restore ESP from MM7
+ jmp esi
+
+ENDM
+
+;
+; Perform early platform initialization
+;
+SecPlatformInit PROC NEAR PUBLIC
+
+ RET_ESI
+
+SecPlatformInit ENDP
+
+;
+; Protected mode portion initializes stack, configures cache, and calls C entry point
+;
+
+;----------------------------------------------------------------------------
+;
+; Procedure: ProtectedModeEntryPoint
+;
+; Input: Executing in 32 Bit Protected (flat) mode
+; cs: 0-4GB
+; ds: 0-4GB
+; es: 0-4GB
+; fs: 0-4GB
+; gs: 0-4GB
+; ss: 0-4GB
+;
+; Output: This function never returns
+;
+; Destroys:
+; ecx
+; edi
+; esi
+; esp
+;
+; Description:
+; Perform any essential early platform initilaisation
+; Setup a stack
+;
+;----------------------------------------------------------------------------
+
+ProtectedModeEntryPoint PROC NEAR C PUBLIC
+ ;
+ ; Dummy function. Consume 2 API to make sure they can be linked.
+ ;
+ mov eax, TempRamInitApi
+
+ ; Should never return
+ jmp $
+
+ProtectedModeEntryPoint ENDP
+
+;
+; ROM-based Global-Descriptor Table for the PEI Phase
+;
+align 16
+PUBLIC BootGdtTable
+
+;
+; GDT[0]: 0x00: Null entry, never used.
+;
+NULL_SEL equ $ - GDT_BASE ; Selector [0]
+GDT_BASE:
+BootGdtTable DD 0
+ DD 0
+;
+; Linear code segment descriptor
+;
+LINEAR_CODE_SEL equ $ - GDT_BASE ; Selector [0x8]
+ DW 0FFFFh ; limit 0xFFFF
+ DW 0 ; base 0
+ DB 0
+ DB 09Bh ; present, ring 0, data, expand-up, not-writable
+ DB 0CFh ; page-granular, 32-bit
+ DB 0
+;
+; System data segment descriptor
+;
+SYS_DATA_SEL equ $ - GDT_BASE ; Selector [0x10]
+ DW 0FFFFh ; limit 0xFFFF
+ DW 0 ; base 0
+ DB 0
+ DB 093h ; present, ring 0, data, expand-up, not-writable
+ DB 0CFh ; page-granular, 32-bit
+ DB 0
+
+GDT_SIZE EQU $ - BootGDTtable ; Size, in bytes
+
+;
+; GDT Descriptor
+;
+GdtDesc: ; GDT descriptor
+ DW GDT_SIZE - 1 ; GDT limit
+ DD OFFSET BootGdtTable ; GDT base address
+
+ProtectedModeEntryLinearAddress LABEL FWORD
+ProtectedModeEntryLinearOffset LABEL DWORD
+ DD OFFSET ProtectedModeEntryPoint ; Offset of our 32 bit code
+ DW LINEAR_CODE_SEL
+
+END
diff --git a/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/Ia32/Flat32.s b/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/Ia32/Flat32.s new file mode 100644 index 0000000000..d46d792477 --- /dev/null +++ b/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/Ia32/Flat32.s @@ -0,0 +1,110 @@ +#------------------------------------------------------------------------------
+#
+# Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<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:
+#
+# This is the code that goes from real-mode to protected mode.
+# It consumes the reset vector, configures the stack.
+#
+#------------------------------------------------------------------------------
+
+
+#
+# Contrary to the name, this file contains 16 bit code as well.
+#
+.text
+
+ASM_GLOBAL ASM_PFX(SecPlatformInit)
+ASM_PFX(SecPlatformInit):
+ movd %mm7, %esi # restore ESP from MM7
+ jmp *%esi
+
+#----------------------------------------------------------------------------
+#
+# Procedure: ProtectedModeEntryPoint
+#
+# Input: Executing in 32 Bit Protected (flat) mode
+# cs: 0-4GB
+# ds: 0-4GB
+# es: 0-4GB
+# fs: 0-4GB
+# gs: 0-4GB
+# ss: 0-4GB
+#
+# Output: This function never returns
+#
+# Destroys:
+# ecx
+# edi
+# esi
+# esp
+#
+# Description:
+# Perform any essential early platform initilaisation
+# Setup a stack
+#
+#----------------------------------------------------------------------------
+ProtectedModeEntryPoint:
+ #
+ # Dummy function. Consume 2 API to make sure they can be linked.
+ #
+ movl ASM_PFX(TempRamInitApi), %eax
+ #
+ # Should never return
+ #
+ jmp . #'$'
+
+#
+# ROM-based Global-Descriptor Table for the PEI Phase
+#
+.align 16
+#
+# GDT[0]: 000h: Null entry, never used.
+#
+.equ NULL_SEL, . - GDT_BASE # Selector [0]
+GDT_BASE:
+BootGdtTable:
+ .long 0
+ .long 0
+#
+# Linear code segment descriptor
+#
+.equ LINEAR_CODE_SEL, . - GDT_BASE # Selector [08h]
+ .word 0xFFFF # limit 0FFFFh
+ .word 0 # base 0
+ .byte 0
+ .byte 0x9B # present, ring 0, data, expand-up, not-writable
+ .byte 0xCF # page-granular, 32-bit
+ .byte 0
+#
+# System data segment descriptor
+#
+.equ SYS_DATA_SEL, . - GDT_BASE # Selector [010h]
+ .word 0xFFFF # limit 0FFFFh
+ .word 0 # base 0
+ .byte 0
+ .byte 0x93 # present, ring 0, data, expand-up, not-writable
+ .byte 0xCF # page-granular, 32-bit
+ .byte 0
+
+.equ GDT_SIZE, . - BootGdtTable # Size, in bytes
+
+#
+# GDT Descriptor
+#
+GdtDesc: # GDT descriptor
+ .word GDT_SIZE - 1
+ .long BootGdtTable
+
+ProtectedModeEntryLinearAddress:
+ProtectedModeEntryLinearOffset:
+ .long ProtectedModeEntryPoint
+ .word LINEAR_CODE_SEL
diff --git a/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/Ia32/SecCarInit.asm b/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/Ia32/SecCarInit.asm new file mode 100644 index 0000000000..31296e0043 --- /dev/null +++ b/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/Ia32/SecCarInit.asm @@ -0,0 +1,51 @@ +;; @file
+; SEC CAR function
+;
+; Copyright (c) 2015, Intel Corporation. All rights reserved.<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
+;
+.586p
+.xmm
+.model flat, c
+
+RET_ESI MACRO
+
+ movd esi, mm7 ; move ReturnAddress from MM7 to ESI
+ jmp esi
+
+ENDM
+
+.code
+
+;-----------------------------------------------------------------------------
+;
+; Section: SecCarInit
+;
+; Description: This function initializes the Cache for Data, Stack, and Code
+;
+;-----------------------------------------------------------------------------
+SecCarInit PROC NEAR PUBLIC
+
+ ;
+ ; Set up CAR
+ ;
+
+ xor eax, eax
+
+SecCarInitExit:
+
+ RET_ESI
+
+SecCarInit ENDP
+
+END
diff --git a/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/Ia32/SecCarInit.s b/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/Ia32/SecCarInit.s new file mode 100644 index 0000000000..7bd40df36a --- /dev/null +++ b/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/Ia32/SecCarInit.s @@ -0,0 +1,37 @@ +#------------------------------------------------------------------------------
+#
+# Copyright (c) 2015, Intel Corporation. All rights reserved.<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:
+#
+# SEC CAR function
+#
+#------------------------------------------------------------------------------
+
+#-----------------------------------------------------------------------------
+#
+# Section: SecCarInit
+#
+# Description: This function initializes the Cache for Data, Stack, and Code
+#
+#-----------------------------------------------------------------------------
+ASM_GLOBAL ASM_PFX(SecCarInit)
+ASM_PFX(SecCarInit):
+
+ #
+ # Set up CAR
+ #
+
+ xor %eax, %eax
+
+SecCarInitExit:
+
+ movd %mm7, %esi #RET_ESI
+ jmp *%esi
diff --git a/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/PlatformSecLibNull.c b/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/PlatformSecLibNull.c new file mode 100644 index 0000000000..7bb95a9054 --- /dev/null +++ b/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/PlatformSecLibNull.c @@ -0,0 +1,33 @@ +/** @file
+ Null instance of Platform Sec Lib.
+
+ Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<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/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/SecFspSecPlatformLibNull.inf b/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/SecFspSecPlatformLibNull.inf new file mode 100644 index 0000000000..1c18a587c3 --- /dev/null +++ b/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/SecFspSecPlatformLibNull.inf @@ -0,0 +1,58 @@ +## @file
+# NULL instance of Platform Sec Lib.
+#
+# Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.<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.asm
+ Ia32/Flat32.s
+ Ia32/SecCarInit.asm
+ Ia32/SecCarInit.s
+
+################################################################################
+#
+# Package Dependency Section - list of Package files that are required for
+# this module.
+#
+################################################################################
+
+[Packages]
+ MdePkg/MdePkg.dec
+ IntelFsp2Pkg/IntelFsp2Pkg.dec
diff --git a/IntelFsp2Pkg/Tools/GenCfgOpt.py b/IntelFsp2Pkg/Tools/GenCfgOpt.py new file mode 100644 index 0000000000..4fd0562e75 --- /dev/null +++ b/IntelFsp2Pkg/Tools/GenCfgOpt.py @@ -0,0 +1,1465 @@ +## @ GenCfgOpt.py
+#
+# Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<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._CfgBlkDict = {}
+ self._CfgPageDict = {}
+ self._CfgItemList = []
+ self._DscFile = ''
+ self._FvDir = ''
+ self._MapVer = 0
+
+ def ParseBuildMode (self, OutputStr):
+ if "RELEASE_" in OutputStr:
+ self.ReleaseMode = True
+ if "DEBUG_" in OutputStr:
+ self.ReleaseMode = False
+ return
+
+ def ParseMacros (self, MacroDefStr):
+ # ['-DABC=1', '-D', 'CFG_DEBUG=1', '-D', 'CFG_OUTDIR=Build']
+ self._MacroDict = {}
+ IsExpression = False
+ for Macro in MacroDefStr:
+ if Macro.startswith('-D'):
+ IsExpression = True
+ if len(Macro) > 2:
+ Macro = Macro[2:]
+ else :
+ continue
+ if IsExpression:
+ IsExpression = False
+ Match = re.match("(\w+)=(.+)", Macro)
+ if Match:
+ self._MacroDict[Match.group(1)] = Match.group(2)
+ else:
+ Match = re.match("(\w+)", Macro)
+ if Match:
+ self._MacroDict[Match.group(1)] = ''
+ if len(self._MacroDict) == 0:
+ Error = 1
+ else:
+ Error = 0
+ if self.Debug:
+ print "INFO : Macro dictionary:"
+ for Each in self._MacroDict:
+ print " $(%s) = [ %s ]" % (Each , self._MacroDict[Each])
+ return Error
+
+ def EvaulateIfdef (self, Macro):
+ Result = Macro in self._MacroDict
+ if self.Debug:
+ print "INFO : Eval Ifdef [%s] : %s" % (Macro, Result)
+ return Result
+
+ def ExpandMacros (self, Input):
+ Line = Input
+ Match = re.findall("\$\(\w+\)", Input)
+ if Match:
+ for Each in Match:
+ Variable = Each[2:-1]
+ if Variable in self._MacroDict:
+ Line = Line.replace(Each, self._MacroDict[Variable])
+ else:
+ if self.Debug:
+ print "WARN : %s is not defined" % Each
+ Line = Line.replace(Each, Each[2:-1])
+ return Line
+
+ def EvaluateExpress (self, Expr):
+ ExpExpr = self.ExpandMacros(Expr)
+ LogExpr = CLogicalExpression()
+ Result = LogExpr.evaluateExpress (ExpExpr)
+ if self.Debug:
+ print "INFO : Eval Express [%s] : %s" % (Expr, Result)
+ return Result
+
+ def FormatListValue(self, ConfigDict):
+ Struct = ConfigDict['struct']
+ if Struct not in ['UINT8','UINT16','UINT32','UINT64']:
+ return
+
+ dataarray = []
+ binlist = ConfigDict['value'][1:-1].split(',')
+ for each in binlist:
+ each = each.strip()
+ if each.startswith('0x'):
+ value = int(each, 16)
+ else:
+ value = int(each)
+ dataarray.append(value)
+
+ unit = int(Struct[4:]) / 8
+ if int(ConfigDict['length']) != unit * len(dataarray):
+ raise Exception("Array size is not proper for '%s' !" % ConfigDict['cname'])
+
+ bytearray = []
+ for each in dataarray:
+ value = each
+ for loop in xrange(unit):
+ bytearray.append("0x%02X" % (value & 0xFF))
+ value = value >> 8
+ newvalue = '{' + ','.join(bytearray) + '}'
+ ConfigDict['value'] = newvalue
+ return ""
+
+ def ParseDscFile (self, DscFile, FvDir, ConfigDscFile, ExtConfigDscFile):
+ self._CfgItemList = []
+ self._CfgPageDict = {}
+ self._CfgBlkDict = {}
+ self._DscFile = DscFile
+ self._FvDir = FvDir
+
+ IsDefSect = False
+ IsUpdSect = False
+ IsVpdSect = False
+ Found = False
+
+ IfStack = []
+ ElifStack = []
+ Error = 0
+ ConfigDict = {}
+
+ DscFd = open(DscFile, "r")
+ DscLines = DscFd.readlines()
+ DscFd.close()
+
+ while len(DscLines):
+ DscLine = DscLines.pop(0).strip()
+ Handle = False
+ Match = re.match("^\[(.+)\]", DscLine)
+ if Match is not None:
+ if Match.group(1).lower() == "Defines".lower():
+ IsDefSect = True
+ IsVpdSect = False
+ IsUpdSect = False
+ elif Match.group(1).lower() == "PcdsDynamicVpd.Upd".lower():
+ ConfigDict = {}
+ ConfigDict['header'] = 'ON'
+ ConfigDict['region'] = 'UPD'
+ ConfigDict['order'] = -1
+ ConfigDict['page'] = ''
+ ConfigDict['name'] = ''
+ ConfigDict['find'] = ''
+ ConfigDict['struct'] = ''
+ ConfigDict['embed'] = ''
+ ConfigDict['comment'] = ''
+ ConfigDict['subreg'] = []
+ IsDefSect = False
+ IsUpdSect = True
+ IsVpdSect = False
+ Found = True
+ else:
+ IsDefSect = False
+ IsUpdSect = False
+ IsVpdSect = False
+ else:
+ if IsDefSect or IsUpdSect or IsVpdSect:
+ if re.match("^!else($|\s+#.+)", DscLine):
+ if IfStack:
+ IfStack[-1] = not IfStack[-1]
+ else:
+ print("ERROR: No paired '!if' found for '!else' for line '%s'" % DscLine)
+ raise SystemExit
+ elif re.match("^!endif($|\s+#.+)", DscLine):
+ if IfStack:
+ IfStack.pop()
+ Level = ElifStack.pop()
+ if Level > 0:
+ del IfStack[-Level:]
+ else:
+ print("ERROR: No paired '!if' found for '!endif' for line '%s'" % DscLine)
+ raise SystemExit
+ else:
+ Result = False
+ Match = re.match("!(ifdef|ifndef)\s+(.+)", DscLine)
+ if Match:
+ Result = self.EvaulateIfdef (Match.group(2))
+ if Match.group(1) == 'ifndef':
+ Result = not Result
+ IfStack.append(Result)
+ ElifStack.append(0)
+ else:
+ Match = re.match("!(if|elseif)\s+(.+)", DscLine)
+ if Match:
+ IsFoundInFile = False
+ MatchPcdFormat = re.match("^\s*(.+)\.(.+)\s*==\s*(.+)", Match.group(2))
+ if MatchPcdFormat:
+ ExtConfigDsc = open(ExtConfigDscFile, "r")
+ ExtConfigDscLines = ExtConfigDsc.readlines()
+ ExtConfigDsc.close()
+
+ while len(ExtConfigDscLines):
+ ExtConfigDscLine = ExtConfigDscLines.pop(0).strip()
+ MatchExtConfigPcd = re.match("^\s*(.+)\s*\|\s*(.+)", ExtConfigDscLine)
+ if MatchExtConfigPcd and IsFoundInFile == False:
+ PcdFormatStr = str(str(MatchPcdFormat.group(1)) + "." + str(MatchPcdFormat.group(2)))
+ ExtConfigPcd = str(MatchExtConfigPcd.group(1))
+ Result = False
+ if PcdFormatStr.strip() == ExtConfigPcd.strip():
+ Result = self.EvaluateExpress(str(str(MatchExtConfigPcd.group(2)) + " == " + str(MatchPcdFormat.group(3))))
+ IsFoundInFile = True
+ break
+ if IsFoundInFile == False:
+ ConfigDsc = open(ConfigDscFile, "r")
+ ConfigDscLines = ConfigDsc.readlines()
+ ConfigDsc.close()
+ while len(ConfigDscLines):
+ ConfigDscLine = ConfigDscLines.pop(0).strip()
+ MatchConfigPcd = re.match("^\s*(.+)\s*\|\s*(.+)", ConfigDscLine)
+ if MatchConfigPcd:
+ PcdFormatStr = str(str(MatchPcdFormat.group(1)) + "." + str(MatchPcdFormat.group(2)))
+ ConfigPcd = str(MatchConfigPcd.group(1))
+ Result = False
+ if PcdFormatStr.strip() == ConfigPcd.strip():
+ Result = self.EvaluateExpress(str(str(MatchConfigPcd.group(2)) + " == " + str(MatchPcdFormat.group(3))))
+ IsFoundInFile = True
+ break
+ else:
+ Result = self.EvaluateExpress(Match.group(2))
+ if Match.group(1) == "if":
+ ElifStack.append(0)
+ IfStack.append(Result)
+ else: #elseif
+ if IfStack:
+ IfStack[-1] = not IfStack[-1]
+ IfStack.append(Result)
+ ElifStack[-1] = ElifStack[-1] + 1
+ else:
+ print("ERROR: No paired '!if' found for '!elif' for line '%s'" % DscLine)
+ raise SystemExit
+ else:
+ if IfStack:
+ Handle = reduce(lambda x,y: x and y, IfStack)
+ else:
+ Handle = True
+ if Handle:
+ Match = re.match("!include\s+(.+)", DscLine)
+ if Match:
+ IncludeFilePath = Match.group(1)
+ IncludeFilePath = self.ExpandMacros(IncludeFilePath)
+ try:
+ IncludeDsc = open(IncludeFilePath, "r")
+ except:
+ print("ERROR: Cannot open file '%s'" % IncludeFilePath)
+ raise SystemExit
+ NewDscLines = IncludeDsc.readlines()
+ IncludeDsc.close()
+ DscLines = NewDscLines + DscLines
+ else:
+ if DscLine.startswith('!'):
+ print("ERROR: Unrecoginized directive for line '%s'" % DscLine)
+ raise SystemExit
+ if not Handle:
+ continue
+
+ if IsDefSect:
+ #DEFINE UPD_TOOL_GUID = 8C3D856A-9BE6-468E-850A-24F7A8D38E09
+ #DEFINE FSP_T_UPD_TOOL_GUID = 34686CA3-34F9-4901-B82A-BA630F0714C6
+ #DEFINE FSP_M_UPD_TOOL_GUID = 39A250DB-E465-4DD1-A2AC-E2BD3C0E2385
+ #DEFINE FSP_S_UPD_TOOL_GUID = CAE3605B-5B34-4C85-B3D7-27D54273C40F
+ Match = re.match("^\s*(?:DEFINE\s+)*(\w+)\s*=\s*([-.\w]+)", DscLine)
+ if Match:
+ self._MacroDict[Match.group(1)] = Match.group(2)
+ if self.Debug:
+ print "INFO : DEFINE %s = [ %s ]" % (Match.group(1), Match.group(2))
+ else:
+ Match = re.match("^\s*#\s+(!BSF|@Bsf|!HDR)\s+(.+)", DscLine)
+ if Match:
+ Remaining = Match.group(2)
+ if Match.group(1) == '!BSF' or Match.group(1) == '@Bsf':
+ Match = re.match("(?:^|.+\s+)PAGES:{(.+?)}", Remaining)
+ if Match:
+ # !BSF PAGES:{HSW:"Haswell System Agent", LPT:"Lynx Point PCH"}
+ PageList = Match.group(1).split(',')
+ for Page in PageList:
+ Page = Page.strip()
+ Match = re.match("(\w+):\"(.+)\"", Page)
+ self._CfgPageDict[Match.group(1)] = Match.group(2)
+
+ Match = re.match("(?:^|.+\s+)BLOCK:{NAME:\"(.+)\"\s*,\s*VER:\"(.+)\"\s*}", Remaining)
+ if Match:
+ self._CfgBlkDict['name'] = Match.group(1)
+ self._CfgBlkDict['ver'] = Match.group(2)
+
+ for Key in self._BsfKeyList:
+ Match = re.match("(?:^|.+\s+)%s:{(.+?)}" % Key, Remaining)
+ if Match:
+ if Key in ['NAME', 'HELP', 'OPTION'] and Match.group(1).startswith('+'):
+ ConfigDict[Key.lower()] += Match.group(1)[1:]
+ else:
+ ConfigDict[Key.lower()] = Match.group(1)
+ else:
+ for Key in self._HdrKeyList:
+ Match = re.match("(?:^|.+\s+)%s:{(.+?)}" % Key, Remaining)
+ if Match:
+ ConfigDict[Key.lower()] = Match.group(1)
+
+ Match = re.match("^\s*#\s+@Prompt\s+(.+)", DscLine)
+ if Match:
+ ConfigDict['name'] = Match.group(1)
+
+ Match = re.match("^\s*#\s*@ValidList\s*(.+)\s*\|\s*(.+)\s*\|\s*(.+)\s*", DscLine)
+ if Match:
+ if Match.group(2).strip() in self._BuidinOption:
+ ConfigDict['option'] = Match.group(2).strip()
+ else:
+ OptionValueList = Match.group(2).split(',')
+ OptionStringList = Match.group(3).split(',')
+ Index = 0
+ for Option in OptionValueList:
+ Option = Option.strip()
+ ConfigDict['option'] = ConfigDict['option'] + str(Option) + ':' + OptionStringList[Index].strip()
+ Index += 1
+ if Index in range(len(OptionValueList)):
+ ConfigDict['option'] += ', '
+ ConfigDict['type'] = "Combo"
+
+ Match = re.match("^\s*#\s*@ValidRange\s*(.+)\s*\|\s*(.+)\s*-\s*(.+)\s*", DscLine)
+ if Match:
+ if "0x" in Match.group(2) or "0x" in Match.group(3):
+ ConfigDict['type'] = "EditNum, HEX, (%s,%s)" % (Match.group(2), Match.group(3))
+ else:
+ ConfigDict['type'] = "EditNum, DEC, (%s,%s)" % (Match.group(2), Match.group(3))
+
+ Match = re.match("^\s*##\s+(.+)", DscLine)
+ if Match:
+ ConfigDict['help'] = Match.group(1)
+
+ # Check VPD/UPD
+ if IsUpdSect:
+ Match = re.match("^([_a-zA-Z0-9]+).([_a-zA-Z0-9]+)\s*\|\s*(0x[0-9A-F]+)\s*\|\s*(\d+|0x[0-9a-fA-F]+)\s*\|\s*(.+)",DscLine)
+ else:
+ Match = re.match("^([_a-zA-Z0-9]+).([_a-zA-Z0-9]+)\s*\|\s*(0x[0-9A-F]+)(?:\s*\|\s*(.+))?", DscLine)
+ if Match:
+ ConfigDict['space'] = Match.group(1)
+ ConfigDict['cname'] = Match.group(2)
+ ConfigDict['offset'] = int (Match.group(3), 16)
+ if ConfigDict['order'] == -1:
+ ConfigDict['order'] = ConfigDict['offset'] << 8
+ else:
+ (Major, Minor) = ConfigDict['order'].split('.')
+ ConfigDict['order'] = (int (Major, 16) << 8 ) + int (Minor, 16)
+ if IsUpdSect:
+ Value = Match.group(5).strip()
+ if Match.group(4).startswith("0x"):
+ Length = int (Match.group(4), 16)
+ else :
+ Length = int (Match.group(4))
+ else:
+ Value = Match.group(4)
+ if Value is None:
+ Value = ''
+ Value = Value.strip()
+ if '|' in Value:
+ Match = re.match("^.+\s*\|\s*(.+)", Value)
+ if Match:
+ Value = Match.group(1)
+ Length = -1
+
+ ConfigDict['length'] = Length
+ Match = re.match("\$\((\w+)\)", Value)
+ if Match:
+ if Match.group(1) in self._MacroDict:
+ Value = self._MacroDict[Match.group(1)]
+
+ ConfigDict['value'] = Value
+ if (len(Value) > 0) and (Value[0] == '{'):
+ Value = self.FormatListValue(ConfigDict)
+
+ if ConfigDict['name'] == '':
+ # Clear BSF specific items
+ ConfigDict['bsfname'] = ''
+ ConfigDict['help'] = ''
+ ConfigDict['type'] = ''
+ ConfigDict['option'] = ''
+
+ self._CfgItemList.append(ConfigDict.copy())
+ ConfigDict['name'] = ''
+ ConfigDict['find'] = ''
+ ConfigDict['struct'] = ''
+ ConfigDict['embed'] = ''
+ ConfigDict['comment'] = ''
+ ConfigDict['order'] = -1
+ ConfigDict['subreg'] = []
+ ConfigDict['option'] = ''
+ else:
+ # It could be a virtual item as below
+ # !BSF FIELD:{1:SerialDebugPortAddress0}
+ # or
+ # @Bsf FIELD:{1:SerialDebugPortAddress0}
+ Match = re.match("^\s*#\s+(!BSF|@Bsf)\s+FIELD:{(.+):(\d+)}", DscLine)
+ if Match:
+ SubCfgDict = ConfigDict
+ SubCfgDict['cname'] = Match.group(2)
+ SubCfgDict['length'] = int (Match.group(3))
+ if SubCfgDict['length'] > 0:
+ LastItem = self._CfgItemList[-1]
+ if len(LastItem['subreg']) == 0:
+ SubOffset = 0
+ else:
+ SubOffset += LastItem['subreg'][-1]['length']
+ SubCfgDict['offset'] = SubOffset
+ LastItem['subreg'].append (SubCfgDict.copy())
+ ConfigDict['name'] = ''
+ return Error
+
+ def UpdateSubRegionDefaultValue (self):
+ Error = 0
+ for Item in self._CfgItemList:
+ if len(Item['subreg']) == 0:
+ continue
+ bytearray = []
+ if Item['value'][0] == '{':
+ binlist = Item['value'][1:-1].split(',')
+ for each in binlist:
+ each = each.strip()
+ if each.startswith('0x'):
+ value = int(each, 16)
+ else:
+ value = int(each)
+ bytearray.append(value)
+ else:
+ if Item['value'].startswith('0x'):
+ value = int(Item['value'], 16)
+ else:
+ value = int(Item['value'])
+ idx = 0;
+ while idx < Item['length']:
+ bytearray.append(value & 0xFF)
+ value = value >> 8
+ idx = idx + 1
+ for SubItem in Item['subreg']:
+ if SubItem['length'] in (1,2,4,8):
+ valuelist = [b for b in bytearray[SubItem['offset']:SubItem['offset']+SubItem['length']]]
+ valuelist.reverse()
+ valuestr = "".join('%02X' % b for b in valuelist)
+ SubItem['value'] = '0x%s' % valuestr
+ else:
+ valuestr = ",".join('0x%02X' % b for b in bytearray[SubItem['offset']:SubItem['offset']+SubItem['length']])
+ SubItem['value'] = '{%s}' % valuestr
+ return Error
+
+ def CreateSplitUpdTxt (self, UpdTxtFile):
+ GuidList = ['FSP_T_UPD_TOOL_GUID','FSP_M_UPD_TOOL_GUID','FSP_S_UPD_TOOL_GUID']
+ SignatureList = ['0x545F', '0x4D5F','0x535F'] # _T, _M, and _S signature for FSPT, FSPM, FSPS
+ for Index in range(len(GuidList)):
+ UpdTxtFile = ''
+ FvDir = self._FvDir
+ if GuidList[Index] not in self._MacroDict:
+ self.Error = "%s definition is missing in DSC file" % (GuidList[Index])
+ return 1
+
+ if UpdTxtFile == '':
+ UpdTxtFile = os.path.join(FvDir, self._MacroDict[GuidList[Index]] + '.txt')
+
+ ReCreate = False
+ if not os.path.exists(UpdTxtFile):
+ ReCreate = True
+ else:
+ DscTime = os.path.getmtime(self._DscFile)
+ TxtTime = os.path.getmtime(UpdTxtFile)
+ if DscTime > TxtTime:
+ ReCreate = True
+
+ if not ReCreate:
+ # DSC has not been modified yet
+ # So don't have to re-generate other files
+ self.Error = 'No DSC file change, skip to create UPD TXT file'
+ return 256
+
+ TxtFd = open(UpdTxtFile, "w")
+ TxtFd.write("%s\n" % (__copyright_txt__ % date.today().year))
+
+ NextOffset = 0
+ SpaceIdx = 0
+ StartAddr = 0
+ EndAddr = 0
+ Default = 'DEFAULT|'
+ InRange = False
+ for Item in self._CfgItemList:
+ if Item['cname'] == 'Signature' and str(Item['value'])[0:6] == SignatureList[Index]:
+ StartAddr = Item['offset']
+ NextOffset = StartAddr
+ InRange = True
+ if Item['cname'] == 'UpdTerminator' and InRange == True:
+ EndAddr = Item['offset']
+ InRange = False
+ InRange = False
+ for Item in self._CfgItemList:
+ if Item['cname'] == 'Signature' and str(Item['value'])[0:6] == SignatureList[Index]:
+ InRange = True
+ if InRange != True:
+ continue
+ if Item['cname'] == 'UpdTerminator':
+ InRange = False
+ if Item['region'] != 'UPD':
+ continue
+ Offset = Item['offset']
+ if StartAddr > Offset or EndAddr < Offset:
+ continue
+ if NextOffset < Offset:
+ # insert one line
+ TxtFd.write("%s.UnusedUpdSpace%d|%s0x%04X|0x%04X|{0}\n" % (Item['space'], SpaceIdx, Default, NextOffset - StartAddr, Offset - NextOffset))
+ SpaceIdx = SpaceIdx + 1
+ NextOffset = Offset + Item['length']
+ if Item['cname'] == 'PcdSerialIoUartDebugEnable':
+ if self.ReleaseMode == False:
+ Item['value'] = 0x01
+ TxtFd.write("%s.%s|%s0x%04X|%s|%s\n" % (Item['space'],Item['cname'],Default,Item['offset'] - StartAddr,Item['length'],Item['value']))
+ TxtFd.close()
+ return 0
+
+ def ProcessMultilines (self, String, MaxCharLength):
+ Multilines = ''
+ StringLength = len(String)
+ CurrentStringStart = 0
+ StringOffset = 0
+ BreakLineDict = []
+ if len(String) <= MaxCharLength:
+ while (StringOffset < StringLength):
+ if StringOffset >= 1:
+ if String[StringOffset - 1] == '\\' and String[StringOffset] == 'n':
+ BreakLineDict.append (StringOffset + 1)
+ StringOffset += 1
+ if BreakLineDict != []:
+ for Each in BreakLineDict:
+ Multilines += " %s\n" % String[CurrentStringStart:Each].lstrip()
+ CurrentStringStart = Each
+ if StringLength - CurrentStringStart > 0:
+ Multilines += " %s\n" % String[CurrentStringStart:].lstrip()
+ else:
+ Multilines = " %s\n" % String
+ else:
+ NewLineStart = 0
+ NewLineCount = 0
+ FoundSpaceChar = False
+ while (StringOffset < StringLength):
+ if StringOffset >= 1:
+ if NewLineCount >= MaxCharLength - 1:
+ if String[StringOffset] == ' ' and StringLength - StringOffset > 10:
+ BreakLineDict.append (NewLineStart + NewLineCount)
+ NewLineStart = NewLineStart + NewLineCount
+ NewLineCount = 0
+ FoundSpaceChar = True
+ elif StringOffset == StringLength - 1 and FoundSpaceChar == False:
+ BreakLineDict.append (0)
+ if String[StringOffset - 1] == '\\' and String[StringOffset] == 'n':
+ BreakLineDict.append (StringOffset + 1)
+ NewLineStart = StringOffset + 1
+ NewLineCount = 0
+ StringOffset += 1
+ NewLineCount += 1
+ if BreakLineDict != []:
+ BreakLineDict.sort ()
+ for Each in BreakLineDict:
+ if Each > 0:
+ Multilines += " %s\n" % String[CurrentStringStart:Each].lstrip()
+ CurrentStringStart = Each
+ if StringLength - CurrentStringStart > 0:
+ Multilines += " %s\n" % String[CurrentStringStart:].lstrip()
+ return Multilines
+
+ def CreateField (self, Item, Name, Length, Offset, Struct, BsfName, Help, Option):
+ PosName = 28
+ PosComment = 30
+ NameLine=''
+ HelpLine=''
+ OptionLine=''
+
+ IsArray = False
+ if Length in [1,2,4,8]:
+ Type = "UINT%d" % (Length * 8)
+ else:
+ IsArray = True
+ Type = "UINT8"
+
+ if Item and Item['value'].startswith('{'):
+ Type = "UINT8"
+ IsArray = True
+
+ if Struct != '':
+ Type = Struct
+ if Struct in ['UINT8','UINT16','UINT32','UINT64']:
+ IsArray = True
+ Unit = int(Type[4:]) / 8
+ Length = Length / Unit
+ else:
+ IsArray = False
+
+ if IsArray:
+ Name = Name + '[%d]' % Length
+
+ if len(Type) < PosName:
+ Space1 = PosName - len(Type)
+ else:
+ Space1 = 1
+
+ if BsfName != '':
+ NameLine=" - %s\n" % BsfName
+ else:
+ NameLine="\n"
+
+ if Help != '':
+ HelpLine = self.ProcessMultilines (Help, 80)
+
+ if Option != '':
+ OptionLine = self.ProcessMultilines (Option, 80)
+
+ if Offset is None:
+ OffsetStr = '????'
+ else:
+ OffsetStr = '0x%04X' % Offset
+
+ return "\n/** Offset %s%s%s%s**/\n %s%s%s;\n" % (OffsetStr, NameLine, HelpLine, OptionLine, Type, ' ' * Space1, Name,)
+
+ def PostProcessBody (self, TextBody):
+ NewTextBody = []
+ OldTextBody = []
+ IncludeLine = False
+ StructName = ''
+ VariableName = ''
+ IsUpdHdrDefined = False
+ IsUpdHeader = False
+ for Line in TextBody:
+ SplitToLines = Line.splitlines()
+ MatchComment = re.match("^/\*\sCOMMENT:(\w+):([\w|\W|\s]+)\s\*/\s([\s\S]*)", SplitToLines[0])
+ if MatchComment:
+ if MatchComment.group(1) == 'FSP_UPD_HEADER':
+ IsUpdHeader = True
+ else:
+ IsUpdHeader = False
+ if IsUpdHdrDefined != True or IsUpdHeader != True:
+ CommentLine = " " + MatchComment.group(2) + "\n"
+ NewTextBody.append("/**" + CommentLine + "**/\n")
+ Line = Line[(len(SplitToLines[0]) + 1):]
+
+ Match = re.match("^/\*\sEMBED_STRUCT:(\w+):(\w+):(START|END)\s\*/\s([\s\S]*)", Line)
+ if Match:
+ Line = Match.group(4)
+ if Match.group(1) == 'FSP_UPD_HEADER':
+ IsUpdHeader = True
+ else:
+ IsUpdHeader = False
+
+ if Match and Match.group(3) == 'START':
+ if IsUpdHdrDefined != True or IsUpdHeader != True:
+ NewTextBody.append ('typedef struct {\n')
+ StructName = Match.group(1)
+ VariableName = Match.group(2)
+ MatchOffset = re.search('/\*\*\sOffset\s0x([a-fA-F0-9]+)', Line)
+ if MatchOffset:
+ Offset = int(MatchOffset.group(1), 16)
+ else:
+ Offset = None
+ Line
+ IncludeLine = True
+ OldTextBody.append (self.CreateField (None, VariableName, 0, Offset, StructName, '', '', ''))
+ if IncludeLine:
+ if IsUpdHdrDefined != True or IsUpdHeader != True:
+ NewTextBody.append (Line)
+ else:
+ OldTextBody.append (Line)
+
+ if Match and Match.group(3) == 'END':
+ if (StructName != Match.group(1)) or (VariableName != Match.group(2)):
+ print "Unmatched struct name '%s' and '%s' !" % (StructName, Match.group(1))
+ else:
+ if IsUpdHdrDefined != True or IsUpdHeader != True:
+ NewTextBody.append ('} %s;\n\n' % StructName)
+ IsUpdHdrDefined = True
+ IncludeLine = False
+ NewTextBody.extend(OldTextBody)
+ return NewTextBody
+
+ def CreateHeaderFile (self, InputHeaderFile):
+ FvDir = self._FvDir
+
+ HeaderFileName = 'FspUpd.h'
+ HeaderFile = os.path.join(FvDir, HeaderFileName)
+
+ # Check if header needs to be recreated
+ ReCreate = False
+
+ TxtBody = []
+ for Item in self._CfgItemList:
+ if str(Item['cname']) == 'Signature' and Item['length'] == 8:
+ Value = int(Item['value'], 16)
+ Chars = []
+ while Value != 0x0:
+ Chars.append(chr(Value & 0xFF))
+ Value = Value >> 8
+ SignatureStr = ''.join(Chars)
+ # Signature will be _T / _M / _S for FSPT / FSPM / FSPS accordingly
+ if '_T' in SignatureStr[6:6+2]:
+ TxtBody.append("#define FSPT_UPD_SIGNATURE %s /* '%s' */\n\n" % (Item['value'], SignatureStr))
+ elif '_M' in SignatureStr[6:6+2]:
+ TxtBody.append("#define FSPM_UPD_SIGNATURE %s /* '%s' */\n\n" % (Item['value'], SignatureStr))
+ elif '_S' in SignatureStr[6:6+2]:
+ TxtBody.append("#define FSPS_UPD_SIGNATURE %s /* '%s' */\n\n" % (Item['value'], SignatureStr))
+ TxtBody.append("\n")
+
+ for Region in ['UPD']:
+ UpdOffsetTable = []
+ UpdSignature = ['0x545F', '0x4D5F', '0x535F'] #['_T', '_M', '_S'] signature for FSPT, FSPM, FSPS
+ UpdStructure = ['FSPT_UPD', 'FSPM_UPD', 'FSPS_UPD']
+ for Item in self._CfgItemList:
+ if Item["cname"] == 'Signature' and Item["value"][0:6] in UpdSignature:
+ UpdOffsetTable.append (Item["offset"])
+
+ for UpdIdx in range(len(UpdOffsetTable)):
+ CommentLine = ""
+ for Item in self._CfgItemList:
+ if Item["comment"] != '' and Item["offset"] >= UpdOffsetTable[UpdIdx]:
+ MatchComment = re.match("^(U|V)PD_DATA_REGION:([\w|\W|\s]+)", Item["comment"])
+ if MatchComment and MatchComment.group(1) == Region[0]:
+ CommentLine = " " + MatchComment.group(2) + "\n"
+ TxtBody.append("/**" + CommentLine + "**/\n")
+ elif Item["offset"] >= UpdOffsetTable[UpdIdx] and Item["comment"] == '':
+ Match = re.match("^FSP([\w|\W|\s])_UPD", UpdStructure[UpdIdx])
+ if Match:
+ TxtBody.append("/** Fsp " + Match.group(1) + " UPD Configuration\n**/\n")
+ TxtBody.append("typedef struct {\n")
+ NextOffset = 0
+ SpaceIdx = 0
+ Offset = 0
+
+ LastVisible = True
+ ResvOffset = 0
+ ResvIdx = 0
+ LineBuffer = []
+ InRange = False
+ for Item in self._CfgItemList:
+ if Item['cname'] == 'Signature' and str(Item['value'])[0:6] == UpdSignature[UpdIdx] or Region[0] == 'V':
+ InRange = True
+ if InRange != True:
+ continue
+ if Item['cname'] == 'UpdTerminator':
+ InRange = False
+
+ if Item['region'] != Region:
+ continue
+
+ if Item["offset"] < UpdOffsetTable[UpdIdx]:
+ continue
+
+ NextVisible = LastVisible
+
+ if LastVisible and (Item['header'] == 'OFF'):
+ NextVisible = False
+ ResvOffset = Item['offset']
+ elif (not LastVisible) and Item['header'] == 'ON':
+ NextVisible = True
+ Name = "Reserved" + Region[0] + "pdSpace%d" % ResvIdx
+ ResvIdx = ResvIdx + 1
+ TxtBody.append(self.CreateField (Item, Name, Item["offset"] - ResvOffset, ResvOffset, '', '', '', ''))
+
+ if Offset < Item["offset"]:
+ if LastVisible:
+ Name = "Unused" + Region[0] + "pdSpace%d" % SpaceIdx
+ LineBuffer.append(self.CreateField (Item, Name, Item["offset"] - Offset, Offset, '', '', '', ''))
+ SpaceIdx = SpaceIdx + 1
+ Offset = Item["offset"]
+
+ LastVisible = NextVisible
+
+ Offset = Offset + Item["length"]
+ if LastVisible:
+ for Each in LineBuffer:
+ TxtBody.append (Each)
+ LineBuffer = []
+ Comment = Item["comment"]
+ Embed = Item["embed"].upper()
+ if Embed.endswith(':START') or Embed.endswith(':END'):
+ if not Comment == '' and Embed.endswith(':START'):
+ Marker = '/* COMMENT:%s */ \n' % Item["comment"]
+ Marker = Marker + '/* EMBED_STRUCT:%s */ ' % Item["embed"]
+ else:
+ Marker = '/* EMBED_STRUCT:%s */ ' % Item["embed"]
+ else:
+ if Embed == '':
+ Marker = '';
+ else:
+ self.Error = "Invalid embedded structure format '%s'!\n" % Item["embed"]
+ return 4
+ Line = Marker + self.CreateField (Item, Item["cname"], Item["length"], Item["offset"], Item['struct'], Item['name'], Item['help'], Item['option'])
+ TxtBody.append(Line)
+ if Item['cname'] == 'UpdTerminator':
+ break
+ TxtBody.append("} " + UpdStructure[UpdIdx] + ";\n\n")
+
+ # Handle the embedded data structure
+ TxtBody = self.PostProcessBody (TxtBody)
+
+ HeaderTFileName = 'FsptUpd.h'
+ HeaderMFileName = 'FspmUpd.h'
+ HeaderSFileName = 'FspsUpd.h'
+
+ UpdRegionCheck = ['FSPT', 'FSPM', 'FSPS'] # FSPX_UPD_REGION
+ UpdConfigCheck = ['FSP_T', 'FSP_M', 'FSP_S'] # FSP_X_CONFIG, FSP_X_TEST_CONFIG, FSP_X_RESTRICTED_CONFIG
+ UpdSignatureCheck = ['FSPT_UPD_SIGNATURE', 'FSPM_UPD_SIGNATURE', 'FSPS_UPD_SIGNATURE']
+ ExcludedSpecificUpd = 'FSPM_ARCH_UPD'
+
+ if InputHeaderFile != '':
+ if not os.path.exists(InputHeaderFile):
+ self.Error = "Input header file '%s' does not exist" % InputHeaderFile
+ return 6
+
+ InFd = open(InputHeaderFile, "r")
+ IncLines = InFd.readlines()
+ InFd.close()
+
+ for item in range(len(UpdRegionCheck)):
+ if UpdRegionCheck[item] == 'FSPT':
+ HeaderFd = open(os.path.join(FvDir, HeaderTFileName), "w")
+ FileBase = os.path.basename(os.path.join(FvDir, HeaderTFileName))
+ elif UpdRegionCheck[item] == 'FSPM':
+ HeaderFd = open(os.path.join(FvDir, HeaderMFileName), "w")
+ FileBase = os.path.basename(os.path.join(FvDir, HeaderMFileName))
+ elif UpdRegionCheck[item] == 'FSPS':
+ HeaderFd = open(os.path.join(FvDir, HeaderSFileName), "w")
+ FileBase = os.path.basename(os.path.join(FvDir, HeaderSFileName))
+ FileName = FileBase.replace(".", "_").upper()
+ HeaderFd.write("%s\n" % (__copyright_h__ % date.today().year))
+ HeaderFd.write("#ifndef __%s__\n" % FileName)
+ HeaderFd.write("#define __%s__\n\n" % FileName)
+ HeaderFd.write("#include <%s>\n\n" % HeaderFileName)
+ HeaderFd.write("#pragma pack(push, 1)\n\n")
+
+ Export = False
+ for Line in IncLines:
+ Match = re.search ("!EXPORT\s+([A-Z]+)\s+EXTERNAL_BOOTLOADER_STRUCT_(BEGIN|END)\s+", Line)
+ if Match:
+ if Match.group(2) == "BEGIN" and Match.group(1) == UpdRegionCheck[item]:
+ Export = True
+ continue
+ else:
+ Export = False
+ continue
+ if Export:
+ HeaderFd.write(Line)
+ HeaderFd.write("\n")
+
+ Index = 0
+ StartIndex = 0
+ EndIndex = 0
+ StructStart = []
+ StructStartWithComment = []
+ StructEnd = []
+ for Line in TxtBody:
+ Index += 1
+ Match = re.match("(typedef struct {)", Line)
+ if Match:
+ StartIndex = Index - 1
+ Match = re.match("}\s([_A-Z0-9]+);", Line)
+ if Match and (UpdRegionCheck[item] in Match.group(1) or UpdConfigCheck[item] in Match.group(1)) and (ExcludedSpecificUpd not in Match.group(1)):
+ EndIndex = Index
+ StructStart.append(StartIndex)
+ StructEnd.append(EndIndex)
+ Index = 0
+ for Line in TxtBody:
+ Index += 1
+ for Item in range(len(StructStart)):
+ if Index == StructStart[Item]:
+ Match = re.match("^(/\*\*\s*)", Line)
+ if Match:
+ StructStartWithComment.append(StructStart[Item])
+ else:
+ StructStartWithComment.append(StructStart[Item] + 1)
+ Index = 0
+ for Line in TxtBody:
+ Index += 1
+ for Item in range(len(StructStart)):
+ if Index >= StructStartWithComment[Item] and Index <= StructEnd[Item]:
+ HeaderFd.write (Line)
+ HeaderFd.write("#pragma pack(pop)\n\n")
+ HeaderFd.write("#endif\n")
+ HeaderFd.close()
+
+ HeaderFd = open(HeaderFile, "w")
+ FileBase = os.path.basename(HeaderFile)
+ FileName = FileBase.replace(".", "_").upper()
+ HeaderFd.write("%s\n" % (__copyright_h__ % date.today().year))
+ HeaderFd.write("#ifndef __%s__\n" % FileName)
+ HeaderFd.write("#define __%s__\n\n" % FileName)
+ HeaderFd.write("#include <FspEas.h>\n\n")
+ HeaderFd.write("#pragma pack(push, 1)\n\n")
+
+ for item in range(len(UpdRegionCheck)):
+ Index = 0
+ StartIndex = 0
+ EndIndex = 0
+ StructStart = []
+ StructStartWithComment = []
+ StructEnd = []
+ for Line in TxtBody:
+ Index += 1
+ Match = re.match("(typedef struct {)", Line)
+ if Match:
+ StartIndex = Index - 1
+ Match = re.match("#define\s([_A-Z0-9]+)\s*", Line)
+ if Match and (UpdSignatureCheck[item] in Match.group(1) or UpdSignatureCheck[item] in Match.group(1)):
+ StructStart.append(Index - 1)
+ StructEnd.append(Index)
+ Index = 0
+ for Line in TxtBody:
+ Index += 1
+ for Item in range(len(StructStart)):
+ if Index == StructStart[Item]:
+ Match = re.match("^(/\*\*\s*)", Line)
+ if Match:
+ StructStartWithComment.append(StructStart[Item])
+ else:
+ StructStartWithComment.append(StructStart[Item] + 1)
+ Index = 0
+ for Line in TxtBody:
+ Index += 1
+ for Item in range(len(StructStart)):
+ if Index >= StructStartWithComment[Item] and Index <= StructEnd[Item]:
+ HeaderFd.write (Line)
+ HeaderFd.write("#pragma pack(pop)\n\n")
+ HeaderFd.write("#endif\n")
+ HeaderFd.close()
+
+ return 0
+
+ def WriteBsfStruct (self, BsfFd, Item):
+ if Item['type'] == "None":
+ Space = "gPlatformFspPkgTokenSpaceGuid"
+ else:
+ Space = Item['space']
+ Line = " $%s_%s" % (Space, Item['cname'])
+ Match = re.match("\s*\{([x0-9a-fA-F,\s]+)\}\s*", Item['value'])
+ if Match:
+ DefaultValue = Match.group(1).strip()
+ else:
+ DefaultValue = Item['value'].strip()
+ BsfFd.write(" %s%s%4d bytes $_DEFAULT_ = %s\n" % (Line, ' ' * (64 - len(Line)), Item['length'], DefaultValue))
+ TmpList = []
+ if Item['type'] == "Combo":
+ if not Item['option'] in self._BuidinOption:
+ OptList = Item['option'].split(',')
+ for Option in OptList:
+ Option = Option.strip()
+ (OpVal, OpStr) = Option.split(':')
+ TmpList.append((OpVal, OpStr))
+ return TmpList
+
+ def WriteBsfOption (self, BsfFd, Item):
+ PcdName = Item['space'] + '_' + Item['cname']
+ WriteHelp = 0
+ if Item['type'] == "Combo":
+ if Item['option'] in self._BuidinOption:
+ Options = self._BuidinOption[Item['option']]
+ else:
+ Options = PcdName
+ BsfFd.write(' %s $%s, "%s", &%s,\n' % (Item['type'], PcdName, Item['name'], Options));
+ WriteHelp = 1
+ elif Item['type'].startswith("EditNum"):
+ Match = re.match("EditNum\s*,\s*(HEX|DEC)\s*,\s*\((\d+|0x[0-9A-Fa-f]+)\s*,\s*(\d+|0x[0-9A-Fa-f]+)\)", Item['type'])
+ if Match:
+ BsfFd.write(' EditNum $%s, "%s", %s,\n' % (PcdName, Item['name'], Match.group(1)));
+ WriteHelp = 2
+ elif Item['type'].startswith("EditText"):
+ BsfFd.write(' %s $%s, "%s",\n' % (Item['type'], PcdName, Item['name']));
+ WriteHelp = 1
+ elif Item['type'] == "Table":
+ Columns = Item['option'].split(',')
+ if len(Columns) != 0:
+ BsfFd.write(' %s $%s "%s",' % (Item['type'], PcdName, Item['name']));
+ for Col in Columns:
+ Fmt = Col.split(':')
+ if len(Fmt) != 3:
+ raise Exception("Column format '%s' is invalid !" % Fmt)
+ try:
+ Dtype = int(Fmt[1].strip())
+ except:
+ raise Exception("Column size '%s' is invalid !" % Fmt[1])
+ BsfFd.write('\n Column "%s", %d bytes, %s' % (Fmt[0].strip(), Dtype, Fmt[2].strip()))
+ BsfFd.write(',\n')
+ WriteHelp = 1
+
+ if WriteHelp > 0:
+ HelpLines = Item['help'].split('\\n\\r')
+ FirstLine = True
+ for HelpLine in HelpLines:
+ if FirstLine:
+ FirstLine = False
+ BsfFd.write(' Help "%s"\n' % (HelpLine));
+ else:
+ BsfFd.write(' "%s"\n' % (HelpLine));
+ if WriteHelp == 2:
+ BsfFd.write(' "Valid range: %s ~ %s"\n' % (Match.group(2), Match.group(3)));
+
+ def GenerateBsfFile (self, BsfFile):
+
+ if BsfFile == '':
+ self.Error = "BSF output file '%s' is invalid" % BsfFile
+ return 1
+
+ Error = 0
+ OptionDict = {}
+ BsfFd = open(BsfFile, "w")
+ BsfFd.write("%s\n" % (__copyright_bsf__ % date.today().year))
+ BsfFd.write("%s\n" % self._GlobalDataDef);
+ BsfFd.write("StructDef\n")
+ NextOffset = -1
+ for Item in self._CfgItemList:
+ if Item['find'] != '':
+ BsfFd.write('\n Find "%s"\n' % Item['find'])
+ NextOffset = Item['offset'] + Item['length']
+ if Item['name'] != '':
+ if NextOffset != Item['offset']:
+ BsfFd.write(" Skip %d bytes\n" % (Item['offset'] - NextOffset))
+ if len(Item['subreg']) > 0:
+ NextOffset = Item['offset']
+ for SubItem in Item['subreg']:
+ NextOffset += SubItem['length']
+ if SubItem['name'] == '':
+ BsfFd.write(" Skip %d bytes\n" % (SubItem['length']))
+ else:
+ Options = self.WriteBsfStruct(BsfFd, SubItem)
+ if len(Options) > 0:
+ OptionDict[SubItem['space']+'_'+SubItem['cname']] = Options
+ if (Item['offset'] + Item['length']) < NextOffset:
+ self.Error = "BSF sub region '%s' length does not match" % (Item['space']+'.'+Item['cname'])
+ return 2
+ else:
+ NextOffset = Item['offset'] + Item['length']
+ Options = self.WriteBsfStruct(BsfFd, Item)
+ if len(Options) > 0:
+ OptionDict[Item['space']+'_'+Item['cname']] = Options
+ BsfFd.write("\nEndStruct\n\n")
+
+ BsfFd.write("%s" % self._BuidinOptionTxt);
+
+ for Each in OptionDict:
+ BsfFd.write("List &%s\n" % Each);
+ for Item in OptionDict[Each]:
+ BsfFd.write(' Selection %s , "%s"\n' % (Item[0], Item[1]));
+ BsfFd.write("EndList\n\n");
+
+ BsfFd.write("BeginInfoBlock\n");
+ BsfFd.write(' PPVer "%s"\n' % (self._CfgBlkDict['ver']));
+ BsfFd.write(' Description "%s"\n' % (self._CfgBlkDict['name']));
+ BsfFd.write("EndInfoBlock\n\n");
+
+ for Each in self._CfgPageDict:
+ BsfFd.write('Page "%s"\n' % self._CfgPageDict[Each]);
+ BsfItems = []
+ for Item in self._CfgItemList:
+ if Item['name'] != '':
+ if Item['page'] != Each:
+ continue
+ if len(Item['subreg']) > 0:
+ for SubItem in Item['subreg']:
+ if SubItem['name'] != '':
+ BsfItems.append(SubItem)
+ else:
+ BsfItems.append(Item)
+
+ BsfItems.sort(key=lambda x: x['order'])
+
+ for Item in BsfItems:
+ self.WriteBsfOption (BsfFd, Item)
+ BsfFd.write("EndPage\n\n");
+
+ BsfFd.close()
+ return Error
+
+
+def Usage():
+ print "GenCfgOpt Version 0.51"
+ print "Usage:"
+ print " GenCfgOpt UPDTXT PlatformDscFile BuildFvDir ConfigDscFile ExtConfigDscFile"
+ print " [-D Macros]"
+ print " GenCfgOpt HEADER PlatformDscFile BuildFvDir ConfigDscFile ExtConfigDscFile"
+ print " InputHFile [-D Macros]"
+ print " GenCfgOpt GENBSF PlatformDscFile BuildFvDir ConfigDscFile ExtConfigDscFile"
+ print " BsfOutFile [-D Macros]"
+
+def Main():
+ #
+ # Parse the options and args
+ #
+ GenCfgOpt = CGenCfgOpt()
+ argc = len(sys.argv)
+ if argc < 4:
+ Usage()
+ return 1
+ else:
+ DscFile = sys.argv[2]
+ if not os.path.exists(DscFile):
+ print "ERROR: Cannot open DSC file '%s' !" % DscFile
+ return 2
+ ConfigDscFile = sys.argv[4]
+ if not os.path.exists(ConfigDscFile):
+ print "ERROR: Cannot open Config DSC file '%s' !" % ConfigDscFile
+ return 2
+ ExtConfigDscFile = sys.argv[5]
+ if not os.path.exists(ExtConfigDscFile):
+ print "ERROR: Cannot open Ext Config DSC file '%s' !" % ExtConfigDscFile
+ return 2
+
+ OutFile = ''
+ if argc > 4:
+ if sys.argv[6][0] == '-':
+ Start = 4
+ else:
+ OutFile = sys.argv[6]
+ Start = 5
+ GenCfgOpt.ParseBuildMode(sys.argv[3])
+ if GenCfgOpt.ParseMacros(sys.argv[Start:]) != 0:
+ print "ERROR: Macro parsing failed !"
+ return 3
+
+ FvDir = sys.argv[3]
+ if not os.path.exists(FvDir):
+ os.makedirs(FvDir)
+
+ if GenCfgOpt.ParseDscFile(DscFile, FvDir, ConfigDscFile, ExtConfigDscFile) != 0:
+ print "ERROR: %s !" % GenCfgOpt.Error
+ return 5
+
+ if GenCfgOpt.UpdateSubRegionDefaultValue() != 0:
+ print "ERROR: %s !" % GenCfgOpt.Error
+ return 7
+
+ if sys.argv[1] == "UPDTXT":
+ Ret = GenCfgOpt.CreateSplitUpdTxt(OutFile)
+ if Ret != 0:
+ # No change is detected
+ if Ret == 256:
+ print "INFO: %s !" % (GenCfgOpt.Error)
+ else :
+ print "ERROR: %s !" % (GenCfgOpt.Error)
+ return Ret
+ elif sys.argv[1] == "HEADER":
+ if GenCfgOpt.CreateHeaderFile(OutFile) != 0:
+ print "ERROR: %s !" % GenCfgOpt.Error
+ return 8
+ elif sys.argv[1] == "GENBSF":
+ if GenCfgOpt.GenerateBsfFile(OutFile) != 0:
+ print "ERROR: %s !" % GenCfgOpt.Error
+ return 9
+ else:
+ if argc < 5:
+ Usage()
+ return 1
+ print "ERROR: Unknown command '%s' !" % sys.argv[1]
+ Usage()
+ return 1
+ return 0
+ return 0
+
+
+if __name__ == '__main__':
+ sys.exit(Main())
diff --git a/IntelFsp2Pkg/Tools/PatchFv.py b/IntelFsp2Pkg/Tools/PatchFv.py new file mode 100644 index 0000000000..fc2ee19bcd --- /dev/null +++ b/IntelFsp2Pkg/Tools/PatchFv.py @@ -0,0 +1,947 @@ +## @ PatchFv.py
+#
+# Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<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/IntelFsp2Pkg/Tools/SplitFspBin.py b/IntelFsp2Pkg/Tools/SplitFspBin.py new file mode 100644 index 0000000000..cc2b87ecc1 --- /dev/null +++ b/IntelFsp2Pkg/Tools/SplitFspBin.py @@ -0,0 +1,363 @@ +## @ FspTool.py
+#
+# Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<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 image.
+It supports:
+ - Split a FSP 2.0 compatibale image into individual FSP-T/M/S/C
+ and generate the mapping header file.
+"""
+
+class c_uint24(Structure):
+ """Little-Endian 24-bit Unsigned Integer"""
+ _pack_ = 1
+ _fields_ = [
+ ('Data', (c_uint8 * 3))
+ ]
+
+ def __init__(self, val=0):
+ self.set_value(val)
+
+ def __str__(self, indent=0):
+ return '0x%.6x' % self.value
+
+ def get_value(self):
+ return (
+ (self.Data[0] ) +
+ (self.Data[1] << 8) +
+ (self.Data[2] << 16)
+ )
+
+ def set_value(self, val):
+ self.Data[0] = (val ) & 0xff
+ self.Data[1] = (val >> 8) & 0xff
+ self.Data[2] = (val >> 16) & 0xff
+
+ value = property(get_value, set_value)
+
+class EFI_FIRMWARE_VOLUME_HEADER(Structure):
+ _fields_ = [
+ ('ZeroVector', ARRAY(c_uint8, 16)),
+ ('FileSystemGuid', ARRAY(c_char, 16)),
+ ('FvLength', c_uint64),
+ ('Signature', c_uint32),
+ ('Attributes', c_uint32),
+ ('HeaderLength', c_uint16),
+ ('Checksum', c_uint16),
+ ('ExtHeaderOffset', c_uint16),
+ ('Reserved', c_uint8),
+ ('Revision', c_uint8)
+ ]
+
+class EFI_FIRMWARE_VOLUME_EXT_HEADER(Structure):
+ _fields_ = [
+ ('FvName', ARRAY(c_char, 16)),
+ ('ExtHeaderSize', c_uint32)
+ ]
+
+class EFI_FFS_INTEGRITY_CHECK(Structure):
+ _fields_ = [
+ ('Header', c_uint8),
+ ('File', c_uint8)
+ ]
+
+class EFI_FFS_FILE_HEADER(Structure):
+ _fields_ = [
+ ('Name', ARRAY(c_char, 16)),
+ ('IntegrityCheck', EFI_FFS_INTEGRITY_CHECK),
+ ('Type', c_uint8),
+ ('Attributes', c_uint8),
+ ('Size', c_uint24),
+ ('State', c_uint8)
+ ]
+
+class EFI_COMMON_SECTION_HEADER(Structure):
+ _fields_ = [
+ ('Size', c_uint24),
+ ('Type', c_uint8)
+ ]
+
+class FSP_INFORMATION_HEADER(Structure):
+ _fields_ = [
+ ('Signature', c_uint32),
+ ('HeaderLength', c_uint32),
+ ('Reserved1', ARRAY(c_uint8, 3)),
+ ('HeaderRevision', c_uint8),
+ ('ImageRevision', c_uint32),
+ ('ImageId', c_uint64),
+ ('ImageSize', c_uint32),
+ ('ImageBase', c_uint32),
+ ('ImageAttribute', c_uint32),
+ ('CfgRegionOffset', c_uint32),
+ ('CfgRegionSize', c_uint32),
+ ('ApiEntryNum', c_uint32),
+ ('NemInitEntry', c_uint32),
+ ('FspInitEntry', c_uint32),
+ ('NotifyPhaseEntry', c_uint32),
+ ('FspMemoryInitEntry', c_uint32),
+ ('TempRamExitEntry', c_uint32),
+ ('FspSiliconInitEntry', c_uint32)
+ ]
+
+class FspFv:
+ HeaderFile = """/*
+ *
+ * Automatically generated file; DO NOT EDIT.
+ * FSP mapping file
+ *
+ */
+"""
+ FspNameDict = {
+ "0" : "-C.Fv",
+ "1" : "-T.Fv",
+ "2" : "-M.Fv",
+ "3" : "-S.Fv",
+ }
+
+ def __init__(self, FvBin):
+ self.FspFv = {}
+ self.FvList = []
+ self.FspBin = FvBin
+ hfsp = open (self.FspBin, 'r+b')
+ self.FspDat = bytearray(hfsp.read())
+ hfsp.close()
+
+ def OutputStruct (self, obj, indent = 0):
+ max_key_len = 20
+ pstr = (' ' * indent + '{0:<%d} = {1}\n') % max_key_len
+ if indent:
+ s = ''
+ else:
+ s = (' ' * indent + '<%s>:\n') % obj.__class__.__name__
+ for field in obj._fields_:
+ key = field[0]
+ val = getattr(obj, key)
+ rep = ''
+
+ if not isinstance(val, c_uint24) and isinstance(val, Structure):
+ s += pstr.format(key, val.__class__.__name__)
+ s += self.OutputStruct (val, indent + 1)
+ else:
+ if type(val) in (int, long):
+ rep = hex(val)
+ elif isinstance(val, str) and (len(val) == 16):
+ rep = str(uuid.UUID(bytes = val))
+ elif isinstance(val, c_uint24):
+ rep = hex(val.get_value())
+ elif 'c_ubyte_Array' in str(type(val)):
+ rep = str(list(bytearray(val)))
+ else:
+ rep = str(val)
+ s += pstr.format(key, rep)
+ return s
+
+ def PrintFv (self):
+ print ("FV LIST:")
+ idx = 0
+ for (fvh, fvhe, offset) in self.FvList:
+ guid = uuid.UUID(bytes = fvhe.FvName)
+ print ("FV%d FV GUID:%s Offset:0x%08X Length:0x%08X" % (idx, str(guid), offset, fvh.FvLength))
+ idx = idx + 1
+ print ("\nFSP LIST:")
+ for fsp in self.FspFv:
+ print "FSP%s contains FV%s" % (fsp, str(self.FspFv[fsp][1]))
+ print "\nFSP%s Info Header:" % fsp
+ fih = self.FspFv[fsp][0]
+
+ def AlaignPtr (self, offset, alignment = 8):
+ return (offset + alignment - 1) & ~(alignment - 1)
+
+ def GetFspInfoHdr (self, fvh, fvhe, fvoffset):
+ if fvhe:
+ offset = fvh.ExtHeaderOffset + fvhe.ExtHeaderSize
+ else:
+ offset = fvh.HeaderLength
+ offset = self.AlaignPtr(offset)
+
+ # Now it should be 1st FFS
+ ffs = EFI_FFS_FILE_HEADER.from_buffer (self.FspDat, offset)
+ offset += sizeof(ffs)
+ offset = self.AlaignPtr(offset)
+
+ # Now it should be 1st Section
+ sec = EFI_COMMON_SECTION_HEADER.from_buffer (self.FspDat, offset)
+ offset += sizeof(sec)
+
+ # Now it should be FSP_INFO_HEADER
+ offset += fvoffset
+ fih = FSP_INFORMATION_HEADER.from_buffer (self.FspDat, offset)
+ if 'FSPH' != bytearray.fromhex('%08X' % fih.Signature)[::-1]:
+ return None
+
+ return fih
+
+ def GetFvHdr (self, offset):
+ fvh = EFI_FIRMWARE_VOLUME_HEADER.from_buffer (self.FspDat, offset)
+ if '_FVH' != bytearray.fromhex('%08X' % fvh.Signature)[::-1]:
+ return None, None
+ if fvh.ExtHeaderOffset > 0:
+ offset += fvh.ExtHeaderOffset
+ fvhe = EFI_FIRMWARE_VOLUME_EXT_HEADER.from_buffer (self.FspDat, offset)
+ else:
+ fvhe = None
+ return fvh, fvhe
+
+ def GetFvData(self, idx):
+ (fvh, fvhe, offset) = self.FvList[idx]
+ return self.FspDat[offset:offset+fvh.FvLength]
+
+ def CheckFsp (self):
+ if len(self.FspFv) == 0:
+ return
+
+ fih = None
+ for fv in self.FspFv:
+ if not fih:
+ fih = self.FspFv[fv][0]
+ else:
+ newfih = self.FspFv[fv][0]
+ if (newfih.ImageId != fih.ImageId) or (newfih.ImageRevision != fih.ImageRevision):
+ raise Exception("Inconsistent FSP ImageId or ImageRevision detected !")
+ return
+
+ def WriteFsp(self, dir, name):
+ if not name:
+ name = self.FspBin
+ fspname, ext = os.path.splitext(os.path.basename(name))
+ for fv in self.FspFv:
+ filename = os.path.join(dir, fspname + fv + ext)
+ hfsp = open(filename, 'w+b')
+ for fvidx in self.FspFv[fv][1]:
+ hfsp.write (self.GetFvData(fvidx))
+ hfsp.close()
+
+ def WriteMap(self, dir, hfile):
+ if not hfile:
+ hfile = os.path.splitext(os.path.basename(self.FspBin))[0] + '.h'
+ fspname, ext = os.path.splitext(os.path.basename(hfile))
+ filename = os.path.join(dir, fspname + ext)
+ hfsp = open(filename, 'w')
+ hfsp.write ('%s\n\n' % self.HeaderFile)
+
+ firstfv = True
+ for fsp in self.FspFv:
+ fih = self.FspFv[fsp][0]
+ fvs = self.FspFv[fsp][1]
+ if firstfv:
+ IdStr = str(bytearray.fromhex('%016X' % fih.ImageId)[::-1])
+ hfsp.write("#define FSP_IMAGE_ID 0x%016X /* '%s' */\n" % (fih.ImageId, IdStr))
+ hfsp.write("#define FSP_IMAGE_REV 0x%08X \n\n" % fih.ImageRevision)
+ firstfv = False
+ hfsp.write ('#define FSP%s_BASE 0x%08X\n' % (fsp, fih.ImageBase))
+ hfsp.write ('#define FSP%s_OFFSET 0x%08X\n' % (fsp, self.FvList[fvs[0]][-1]))
+ hfsp.write ('#define FSP%s_LENGTH 0x%08X\n\n' % (fsp, fih.ImageSize))
+ hfsp.close()
+
+ def ParseFsp (self):
+ self.FspFv = {}
+ flen = 0
+ for (fvh, fvhe, offset) in self.FvList:
+ fih = self.GetFspInfoHdr (fvh, fvhe, offset)
+ if fih:
+ if flen != 0:
+ raise Exception("Incorrect FV size in image !")
+ ftype = str((fih.ImageAttribute >> 28) & 0xF)
+ if ftype not in self.FspNameDict:
+ raise Exception("Unknown Attribute in image !")
+ fname = self.FspNameDict[str(ftype)]
+ if fname in self.FspFv:
+ raise Exception("Multiple '%s' in image !" % fname)
+ self.FspFv[fname] = (copy.deepcopy(fih), [])
+ flen = fih.ImageSize
+ if flen > 0:
+ flen = flen - fvh.FvLength
+ if flen < 0:
+ raise Exception("Incorrect FV size in image !")
+ self.FspFv[fname][1].append(self.FvList.index((fvh, fvhe, offset)))
+
+ def AddFv(self, offset):
+ fvh, fvhe = self.GetFvHdr (offset)
+ if fvh is None:
+ raise Exception('FV signature is not valid !')
+ fvitem = (copy.deepcopy(fvh), copy.deepcopy(fvhe), offset)
+ self.FvList.append(fvitem)
+ return fvh.FvLength
+
+ def ParseFv(self):
+ offset = 0
+ while (offset < len(self.FspDat)):
+ fv_len = self.AddFv (offset)
+ offset += fv_len
+
+def GenFspHdr (fspfile, outdir, hfile, show):
+ fsp_fv = FspFv(fspfile)
+ fsp_fv.ParseFv()
+ fsp_fv.ParseFsp()
+ fsp_fv.CheckFsp()
+ if show:
+ fsp_fv.PrintFv()
+ fsp_fv.WriteMap(outdir, hfile)
+
+def SplitFspBin (fspfile, outdir, nametemplate, show):
+ fsp_fv = FspFv(fspfile)
+ fsp_fv.ParseFv()
+ fsp_fv.ParseFsp()
+ if show:
+ fsp_fv.PrintFv()
+ fsp_fv.WriteFsp(outdir, nametemplate)
+
+def main ():
+ parser = argparse.ArgumentParser()
+ subparsers = parser.add_subparsers(title='commands')
+
+ parser_split = subparsers.add_parser('split', help='split a FSP into multiple components')
+ parser_split.set_defaults(which='split')
+ parser_split.add_argument('-f', '--fspbin' , dest='FspBinary', type=str, help='FSP binary file path', required = True)
+ parser_split.add_argument('-o', '--outdir' , dest='OutputDir', type=str, help='Output directory path', default = '.')
+ parser_split.add_argument('-n', '--nametpl', dest='NameTemplate', type=str, help='Output name template', default = '')
+ parser_split.add_argument('-p', action='store_true', help='Print FSP FV information', default = False)
+
+ parser_genhdr = subparsers.add_parser('genhdr', help='generate a header file for FSP binary')
+ parser_genhdr.set_defaults(which='genhdr')
+ parser_genhdr.add_argument('-f', '--fspbin' , dest='FspBinary', type=str, help='FSP binary file path', required = True)
+ parser_genhdr.add_argument('-o', '--outdir' , dest='OutputDir', type=str, help='Output directory path', default = '.')
+ parser_genhdr.add_argument('-n', '--hfile', dest='HFileName', type=str, help='Output header file name', default = '')
+ parser_genhdr.add_argument('-p', action='store_true', help='Print FSP FV information', default = False)
+
+ args = parser.parse_args()
+ if args.which in ['split', 'genhdr']:
+ if not os.path.exists(args.FspBinary):
+ raise Exception ("Could not locate FSP binary file '%s' !" % args.FspBinary)
+ if not os.path.exists(args.OutputDir):
+ raise Exception ("Invalid output directory '%s' !" % args.OutputDir)
+
+ if args.which == 'split':
+ SplitFspBin (args.FspBinary, args.OutputDir, args.NameTemplate, args.p)
+ elif args.which == 'genhdr':
+ GenFspHdr (args.FspBinary, args.OutputDir, args.HFileName, args.p)
+ else:
+ pass
+
+ print 'Done!'
+ return 0
+
+if __name__ == '__main__':
+ sys.exit(main())
diff --git a/IntelFsp2Pkg/Tools/UserManuals/GenCfgOptUserManual.docx b/IntelFsp2Pkg/Tools/UserManuals/GenCfgOptUserManual.docx Binary files differnew file mode 100644 index 0000000000..c8766d5775 --- /dev/null +++ b/IntelFsp2Pkg/Tools/UserManuals/GenCfgOptUserManual.docx diff --git a/IntelFsp2Pkg/Tools/UserManuals/PatchFvUserManual.docx b/IntelFsp2Pkg/Tools/UserManuals/PatchFvUserManual.docx Binary files differnew file mode 100644 index 0000000000..ab1eda993e --- /dev/null +++ b/IntelFsp2Pkg/Tools/UserManuals/PatchFvUserManual.docx |