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