From 5633abb172743e1e61749dc2df96b1f4a2743b27 Mon Sep 17 00:00:00 2001 From: Guo Mang Date: Fri, 23 Dec 2016 14:34:18 +0800 Subject: BroxtonPlatformPkg: Add IntelFsp2WrapperPkg Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Guo Mang --- .../IntelFsp2WrapperPkg/FspInitPei/FindPeiCore.c | 200 +++++++++++ .../IntelFsp2WrapperPkg/FspInitPei/SecMain.c | 312 ++++++++++++++++++ .../IntelFsp2WrapperPkg/FspInitPei/SecMain.h | 118 +++++++ .../FspNotifyDxe/FspNotifyDxe.c | 261 +++++++++++++++ .../FspNotifyDxe/FspNotifyDxe.inf | 76 +++++ .../IntelFsp2WrapperPkg/FspNotifyDxe/LoadBelow4G.c | 151 +++++++++ .../FspmWrapperPeim/FspmWrapperPeim.c | 266 +++++++++++++++ .../FspmWrapperPeim/FspmWrapperPeim.inf | 105 ++++++ .../FspsWrapperPeim/FspsWrapperPeim.c | 332 +++++++++++++++++++ .../FspsWrapperPeim/FspsWrapperPeim.inf | 105 ++++++ .../Include/Library/FspHobProcessLib.h | 71 ++++ .../Include/Library/FspPlatformInfoLib.h | 167 ++++++++++ .../Include/Library/FspPlatformSecLib.h | 71 ++++ .../IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec | 113 +++++++ .../BaseFspWrapperApiLib/BaseFspWrapperApiLib.inf | 73 +++++ .../BaseFspWrapperApiLib/FspWrapperApiLib.c | 222 +++++++++++++ .../BaseFspWrapperApiLib/IA32/DispatchExecute.c | 61 ++++ .../BaseFspWrapperApiLib/X64/DispatchExecute.c | 111 +++++++ .../Library/BaseFspWrapperApiLib/X64/Thunk64To32.S | 224 +++++++++++++ .../BaseFspWrapperApiLib/X64/Thunk64To32.asm | 227 +++++++++++++ .../FspPlatformSecLibSample.c | 153 +++++++++ .../Ia32/AsmSaveSecContext.S | 37 +++ .../Ia32/AsmSaveSecContext.asm | 45 +++ .../SecPeiFspPlatformSecLibSample/Ia32/Fsp.h | 50 +++ .../Ia32/PeiCoreEntry.S | 124 +++++++ .../Ia32/PeiCoreEntry.asm | 135 ++++++++ .../SecPeiFspPlatformSecLibSample/Ia32/SecEntry.S | 322 ++++++++++++++++++ .../Ia32/SecEntry.asm | 340 +++++++++++++++++++ .../SecPeiFspPlatformSecLibSample/Ia32/Stack.S | 74 +++++ .../SecPeiFspPlatformSecLibSample/Ia32/Stack.asm | 81 +++++ .../SecPeiFspPlatformSecLibSample/PlatformInit.c | 44 +++ .../SecPeiFspPlatformSecLibSample/SaveSecContext.c | 115 +++++++ .../SecGetPerformance.c | 92 ++++++ .../SecPeiFspPlatformSecLibSample.inf | 97 ++++++ .../SecPeiFspPlatformSecLibSample.uni | Bin 0 -> 1700 bytes .../SecPlatformInformation.c | 86 +++++ .../SecPeiFspPlatformSecLibSample/SecRamInitData.c | 24 ++ .../SecTempRamSupport.c | 148 +++++++++ .../IntelFsp2WrapperPkg/Tools/fsptool.py | 365 +++++++++++++++++++++ 39 files changed, 5598 insertions(+) create mode 100644 Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/FspInitPei/FindPeiCore.c create mode 100644 Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/FspInitPei/SecMain.c create mode 100644 Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/FspInitPei/SecMain.h create mode 100644 Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/FspNotifyDxe/FspNotifyDxe.c create mode 100644 Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/FspNotifyDxe/FspNotifyDxe.inf create mode 100644 Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/FspNotifyDxe/LoadBelow4G.c create mode 100644 Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/FspmWrapperPeim/FspmWrapperPeim.c create mode 100644 Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/FspmWrapperPeim/FspmWrapperPeim.inf create mode 100644 Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/FspsWrapperPeim/FspsWrapperPeim.c create mode 100644 Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/FspsWrapperPeim/FspsWrapperPeim.inf create mode 100644 Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Include/Library/FspHobProcessLib.h create mode 100644 Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Include/Library/FspPlatformInfoLib.h create mode 100644 Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Include/Library/FspPlatformSecLib.h create mode 100644 Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec create mode 100644 Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/BaseFspWrapperApiLib.inf create mode 100644 Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/FspWrapperApiLib.c create mode 100644 Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/IA32/DispatchExecute.c create mode 100644 Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/X64/DispatchExecute.c create mode 100644 Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/X64/Thunk64To32.S create mode 100644 Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/X64/Thunk64To32.asm create mode 100644 Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/FspPlatformSecLibSample.c create mode 100644 Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/AsmSaveSecContext.S create mode 100644 Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/AsmSaveSecContext.asm create mode 100644 Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/Fsp.h create mode 100644 Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/PeiCoreEntry.S create mode 100644 Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/PeiCoreEntry.asm create mode 100644 Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/SecEntry.S create mode 100644 Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/SecEntry.asm create mode 100644 Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/Stack.S create mode 100644 Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/Stack.asm create mode 100644 Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/PlatformInit.c create mode 100644 Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/SaveSecContext.c create mode 100644 Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecGetPerformance.c create mode 100644 Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecPeiFspPlatformSecLibSample.inf create mode 100644 Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecPeiFspPlatformSecLibSample.uni create mode 100644 Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecPlatformInformation.c create mode 100644 Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecRamInitData.c create mode 100644 Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecTempRamSupport.c create mode 100644 Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Tools/fsptool.py (limited to 'Platform/BroxtonPlatformPkg/Common/SampleCode') diff --git a/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/FspInitPei/FindPeiCore.c b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/FspInitPei/FindPeiCore.c new file mode 100644 index 0000000000..b2bf25349f --- /dev/null +++ b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/FspInitPei/FindPeiCore.c @@ -0,0 +1,200 @@ +/** @file + Locate the entry point for the PEI Core. + + Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include +#include + +#include "SecMain.h" + +/** + Find core image base. + + @param[in] BootFirmwareVolumePtr Point to the boot firmware volume. + @param[out] SecCoreImageBase The base address of the SEC core image. + @param[out] PeiCoreImageBase The base address of the PEI core image. + +**/ +EFI_STATUS +EFIAPI +FindImageBase ( + IN EFI_FIRMWARE_VOLUME_HEADER *BootFirmwareVolumePtr, + OUT EFI_PHYSICAL_ADDRESS *SecCoreImageBase, + OUT EFI_PHYSICAL_ADDRESS *PeiCoreImageBase + ) +{ + EFI_PHYSICAL_ADDRESS CurrentAddress; + EFI_PHYSICAL_ADDRESS EndOfFirmwareVolume; + EFI_FFS_FILE_HEADER *File; + UINT32 Size; + EFI_PHYSICAL_ADDRESS EndOfFile; + EFI_COMMON_SECTION_HEADER *Section; + EFI_PHYSICAL_ADDRESS EndOfSection; + + *SecCoreImageBase = 0; + *PeiCoreImageBase = 0; + + CurrentAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) BootFirmwareVolumePtr; + EndOfFirmwareVolume = CurrentAddress + BootFirmwareVolumePtr->FvLength; + + // + // Loop through the FFS files in the Boot Firmware Volume + // + for (EndOfFile = CurrentAddress + BootFirmwareVolumePtr->HeaderLength; ; ) { + + CurrentAddress = (EndOfFile + 7) & 0xfffffffffffffff8ULL; + if (CurrentAddress > EndOfFirmwareVolume) { + return EFI_NOT_FOUND; + } + + File = (EFI_FFS_FILE_HEADER*)(UINTN) CurrentAddress; + if (IS_FFS_FILE2 (File)) { + Size = FFS_FILE2_SIZE (File); + if (Size <= 0x00FFFFFF) { + return EFI_NOT_FOUND; + } + } else { + Size = FFS_FILE_SIZE (File); + if (Size < sizeof (EFI_FFS_FILE_HEADER)) { + return EFI_NOT_FOUND; + } + } + + EndOfFile = CurrentAddress + Size; + if (EndOfFile > EndOfFirmwareVolume) { + return EFI_NOT_FOUND; + } + + // + // Look for SEC Core / PEI Core files + // + if (File->Type != EFI_FV_FILETYPE_SECURITY_CORE && + File->Type != EFI_FV_FILETYPE_PEI_CORE) { + continue; + } + + // + // Loop through the FFS file sections within the FFS file + // + if (IS_FFS_FILE2 (File)) { + EndOfSection = (EFI_PHYSICAL_ADDRESS) (UINTN) ((UINT8 *) File + sizeof (EFI_FFS_FILE_HEADER2)); + } else { + EndOfSection = (EFI_PHYSICAL_ADDRESS) (UINTN) ((UINT8 *) File + sizeof (EFI_FFS_FILE_HEADER)); + } + for (;;) { + CurrentAddress = (EndOfSection + 3) & 0xfffffffffffffffcULL; + Section = (EFI_COMMON_SECTION_HEADER*)(UINTN) CurrentAddress; + + if (IS_SECTION2 (Section)) { + Size = SECTION2_SIZE (Section); + if (Size <= 0x00FFFFFF) { + return EFI_NOT_FOUND; + } + } else { + Size = SECTION_SIZE (Section); + if (Size < sizeof (EFI_COMMON_SECTION_HEADER)) { + return EFI_NOT_FOUND; + } + } + + EndOfSection = CurrentAddress + Size; + if (EndOfSection > EndOfFile) { + return EFI_NOT_FOUND; + } + + // + // Look for executable sections + // + if (Section->Type == EFI_SECTION_PE32 || Section->Type == EFI_SECTION_TE) { + if (File->Type == EFI_FV_FILETYPE_SECURITY_CORE) { + if (IS_SECTION2 (Section)) { + *SecCoreImageBase = (PHYSICAL_ADDRESS) (UINTN) ((UINT8 *) Section + sizeof (EFI_COMMON_SECTION_HEADER2)); + } else { + *SecCoreImageBase = (PHYSICAL_ADDRESS) (UINTN) ((UINT8 *) Section + sizeof (EFI_COMMON_SECTION_HEADER)); + } + } else { + if (IS_SECTION2 (Section)) { + *PeiCoreImageBase = (PHYSICAL_ADDRESS) (UINTN) ((UINT8 *) Section + sizeof (EFI_COMMON_SECTION_HEADER2)); + } else { + *PeiCoreImageBase = (PHYSICAL_ADDRESS) (UINTN) ((UINT8 *) Section + sizeof (EFI_COMMON_SECTION_HEADER)); + } + } + break; + } + } + + // + // Both SEC Core and PEI Core images found + // + if (*SecCoreImageBase != 0 && *PeiCoreImageBase != 0) { + return EFI_SUCCESS; + } + } +} + +/** + Find and return Pei Core entry point. + + It also find SEC and PEI Core file debug inforamtion. It will report them if + remote debug is enabled. + + @param[in] BootFirmwareVolumePtr Point to the boot firmware volume. + @param[out] PeiCoreEntryPoint The entry point of the PEI core. + +**/ +VOID +EFIAPI +FindAndReportEntryPoints ( + IN EFI_FIRMWARE_VOLUME_HEADER *BootFirmwareVolumePtr, + OUT EFI_PEI_CORE_ENTRY_POINT *PeiCoreEntryPoint + ) +{ + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS SecCoreImageBase; + EFI_PHYSICAL_ADDRESS PeiCoreImageBase; + PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; + + // + // Find SEC Core and PEI Core image base + // + Status = FindImageBase (BootFirmwareVolumePtr, &SecCoreImageBase, &PeiCoreImageBase); + ASSERT_EFI_ERROR (Status); + + ZeroMem ((VOID *) &ImageContext, sizeof (PE_COFF_LOADER_IMAGE_CONTEXT)); + // + // Report SEC Core debug information when remote debug is enabled + // + ImageContext.ImageAddress = SecCoreImageBase; + ImageContext.PdbPointer = PeCoffLoaderGetPdbPointer ((VOID*) (UINTN) ImageContext.ImageAddress); + PeCoffLoaderRelocateImageExtraAction (&ImageContext); + + // + // Report PEI Core debug information when remote debug is enabled + // + ImageContext.ImageAddress = PeiCoreImageBase; + ImageContext.PdbPointer = PeCoffLoaderGetPdbPointer ((VOID*) (UINTN) ImageContext.ImageAddress); + PeCoffLoaderRelocateImageExtraAction (&ImageContext); + + // + // Find PEI Core entry point + // + Status = PeCoffLoaderGetEntryPoint ((VOID *) (UINTN) PeiCoreImageBase, (VOID**) PeiCoreEntryPoint); + if (EFI_ERROR (Status)) { + *PeiCoreEntryPoint = 0; + } + + return; +} + diff --git a/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/FspInitPei/SecMain.c b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/FspInitPei/SecMain.c new file mode 100644 index 0000000000..05816c5a65 --- /dev/null +++ b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/FspInitPei/SecMain.c @@ -0,0 +1,312 @@ +/** @file + C functions in SEC. + + Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + + +#include "SecMain.h" + +EFI_PEI_PPI_DESCRIPTOR mPeiSecMainPpi[] = { + { + EFI_PEI_PPI_DESCRIPTOR_PPI, + &gTopOfTemporaryRamPpiGuid, + NULL // To be patched later. + }, + { + EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST, + &gFspSiliconInitDonePpiGuid, + &gFspSiliconInitDonePpi + }, +}; + +FSP_SILICON_INIT_DONE_PPI gFspSiliconInitDonePpi = { + FspSiliconInitDoneGetFspHobList +}; + +// +// These are IDT entries pointing to 10:FFFFFFE4h. +// +UINT64 mIdtEntryTemplate = 0xffff8e000010ffe4ULL; + +/** + Caller provided function to be invoked at the end of InitializeDebugAgent(). + + Entry point to the C language phase of SEC. After the SEC assembly + code has initialized some temporary memory and set up the stack, + the control is transferred to this function. + + @param[in] Context The first input parameter of InitializeDebugAgent(). + +**/ +VOID +EFIAPI +SecStartupPhase2( + IN VOID *Context + ); + + +/** + Entry point to the C language phase of SEC. After the SEC assembly + code has initialized some temporary memory and set up the stack, + the control is transferred to this function. + + @param[in] SizeOfRam Size of the temporary memory available for use. + @param[in] TempRamBase Base address of tempory ram + @param[in] BootFirmwareVolume Base address of the Boot Firmware Volume. + +**/ +VOID +EFIAPI +SecStartup ( + IN UINT32 SizeOfRam, + IN UINT32 TempRamBase, + IN VOID *BootFirmwareVolume + ) +{ + EFI_SEC_PEI_HAND_OFF SecCoreData; + IA32_DESCRIPTOR IdtDescriptor; + SEC_IDT_TABLE IdtTableInStack; + UINT32 Index; + UINT32 PeiStackSize; + + PeiStackSize = PcdGet32 (PcdPeiTemporaryRamStackSize); + if (PeiStackSize == 0) { + PeiStackSize = (SizeOfRam >> 1); + } + + ASSERT (PeiStackSize < SizeOfRam); + + // + // Process all libraries constructor function linked to SecCore. + // + ProcessLibraryConstructorList (); + + DEBUG ((DEBUG_INFO, "FspPei - SecStartup\n")); + + // + // Initialize floating point operating environment + // to be compliant with UEFI spec. + // + InitializeFloatingPointUnits (); + + + // |-------------------|----> + // |Idt Table | + // |-------------------| + // |PeiService Pointer | PeiStackSize + // |-------------------| + // | | + // | Stack | + // |-------------------|----> + // | | + // | | + // | Heap | PeiTemporayRamSize + // | | + // | | + // |-------------------|----> TempRamBase + + IdtTableInStack.PeiService = 0; + for (Index = 0; Index < SEC_IDT_ENTRY_COUNT; Index ++) { + CopyMem ((VOID*)&IdtTableInStack.IdtTable[Index], (VOID*)&mIdtEntryTemplate, sizeof (UINT64)); + } + + IdtDescriptor.Base = (UINTN) &IdtTableInStack.IdtTable; + IdtDescriptor.Limit = (UINT16)(sizeof (IdtTableInStack.IdtTable) - 1); + + AsmWriteIdtr (&IdtDescriptor); + + // + // Update the base address and length of Pei temporary memory + // + SecCoreData.DataSize = (UINT16) sizeof (EFI_SEC_PEI_HAND_OFF); + SecCoreData.BootFirmwareVolumeBase = BootFirmwareVolume; + SecCoreData.BootFirmwareVolumeSize = (UINTN) (SIZE_4GB - (UINTN) BootFirmwareVolume); + SecCoreData.TemporaryRamBase = (VOID*) (UINTN) TempRamBase; + SecCoreData.TemporaryRamSize = SizeOfRam; + SecCoreData.PeiTemporaryRamBase = SecCoreData.TemporaryRamBase; + SecCoreData.PeiTemporaryRamSize = SizeOfRam - PeiStackSize; + SecCoreData.StackBase = (VOID*) (UINTN) (TempRamBase + SecCoreData.PeiTemporaryRamSize); + SecCoreData.StackSize = PeiStackSize; + + DEBUG ((DEBUG_INFO, "FspWrapper BootFirmwareVolumeBase - 0x%x\n", SecCoreData.BootFirmwareVolumeBase)); + DEBUG ((DEBUG_INFO, "FspWrapper BootFirmwareVolumeSize - 0x%x\n", SecCoreData.BootFirmwareVolumeSize)); + DEBUG ((DEBUG_INFO, "FspWrapper TemporaryRamBase - 0x%x\n", SecCoreData.TemporaryRamBase)); + DEBUG ((DEBUG_INFO, "FspWrapper TemporaryRamSize - 0x%x\n", SecCoreData.TemporaryRamSize)); + DEBUG ((DEBUG_INFO, "FspWrapper PeiTemporaryRamBase - 0x%x\n", SecCoreData.PeiTemporaryRamBase)); + DEBUG ((DEBUG_INFO, "FspWrapper PeiTemporaryRamSize - 0x%x\n", SecCoreData.PeiTemporaryRamSize)); + DEBUG ((DEBUG_INFO, "FspWrapper StackBase - 0x%x\n", SecCoreData.StackBase)); + DEBUG ((DEBUG_INFO, "FspWrapper StackSize - 0x%x\n", SecCoreData.StackSize)); + + // + // Initialize Debug Agent to support source level debug in SEC/PEI phases before memory ready. + // + InitializeDebugAgent (DEBUG_AGENT_INIT_PREMEM_SEC, &SecCoreData, SecStartupPhase2); + +} + +/** + This API patch the TopOfTemporaryRam value in SecPpiList. + + @param[in,out] SecPpiList PPI list to be patched. + @param[in] TopOfTemporaryRam The top of Temporary Ram. + +**/ +VOID +PatchTopOfTemporaryRamPpi ( + IN OUT EFI_PEI_PPI_DESCRIPTOR *SecPpiList, + IN VOID *TopOfTemporaryRam + ) +{ + SecPpiList[0].Ppi = TopOfTemporaryRam; +} + +/** + Caller provided function to be invoked at the end of InitializeDebugAgent(). + + Entry point to the C language phase of SEC. After the SEC assembly + code has initialized some temporary memory and set up the stack, + the control is transferred to this function. + + @param[in] Context The first input parameter of InitializeDebugAgent(). + +**/ +VOID +EFIAPI +SecStartupPhase2( + IN VOID *Context + ) +{ + EFI_SEC_PEI_HAND_OFF *SecCoreData; + EFI_PEI_PPI_DESCRIPTOR *PpiList; + UINT32 Index; + EFI_PEI_PPI_DESCRIPTOR LocalSecPpiList[sizeof (mPeiSecMainPpi) / sizeof (mPeiSecMainPpi[0])]; + EFI_PEI_PPI_DESCRIPTOR AllSecPpiList[FixedPcdGet32(PcdSecCoreMaxPpiSupported)]; + EFI_PEI_CORE_ENTRY_POINT PeiCoreEntryPoint; + + SecCoreData = (EFI_SEC_PEI_HAND_OFF *) Context; + // + // Find Pei Core entry point. It will report SEC and Pei Core debug information if remote debug + // is enabled. + // + FindAndReportEntryPoints ((EFI_FIRMWARE_VOLUME_HEADER *) SecCoreData->BootFirmwareVolumeBase, &PeiCoreEntryPoint); + if (PeiCoreEntryPoint == NULL) + { + CpuDeadLoop (); + } + + CopyMem (LocalSecPpiList, mPeiSecMainPpi, sizeof (mPeiSecMainPpi)); + PatchTopOfTemporaryRamPpi (LocalSecPpiList, (VOID *) ((UINTN) SecCoreData->TemporaryRamBase + SecCoreData->TemporaryRamSize)); + + // + // Perform platform specific initialization before entering PeiCore. + // + PpiList = SecPlatformMain (SecCoreData); + if (PpiList != NULL) { + // + // Remove the terminal flag from the terminal Ppi + // + CopyMem (AllSecPpiList, LocalSecPpiList, sizeof (LocalSecPpiList)); + for (Index = 0; Index < PcdGet32 (PcdSecCoreMaxPpiSupported); Index ++) { + if ((AllSecPpiList[Index].Flags & EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) == EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) { + break; + } + } + AllSecPpiList[Index].Flags = AllSecPpiList[Index].Flags & (~EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST); + + // + // Append the platform additional Ppi list + // + Index += 1; + while (Index < PcdGet32 (PcdSecCoreMaxPpiSupported) && + ((PpiList->Flags & EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) != EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST)) { + CopyMem (&AllSecPpiList[Index], PpiList, sizeof (EFI_PEI_PPI_DESCRIPTOR)); + Index++; + PpiList++; + } + + // + // Check whether the total Ppis exceeds the max supported Ppi. + // + if (Index >= PcdGet32 (PcdSecCoreMaxPpiSupported)) { + // + // the total Ppi is larger than the supported Max + // PcdSecCoreMaxPpiSupported can be enlarged to solve it. + // + CpuDeadLoop (); + } else { + // + // Add the terminal Ppi + // + CopyMem (&AllSecPpiList[Index], PpiList, sizeof (EFI_PEI_PPI_DESCRIPTOR)); + } + + // + // Set PpiList to the total Ppi + // + PpiList = &AllSecPpiList[0]; + } else { + // + // No addition Ppi, PpiList directly point to the common Ppi list. + // + PpiList = &LocalSecPpiList[0]; + } + + // + // Transfer the control to the PEI core + // + ASSERT (PeiCoreEntryPoint != NULL); + (*PeiCoreEntryPoint) (SecCoreData, PpiList); + + // + // Should not come here. + // + return ; +} + +/** + Return Hob list produced by FSP. + + @param[in] PeiServices The pointer to the PEI Services Table. + @param[in] This The pointer to this instance of this PPI. + @param[out] FspHobList The pointer to Hob list produced by FSP. + + @return EFI_SUCCESS FReturn Hob list produced by FSP successfully. + +**/ +EFI_STATUS +EFIAPI +FspSiliconInitDoneGetFspHobList ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN FSP_SILICON_INIT_DONE_PPI *This, + OUT VOID **FspHobList + ) +{ + VOID *TopOfTemporaryRamPpi; + EFI_STATUS Status; + + Status = (*PeiServices)->LocatePpi ( + PeiServices, + &gTopOfTemporaryRamPpiGuid, + 0, + NULL, + (VOID **) &TopOfTemporaryRamPpi + ); + if (EFI_ERROR (Status)) { + return EFI_NOT_FOUND; + } + + *FspHobList = (VOID *) (UINTN) (*(UINT32 *) ((UINTN) TopOfTemporaryRamPpi - sizeof (UINT32))); + + return EFI_SUCCESS; +} + diff --git a/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/FspInitPei/SecMain.h b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/FspInitPei/SecMain.h new file mode 100644 index 0000000000..68688c5cbd --- /dev/null +++ b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/FspInitPei/SecMain.h @@ -0,0 +1,118 @@ +/** @file + Master header file for SecCore. + + Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef _SEC_CORE_H_ +#define _SEC_CORE_H_ + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define SEC_IDT_ENTRY_COUNT 34 + +typedef struct _SEC_IDT_TABLE { + // + // Reserved 8 bytes preceding IDT to store EFI_PEI_SERVICES**, since IDT base + // address should be 8-byte alignment. + // Note: For IA32, only the 4 bytes immediately preceding IDT is used to store + // EFI_PEI_SERVICES** + // + UINT64 PeiService; + UINT64 IdtTable[SEC_IDT_ENTRY_COUNT]; +} SEC_IDT_TABLE; + +/** + Entry point to the C language phase of SEC. After the SEC assembly + code has initialized some temporary memory and set up the stack, + the control is transferred to this function. + + @param[in] SizeOfRam Size of the temporary memory available for use. + @param[in] TempRamBase Base address of tempory ram + @param[in] BootFirmwareVolume Base address of the Boot Firmware Volume. + +**/ +VOID +EFIAPI +SecStartup ( + IN UINT32 SizeOfRam, + IN UINT32 TempRamBase, + IN VOID *BootFirmwareVolume + ); + +/** + Find and return Pei Core entry point. + + It also find SEC and PEI Core file debug inforamtion. It will report them if + remote debug is enabled. + + @param[in] BootFirmwareVolumePtr Point to the boot firmware volume. + @param[out] PeiCoreEntryPoint Point to the PEI core entry point. + +**/ +VOID +EFIAPI +FindAndReportEntryPoints ( + IN EFI_FIRMWARE_VOLUME_HEADER *BootFirmwareVolumePtr, + OUT EFI_PEI_CORE_ENTRY_POINT *PeiCoreEntryPoint + ); + +/** + Autogenerated function that calls the library constructors for all of the module's + dependent libraries. This function must be called by the SEC Core once a stack has + been established. + +**/ +VOID +EFIAPI +ProcessLibraryConstructorList ( + VOID + ); + +/** + Return Hob list produced by FSP. + + @param[in] PeiServices The pointer to the PEI Services Table. + @param[in] This The pointer to this instance of this PPI. + @param[out] FspHobList The pointer to Hob list produced by FSP. + + @return EFI_SUCCESS FReturn Hob list produced by FSP successfully. + +**/ +EFI_STATUS +EFIAPI +FspSiliconInitDoneGetFspHobList ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN FSP_SILICON_INIT_DONE_PPI *This, + OUT VOID **FspHobList + ); + +extern FSP_SILICON_INIT_DONE_PPI gFspSiliconInitDonePpi; + +#endif + diff --git a/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/FspNotifyDxe/FspNotifyDxe.c b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/FspNotifyDxe/FspNotifyDxe.c new file mode 100644 index 0000000000..8d023416ee --- /dev/null +++ b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/FspNotifyDxe/FspNotifyDxe.c @@ -0,0 +1,261 @@ +/** @file + This driver will register two callbacks to call fsp's notifies. + + Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +typedef +EFI_STATUS +(EFIAPI * ADD_PERFORMANCE_RECORDS)( + IN CONST VOID *HobStart + ); + +struct _ADD_PERFORMANCE_RECORD_PROTOCOL { + ADD_PERFORMANCE_RECORDS AddPerformanceRecords; +}; + +typedef struct _ADD_PERFORMANCE_RECORD_PROTOCOL ADD_PERFORMANCE_RECORD_PROTOCOL; + + +extern EFI_GUID gAddPerfRecordProtocolGuid; +extern EFI_GUID gFspHobGuid; +extern EFI_GUID gFspApiPerformanceGuid; + +EFI_EVENT mExitBootServicesEvent = NULL; + +/** + Perform platform related reset in FSP wrapper. + + @param[in] ResetType The type of reset the platform has to perform. + + @return Will reset the system based on Reset status provided. + +**/ +VOID +EFIAPI +CallFspWrapperResetSystem ( + IN UINT32 ResetType + ); + +/** + Relocate this image under 4G memory. + + @param ImageHandle Handle of driver image. + @param SystemTable Pointer to system table. + + @retval EFI_SUCCESS Image successfully relocated. + @retval EFI_ABORTED Failed to relocate image. + +**/ +EFI_STATUS +RelocateImageUnder4GIfNeeded ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +FSP_INFO_HEADER *mFspHeader = NULL; + +/** + PciEnumerationComplete Protocol notification event handler. + + @param[in] Event Event whose notification function is being invoked. + @param[in] Context Pointer to the notification function's context. + +**/ +VOID +EFIAPI +OnPciEnumerationComplete ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + return; +} + +/** + Notification function of EVT_GROUP_READY_TO_BOOT event group. + + This is a notification function registered on EVT_GROUP_READY_TO_BOOT event group. + When the Boot Manager is about to load and execute a boot option, it reclaims variable + storage if free size is below the threshold. + + @param[in] Event Event whose notification function is being invoked. + @param[in] Context Pointer to the notification function's context. + +**/ +VOID +EFIAPI +OnReadyToBoot ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + NOTIFY_PHASE_PARAMS NotifyPhaseParams; + EFI_STATUS Status; + ADD_PERFORMANCE_RECORD_PROTOCOL *AddPerfRecordInterface; + EFI_PEI_HOB_POINTERS Hob; + VOID **FspHobListPtr; + + gBS->CloseEvent (Event); + NotifyPhaseParams.Phase = EnumInitPhaseReadyToBoot; + PERF_START_EX (&gFspApiPerformanceGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_READY_TO_BOOT_NOTIFICATION | FSP_STATUS_CODE_API_ENTRY); + Status = CallFspNotifyPhase (&NotifyPhaseParams); + PERF_END_EX (&gFspApiPerformanceGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_READY_TO_BOOT_NOTIFICATION | FSP_STATUS_CODE_API_EXIT); + + // + // Reset the system if FSP API returned FSP_STATUS_RESET_REQUIRED status + // + if ((Status & ~(0xF)) == (FSP_STATUS_RESET_REQUIRED_COLD & ~(0xF))) { + DEBUG ((DEBUG_INFO, "FSP NotifyPhase ReadyToBoot requested reset 0x%x\n", Status)); + CallFspWrapperResetSystem ((UINT32) Status); + } + if (Status != EFI_SUCCESS) { + DEBUG ((DEBUG_ERROR, "FSP NotifyPhase ReadyToBoot failed, status: 0x%x\n", Status)); + } else { + DEBUG ((DEBUG_INFO, "FSP NotifyPhase ReadyToBoot Success.\n")); + } + + Status = gBS->LocateProtocol ( + &gAddPerfRecordProtocolGuid, + NULL, + (VOID **) &AddPerfRecordInterface + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "gAddPerfRecordProtocolGuid - Locate protocol failed\n")); + return; + } else { + Hob.Raw = GetHobList (); + if (Hob.Raw != NULL) { + Hob.Raw = GetNextGuidHob (&gFspHobGuid, Hob.Raw); + FspHobListPtr = GET_GUID_HOB_DATA (Hob.Raw); + AddPerfRecordInterface->AddPerformanceRecords ((VOID *) (UINTN) (((UINT32) (UINTN) *FspHobListPtr) & 0xFFFFFFFF)); + } + } +} + +/** + This stage is notified just before the firmware/Preboot environment transfers + management of all system resources to the OS or next level execution environment. + + @param Event Event whose notification function is being invoked. + @param Context Pointer to the notification function's context, which is + always zero in current implementation. + +**/ +VOID +EFIAPI +OnEndOfFirmware ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + NOTIFY_PHASE_PARAMS NotifyPhaseParams; + EFI_STATUS Status; + + gBS->CloseEvent (Event); + + NotifyPhaseParams.Phase = EnumInitPhaseEndOfFirmware; + PERF_START_EX (&gFspApiPerformanceGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_END_OF_FIRMWARE_NOTIFICATION | FSP_STATUS_CODE_API_ENTRY); + Status = CallFspNotifyPhase (&NotifyPhaseParams); + PERF_END_EX (&gFspApiPerformanceGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_END_OF_FIRMWARE_NOTIFICATION | FSP_STATUS_CODE_API_EXIT); + + // + // Reset the system if FSP API returned FSP_STATUS_RESET_REQUIRED status + // + if ((Status & ~(0xF)) == (FSP_STATUS_RESET_REQUIRED_COLD & ~(0xF))) { + DEBUG ((DEBUG_INFO, "FSP NotifyPhase EndOfFirmware requested reset 0x%x\n", Status)); + CallFspWrapperResetSystem ((UINT32) Status); + } + if (Status != EFI_SUCCESS) { + DEBUG ((DEBUG_ERROR, "FSP NotifyPhase EndOfFirmware failed, status: 0x%x\n", Status)); + } else { + DEBUG ((DEBUG_INFO, "FSP NotifyPhase EndOfFirmware Success.\n")); + } +} + + +/** + Main entry for the FSP DXE module. + + This routine registers two callbacks to call fsp's notifies. + + @param[in] ImageHandle The firmware allocated handle for the EFI image. + @param[in] SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The entry point is executed successfully. + @retval other Some error occurs when executing this entry point. + +**/ +EFI_STATUS +EFIAPI +FspDxeEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + EFI_EVENT ReadyToBootEvent; + VOID *Registration; + EFI_EVENT ProtocolNotifyEvent; + + // + // Load this driver's image to memory + // + Status = RelocateImageUnder4GIfNeeded (ImageHandle, SystemTable); + if (EFI_ERROR (Status)) { + return EFI_SUCCESS; + } + + ProtocolNotifyEvent = EfiCreateProtocolNotifyEvent ( + &gEfiPciEnumerationCompleteProtocolGuid, + TPL_CALLBACK, + OnPciEnumerationComplete, + NULL, + &Registration + ); + ASSERT (ProtocolNotifyEvent != NULL); + + Status = EfiCreateEventReadyToBootEx ( + TPL_CALLBACK, + OnReadyToBoot, + NULL, + &ReadyToBootEvent + ); + ASSERT_EFI_ERROR (Status); + + Status = gBS->CreateEventEx ( + EVT_NOTIFY_SIGNAL, + TPL_NOTIFY, + OnEndOfFirmware, + NULL, + &gEfiEventExitBootServicesGuid, + &mExitBootServicesEvent + ); + ASSERT_EFI_ERROR (Status); + + return EFI_SUCCESS; +} + diff --git a/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/FspNotifyDxe/FspNotifyDxe.inf b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/FspNotifyDxe/FspNotifyDxe.inf new file mode 100644 index 0000000000..5300bb1915 --- /dev/null +++ b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/FspNotifyDxe/FspNotifyDxe.inf @@ -0,0 +1,76 @@ +## @file +# FSP DXE Module +# +# This driver will register two callbacks to call fsp's notifies. +# +# Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = FspNotifyDxe + FILE_GUID = AD61999A-507E-47E6-BA28-79CC609FA1A4 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = FspDxeEntryPoint + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources] + FspNotifyDxe.c + LoadBelow4G.c + +[Packages] + MdePkg/MdePkg.dec + BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec + BroxtonPlatformPkg/PlatformPkg.dec + BroxtonFspPkg/BroxtonFspPkg.dec + IntelFsp2Pkg/IntelFsp2Pkg.dec + IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec + +[LibraryClasses] + UefiDriverEntryPoint + UefiBootServicesTableLib + DebugLib + BaseMemoryLib + UefiLib + FspWrapperApiLib + FspWrapperPlatformResetLib + PeCoffLib + CacheMaintenanceLib + DxeServicesLib + PerformanceLib + HobLib + ReportStatusCodeLib + +[Protocols] + gEfiPciEnumerationCompleteProtocolGuid ## CONSUMES + gAddPerfRecordProtocolGuid ## CONSUMES + +[Guids] + gEfiEventExitBootServicesGuid ## CONSUMES + gFspApiPerformanceGuid ## CONSUMES + gFspHobGuid ## CONSUMES + gFspPerformanceDataGuid ## CONSUMES + +[Pcd] + gIntelFsp2WrapperTokenSpaceGuid.PcdFlashFvFspBase ## CONSUMES + gIntelFsp2WrapperTokenSpaceGuid.PcdFlashFvSecondFspBase ## CONSUMES + gIntelFsp2WrapperTokenSpaceGuid.PcdFlashFvFspSize ## CONSUMES + gIntelFsp2WrapperTokenSpaceGuid.PcdFspsBaseAddress ## CONSUMES + +[Depex] + TRUE diff --git a/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/FspNotifyDxe/LoadBelow4G.c b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/FspNotifyDxe/LoadBelow4G.c new file mode 100644 index 0000000000..c055c7f160 --- /dev/null +++ b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/FspNotifyDxe/LoadBelow4G.c @@ -0,0 +1,151 @@ +/** @file + Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** + Relocate this image under 4G memory. + + @param ImageHandle Handle of driver image. + @param SystemTable Pointer to system table. + + @retval EFI_SUCCESS Image successfully relocated. + @retval EFI_ABORTED Failed to relocate image. + +**/ +EFI_STATUS +RelocateImageUnder4GIfNeeded ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + UINT8 *Buffer; + UINTN BufferSize; + EFI_HANDLE NewImageHandle; + UINTN Pages; + EFI_PHYSICAL_ADDRESS FfsBuffer; + PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; + VOID *Interface; + + // + // If it is already <4G, no need do relocate + // + if ((UINTN)RelocateImageUnder4GIfNeeded < 0xFFFFFFFF) { + return EFI_SUCCESS; + } + + // + // If locate gEfiCallerIdGuid success, it means 2nd entry. + // + Status = gBS->LocateProtocol (&gEfiCallerIdGuid, NULL, &Interface); + if (!EFI_ERROR (Status)) { + DEBUG ((EFI_D_INFO, "FspNotifyDxe - 2nd entry\n")); + return EFI_SUCCESS; + } + + DEBUG ((EFI_D_INFO, "FspNotifyDxe - 1st entry\n")); + + // + // Here we install a dummy handle + // + NewImageHandle = NULL; + Status = gBS->InstallProtocolInterface ( + &NewImageHandle, + &gEfiCallerIdGuid, + EFI_NATIVE_INTERFACE, + NULL + ); + ASSERT_EFI_ERROR (Status); + + // + // Reload image itself to <4G mem + // + Status = GetSectionFromAnyFv ( + &gEfiCallerIdGuid, + EFI_SECTION_PE32, + 0, + (VOID **) &Buffer, + &BufferSize + ); + ASSERT_EFI_ERROR (Status); + ImageContext.Handle = Buffer; + ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory; + // + // Get information about the image being loaded + // + Status = PeCoffLoaderGetImageInfo (&ImageContext); + ASSERT_EFI_ERROR (Status); + if (ImageContext.SectionAlignment > EFI_PAGE_SIZE) { + Pages = EFI_SIZE_TO_PAGES ((UINTN) (ImageContext.ImageSize + ImageContext.SectionAlignment)); + } else { + Pages = EFI_SIZE_TO_PAGES ((UINTN) ImageContext.ImageSize); + } + FfsBuffer = 0xFFFFFFFF; + Status = gBS->AllocatePages ( + AllocateMaxAddress, + EfiBootServicesCode, + Pages, + &FfsBuffer + ); + ASSERT_EFI_ERROR (Status); + ImageContext.ImageAddress = (PHYSICAL_ADDRESS) (UINTN) FfsBuffer; + // + // Align buffer on section boundry + // + ImageContext.ImageAddress += ImageContext.SectionAlignment - 1; + ImageContext.ImageAddress &= ~((EFI_PHYSICAL_ADDRESS) (ImageContext.SectionAlignment - 1)); + // + // Load the image to our new buffer + // + Status = PeCoffLoaderLoadImage (&ImageContext); + ASSERT_EFI_ERROR (Status); + + // + // Relocate the image in our new buffer + // + Status = PeCoffLoaderRelocateImage (&ImageContext); + ASSERT_EFI_ERROR (Status); + + // + // Free the buffer allocated by ReadSection since the image has been relocated in the new buffer + // + gBS->FreePool (Buffer); + + // + // Flush the instruction cache so the image data is written before we execute it + // + InvalidateInstructionCacheRange ((VOID *) (UINTN) ImageContext.ImageAddress, (UINTN) ImageContext.ImageSize); + + DEBUG ((EFI_D_INFO, "Loading driver at 0x%08x EntryPoint=0x%08x\n", (UINTN) ImageContext.ImageAddress, (UINTN) ImageContext.EntryPoint)); + Status = ((EFI_IMAGE_ENTRY_POINT) (UINTN) (ImageContext.EntryPoint)) (NewImageHandle, gST); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "Error: Image at 0x%08x start failed: %r\n", ImageContext.ImageAddress, Status)); + gBS->FreePages (FfsBuffer, Pages); + } + + // + // return error to unload >4G copy, if we already relocate itself to <4G. + // + return EFI_ALREADY_STARTED; +} + diff --git a/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/FspmWrapperPeim/FspmWrapperPeim.c b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/FspmWrapperPeim/FspmWrapperPeim.c new file mode 100644 index 0000000000..f403d1e214 --- /dev/null +++ b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/FspmWrapperPeim/FspmWrapperPeim.c @@ -0,0 +1,266 @@ +/** @file + This will be invoked only once. It will call FspMemoryInit API, + register TemporaryRamDonePpi to call TempRamExit API, and register MemoryDiscoveredPpi + notify to call FspSiliconInit API. + + Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +BOOLEAN ImageInMemory = FALSE; + + +VOID +EFIAPI +FspPolicyInitPreMem ( + IN OUT FSPM_UPD *FspmUpd + ); +/** + This function is called after PEI core discover memory and finish migration. + + @param[in] PeiServices Pointer to PEI Services Table. + @param[in] NotifyDesc Pointer to the descriptor for the Notification event that + caused this function to execute. + @param[in] Ppi Pointer to the PPI data associated with this function. + + @retval EFI_STATUS Always return EFI_SUCCESS + +**/ +EFI_STATUS +EFIAPI +PeiMemoryDiscoveredNotify ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc, + IN VOID *Ppi + ); + +EFI_PEI_NOTIFY_DESCRIPTOR mPeiPreMemNotifyDesc[] = { + { + (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gEfiPeiMemoryDiscoveredPpiGuid, + PeiMemoryDiscoveredNotify + } +}; + +EFI_PEI_PPI_DESCRIPTOR mFspTempRamExitPpiList[] = { + { + (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gFspTempRamExitGuid, + NULL + } +}; + + +/** + Call FspMemoryInit API. + + @return Status returned by FspMemoryInit API. + +**/ +EFI_STATUS +PeiFspMemoryInit ( + IN CONST EFI_PEI_SERVICES **PeiServices + ) +{ + FSP_INFO_HEADER *FspmHeaderPtr; + EFI_STATUS Status; + UINT64 TimeStampCounterStart; + VOID *FspHobListPtr; + VOID *HobData; + FSPM_UPD *FspmUpdDataPtr; + UINTN *SourceData; + + DEBUG ((DEBUG_INFO, "PeiFspMemoryInit enter\n")); + + FspHobListPtr = NULL; + + // + // Copy default FSP-M UPD data from Flash + // + FspmHeaderPtr = (FSP_INFO_HEADER *) FspFindFspHeader (PcdGet32 (PcdFspmBaseAddress)); + + DEBUG ((DEBUG_INFO, "PcdFspmBaseAddress = 0x%X\n", PcdGet32 (PcdFspmBaseAddress))); + DEBUG ((DEBUG_INFO, "FspmHeaderPtr = 0x%X\n", FspmHeaderPtr)); + DEBUG ((DEBUG_INFO, "FspmHeaderPtr->CfgRegionSize = 0x%X\n", FspmHeaderPtr->CfgRegionSize)); + + FspmUpdDataPtr = (FSPM_UPD *) AllocateZeroPool ((UINTN) FspmHeaderPtr->CfgRegionSize); + ASSERT (FspmUpdDataPtr != NULL); + SourceData = (UINTN *) ((UINTN) FspmHeaderPtr->ImageBase + (UINTN) FspmHeaderPtr->CfgRegionOffset); + CopyMem (FspmUpdDataPtr, SourceData, (UINTN)FspmHeaderPtr->CfgRegionSize); + + DEBUG ((DEBUG_INFO, "FspWrapperPlatformInitPreMem enter\n")); + FspmUpdDataPtr = UpdateFspUpdConfigs (PeiServices, FspmUpdDataPtr); + FspPolicyInitPreMem (FspmUpdDataPtr); + + DEBUG ((DEBUG_INFO, " NvsBufferPtr - 0x%x\n", FspmUpdDataPtr->FspmArchUpd.NvsBufferPtr)); + DEBUG ((DEBUG_INFO, " StackBase - 0x%x\n", FspmUpdDataPtr->FspmArchUpd.StackBase)); + DEBUG ((DEBUG_INFO, " StackSize - 0x%x\n", FspmUpdDataPtr->FspmArchUpd.StackSize)); + DEBUG ((DEBUG_INFO, " BootLoaderTolumSize - 0x%x\n", FspmUpdDataPtr->FspmArchUpd.BootLoaderTolumSize)); + DEBUG ((DEBUG_INFO, " BootMode - 0x%x\n", FspmUpdDataPtr->FspmArchUpd.BootMode)); + DEBUG ((DEBUG_INFO, " HobListPtr - 0x%x\n", &FspHobListPtr)); + TimeStampCounterStart = AsmReadTsc (); + Status = CallFspMemoryInit (FspmUpdDataPtr, &FspHobListPtr); + PERF_START_EX (&gFspApiPerformanceGuid, "EventRec", NULL, TimeStampCounterStart, 0xD000); + PERF_END_EX (&gFspApiPerformanceGuid, "EventRec", NULL, 0, 0xD07F); + DEBUG ((DEBUG_INFO, "Total time spent executing FspMemoryInitApi: %d millisecond\n", DivU64x32(GetTimeInNanoSecond(AsmReadTsc() - TimeStampCounterStart), 1000000))); + // Reset the system if FSP API returned FSP_STATUS_RESET_REQUIRED status + if ((Status & ~(0xF)) == (FSP_STATUS_RESET_REQUIRED_COLD & ~(0xF))) { + DEBUG ((DEBUG_INFO, "FspMemoryInitApi requested reset 0x%x\n", Status)); + CallFspWrapperResetSystem ((UINT32) Status); + } + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "ERROR - Failed to execute FspMemoryInitApi(), Status = %r\n", Status)); + } + DEBUG ((DEBUG_INFO, "FspMemoryInit status: 0x%x\n", Status)); + ASSERT_EFI_ERROR (Status); + + DEBUG ((DEBUG_INFO, " FspHobListPtr (returned) - 0x%x\n", FspHobListPtr)); + ASSERT (FspHobListPtr != NULL); + + FspHobProcessForMemoryResource (FspHobListPtr); + + // + // FspHobList is not complete at this moment. + // Save FspHobList pointer to hob, so that it can be got later + // + HobData = BuildGuidHob ( + &gFspHobGuid, + sizeof (VOID *) + ); + ASSERT (HobData != NULL); + CopyMem (HobData, &FspHobListPtr, sizeof (FspHobListPtr)); + + return Status; +} + +/** + TemporaryRamDone() disables the use of Temporary RAM. If present, this service is invoked + by the PEI Foundation after the EFI_PEI_PERMANANT_MEMORY_INSTALLED_PPI is installed. + + @retval EFI_SUCCESS Use of Temporary RAM was disabled. + @retval EFI_INVALID_PARAMETER Temporary RAM could not be disabled. + +**/ +EFI_STATUS +EFIAPI +PeiMemoryDiscoveredNotify ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc, + IN VOID *Ppi + ) +{ + UINT64 TimeStampCounterStart; + EFI_STATUS Status; + VOID *TempRamExitParam; + + DEBUG ((DEBUG_INFO, "PeiTemporaryRamDone enter\n")); + + TempRamExitParam = GetTempRamExitParam (); + TimeStampCounterStart = AsmReadTsc (); + PERF_START_EX (&gFspApiPerformanceGuid, "EventRec", NULL, 0, 0xB000); + Status = CallTempRamExit (TempRamExitParam); + PERF_END_EX (&gFspApiPerformanceGuid, "EventRec", NULL, 0, 0xB07F); + DEBUG ((DEBUG_INFO, "Total time spent executing FspTempRamExitApi: %d millisecond\n", DivU64x32 (GetTimeInNanoSecond (AsmReadTsc () - TimeStampCounterStart), 1000000))); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "ERROR - Failed to execute FspTempRamExitApi(), Status = %r\n", Status)); + } + DEBUG ((DEBUG_INFO, "TempRamExit status: 0x%x\n", Status)); + ASSERT_EFI_ERROR (Status); + + // + // Install gFspTempRamExitGuid to notify wrapper. + // + Status = PeiServicesInstallPpi (mFspTempRamExitPpiList); + ASSERT_EFI_ERROR (Status); + + return EFI_SUCCESS; +} + +/** + Do FSP initialization. + + @return FSP initialization status. + +**/ +EFI_STATUS +EFIAPI +FspmWrapperInit ( + IN CONST EFI_PEI_SERVICES **PeiServices + ) +{ + EFI_STATUS Status; + + if (!ImageInMemory) { + Status = PeiFspMemoryInit (PeiServices); + ASSERT_EFI_ERROR (Status); + } else { + // + // Register MemoryDiscovered Notify to run TempRamExit + // + Status = PeiServicesNotifyPpi (&mPeiPreMemNotifyDesc[0]); + ASSERT_EFI_ERROR (Status); + } + return Status; +} + +/** + This is the entrypoint of PEIM + + @param[in] FileHandle Handle of the file being invoked. + @param[in] PeiServices Describes the list of possible PEI Services. + + @retval EFI_SUCCESS if it completed successfully. + +**/ +EFI_STATUS +EFIAPI +FspmWrapperPeimEntryPoint ( + IN EFI_PEI_FILE_HANDLE FileHandle, + IN CONST EFI_PEI_SERVICES **PeiServices + ) +{ + EFI_STATUS Status = EFI_SUCCESS; + + Status = (*PeiServices)->RegisterForShadow (FileHandle); + + if (Status == EFI_ALREADY_STARTED) { + ImageInMemory = TRUE; + } else if (Status == EFI_NOT_FOUND) { + ASSERT_EFI_ERROR (Status); + } + + DEBUG((DEBUG_INFO, "FspmWrapperPeimEntryPoint\n")); + FspmWrapperInit (PeiServices); + + return EFI_SUCCESS; +} + diff --git a/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/FspmWrapperPeim/FspmWrapperPeim.inf b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/FspmWrapperPeim/FspmWrapperPeim.inf new file mode 100644 index 0000000000..9e5fa965c0 --- /dev/null +++ b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/FspmWrapperPeim/FspmWrapperPeim.inf @@ -0,0 +1,105 @@ +## @file +# FSP-M wrapper PEI Module +# +# This PEIM initialize FSP. +# This will be invoked only once. It will call FspMemoryInit API, +# register TemporaryRamDonePpi to call TempRamExit API, and register MemoryDiscoveredPpi +# notify to call FspSiliconInit API. +# +# Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +[Defines] + INF_VERSION = 0x00010017 + BASE_NAME = FspmWrapperPeim + FILE_GUID = 9FAAD0FF-0E0C-4885-A738-BAB4E4FA1E66 + VERSION_STRING = 1.0 + MODULE_TYPE = PEIM + ENTRY_POINT = FspmWrapperPeimEntryPoint + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 +# + +[LibraryClasses] + PeimEntryPoint + PeiServicesLib + PeiServicesTablePointerLib + BaseLib + BaseMemoryLib + MemoryAllocationLib + DebugLib + HobLib + FspWrapperPlatformLib + FspWrapperHobProcessLib + DebugAgentLib + UefiCpuLib + PeCoffGetEntryPointLib + PeCoffExtraActionLib + PerformanceLib + TimerLib + FspWrapperApiLib + FspWrapperApiTestLib + FspPlatformSecLib + FspPolicyInitLib + PerformanceLib + FspWrapperPlatformResetLib + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + UefiCpuPkg/UefiCpuPkg.dec + BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec + IntelFsp2Pkg/IntelFsp2Pkg.dec + IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec + BroxtonPlatformPkg/PlatformPkg.dec + BroxtonSiPkg/BroxtonSiPkg.dec + BroxtonFspPkg/BroxtonFspPkg.dec + +[Pcd] + gIntelFsp2WrapperTokenSpaceGuid.PcdFspmBaseAddress ## CONSUMES + gIntelFsp2WrapperTokenSpaceGuid.PcdPeiTemporaryRamStackSize ## CONSUMES + gIntelFsp2WrapperTokenSpaceGuid.PcdFlashFvFspBase ## CONSUMES + gIntelFsp2WrapperTokenSpaceGuid.PcdFlashFvSecondFspBase ## CONSUMES + gIntelFsp2WrapperTokenSpaceGuid.PcdFlashFvFspSize ## CONSUMES + gIntelFsp2WrapperTokenSpaceGuid.PcdFspsBaseAddress ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase + gIntelFsp2PkgTokenSpaceGuid.PcdFspAreaSize + +[Sources] + FspmWrapperPeim.c + ..\FspInitPei\SecMain.c + ..\FspInitPei\SecMain.h + ..\FspInitPei\FindPeiCore.c + +[Ppis] + gTopOfTemporaryRamPpiGuid ## PRODUCES + gEfiEndOfPeiSignalPpiGuid ## PRODUCES + gEfiTemporaryRamDonePpiGuid ## PRODUCES + gEfiPeiMemoryDiscoveredPpiGuid ## PRODUCES + gEfiPeiMasterBootModePpiGuid + +[FixedPcd] + gIntelFsp2WrapperTokenSpaceGuid.PcdSecCoreMaxPpiSupported ## CONSUMES + +[Guids] + gFspHobGuid ## PRODUCES ## HOB + gEfiPlatformInfoGuid + gEfiSystemNvDataFvGuid + gFspApiPerformanceGuid ## CONSUMES + gFspTempRamExitGuid + +[Depex] + TRUE + diff --git a/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/FspsWrapperPeim/FspsWrapperPeim.c b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/FspsWrapperPeim/FspsWrapperPeim.c new file mode 100644 index 0000000000..7343b77b58 --- /dev/null +++ b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/FspsWrapperPeim/FspsWrapperPeim.c @@ -0,0 +1,332 @@ +/** @file + This will be invoked only once. It will call FspMemoryInit API, + register TemporaryRamDonePpi to call TempRamExit API, and register MemoryDiscoveredPpi + notify to call FspSiliconInit API. + + Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern EFI_PEI_NOTIFY_DESCRIPTOR mS3EndOfPeiNotifyDesc; +extern EFI_GUID gFspApiPerformanceGuid; + +VOID +EFIAPI +FspPolicyInit ( + IN OUT FSPS_UPD *FspsUpd + ); + +/** + This function handles S3 resume task at the end of PEI + + @param[in] PeiServices Pointer to PEI Services Table. + @param[in] NotifyDesc Pointer to the descriptor for the Notification event that + caused this function to execute. + @param[in] Ppi Pointer to the PPI data associated with this function. + + @retval EFI_STATUS Always return EFI_SUCCESS + +**/ +EFI_STATUS +EFIAPI +S3EndOfPeiNotify ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc, + IN VOID *Ppi + ); + +EFI_PEI_NOTIFY_DESCRIPTOR mS3EndOfPeiNotifyDesc = { + (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gEfiEndOfPeiSignalPpiGuid, + S3EndOfPeiNotify +}; + +/** + This function handles S3 resume task at the end of PEI + + @param[in] PeiServices Pointer to PEI Services Table. + @param[in] NotifyDesc Pointer to the descriptor for the Notification event that + caused this function to execute. + @param[in] Ppi Pointer to the PPI data associated with this function. + + @retval EFI_STATUS Always return EFI_SUCCESS + +**/ +EFI_STATUS +EFIAPI +S3EndOfPeiNotify ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc, + IN VOID *Ppi + ) +{ + NOTIFY_PHASE_PARAMS NotifyPhaseParams; + EFI_STATUS Status; + + DEBUG ((DEBUG_INFO, "S3EndOfPeiNotify enter\n")); + + NotifyPhaseParams.Phase = EnumInitPhaseAfterPciEnumeration; + Status = CallFspNotifyPhase (&NotifyPhaseParams); + DEBUG((DEBUG_INFO, "FSP S3NotifyPhase AfterPciEnumeration status: 0x%x\n", Status)); + + NotifyPhaseParams.Phase = EnumInitPhaseReadyToBoot; + Status = CallFspNotifyPhase (&NotifyPhaseParams); + DEBUG((DEBUG_INFO, "FSP S3NotifyPhase ReadyToBoot status: 0x%x\n", Status)); + + NotifyPhaseParams.Phase = EnumInitPhaseEndOfFirmware; + Status = CallFspNotifyPhase (&NotifyPhaseParams); + DEBUG((DEBUG_INFO, "FSP S3NotifyPhase EndOfFirmware status: 0x%x\n", Status)); + + return EFI_SUCCESS; +} + +/** + Return Hob list produced by FSP. + + @param[in] PeiServices The pointer to the PEI Services Table. + @param[in] This The pointer to this instance of this PPI. + @param[out] FspHobList The pointer to Hob list produced by FSP. + + @return EFI_SUCCESS FReturn Hob list produced by FSP successfully. + +**/ +EFI_STATUS +EFIAPI +FspSiliconInitDoneGetFspHobList ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN FSP_SILICON_INIT_DONE_PPI *This, + OUT VOID **FspHobList + ); + +FSP_SILICON_INIT_DONE_PPI mFspSiliconInitDonePpi = { + FspSiliconInitDoneGetFspHobList +}; + +EFI_PEI_PPI_DESCRIPTOR mPeiFspSiliconInitDonePpi = { + EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST, + &gFspSiliconInitDonePpiGuid, + &mFspSiliconInitDonePpi +}; + +/** + This function is called after PEI core discover memory and finish migration. + + @param[in] PeiServices Pointer to PEI Services Table. + @param[in] NotifyDesc Pointer to the descriptor for the Notification event that + caused this function to execute. + @param[in] Ppi Pointer to the PPI data associated with this function. + + @retval EFI_STATUS Always return EFI_SUCCESS + +**/ +EFI_STATUS +EFIAPI +PeiMasterBootModeNotify ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc, + IN VOID *Ppi + ); + +EFI_PEI_NOTIFY_DESCRIPTOR mPeiNotifyDesc[] = { + { + (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gEfiPeiMasterBootModePpiGuid, + PeiMasterBootModeNotify + } +}; + +/** + Return Hob list produced by FSP. + + @param[in] PeiServices The pointer to the PEI Services Table. + @param[in] This The pointer to this instance of this PPI. + @param[out] FspHobList The pointer to Hob list produced by FSP. + + @return EFI_SUCCESS FReturn Hob list produced by FSP successfully. + +**/ +EFI_STATUS +EFIAPI +FspSiliconInitDoneGetFspHobList ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN FSP_SILICON_INIT_DONE_PPI *This, + OUT VOID **FspHobList + ) +{ + EFI_HOB_GUID_TYPE *GuidHob; + + GuidHob = GetFirstGuidHob (&gFspHobGuid); + if (GuidHob != NULL) { + *FspHobList = *(VOID **)GET_GUID_HOB_DATA (GuidHob); + return EFI_SUCCESS; + } else { + return EFI_NOT_FOUND; + } +} + + +/** + This function is called after PEI core discover memory and finish migration. + + @param[in] PeiServices Pointer to PEI Services Table. + @param[in] NotifyDesc Pointer to the descriptor for the Notification event that + caused this function to execute. + @param[in] Ppi Pointer to the PPI data associated with this function. + + @retval EFI_STATUS Always return EFI_SUCCESS + +**/ +EFI_STATUS +EFIAPI +PeiMasterBootModeNotify ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc, + IN VOID *Ppi + ) +{ + FSP_INFO_HEADER *FspsHeaderPtr; + UINT64 TimeStampCounterStart; + EFI_STATUS Status; + VOID *FspHobListPtr; + EFI_HOB_GUID_TYPE *GuidHob; + FSPS_UPD_COMMON *FspsUpdDataPtr; + UINTN *SourceData; + + DEBUG ((DEBUG_INFO, "FspSiliconInit enter\n")); + + // + // Copy default FSP-S UPD data from Flash + // + FspsHeaderPtr = (FSP_INFO_HEADER *) FspFindFspHeader (PcdGet32 (PcdFspsBaseAddress)); + FspsHeaderPtr->ImageBase = (UINT32) (PcdGet32 (PcdFspsBaseAddress)); + + FspsUpdDataPtr = (FSPS_UPD_COMMON *) AllocateZeroPool ((UINTN) FspsHeaderPtr->CfgRegionSize); + ASSERT (FspsUpdDataPtr != NULL); + SourceData = (UINTN *) ((UINTN) FspsHeaderPtr->ImageBase + (UINTN) FspsHeaderPtr->CfgRegionOffset); + CopyMem (FspsUpdDataPtr, SourceData, (UINTN) FspsHeaderPtr->CfgRegionSize); + FspPolicyInit ((FSPS_UPD *) FspsUpdDataPtr); + + TimeStampCounterStart = AsmReadTsc (); + PERF_START_EX (&gFspApiPerformanceGuid, "EventRec", NULL, 0, 0x9000); + Status = CallFspSiliconInit ((VOID *) FspsUpdDataPtr); + PERF_END_EX (&gFspApiPerformanceGuid, "EventRec", NULL, 0, 0x907F); + + DEBUG ((DEBUG_INFO, "Total time spent executing FspSiliconInitApi: %d millisecond\n", DivU64x32 (GetTimeInNanoSecond (AsmReadTsc () - TimeStampCounterStart), 1000000))); + + // + // Reset the system if FSP API returned FSP_STATUS_RESET_REQUIRED status + // + if ((Status & ~(0xF)) == (FSP_STATUS_RESET_REQUIRED_COLD & ~(0xF))) { + DEBUG ((DEBUG_INFO, "FspSiliconInitApi requested reset 0x%x\n", Status)); + CallFspWrapperResetSystem ((UINT32) Status); + } + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "ERROR - Failed to execute FspSiliconInitApi(), Status = %r\n", Status)); + } + DEBUG ((DEBUG_INFO, "FspSiliconInit status: 0x%x\n", Status)); + ASSERT_EFI_ERROR (Status); + + // + // Now FspHobList complete, process it + // + GuidHob = GetFirstGuidHob (&gFspHobGuid); + ASSERT (GuidHob != NULL); + FspHobListPtr = *(VOID **) GET_GUID_HOB_DATA (GuidHob); + DEBUG ((DEBUG_INFO, "FspHobListPtr - 0x%x\n", FspHobListPtr)); + FspHobProcessForOtherData (FspHobListPtr); + DumpFspSmbiosMemoryInfoHob (FspHobListPtr); + + // + // Install FspSiliconInitDonePpi so that any other driver can consume this info. + // + Status = PeiServicesInstallPpi (&mPeiFspSiliconInitDonePpi); + ASSERT_EFI_ERROR (Status); + + return Status; +} + +/** + Do FSP initialization. + + @return FSP initialization status. + +**/ +EFI_STATUS +FspsWrapperInit ( + VOID + ) +{ + EFI_STATUS Status; + EFI_BOOT_MODE BootMode; + + // + // Register MemoryDiscovered Notify to run FspSiliconInit + // + Status = PeiServicesNotifyPpi (&mPeiNotifyDesc[0]); + ASSERT_EFI_ERROR (Status); + + // + // Register EndOfPei Notify for S3 to run FSP NotifyPhase + // + PeiServicesGetBootMode (&BootMode); + if (BootMode == BOOT_ON_S3_RESUME) { + Status = PeiServicesNotifyPpi (&mS3EndOfPeiNotifyDesc); + ASSERT_EFI_ERROR (Status); + } + + return EFI_SUCCESS; +} + +/** + This is the entrypoint of PEIM + + @param[in] FileHandle Handle of the file being invoked. + @param[in] PeiServices Describes the list of possible PEI Services. + + @retval EFI_SUCCESS if it completed successfully. + +**/ +EFI_STATUS +EFIAPI +FspsWrapperPeimEntryPoint ( + IN EFI_PEI_FILE_HANDLE FileHandle, + IN CONST EFI_PEI_SERVICES **PeiServices + ) +{ + DEBUG ((DEBUG_INFO, "FspsWrapperPeimEntryPoint\n")); + + FspsWrapperInit (); + + return EFI_SUCCESS; +} + diff --git a/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/FspsWrapperPeim/FspsWrapperPeim.inf b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/FspsWrapperPeim/FspsWrapperPeim.inf new file mode 100644 index 0000000000..cdb666d9df --- /dev/null +++ b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/FspsWrapperPeim/FspsWrapperPeim.inf @@ -0,0 +1,105 @@ +## @file +# FSP-S wrapper PEI Module +# +# This PEIM initialize FSP. +# This will be invoked only once. It will call FspMemoryInit API, +# register TemporaryRamDonePpi to call TempRamExit API, and register MemoryDiscoveredPpi +# notify to call FspSiliconInit API. +# +# Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +[Defines] + INF_VERSION = 0x00010017 + BASE_NAME = FspsWrapperPeim + FILE_GUID = 0D244DF9-6CE3-4133-A1CF-53200AB663AC + VERSION_STRING = 1.0 + MODULE_TYPE = PEIM + ENTRY_POINT = FspsWrapperPeimEntryPoint + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 +# + +[LibraryClasses] + PeimEntryPoint + PeiServicesLib + PeiServicesTablePointerLib + BaseLib + BaseMemoryLib + TimerLib + DebugLib + HobLib + MemoryAllocationLib + FspWrapperPlatformLib + FspWrapperHobProcessLib + DebugAgentLib + UefiCpuLib + PeCoffGetEntryPointLib + PeCoffExtraActionLib + PerformanceLib + FspWrapperApiLib + FspWrapperApiTestLib + FspCommonLib + FspPolicyInitLib + FspPlatformSecLib + FspWrapperPlatformResetLib + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + UefiCpuPkg/UefiCpuPkg.dec + BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec + IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec + BroxtonSiPkg/BroxtonSiPkg.dec + BroxtonFspPkg/BroxtonFspPkg.dec + IntelFsp2Pkg/IntelFsp2Pkg.dec + +[Ppis] + gTopOfTemporaryRamPpiGuid ## PRODUCES + gFspSiliconInitDonePpiGuid ## PRODUCES + gEfiEndOfPeiSignalPpiGuid ## PRODUCES + gEfiTemporaryRamDonePpiGuid ## PRODUCES + gEfiPeiMemoryDiscoveredPpiGuid ## PRODUCES + gEfiPeiMasterBootModePpiGuid + +[FixedPcd] + gIntelFsp2WrapperTokenSpaceGuid.PcdSecCoreMaxPpiSupported ## CONSUMES + +[Pcd] + gIntelFsp2WrapperTokenSpaceGuid.PcdFspsBaseAddress ## CONSUMES + gIntelFsp2WrapperTokenSpaceGuid.PcdPeiTemporaryRamStackSize ## CONSUMES + gIntelFsp2WrapperTokenSpaceGuid.PcdFlashFvFspBase ## CONSUMES + gIntelFsp2WrapperTokenSpaceGuid.PcdFlashFvSecondFspBase ## CONSUMES + gIntelFsp2WrapperTokenSpaceGuid.PcdFlashFvFspSize ## CONSUMES + gIntelFsp2WrapperTokenSpaceGuid.PcdFspsBaseAddress ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase + gIntelFsp2PkgTokenSpaceGuid.PcdFspAreaSize + +[Guids] + gFspHobGuid ## CONSUMES ## HOB + gFspApiPerformanceGuid ## CONSUMES ## GUID + gEfiPlatformInfoGuid + gEfiSystemNvDataFvGuid + gFspNonVolatileStorageHobGuid ## CONSUMES + +[Sources] + FspsWrapperPeim.c + ..\FspInitPei\SecMain.c + ..\FspInitPei\SecMain.h + ..\FspInitPei\FindPeiCore.c + +[Depex] + TRUE + diff --git a/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Include/Library/FspHobProcessLib.h b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Include/Library/FspHobProcessLib.h new file mode 100644 index 0000000000..b7ec68e813 --- /dev/null +++ b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Include/Library/FspHobProcessLib.h @@ -0,0 +1,71 @@ +/** @file + Provide FSP hob process related function. + + Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef __FSP_HOB_PROCESS_LIB_H__ +#define __FSP_HOB_PROCESS_LIB_H__ + +/** + BIOS process FspBobList. + + @param[in] FspHobList Pointer to the HOB data structure produced by FSP. + + @return If platform process the FSP hob list successfully. + +**/ +EFI_STATUS +EFIAPI +FspHobProcess ( + IN VOID *FspHobList + ); + +/** + BIOS process FspBobList for Memory Resource Descriptor. + + @param[in] FspHobList Pointer to the HOB data structure produced by FSP. + + @return If platform process the FSP hob list successfully. + +**/ +EFI_STATUS +EFIAPI +FspHobProcessForMemoryResource ( + IN VOID *FspHobList + ); + +/** + BIOS process FspBobList for other data (not Memory Resource Descriptor). + + @param[in] FspHobList Pointer to the HOB data structure produced by FSP. + + @return If platform process the FSP hob list successfully. + +**/ +EFI_STATUS +EFIAPI +FspHobProcessForOtherData ( + IN VOID *FspHobList + ); + +/** + Dump FSP SMBIOS memory info HOB + +**/ +VOID +DumpFspSmbiosMemoryInfoHob ( + IN VOID *FspHobList + ); + +#endif + diff --git a/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Include/Library/FspPlatformInfoLib.h b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Include/Library/FspPlatformInfoLib.h new file mode 100644 index 0000000000..f965b02647 --- /dev/null +++ b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Include/Library/FspPlatformInfoLib.h @@ -0,0 +1,167 @@ +/** @file + Provide FSP platform information related function. + + Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef __FSP_PLATFORM_INFO_LIB_H__ +#define __FSP_PLATFORM_INFO_LIB_H__ + +/** + Get current boot mode. + + @note At this point, memory is ready, PeiServices are NOT available to use. + Platform can get some data from chipset register. + + @return BootMode current boot mode. + +**/ +UINT32 +EFIAPI +GetBootMode ( + VOID + ); + +/** + Get NVS buffer parameter. + + @note At this point, memory is NOT ready, PeiServices are available to use. + + @return NvsBuffer NVS buffer parameter. + +**/ +VOID * +EFIAPI +GetNvsBuffer ( + VOID + ); + +/** + This function overrides the default configurations in the UPD data region. + + @param[in] PeiServices Describes the list of possible PEI Services. + @param[in, out] FspUpdRgnPtr A pointer to the UPD data region data strcture. + + @return FspUpdRgnPtr A pointer to the UPD data region data strcture. + +**/ +VOID * +EFIAPI +UpdateFspUpdConfigs ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN OUT VOID *FspUpdRgnPtr + ); + +/** + Get BootLoader Tolum size. + + @note At this point, memory is NOT ready, PeiServices are available to use. + + @return BootLoader Tolum size. + +**/ +UINT32 +EFIAPI +GetBootLoaderTolumSize ( + VOID + ); + +/** + Get TempRamExit parameter. + + @note At this point, memory is ready, PeiServices are available to use. + + @return TempRamExit parameter. + +**/ +VOID * +EFIAPI +GetTempRamExitParam ( + VOID + ); + +/** + Get FspSiliconInit parameter. + + @note At this point, memory is ready, PeiServices are available to use. + + @return FspSiliconInit parameter. + +**/ +VOID * +EFIAPI +GetFspSiliconInitParam ( + VOID + ); + +/** + Get S3 PEI memory information. + + @note At this point, memory is ready, and PeiServices are available to use. + Platform can get some data from SMRAM directly. + + @param[out] S3PeiMemSize PEI memory size to be installed in S3 phase. + @param[out] S3PeiMemBase PEI memory base to be installed in S3 phase. + + @return If S3 PEI memory information is got successfully. + +**/ +EFI_STATUS +EFIAPI +GetS3MemoryInfo ( + OUT UINT64 *S3PeiMemSize, + OUT EFI_PHYSICAL_ADDRESS *S3PeiMemBase + ); + +/** + Get stack information according to boot mode. + + @note If BootMode is BOOT_ON_S3_RESUME or BOOT_ON_FLASH_UPDATE, + this stack should be in some reserved memory space. + + @note If FspInitDone is TRUE, memory is ready, but no PeiServices there. + Platform can get some data from SMRAM directly. + @note If FspInitDone is FALSE, memory is NOT ready, but PeiServices are available to use. + Platform can get some data from variable via VariablePpi. + + @param[in] BootMode Current boot mode. + @param[in] FspInitDone If FspInit is called. + @param[out] StackSize Stack size to be used in PEI phase. + @param[out] StackBase Stack base to be used in PEI phase. + + @return If Stack information is got successfully. + +**/ +EFI_STATUS +EFIAPI +GetStackInfo ( + IN UINT32 BootMode, + IN BOOLEAN FspInitDone, + OUT UINT64 *StackSize, + OUT EFI_PHYSICAL_ADDRESS *StackBase + ); + +/** + Perform platform related reset in FSP wrapper. + + @param[in] ResetType The type of reset the platform has to perform. + + @return Will reset the system based on Reset status provided. + +**/ +VOID +EFIAPI +CallFspWrapperResetSystem ( + IN UINT32 ResetType + ); +#endif + diff --git a/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Include/Library/FspPlatformSecLib.h b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Include/Library/FspPlatformSecLib.h new file mode 100644 index 0000000000..034651b203 --- /dev/null +++ b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Include/Library/FspPlatformSecLib.h @@ -0,0 +1,71 @@ +/** @file + Provide FSP wrapper platform sec related function. + + Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef __FSP_PLATFORM_SEC_LIB_H__ +#define __FSP_PLATFORM_SEC_LIB_H__ + +/** + A developer supplied function to perform platform specific operations. + + It's a developer supplied function to perform any operations appropriate to a + given platform. It's invoked just before passing control to PEI core by SEC + core. Platform developer may modify the SecCoreData passed to PEI Core. + It returns a platform specific PPI list that platform wishes to pass to PEI core. + The Generic SEC core module will merge this list to join the final list passed to + PEI core. + + @param[in, out] SecCoreData The same parameter as passing to PEI core. It + could be overridden by this function. + + @return The platform specific PPI list to be passed to PEI core or + NULL if there is no need of such platform specific PPI list. + +**/ +EFI_PEI_PPI_DESCRIPTOR * +EFIAPI +SecPlatformMain ( + IN OUT EFI_SEC_PEI_HAND_OFF *SecCoreData + ); + +/** + Call PEI core entry point with new temporary RAM. + + @param[in] FspHobList HobList produced by FSP. + @param[in] StartOfRange Start of temporary RAM. + @param[in] EndOfRange End of temporary RAM. + +**/ +VOID +EFIAPI +CallPeiCoreEntryPoint ( + IN VOID *FspHobList, + IN VOID *StartOfRange, + IN VOID *EndOfRange + ); + +/** + Save SEC context before call FspInit. + + @param[in] PeiServices Pointer to PEI Services Table. + +**/ +VOID +EFIAPI +SaveSecContext ( + IN CONST EFI_PEI_SERVICES **PeiServices + ); + +#endif + diff --git a/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec new file mode 100644 index 0000000000..55d3d167ac --- /dev/null +++ b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec @@ -0,0 +1,113 @@ +## @file +# Provides drivers and definitions to support fsp in EDKII bios. +# +# Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +[Defines] + DEC_SPECIFICATION = 0x00010005 + PACKAGE_NAME = IntelFsp2WrapperPkg + PACKAGE_GUID = FAFE06D4-7245-42D7-9FD2-E5D5E36AB0A0 + PACKAGE_VERSION = 0.1 + +[Includes] + Include + +[LibraryClasses] + ## @libraryclass Provide FSP API related function. + FspWrapperApiLib|Include/Library/FspWrapperApiLib.h + FspWrapperApiTestLib|Include/Library/FspWrapperApiTestLib.h + + ## @libraryclass Provide FSP hob process related function. + FspHobProcessLib|Include/Library/FspHobProcessLib.h + + ## @libraryclass Provide FSP platform information related function. + FspPlatformInfoLib|Include/Library/FspPlatformInfoLib.h + + ## @libraryclass Provide FSP wrapper platform sec related function. + FspPlatformSecLib|Include/Library/FspPlatformSecLib.h + +[Guids] + # + # GUID defined in package + # + gIntelFsp2WrapperTokenSpaceGuid = { 0xa34cf082, 0xf50, 0x4f0d, { 0x89, 0x8a, 0x3d, 0x39, 0x30, 0x2b, 0xc5, 0x1e } } + gFspHobGuid = { 0x6d86fb36, 0xba90, 0x472c, { 0xb5, 0x83, 0x3f, 0xbe, 0xd3, 0xfb, 0x20, 0x9a } } + +[Ppis] + gFspSiliconInitDonePpiGuid = { 0x4eb6e09c, 0xd256, 0x4e1e, { 0xb5, 0x0a, 0x87, 0x4b, 0xd2, 0x84, 0xb3, 0xde } } + gTopOfTemporaryRamPpiGuid = { 0x2f3962b2, 0x57c5, 0x44ec, { 0x9e, 0xfc, 0xa6, 0x9f, 0xd3, 0x02, 0x03, 0x2b } } + +[Protocols] + +################################################################################ +# +# PCD Declarations section - list of all PCDs Declared by this Package +# Only this package should be providing the +# declaration, other packages should not. +# +################################################################################ +[PcdsFixedAtBuild, PcdsPatchableInModule] + ## Provides the memory mapped base address of the BIOS CodeCache Flash Device. + gIntelFsp2WrapperTokenSpaceGuid.PcdFlashCodeCacheAddress|0xFFE00000|UINT32|0x10000001 + ## Provides the size of the BIOS Flash Device. + gIntelFsp2WrapperTokenSpaceGuid.PcdFlashCodeCacheSize|0x00200000|UINT32|0x10000002 + + ## Indicates the base address of the factory FSP binary. + gIntelFsp2WrapperTokenSpaceGuid.PcdFlashFvFspBase|0xFFF80000|UINT32|0x10000003 + ## Indicates the base address of the updatable FSP binary to support Dual FSP. + # There could be two FSP images at different locations in a flash - + # one factory version (default) and updatable version (updatable). + # TempRamInit, FspMemoryInit and TempRamExit are always executed from factory version. + # FspSiliconInit and NotifyPhase can be executed from updatable version if it is available, + # FspSiliconInit and NotifyPhase are executed from factory version if there is no updateable version, + # PcdFlashFvFspBase is base address of factory FSP, and PcdFlashFvSecondFspBase + # is base address of updatable FSP. If PcdFlashFvSecondFspBase is 0, that means + # there is no updatable FSP. + gIntelFsp2WrapperTokenSpaceGuid.PcdFlashFvSecondFspBase|0x00000000|UINT32|0x10000008 + ## Provides the size of the factory FSP binary. + gIntelFsp2WrapperTokenSpaceGuid.PcdFlashFvFspSize|0x00048000|UINT32|0x10000004 + ## Provides the size of the updatable FSP binary to support Dual FSP. + gIntelFsp2WrapperTokenSpaceGuid.PcdFlashFvSecondFspSize|0x00000000|UINT32|0x10000009 + + ## Indicates the base address of the first Microcode Patch in the Microcode Region + gIntelFsp2WrapperTokenSpaceGuid.PcdCpuMicrocodePatchAddress|0x0|UINT64|0x10000005 + gIntelFsp2WrapperTokenSpaceGuid.PcdCpuMicrocodePatchRegionSize|0x0|UINT64|0x10000006 + ## Indicates the offset of the Cpu Microcode. + gIntelFsp2WrapperTokenSpaceGuid.PcdFlashMicroCodeOffset|0x90|UINT32|0x10000007 + + ## + # Maximum number of Ppi is provided by SecCore. + ## + gIntelFsp2WrapperTokenSpaceGuid.PcdSecCoreMaxPpiSupported|0x6|UINT32|0x20000001 + + + ## Stack size in the temporary RAM. + # 0 means half of TemporaryRamSize. + gIntelFsp2WrapperTokenSpaceGuid.PcdPeiTemporaryRamStackSize|0|UINT32|0x40000001 + + # This is temporary DRAM base and size for StackTop in FspInit + gIntelFsp2WrapperTokenSpaceGuid.PcdTemporaryRamBase|0x00080000|UINT32|0x40000002 + gIntelFsp2WrapperTokenSpaceGuid.PcdTemporaryRamSize|0x00010000|UINT32|0x40000003 + + # This is stack base and size for FSP in MemoryInit + gIntelFsp2WrapperTokenSpaceGuid.PcdFspStackBase|0x00000000|UINT32|0x40000004 + gIntelFsp2WrapperTokenSpaceGuid.PcdFspStackSize|0x00000000|UINT32|0x40000005 + + + ## Indicate the PEI memory size platform want to report + gIntelFsp2WrapperTokenSpaceGuid.PcdPeiMinMemSize|0x1800000|UINT32|0x40000006 + ## Indicate the PEI memory size platform want to report + gIntelFsp2WrapperTokenSpaceGuid.PcdPeiRecoveryMinMemSize|0x3000000|UINT32|0x40000007 + +[PcdsDynamic,PcdsDynamicEx] + gIntelFsp2WrapperTokenSpaceGuid.PcdFspsBaseAddress|0x00000000|UINT32|0x00001001 diff --git a/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/BaseFspWrapperApiLib.inf b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/BaseFspWrapperApiLib.inf new file mode 100644 index 0000000000..c605eb2ad7 --- /dev/null +++ b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/BaseFspWrapperApiLib.inf @@ -0,0 +1,73 @@ +## @file +# Provide FSP API related function. +# +# Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +################################################################################ +# +# Defines Section - statements that will be processed to create a Makefile. +# +################################################################################ +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = BaseFspWrapperApiLib + FILE_GUID = F42C789F-4D66-49AF-8C73-1AADC00437AC + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = FspWrapperApiLib + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +################################################################################ +# +# Sources Section - list of files that are required for the build to succeed. +# +################################################################################ + +[Sources] + FspWrapperApiLib.c + +[Sources.IA32] + IA32/DispatchExecute.c + +[Sources.X64] + X64/DispatchExecute.c + X64/Thunk64To32.asm + X64/Thunk64To32.S + +################################################################################ +# +# Package Dependency Section - list of Package files that are required for +# this module. +# +################################################################################ + +[Packages] + MdePkg/MdePkg.dec + IntelFsp2Pkg/IntelFsp2Pkg.dec + BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec + IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec + +[LibraryClasses] + BaseLib + +[Guids] + gFspHeaderFileGuid ## CONSUMES ## GUID + +[Pcd] + gIntelFsp2WrapperTokenSpaceGuid.PcdFspmBaseAddress ## CONSUMES + gIntelFsp2WrapperTokenSpaceGuid.PcdFspsBaseAddress ## CONSUMES diff --git a/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/FspWrapperApiLib.c b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/FspWrapperApiLib.c new file mode 100644 index 0000000000..f763f86a59 --- /dev/null +++ b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/FspWrapperApiLib.c @@ -0,0 +1,222 @@ +/** @file + Provide FSP API related function. + + Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include +#include +#include +#include +#include + +/** + Wrapper for a thunk to transition from long mode to compatibility mode to execute 32-bit code and then transit back to + long mode. + + @param[in] Function The 32bit code entry to be executed. + @param[in] Param1 The first parameter to pass to 32bit code. + + @return EFI_STATUS + +**/ +EFI_STATUS +Execute32BitCode ( + IN UINT64 Function, + IN UINT64 Param1, + IN UINT64 Param2 + ); + +/** + Find FSP header pointer. + + @param[in] FlashFvFspBase Flash address of FSP FV. + + @return FSP header pointer. + +**/ +FSP_INFO_HEADER * +EFIAPI +FspFindFspHeader ( + IN EFI_PHYSICAL_ADDRESS FlashFvFspBase + ) +{ + UINT8 *CheckPointer; + + DEBUG ((DEBUG_INFO, "FspFindFspHeader\n")); + + CheckPointer = (UINT8 *) (UINTN) FlashFvFspBase; + + if (((EFI_FIRMWARE_VOLUME_HEADER *) CheckPointer)->Signature != EFI_FVH_SIGNATURE) { + DEBUG ((DEBUG_INFO, "return 1\n")); + return NULL; + } + + if (((EFI_FIRMWARE_VOLUME_HEADER *) CheckPointer)->ExtHeaderOffset != 0) { + CheckPointer = CheckPointer + ((EFI_FIRMWARE_VOLUME_HEADER *) CheckPointer)->ExtHeaderOffset; + CheckPointer = CheckPointer + ((EFI_FIRMWARE_VOLUME_EXT_HEADER *) CheckPointer)->ExtHeaderSize; + CheckPointer = (UINT8 *) ALIGN_POINTER (CheckPointer, 8); + } else { + CheckPointer = CheckPointer + ((EFI_FIRMWARE_VOLUME_HEADER *)CheckPointer)->HeaderLength; + } + + CheckPointer = CheckPointer + sizeof (EFI_FFS_FILE_HEADER); + + if (((EFI_RAW_SECTION *) CheckPointer)->Type != EFI_SECTION_RAW) { + DEBUG ((DEBUG_INFO, "return 2\n")); + return NULL; + } + + CheckPointer = CheckPointer + sizeof (EFI_RAW_SECTION); + + return (FSP_INFO_HEADER *) CheckPointer; +} + +/** + Call FSP API - FspNotifyPhase. + + @param[in] NotifyPhaseParams Address pointer to the NOTIFY_PHASE_PARAMS structure. + + @return EFI status returned by FspNotifyPhase API. + +**/ +EFI_STATUS +EFIAPI +CallFspNotifyPhase ( + IN NOTIFY_PHASE_PARAMS *NotifyPhaseParams + ) +{ + FSP_INFO_HEADER *FspHeader; + FSP_NOTIFY_PHASE NotifyPhaseApi; + EFI_STATUS Status; + BOOLEAN InterruptState; + + FspHeader = (FSP_INFO_HEADER *) FspFindFspHeader (PcdGet32 (PcdFspsBaseAddress)); + if (FspHeader == NULL) { + return EFI_DEVICE_ERROR; + } + + NotifyPhaseApi = (FSP_NOTIFY_PHASE) (UINTN) (FspHeader->ImageBase + FspHeader->NotifyPhaseEntryOffset); + InterruptState = SaveAndDisableInterrupts (); + Status = Execute32BitCode ((UINTN) NotifyPhaseApi, (UINTN) NotifyPhaseParams, (UINTN) NULL); + SetInterruptState (InterruptState); + + return Status; +} + +/** + Call FSP API - FspMemoryInit. + + @param[in,out] FspMemoryInitParams Address pointer to the FSP_MEMORY_INIT_PARAMS structure. + + @return EFI status returned by FspMemoryInit API. + +**/ +EFI_STATUS +EFIAPI +CallFspMemoryInit ( + IN VOID *FspmUpdDataPtr, + OUT VOID **HobListPtr + ) +{ + FSP_INFO_HEADER *FspHeader; + FSP_MEMORY_INIT FspMemoryInitApi; + EFI_STATUS Status; + BOOLEAN InterruptState; + + FspHeader = (FSP_INFO_HEADER *) FspFindFspHeader (PcdGet32 (PcdFspmBaseAddress)); + if (FspHeader == NULL) { + return EFI_DEVICE_ERROR; + } + + FspMemoryInitApi = (FSP_MEMORY_INIT) (UINTN) (FspHeader->ImageBase + FspHeader->FspMemoryInitEntryOffset); + InterruptState = SaveAndDisableInterrupts (); + Status = Execute32BitCode ((UINTN) FspMemoryInitApi, (UINTN) FspmUpdDataPtr, (UINTN) HobListPtr); + SetInterruptState (InterruptState); + + return Status; +} + +/** + Call FSP API - TempRamExit. + + @param[in,out] TempRamExitParam Address pointer to the TempRamExit parameters structure. + + @return EFI status returned by TempRamExit API. + +**/ +EFI_STATUS +EFIAPI +CallTempRamExit ( + IN VOID *TempRamExitParam + ) +{ + FSP_INFO_HEADER *FspHeader; + FSP_TEMP_RAM_EXIT TempRamExitApi; + EFI_STATUS Status; + BOOLEAN InterruptState; + + FspHeader = (FSP_INFO_HEADER *) FspFindFspHeader (PcdGet32 (PcdFspmBaseAddress)); + if (FspHeader == NULL) { + return EFI_DEVICE_ERROR; + } + + TempRamExitApi = (FSP_TEMP_RAM_EXIT) (UINTN) (FspHeader->ImageBase + FspHeader->TempRamExitEntryOffset); + InterruptState = SaveAndDisableInterrupts (); + + DEBUG ((DEBUG_INFO, "** calling TempRamExitApi\n")); + + Status = Execute32BitCode ((UINTN) TempRamExitApi, (UINTN) TempRamExitParam, (UINTN) NULL); + DEBUG ((DEBUG_INFO, "** TempRamExitApi returns\n")); + SetInterruptState (InterruptState); + DEBUG ((DEBUG_INFO, "** return\n")); + return Status; +} + +/** + Call FSP API - FspSiliconInit. + + @param[in,out] FspSiliconInitParam Address pointer to the Silicon Init parameters structure. + + @return EFI status returned by FspSiliconInit API. + +**/ +EFI_STATUS +EFIAPI +CallFspSiliconInit ( + IN VOID *FspsUpdDataPtr + ) +{ + FSP_INFO_HEADER *FspHeader; + FSP_SILICON_INIT FspSiliconInitApi; + EFI_STATUS Status; + BOOLEAN InterruptState; + + DEBUG ((DEBUG_INFO, "PcdGet32 (PcdFspsBaseAddress) = 0x%X\n", PcdGet32 (PcdFspsBaseAddress))); + + FspHeader = (FSP_INFO_HEADER *) FspFindFspHeader (PcdGet32 (PcdFspsBaseAddress)); + if (FspHeader == NULL) { + return EFI_DEVICE_ERROR; + } + DEBUG ((DEBUG_INFO, "FspHeader = 0x%X\n", FspHeader)); + + FspSiliconInitApi = (FSP_SILICON_INIT) (UINTN) (FspHeader->ImageBase + FspHeader->FspSiliconInitEntryOffset); + DEBUG ((DEBUG_INFO, "FspSiliconInitApi = 0x%X\n", FspSiliconInitApi)); + + InterruptState = SaveAndDisableInterrupts (); + Status = Execute32BitCode ((UINTN) FspSiliconInitApi, (UINTN) FspsUpdDataPtr, (UINTN) NULL); + SetInterruptState (InterruptState); + + return Status; +} + diff --git a/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/IA32/DispatchExecute.c b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/IA32/DispatchExecute.c new file mode 100644 index 0000000000..018590f4fa --- /dev/null +++ b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/IA32/DispatchExecute.c @@ -0,0 +1,61 @@ +/** @file + Execute 32-bit code in Protected Mode. + + Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include + +/** + FSP API functions. + + @param[in] Param1 The first parameter to pass to 32bit code. + @param[in] Param2 The second parameter to pass to 32bit code. + + @return EFI_STATUS + +**/ +typedef +EFI_STATUS +(EFIAPI *FSP_FUNCTION) ( + IN VOID *Param1, + IN VOID *Param2 + ); + +/** + Wrapper for a thunk to transition from long mode to compatibility mode to execute 32-bit code and then transit back to + long mode. + + @param[in] Function The 32bit code entry to be executed. + @param[in] Param1 The first parameter to pass to 32bit code. + @param[in] Param2 The second parameter to pass to 32bit code. + + @return EFI_STATUS + +**/ +EFI_STATUS +Execute32BitCode ( + IN UINT64 Function, + IN UINT64 Param1, + IN UINT64 Param2 + ) +{ + FSP_FUNCTION EntryFunc; + EFI_STATUS Status; + + EntryFunc = (FSP_FUNCTION) (UINTN) (Function); + Status = EntryFunc ((VOID *) (UINTN) Param1, (VOID *) (UINTN) Param2); + + return Status; +} + diff --git a/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/X64/DispatchExecute.c b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/X64/DispatchExecute.c new file mode 100644 index 0000000000..34d85a612b --- /dev/null +++ b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/X64/DispatchExecute.c @@ -0,0 +1,111 @@ +/** @file + Execute 32-bit code in Long Mode. + Provide a thunk function to transition from long mode to compatibility mode to execute 32-bit code and then transit + back to long mode. + + Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include +#include + +#pragma pack(1) +typedef union { + struct { + UINT32 LimitLow : 16; + UINT32 BaseLow : 16; + UINT32 BaseMid : 8; + UINT32 Type : 4; + UINT32 System : 1; + UINT32 Dpl : 2; + UINT32 Present : 1; + UINT32 LimitHigh : 4; + UINT32 Software : 1; + UINT32 Reserved : 1; + UINT32 DefaultSize : 1; + UINT32 Granularity : 1; + UINT32 BaseHigh : 8; + } Bits; + UINT64 Uint64; +} IA32_GDT; +#pragma pack() + +GLOBAL_REMOVE_IF_UNREFERENCED IA32_GDT mGdtEntries[] = { + {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 0x0: reserve */ + {{0xFFFF, 0, 0, 0xB, 1, 0, 1, 0xF, 0, 0, 1, 1, 0}}, /* 0x8: compatibility mode */ + {{0xFFFF, 0, 0, 0xB, 1, 0, 1, 0xF, 0, 1, 0, 1, 0}}, /* 0x10: for long mode */ + {{0xFFFF, 0, 0, 0x3, 1, 0, 1, 0xF, 0, 0, 1, 1, 0}}, /* 0x18: data */ + {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 0x20: reserve */ +}; + +// +// IA32 Gdt register +// +GLOBAL_REMOVE_IF_UNREFERENCED IA32_DESCRIPTOR mGdt = { + sizeof (mGdtEntries) - 1, + (UINTN) mGdtEntries + }; + +/** + Assembly function to transition from long mode to compatibility mode to execute 32-bit code and then transit back to + long mode. + + @param[in] Function The 32bit code entry to be executed. + @param[in] Param1 The first parameter to pass to 32bit code + @param[in] Param2 The second parameter to pass to 32bit code + @param[in] InternalGdtr The GDT and GDT descriptor used by this library + + @return status + +**/ +UINT32 +AsmExecute32BitCode ( + IN UINT64 Function, + IN UINT64 Param1, + IN UINT64 Param2, + IN IA32_DESCRIPTOR *InternalGdtr + ); + +/** + Wrapper for a thunk to transition from long mode to compatibility mode to execute 32-bit code and then transit back to + long mode. + + @param[in] Function The 32bit code entry to be executed. + @param[in] Param1 The first parameter to pass to 32bit code. + @param[in] Param2 The second parameter to pass to 32bit code. + + @return EFI_STATUS + +**/ +EFI_STATUS +Execute32BitCode ( + IN UINT64 Function, + IN UINT64 Param1, + IN UINT64 Param2 + ) +{ + EFI_STATUS Status; + IA32_DESCRIPTOR Idtr; + + // + // Idtr might be changed inside of FSP. 32bit FSP only knows the <4G address. + // If IDTR.Base is >4G, FSP can not handle. So we need save/restore IDTR here for X64 only. + // Interrupt is already disabled here, so it is safety to update IDTR. + // + AsmReadIdtr (&Idtr); + Status = AsmExecute32BitCode (Function, Param1, Param2, &mGdt); + AsmWriteIdtr (&Idtr); + + return Status; +} + diff --git a/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/X64/Thunk64To32.S b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/X64/Thunk64To32.S new file mode 100644 index 0000000000..923007cb17 --- /dev/null +++ b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/X64/Thunk64To32.S @@ -0,0 +1,224 @@ +## @file +# This is the assembly code to transition from long mode to compatibility mode to execute 32-bit code and then +# transit back to long mode. +# +# Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED +# +## + +#---------------------------------------------------------------------------- +# Procedure: AsmExecute32BitCode +# +# Input: None +# +# Output: None +# +# Prototype: UINT32 +# AsmExecute32BitCode ( +# IN UINT64 Function, +# IN UINT64 Param1, +# IN UINT64 Param2, +# IN IA32_DESCRIPTOR *InternalGdtr +# ); +# +# +# Description: A thunk function to execute 32-bit code in long mode. +# +#---------------------------------------------------------------------------- + +ASM_GLOBAL ASM_PFX(AsmExecute32BitCode) +ASM_PFX(AsmExecute32BitCode): + # + # save IFLAG and disable it + # + pushfq + cli + + # + # save orignal GDTR and CS + # + movl %ds, %eax + push %rax + movl %cs, %eax + push %rax + subq $0x10, %rsp + sgdt (%rsp) + # + # load internal GDT + # + lgdt (%r9) + # + # Save general purpose register and rflag register + # + pushfq + push %rdi + push %rsi + push %rbp + push %rbx + + # + # save CR3 + # + movq %cr3, %rax + movq %rax, %rbp + + # + # Prepare the CS and return address for the transition from 32-bit to 64-bit mode + # + movq $0x10, %rax # load long mode selector + shl $32, %rax + lea ReloadCS(%rip), %r9 #Assume the ReloadCS is under 4G + orq %r9, %rax + push %rax + # + # Save parameters for 32-bit function call + # + movq %r8, %rax + shl $32, %rax + orq %rdx, %rax + push %rax + # + # save the 32-bit function entry and the return address into stack which will be + # retrieve in compatibility mode. + # + lea ReturnBack(%rip), %rax #Assume the ReloadCS is under 4G + shl $32, %rax + orq %rcx, %rax + push %rax + + # + # let rax save DS + # + movq $0x18, %rax + + # + # Change to Compatible Segment + # + movq $8, %rcx # load compatible mode selector + shl $32, %rcx + lea Compatible(%rip), %rdx # assume address < 4G + orq %rdx, %rcx + push %rcx + .byte 0xcb # retf + +Compatible: + # reload DS/ES/SS to make sure they are correct referred to current GDT + movw %ax, %ds + movw %ax, %es + movw %ax, %ss + + # + # Disable paging + # + movq %cr0, %rcx + btc $31, %ecx + movq %rcx, %cr0 + # + # Clear EFER.LME + # + movl $0xC0000080, %ecx + rdmsr + btc $8, %eax + wrmsr + +# Now we are in protected mode + # + # Call 32-bit function. Assume the function entry address and parameter value is less than 4G + # + pop %rax # Here is the function entry + # + # Now the parameter is at the bottom of the stack, then call in to IA32 function. + # + jmp *%rax +ReturnBack: + movl %eax, %ebx # save return status + pop %rcx # drop param1 + pop %rcx # drop param2 + + # + # restore CR4 + # + movq %cr4, %rax + bts $5, %eax + movq %rax, %cr4 + + # + # restore CR3 + # + movl %ebp, %eax + movq %rax, %cr3 + + # + # Set EFER.LME to re-enable ia32-e + # + movl $0xC0000080, %ecx + rdmsr + bts $8, %eax + wrmsr + # + # Enable paging + # + movq %cr0, %rax + bts $31, %eax + mov %rax, %cr0 +# Now we are in compatible mode + + # + # Reload cs register + # + .byte 0xcb # retf +ReloadCS: + # + # Now we're in Long Mode + # + # + # Restore C register and eax hold the return status from 32-bit function. + # Note: Do not touch rax from now which hold the return value from IA32 function + # + movl %ebx, %eax # put return status to EAX + pop %rbx + pop %rbp + pop %rsi + pop %rdi + popfq + # + # Switch to orignal GDT and CS. here rsp is pointer to the orignal GDT descriptor. + # + lgdt (%rsp) + # + # drop GDT descriptor in stack + # + addq $0x10, %rsp + # + # switch to orignal CS and GDTR + # + pop %r9 # get CS + shl $32, %r9 # rcx[32..47] <- Cs + lea ReturnToLongMode(%rip), %rcx + orq %r9, %rcx + push %rcx + .byte 0xcb # retf +ReturnToLongMode: + # + # Reload original DS/ES/SS + # + pop %rcx + movl %ecx, %ds + movl %ecx, %es + movl %ecx, %ss + + # + # Restore IFLAG + # + popfq + + ret + diff --git a/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/X64/Thunk64To32.asm b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/X64/Thunk64To32.asm new file mode 100644 index 0000000000..2108893e76 --- /dev/null +++ b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/X64/Thunk64To32.asm @@ -0,0 +1,227 @@ +;; @file +; This is the assembly code to transition from long mode to compatibility mode to execute 32-bit code and then +; transit back to long mode. +; +; Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+; +; This program and the accompanying materials +; are licensed and made available under the terms and conditions of the BSD License +; which accompanies this distribution. The full text of the license may be found at +; http://opensource.org/licenses/bsd-license.php. +; +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED +; +;; + +;------------------------------------------------------------------------------- + .code +;---------------------------------------------------------------------------- +; Procedure: AsmExecute32BitCode +; +; Input: None +; +; Output: None +; +; Prototype: UINT32 +; AsmExecute32BitCode ( +; IN UINT64 Function, +; IN UINT64 Param1, +; IN UINT64 Param2, +; IN IA32_DESCRIPTOR *InternalGdtr +; ); +; +; +; Description: A thunk function to execute 32-bit code in long mode. +; +;---------------------------------------------------------------------------- +AsmExecute32BitCode PROC + ; + ; save IFLAG and disable it + ; + pushfq + cli + + ; + ; save orignal GDTR and CS + ; + mov rax, ds + push rax + mov rax, cs + push rax + sub rsp, 10h + sgdt fword ptr [rsp] + ; + ; load internal GDT + ; + lgdt fword ptr [r9] + ; + ; Save general purpose register and rflag register + ; + pushfq + push rdi + push rsi + push rbp + push rbx + + ; + ; save CR3 + ; + mov rax, cr3 + mov rbp, rax + + ; + ; Prepare the CS and return address for the transition from 32-bit to 64-bit mode + ; + mov rax, 10h ; load long mode selector + shl rax, 32 + mov r9, OFFSET ReloadCS ;Assume the ReloadCS is under 4G + or rax, r9 + push rax + ; + ; Save parameters for 32-bit function call + ; + mov rax, r8 + shl rax, 32 + or rax, rdx + push rax + ; + ; save the 32-bit function entry and the return address into stack which will be + ; retrieve in compatibility mode. + ; + mov rax, OFFSET ReturnBack ;Assume the ReloadCS is under 4G + shl rax, 32 + or rax, rcx + push rax + + ; + ; let rax save DS + ; + mov rax, 018h + + ; + ; Change to Compatible Segment + ; + mov rcx, 08h ; load compatible mode selector + shl rcx, 32 + mov rdx, OFFSET Compatible ; assume address < 4G + or rcx, rdx + push rcx + retf + +Compatible: + ; reload DS/ES/SS to make sure they are correct referred to current GDT + mov ds, ax + mov es, ax + mov ss, ax + + ; + ; Disable paging + ; + mov rcx, cr0 + btc ecx, 31 + mov cr0, rcx + ; + ; Clear EFER.LME + ; + mov ecx, 0C0000080h + rdmsr + btc eax, 8 + wrmsr + +; Now we are in protected mode + ; + ; Call 32-bit function. Assume the function entry address and parameter value is less than 4G + ; + pop rax ; Here is the function entry + ; + ; Now the parameter is at the bottom of the stack, then call in to IA32 function. + ; + jmp rax +ReturnBack: + mov ebx, eax ; save return status + pop rcx ; drop param1 + pop rcx ; drop param2 + + ; + ; restore CR4 + ; + mov rax, cr4 + bts eax, 5 + mov cr4, rax + + ; + ; restore CR3 + ; + mov eax, ebp + mov cr3, rax + + ; + ; Set EFER.LME to re-enable ia32-e + ; + mov ecx, 0C0000080h + rdmsr + bts eax, 8 + wrmsr + ; + ; Enable paging + ; + mov rax, cr0 + bts eax, 31 + mov cr0, rax +; Now we are in compatible mode + + ; + ; Reload cs register + ; + retf +ReloadCS: + ; + ; Now we're in Long Mode + ; + ; + ; Restore C register and eax hold the return status from 32-bit function. + ; Note: Do not touch rax from now which hold the return value from IA32 function + ; + mov eax, ebx ; put return status to EAX + pop rbx + pop rbp + pop rsi + pop rdi + popfq + ; + ; Switch to orignal GDT and CS. here rsp is pointer to the orignal GDT descriptor. + ; + lgdt fword ptr[rsp] + ; + ; drop GDT descriptor in stack + ; + add rsp, 10h + ; + ; switch to orignal CS and GDTR + ; + pop r9 ; get CS + shl r9, 32 ; rcx[32..47] <- Cs + mov rcx, OFFSET @F + or rcx, r9 + push rcx + retf +@@: + ; + ; Reload original DS/ES/SS + ; + pop rcx + mov ds, rcx + mov es, rcx + mov ss, rcx + + ; + ; Restore IFLAG + ; + popfq + + ret +AsmExecute32BitCode ENDP + + END + diff --git a/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/FspPlatformSecLibSample.c b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/FspPlatformSecLibSample.c new file mode 100644 index 0000000000..ca0728afc2 --- /dev/null +++ b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/FspPlatformSecLibSample.c @@ -0,0 +1,153 @@ +/** @file + Sample to provide FSP wrapper platform sec related function. + + Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include + +#include +#include +#include + +#include + +/** + This interface conveys state information out of the Security (SEC) phase into PEI. + + @param[in] PeiServices Pointer to the PEI Services Table. + @param[in,out] StructureSize Pointer to the variable describing size of the input buffer. + @param[out] PlatformInformationRecord Pointer to the EFI_SEC_PLATFORM_INFORMATION_RECORD. + + @retval EFI_SUCCESS The data was successfully returned. + @retval EFI_BUFFER_TOO_SMALL The buffer was too small. + +**/ +EFI_STATUS +EFIAPI +SecPlatformInformation ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN OUT UINT64 *StructureSize, + OUT EFI_SEC_PLATFORM_INFORMATION_RECORD *PlatformInformationRecord + ); + +/** + This interface conveys performance information out of the Security (SEC) phase into PEI. + + This service is published by the SEC phase. The SEC phase handoff has an optional + EFI_PEI_PPI_DESCRIPTOR list as its final argument when control is passed from SEC into the + PEI Foundation. As such, if the platform supports collecting performance data in SEC, + this information is encapsulated into the data structure abstracted by this service. + This information is collected for the boot-strap processor (BSP) on IA-32. + + @param[in] PeiServices The pointer to the PEI Services Table. + @param[in] This The pointer to this instance of the PEI_SEC_PERFORMANCE_PPI. + @param[out] Performance The pointer to performance data collected in SEC phase. + + @retval EFI_SUCCESS The data was successfully returned. + +**/ +EFI_STATUS +EFIAPI +SecGetPerformance ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN PEI_SEC_PERFORMANCE_PPI *This, + OUT FIRMWARE_SEC_PERFORMANCE *Performance + ); + +/** + This service of the TEMPORARY_RAM_SUPPORT_PPI that migrates temporary RAM into + permanent memory. + + @param[in] PeiServices Pointer to the PEI Services Table. + @param[in] TemporaryMemoryBase Source Address in temporary memory from which the SEC or PEIM will copy the + Temporary RAM contents. + @param[in] PermanentMemoryBase Destination Address in permanent memory into which the SEC or PEIM will copy the + Temporary RAM contents. + @param[in] CopySize Amount of memory to migrate from temporary to permanent memory. + + @retval EFI_SUCCESS The data was successfully returned. + @retval EFI_INVALID_PARAMETER PermanentMemoryBase + CopySize > TemporaryMemoryBase when + TemporaryMemoryBase > PermanentMemoryBase. + +**/ +EFI_STATUS +EFIAPI +SecTemporaryRamSupport ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase, + IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase, + IN UINTN CopySize + ); + +EFI_SEC_PLATFORM_INFORMATION_PPI mSecPlatformInformationPpi = { + SecPlatformInformation +}; + +PEI_SEC_PERFORMANCE_PPI mSecPerformancePpi = { + SecGetPerformance +}; + +EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI gSecTemporaryRamSupportPpi = { + SecTemporaryRamSupport +}; + +EFI_PEI_PPI_DESCRIPTOR mPeiSecPlatformPpi[] = { + { + EFI_PEI_PPI_DESCRIPTOR_PPI, + &gEfiSecPlatformInformationPpiGuid, + &mSecPlatformInformationPpi + }, + { + EFI_PEI_PPI_DESCRIPTOR_PPI, + &gPeiSecPerformancePpiGuid, + &mSecPerformancePpi + }, + { + EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST, + &gEfiTemporaryRamSupportPpiGuid, + &gSecTemporaryRamSupportPpi + }, +}; + +/** + A developer supplied function to perform platform specific operations. + + It's a developer supplied function to perform any operations appropriate to a + given platform. It's invoked just before passing control to PEI core by SEC + core. Platform developer may modify the SecCoreData passed to PEI Core. + It returns a platform specific PPI list that platform wishes to pass to PEI core. + The Generic SEC core module will merge this list to join the final list passed to + PEI core. + + @param[in,out] SecCoreData The same parameter as passing to PEI core. It + could be overridden by this function. + + @return The platform specific PPI list to be passed to PEI core or + NULL if there is no need of such platform specific PPI list. + +**/ +EFI_PEI_PPI_DESCRIPTOR * +EFIAPI +SecPlatformMain ( + IN OUT EFI_SEC_PEI_HAND_OFF *SecCoreData + ) +{ + EFI_PEI_PPI_DESCRIPTOR *PpiList; + + InitializeApicTimer (0, (UINT32) -1, TRUE, 5); + + PpiList = &mPeiSecPlatformPpi[0]; + + return PpiList; +} + diff --git a/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/AsmSaveSecContext.S b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/AsmSaveSecContext.S new file mode 100644 index 0000000000..082517eebd --- /dev/null +++ b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/AsmSaveSecContext.S @@ -0,0 +1,37 @@ +## @file +# Save Sec Conext before call FspInit API. +# +# Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED +# +## + +#---------------------------------------------------------------------------- +# MMX Usage: +# MM0 = BIST State +# MM5 = Save time-stamp counter value high32bit +# MM6 = Save time-stamp counter value low32bit. +# +# It should be same as SecEntry.asm and PeiCoreEntry.asm. +#---------------------------------------------------------------------------- + +ASM_GLOBAL ASM_PFX(AsmSaveBistValue) +ASM_PFX(AsmSaveBistValue): + movl 4(%esp), %eax + movd %eax, %mm0 + ret + +ASM_GLOBAL ASM_PFX(AsmSaveTickerValue) +ASM_PFX(AsmSaveTickerValue): + movl 4(%esp), %eax + movd %eax, %mm6 + movl 8(%esp), %eax + movd %eax, %mm5 + ret diff --git a/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/AsmSaveSecContext.asm b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/AsmSaveSecContext.asm new file mode 100644 index 0000000000..c9f872202a --- /dev/null +++ b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/AsmSaveSecContext.asm @@ -0,0 +1,45 @@ +;; @file +; Save Sec Conext before call FspInit API. +; +; Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+; +; This program and the accompanying materials +; are licensed and made available under the terms and conditions of the BSD License +; which accompanies this distribution. The full text of the license may be found at +; http://opensource.org/licenses/bsd-license.php. +; +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED +; +;; + +.686p +.xmm +.model flat,c +.code + +;---------------------------------------------------------------------------- +; MMX Usage: +; MM0 = BIST State +; MM5 = Save time-stamp counter value high32bit +; MM6 = Save time-stamp counter value low32bit. +; +; It should be same as SecEntry.asm and PeiCoreEntry.asm. +;---------------------------------------------------------------------------- + +AsmSaveBistValue PROC PUBLIC + mov eax, [esp+4] + movd mm0, eax + ret +AsmSaveBistValue ENDP + +AsmSaveTickerValue PROC PUBLIC + mov eax, [esp+4] + movd mm6, eax + mov eax, [esp+8] + movd mm5, eax + ret +AsmSaveTickerValue ENDP + +END + diff --git a/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/Fsp.h b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/Fsp.h new file mode 100644 index 0000000000..c74d0efd44 --- /dev/null +++ b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/Fsp.h @@ -0,0 +1,50 @@ +/** @file + Fsp related definitions + + Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef __FSP_H__ +#define __FSP_H__ + +// +// Fv Header +// +#define FVH_SIGINATURE_OFFSET 0x28 +#define FVH_SIGINATURE_VALID_VALUE 0x4856465F // valid signature:_FVH +#define FVH_HEADER_LENGTH_OFFSET 0x30 +#define FVH_EXTHEADER_OFFSET_OFFSET 0x34 +#define FVH_EXTHEADER_SIZE_OFFSET 0x10 + +// +// Ffs Header +// +#define FSP_HEADER_GUID_DWORD1 0x912740BE +#define FSP_HEADER_GUID_DWORD2 0x47342284 +#define FSP_HEADER_GUID_DWORD3 0xB08471B9 +#define FSP_HEADER_GUID_DWORD4 0x0C3F3527 +#define FFS_HEADER_SIZE_VALUE 0x18 + +// +// Section Header +// +#define SECTION_HEADER_TYPE_OFFSET 0x03 +#define RAW_SECTION_HEADER_SIZE_VALUE 0x04 + +// +// Fsp Header +// +#define FSP_HEADER_IMAGEBASE_OFFSET 0x1C +#define FSP_HEADER_TEMPRAMINIT_OFFSET 0x30 + +#endif + diff --git a/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/PeiCoreEntry.S b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/PeiCoreEntry.S new file mode 100644 index 0000000000..004d9ff0a0 --- /dev/null +++ b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/PeiCoreEntry.S @@ -0,0 +1,124 @@ +## @file +# Find and call SecStartup. +# +# Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED +# +## + +ASM_GLOBAL ASM_PFX(CallPeiCoreEntryPoint) +ASM_PFX(CallPeiCoreEntryPoint): + # + # Obtain the hob list pointer + # + movl 0x4(%esp), %eax + # + # Obtain the stack information + # ECX: start of range + # EDX: end of range + # + movl 0x8(%esp), %ecx + movl 0xC(%esp), %edx + + # + # Platform init + # + pushal + pushl %edx + pushl %ecx + pushl %eax + call ASM_PFX(PlatformInit) + popl %eax + popl %eax + popl %eax + popal + + # + # Set stack top pointer + # + movl %edx, %esp + + # + # Push the hob list pointer + # + pushl %eax + + # + # Save the value + # ECX: start of range + # EDX: end of range + # + movl %esp, %ebp + pushl %ecx + pushl %edx + + # + # Push processor count to stack first, then BIST status (AP then BSP) + # + movl $1, %eax + cpuid + shr $16, %ebx + andl $0x000000FF, %ebx + cmp $1, %bl + jae PushProcessorCount + + # + # Some processors report 0 logical processors. Effectively 0 = 1. + # So we fix up the processor count + # + inc %ebx + +PushProcessorCount: + pushl %ebx + + # + # We need to implement a long-term solution for BIST capture. For now, we just copy BSP BIST + # for all processor threads + # + xorl %ecx, %ecx + movb %bl, %cl +PushBist: + movd %mm0, %eax + pushl %eax + loop PushBist + + # Save Time-Stamp Counter + movd %mm5, %eax + pushl %eax + + movd %mm6, %eax + pushl %eax + + # + # Pass entry point of the PEI core + # + movl $0xFFFFFFE0, %edi + pushl %ds:(%edi) + + # + # Pass BFV into the PEI Core + # + movl $0xFFFFFFFC, %edi + pushl %ds:(%edi) + + # + # Pass stack size into the PEI Core + # + movl -4(%ebp), %ecx + movl -8(%ebp), %edx + pushl %ecx # RamBase + + subl %ecx, %edx + pushl %edx # RamSize + + # + # Pass Control into the PEI Core + # + call ASM_PFX(SecStartup) diff --git a/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/PeiCoreEntry.asm b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/PeiCoreEntry.asm new file mode 100644 index 0000000000..edb7bd1fda --- /dev/null +++ b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/PeiCoreEntry.asm @@ -0,0 +1,135 @@ +;; @file +; Find and call SecStartup. +; +; Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+; +; This program and the accompanying materials +; are licensed and made available under the terms and conditions of the BSD License +; which accompanies this distribution. The full text of the license may be found at +; http://opensource.org/licenses/bsd-license.php. +; +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED +; +;; + +.686p +.xmm +.model flat, c +.code + +EXTRN SecStartup:NEAR +EXTRN PlatformInit:NEAR + +CallPeiCoreEntryPoint PROC PUBLIC + ; + ; Obtain the hob list pointer + ; + mov eax, [esp+4] + ; + ; Obtain the stack information + ; ECX: start of range + ; EDX: end of range + ; + mov ecx, [esp+8] + mov edx, [esp+0Ch] + + ; + ; Platform init + ; + pushad + push edx + push ecx + push eax + call PlatformInit + pop eax + pop eax + pop eax + popad + + ; + ; Set stack top pointer + ; + mov esp, edx + + ; + ; Push the hob list pointer + ; + push eax + + ; + ; Save the value + ; ECX: start of range + ; EDX: end of range + ; + mov ebp, esp + push ecx + push edx + + ; + ; Push processor count to stack first, then BIST status (AP then BSP) + ; + mov eax, 1 + cpuid + shr ebx, 16 + and ebx, 0000000FFh + cmp bl, 1 + jae PushProcessorCount + + ; + ; Some processors report 0 logical processors. Effectively 0 = 1. + ; So we fix up the processor count + ; + inc ebx + +PushProcessorCount: + push ebx + + ; + ; We need to implement a long-term solution for BIST capture. For now, we just copy BSP BIST + ; for all processor threads + ; + xor ecx, ecx + mov cl, bl +PushBist: + movd eax, mm0 + push eax + loop PushBist + + ; Save Time-Stamp Counter + movd eax, mm5 + push eax + + movd eax, mm6 + push eax + + ; + ; Pass entry point of the PEI core + ; + mov edi, 0FFFFFFE0h + push DWORD PTR ds:[edi] + + ; + ; Pass BFV into the PEI Core + ; + mov edi, 0FFFFFFFCh + push DWORD PTR ds:[edi] + + ; + ; Pass stack size into the PEI Core + ; + mov ecx, [ebp - 4] + mov edx, [ebp - 8] + push ecx ; RamBase + + sub edx, ecx + push edx ; RamSize + + ; + ; Pass Control into the PEI Core + ; + call SecStartup +CallPeiCoreEntryPoint ENDP + +END + diff --git a/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/SecEntry.S b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/SecEntry.S new file mode 100644 index 0000000000..c7870fe42e --- /dev/null +++ b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/SecEntry.S @@ -0,0 +1,322 @@ +## @file +# This is the code that goes from real-mode to protected mode. +# It consumes the reset vector, calls TempRamInit API from FSP binary. +# +# Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED +# +## + +#include "Fsp.h" + +ASM_GLOBAL ASM_PFX(_gPcd_FixedAtBuild_PcdFlashFvFspBase) +ASM_GLOBAL ASM_PFX(_gPcd_FixedAtBuild_PcdFlashFvFspSize) + +ASM_GLOBAL ASM_PFX(_TEXT_REALMODE) +ASM_PFX(_TEXT_REALMODE): +#---------------------------------------------------------------------------- +# +# Procedure: _ModuleEntryPoint +# +# Input: None +# +# Output: None +# +# Destroys: Assume all registers +# +# Description: +# +# Transition to non-paged flat-model protected mode from a +# hard-coded GDT that provides exactly two descriptors. +# This is a bare bones transition to protected mode only +# used for a while in PEI and possibly DXE. +# +# After enabling protected mode, a far jump is executed to +# transfer to PEI using the newly loaded GDT. +# +# Return: None +# +# MMX Usage: +# MM0 = BIST State +# MM5 = Save time-stamp counter value high32bit +# MM6 = Save time-stamp counter value low32bit. +# +#---------------------------------------------------------------------------- + +.align 4 +ASM_GLOBAL ASM_PFX(_ModuleEntryPoint) +ASM_PFX(_ModuleEntryPoint): + fninit # clear any pending Floating point exceptions + # + # Store the BIST value in mm0 + # + movd %eax, %mm0 + + # + # Save time-stamp counter value + # rdtsc load 64bit time-stamp counter to EDX:EAX + # + rdtsc + movd %edx, %mm5 + movd %ecx, %mm6 + + # + # Load the GDT table in GdtDesc + # + movl $GdtDesc, %esi + .byte 0x66 + lgdt %cs:(%si) + + # + # Transition to 16 bit protected mode + # + movl %cr0, %eax # Get control register 0 + orl $0x00000003, %eax # Set PE bit (bit #0) & MP bit (bit #1) + movl %eax, %cr0 # Activate protected mode + + movl %cr4, %eax # Get control register 4 + orl $0x00000600, %eax # Set OSFXSR bit (bit #9) & OSXMMEXCPT bit (bit #10) + movl %eax, %cr4 + + # + # Now we're in 16 bit protected mode + # Set up the selectors for 32 bit protected mode entry + # + movw SYS_DATA_SEL, %ax + movw %ax, %ds + movw %ax, %es + movw %ax, %fs + movw %ax, %gs + movw %ax, %ss + + # + # Transition to Flat 32 bit protected mode + # The jump to a far pointer causes the transition to 32 bit mode + # + movl ASM_PFX(ProtectedModeEntryLinearAddress), %esi + jmp *%cs:(%si) + +ASM_GLOBAL ASM_PFX(_TEXT_PROTECTED_MODE) +ASM_PFX(_TEXT_PROTECTED_MODE): + +#---------------------------------------------------------------------------- +# +# Procedure: ProtectedModeEntryPoint +# +# Input: None +# +# Output: None +# +# Destroys: Assume all registers +# +# Description: +# +# This function handles: +# Call two basic APIs from FSP binary +# Initializes stack with some early data (BIST, PEI entry, etc) +# +# Return: None +# +#---------------------------------------------------------------------------- + +.align 4 +ASM_GLOBAL ASM_PFX(ProtectedModeEntryPoint) +ASM_PFX(ProtectedModeEntryPoint): + + # Find the fsp info header + movl ASM_PFX(_gPcd_FixedAtBuild_PcdFlashFvFspBase), %edi + movl ASM_PFX(_gPcd_FixedAtBuild_PcdFlashFvFspSize), %ecx + + movl FVH_SIGINATURE_OFFSET(%edi), %eax + cmp $FVH_SIGINATURE_VALID_VALUE, %eax + jnz FspHeaderNotFound + + xorl %eax, %eax + movw FVH_EXTHEADER_OFFSET_OFFSET(%edi), %ax + cmp %ax, 0 + jnz FspFvExtHeaderExist + + xorl %eax, %eax + movw FVH_HEADER_LENGTH_OFFSET(%edi), %ax # Bypass Fv Header + addl %eax, %edi + jmp FspCheckFfsHeader + +FspFvExtHeaderExist: + addl %eax, %edi + movl FVH_EXTHEADER_SIZE_OFFSET(%edi), %eax # Bypass Ext Fv Header + addl %eax, %edi + + # Round up to 8 byte alignment + movl %edi, %eax + andb $0x07, %al + jz FspCheckFfsHeader + + and $0xFFFFFFF8, %edi + add $0x08, %edi + +FspCheckFfsHeader: + # Check the ffs guid + movl (%edi), %eax + cmp $FSP_HEADER_GUID_DWORD1, %eax + jnz FspHeaderNotFound + + movl 0x4(%edi), %eax + cmp $FSP_HEADER_GUID_DWORD2, %eax + jnz FspHeaderNotFound + + movl 0x08(%edi), %eax + cmp $FSP_HEADER_GUID_DWORD3, %eax + jnz FspHeaderNotFound + + movl 0x0c(%edi), %eax + cmp $FSP_HEADER_GUID_DWORD4, %eax + jnz FspHeaderNotFound + + add $FFS_HEADER_SIZE_VALUE, %edi # Bypass the ffs header + + # Check the section type as raw section + movb SECTION_HEADER_TYPE_OFFSET(%edi), %al + cmp $0x19, %al + jnz FspHeaderNotFound + + addl $RAW_SECTION_HEADER_SIZE_VALUE, %edi # Bypass the section header + jmp FspHeaderFound + +FspHeaderNotFound: + jmp . + +FspHeaderFound: + # Get the fsp TempRamInit Api address + movl FSP_HEADER_IMAGEBASE_OFFSET(%edi), %eax + addl FSP_HEADER_TEMPRAMINIT_OFFSET(%edi), %eax + + # Setup the hardcode stack + movl $TempRamInitStack, %esp + + # Call the fsp TempRamInit Api + jmp *%eax + +TempRamInitDone: + cmp $0x0, %eax + jnz FspApiFailed + + # ECX: start of range + # EDX: end of range + movl %edx, %esp + pushl %edx + pushl %ecx + pushl %eax # zero - no hob list yet + call ASM_PFX(CallPeiCoreEntryPoint) + +FspApiFailed: + jmp . + +.align 0x10 +TempRamInitStack: + .long TempRamInitDone + .long ASM_PFX(TempRamInitParams) + +# +# ROM-based Global-Descriptor Table for the Tiano PEI Phase +# +.align 16 + +# +# GDT[0]: 0x00: Null entry, never used. +# +.equ NULL_SEL, . - GDT_BASE # Selector [0] +GDT_BASE: +BootGdtTable: .long 0 + .long 0 +# +# Linear data segment descriptor +# +.equ LINEAR_SEL, . - GDT_BASE # Selector [0x8] + .word 0xFFFF # limit 0xFFFFF + .word 0 # base 0 + .byte 0 + .byte 0x92 # present, ring 0, data, expand-up, writable + .byte 0xCF # page-granular, 32-bit + .byte 0 +# +# Linear code segment descriptor +# +.equ LINEAR_CODE_SEL, . - GDT_BASE # Selector [0x10] + .word 0xFFFF # limit 0xFFFFF + .word 0 # base 0 + .byte 0 + .byte 0x9B # present, ring 0, data, expand-up, not-writable + .byte 0xCF # page-granular, 32-bit + .byte 0 +# +# System data segment descriptor +# +.equ SYS_DATA_SEL, . - GDT_BASE # Selector [0x18] + .word 0xFFFF # limit 0xFFFFF + .word 0 # base 0 + .byte 0 + .byte 0x93 # present, ring 0, data, expand-up, not-writable + .byte 0xCF # page-granular, 32-bit + .byte 0 + +# +# System code segment descriptor +# +.equ SYS_CODE_SEL, . - GDT_BASE # Selector [0x20] + .word 0xFFFF # limit 0xFFFFF + .word 0 # base 0 + .byte 0 + .byte 0x9A # present, ring 0, data, expand-up, writable + .byte 0xCF # page-granular, 32-bit + .byte 0 +# +# Spare segment descriptor +# +.equ SYS16_CODE_SEL, . - GDT_BASE # Selector [0x28] + .word 0xFFFF # limit 0xFFFFF + .word 0 # base 0 + .byte 0x0E # Changed from F000 to E000. + .byte 0x9B # present, ring 0, code, expand-up, writable + .byte 0x00 # byte-granular, 16-bit + .byte 0 +# +# Spare segment descriptor +# +.equ SYS16_DATA_SEL, . - GDT_BASE # Selector [0x30] + .word 0xFFFF # limit 0xFFFF + .word 0 # base 0 + .byte 0 + .byte 0x93 # present, ring 0, data, expand-up, not-writable + .byte 0x00 # byte-granular, 16-bit + .byte 0 + +# +# Spare segment descriptor +# +.equ SPARE5_SEL, . - GDT_BASE # Selector [0x38] + .word 0 # limit 0 + .word 0 # base 0 + .byte 0 + .byte 0 # present, ring 0, data, expand-up, writable + .byte 0 # page-granular, 32-bit + .byte 0 +.equ GDT_SIZE, . - BootGdtTable # Size, in bytes + +# +# GDT Descriptor +# +GdtDesc: # GDT descriptor + .word GDT_SIZE - 1 # GDT limit + .long BootGdtTable # GDT base address + +ASM_PFX(ProtectedModeEntryLinearAddress): +ProtectedModeEntryLinearOffset: + .long ASM_PFX(ProtectedModeEntryPoint) # Offset of our 32 bit code + .word LINEAR_CODE_SEL diff --git a/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/SecEntry.asm b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/SecEntry.asm new file mode 100644 index 0000000000..b7958ddf66 --- /dev/null +++ b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/SecEntry.asm @@ -0,0 +1,340 @@ +;; @file +; This is the code that goes from real-mode to protected mode. +; It consumes the reset vector, calls TempRamInit API from FSP binary. +; +; Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+; +; This program and the accompanying materials +; are licensed and made available under the terms and conditions of the BSD License +; which accompanies this distribution. The full text of the license may be found at +; http://opensource.org/licenses/bsd-license.php. +; +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED +; +;; + +#include "Fsp.h" + +.686p +.xmm +.model small, c + +EXTRN CallPeiCoreEntryPoint:NEAR +EXTRN TempRamInitParams:FAR + +; Pcds +EXTRN PcdGet32 (PcdFlashFvFspBase):DWORD +EXTRN PcdGet32 (PcdFlashFvFspSize):DWORD + +_TEXT_REALMODE SEGMENT PARA PUBLIC USE16 'CODE' + ASSUME CS:_TEXT_REALMODE, DS:_TEXT_REALMODE + +;---------------------------------------------------------------------------- +; +; Procedure: _ModuleEntryPoint +; +; Input: None +; +; Output: None +; +; Destroys: Assume all registers +; +; Description: +; +; Transition to non-paged flat-model protected mode from a +; hard-coded GDT that provides exactly two descriptors. +; This is a bare bones transition to protected mode only +; used for a while in PEI and possibly DXE. +; +; After enabling protected mode, a far jump is executed to +; transfer to PEI using the newly loaded GDT. +; +; Return: None +; +; MMX Usage: +; MM0 = BIST State +; MM5 = Save time-stamp counter value high32bit +; MM6 = Save time-stamp counter value low32bit. +; +;---------------------------------------------------------------------------- + +align 4 +_ModuleEntryPoint PROC NEAR C PUBLIC + fninit ; clear any pending Floating point exceptions + ; + ; Store the BIST value in mm0 + ; + movd mm0, eax + + ; + ; Save time-stamp counter value + ; rdtsc load 64bit time-stamp counter to EDX:EAX + ; + rdtsc + movd mm5, edx + movd mm6, eax + + ; + ; Load the GDT table in GdtDesc + ; + mov esi, OFFSET GdtDesc + DB 66h + lgdt fword ptr cs:[si] + + ; + ; Transition to 16 bit protected mode + ; + mov eax, cr0 ; Get control register 0 + or eax, 00000003h ; Set PE bit (bit #0) & MP bit (bit #1) + mov cr0, eax ; Activate protected mode + + mov eax, cr4 ; Get control register 4 + or eax, 00000600h ; Set OSFXSR bit (bit #9) & OSXMMEXCPT bit (bit #10) + mov cr4, eax + + ; + ; Now we're in 16 bit protected mode + ; Set up the selectors for 32 bit protected mode entry + ; + mov ax, SYS_DATA_SEL + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + mov ss, ax + + ; + ; Transition to Flat 32 bit protected mode + ; The jump to a far pointer causes the transition to 32 bit mode + ; + mov esi, offset ProtectedModeEntryLinearAddress + jmp fword ptr cs:[si] + +_ModuleEntryPoint ENDP +_TEXT_REALMODE ENDS + +_TEXT_PROTECTED_MODE SEGMENT PARA PUBLIC USE32 'CODE' + ASSUME CS:_TEXT_PROTECTED_MODE, DS:_TEXT_PROTECTED_MODE + +;---------------------------------------------------------------------------- +; +; Procedure: ProtectedModeEntryPoint +; +; Input: None +; +; Output: None +; +; Destroys: Assume all registers +; +; Description: +; +; This function handles: +; Call two basic APIs from FSP binary +; Initializes stack with some early data (BIST, PEI entry, etc) +; +; Return: None +; +;---------------------------------------------------------------------------- + +align 4 +ProtectedModeEntryPoint PROC NEAR PUBLIC + + ; Find the fsp info header + mov edi, PcdGet32 (PcdFlashFvFspBase) + mov ecx, PcdGet32 (PcdFlashFvFspSize) + + mov eax, dword ptr [edi + FVH_SIGINATURE_OFFSET] + cmp eax, FVH_SIGINATURE_VALID_VALUE + jnz FspHeaderNotFound + + xor eax, eax + mov ax, word ptr [edi + FVH_EXTHEADER_OFFSET_OFFSET] + cmp ax, 0 + jnz FspFvExtHeaderExist + + xor eax, eax + mov ax, word ptr [edi + FVH_HEADER_LENGTH_OFFSET] ; Bypass Fv Header + add edi, eax + jmp FspCheckFfsHeader + +FspFvExtHeaderExist: + add edi, eax + mov eax, dword ptr [edi + FVH_EXTHEADER_SIZE_OFFSET] ; Bypass Ext Fv Header + add edi, eax + + ; Round up to 8 byte alignment + mov eax, edi + and al, 07h + jz FspCheckFfsHeader + + and edi, 0FFFFFFF8h + add edi, 08h + +FspCheckFfsHeader: + ; Check the ffs guid + mov eax, dword ptr [edi] + cmp eax, FSP_HEADER_GUID_DWORD1 + jnz FspHeaderNotFound + + mov eax, dword ptr [edi + 4] + cmp eax, FSP_HEADER_GUID_DWORD2 + jnz FspHeaderNotFound + + mov eax, dword ptr [edi + 8] + cmp eax, FSP_HEADER_GUID_DWORD3 + jnz FspHeaderNotFound + + mov eax, dword ptr [edi + 0Ch] + cmp eax, FSP_HEADER_GUID_DWORD4 + jnz FspHeaderNotFound + + add edi, FFS_HEADER_SIZE_VALUE ; Bypass the ffs header + + ; Check the section type as raw section + mov al, byte ptr [edi + SECTION_HEADER_TYPE_OFFSET] + cmp al, 019h + jnz FspHeaderNotFound + + add edi, RAW_SECTION_HEADER_SIZE_VALUE ; Bypass the section header + jmp FspHeaderFound + +FspHeaderNotFound: + jmp $ + +FspHeaderFound: + ; Get the fsp TempRamInit Api address + mov eax, dword ptr [edi + FSP_HEADER_IMAGEBASE_OFFSET] + add eax, dword ptr [edi + FSP_HEADER_TEMPRAMINIT_OFFSET] + + ; Setup the hardcode stack + mov esp, OFFSET TempRamInitStack + + ; Call the fsp TempRamInit Api + jmp eax + +TempRamInitDone: + cmp eax, 0 + jnz FspApiFailed + + ; ECX: start of range + ; EDX: end of range + mov esp, edx + push edx + push ecx + push eax ; zero - no hob list yet + call CallPeiCoreEntryPoint + +FspApiFailed: + jmp $ + +align 10h +TempRamInitStack: + DD OFFSET TempRamInitDone + DD OFFSET TempRamInitParams + +ProtectedModeEntryPoint ENDP + +; +; ROM-based Global-Descriptor Table for the Tiano PEI Phase +; +align 16 +PUBLIC BootGdtTable + +; +; GDT[0]: 0x00: Null entry, never used. +; +NULL_SEL EQU $ - GDT_BASE ; Selector [0] +GDT_BASE: +BootGdtTable DD 0 + DD 0 +; +; Linear data segment descriptor +; +LINEAR_SEL EQU $ - GDT_BASE ; Selector [0x8] + DW 0FFFFh ; limit 0xFFFFF + DW 0 ; base 0 + DB 0 + DB 092h ; present, ring 0, data, expand-up, writable + DB 0CFh ; page-granular, 32-bit + DB 0 +; +; Linear code segment descriptor +; +LINEAR_CODE_SEL EQU $ - GDT_BASE ; Selector [0x10] + DW 0FFFFh ; limit 0xFFFFF + DW 0 ; base 0 + DB 0 + DB 09Bh ; present, ring 0, data, expand-up, not-writable + DB 0CFh ; page-granular, 32-bit + DB 0 +; +; System data segment descriptor +; +SYS_DATA_SEL EQU $ - GDT_BASE ; Selector [0x18] + DW 0FFFFh ; limit 0xFFFFF + DW 0 ; base 0 + DB 0 + DB 093h ; present, ring 0, data, expand-up, not-writable + DB 0CFh ; page-granular, 32-bit + DB 0 + +; +; System code segment descriptor +; +SYS_CODE_SEL EQU $ - GDT_BASE ; Selector [0x20] + DW 0FFFFh ; limit 0xFFFFF + DW 0 ; base 0 + DB 0 + DB 09Ah ; present, ring 0, data, expand-up, writable + DB 0CFh ; page-granular, 32-bit + DB 0 +; +; Spare segment descriptor +; +SYS16_CODE_SEL EQU $ - GDT_BASE ; Selector [0x28] + DW 0FFFFh ; limit 0xFFFFF + DW 0 ; base 0 + DB 0Eh ; Changed from F000 to E000. + DB 09Bh ; present, ring 0, code, expand-up, writable + DB 00h ; byte-granular, 16-bit + DB 0 +; +; Spare segment descriptor +; +SYS16_DATA_SEL EQU $ - GDT_BASE ; Selector [0x30] + DW 0FFFFh ; limit 0xFFFF + DW 0 ; base 0 + DB 0 + DB 093h ; present, ring 0, data, expand-up, not-writable + DB 00h ; byte-granular, 16-bit + DB 0 + +; +; Spare segment descriptor +; +SPARE5_SEL EQU $ - GDT_BASE ; Selector [0x38] + DW 0 ; limit 0 + DW 0 ; base 0 + DB 0 + DB 0 ; present, ring 0, data, expand-up, writable + DB 0 ; page-granular, 32-bit + DB 0 +GDT_SIZE EQU $ - BootGdtTable ; Size, in bytes + +; +; GDT Descriptor +; +GdtDesc: ; GDT descriptor + DW GDT_SIZE - 1 ; GDT limit + DD OFFSET BootGdtTable ; GDT base address + + +ProtectedModeEntryLinearAddress LABEL FWORD +ProtectedModeEntryLinearOffset LABEL DWORD + DD OFFSET ProtectedModeEntryPoint ; Offset of our 32 bit code + DW LINEAR_CODE_SEL + +_TEXT_PROTECTED_MODE ENDS +END + diff --git a/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/Stack.S b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/Stack.S new file mode 100644 index 0000000000..cf4522c89b --- /dev/null +++ b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/Stack.S @@ -0,0 +1,74 @@ +## @file +# Switch the stack from temporary memory to permenent memory. +# +# Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED +# +## + +#------------------------------------------------------------------------------ +# VOID +# EFIAPI +# SecSwitchStack ( +# UINT32 TemporaryMemoryBase, +# UINT32 PermenentMemoryBase +# )# +#------------------------------------------------------------------------------ +ASM_GLOBAL ASM_PFX (SecSwitchStack) +ASM_PFX(SecSwitchStack): + # + # Save standard registers so they can be used to change stack + # + pushl %eax + pushl %ebx + pushl %ecx + pushl %edx + + # + # !!CAUTION!! this function address's is pushed into stack after + # migration of whole temporary memory, so need save it to permenent + # memory at first! + # + movl 20(%esp), %ebx # Save the first parameter + movl 24(%esp), %ecx # Save the second parameter + + # + # Save this function's return address into permenent memory at first. + # Then, Fixup the esp point to permenent memory + # + movl %esp, %eax + subl %ebx, %eax + addl %ecx, %eax + movl 0(%esp), %edx # copy pushed register's value to permenent memory + movl %edx, 0(%eax) + movl 4(%esp), %edx + movl %edx, 4(%eax) + movl 8(%esp), %edx + movl %edx, 8(%eax) + movl 12(%esp), %edx + movl %edx, 12(%eax) + movl 16(%esp), %edx # Update this function's return address into permenent memory + movl %edx, 16(%eax) + movl %eax, %esp # From now, esp is pointed to permenent memory + + # + # Fixup the ebp point to permenent memory + # + movl %ebp, %eax + subl %ebx, %eax + addl %ecx, %eax + movl %eax, %ebp # From now, ebp is pointed to permenent memory + + popl %edx + popl %ecx + popl %ebx + popl %eax + ret + diff --git a/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/Stack.asm b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/Stack.asm new file mode 100644 index 0000000000..42d6e9a990 --- /dev/null +++ b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/Stack.asm @@ -0,0 +1,81 @@ +;; @file +; Switch the stack from temporary memory to permenent memory. +; +; Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+; +; This program and the accompanying materials +; are licensed and made available under the terms and conditions of the BSD License +; which accompanies this distribution. The full text of the license may be found at +; http://opensource.org/licenses/bsd-license.php. +; +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED +; +;; + + .586p + .model flat,C + .code + +;------------------------------------------------------------------------------ +; VOID +; EFIAPI +; SecSwitchStack ( +; UINT32 TemporaryMemoryBase, +; UINT32 PermenentMemoryBase +; ); +;------------------------------------------------------------------------------ +SecSwitchStack PROC + ; + ; Save three register: eax, ebx, ecx + ; + push eax + push ebx + push ecx + push edx + + ; + ; !!CAUTION!! this function address's is pushed into stack after + ; migration of whole temporary memory, so need save it to permenent + ; memory at first! + ; + + mov ebx, [esp + 20] ; Save the first parameter + mov ecx, [esp + 24] ; Save the second parameter + + ; + ; Save this function's return address into permenent memory at first. + ; Then, Fixup the esp point to permenent memory + ; + mov eax, esp + sub eax, ebx + add eax, ecx + mov edx, dword ptr [esp] ; copy pushed register's value to permenent memory + mov dword ptr [eax], edx + mov edx, dword ptr [esp + 4] + mov dword ptr [eax + 4], edx + mov edx, dword ptr [esp + 8] + mov dword ptr [eax + 8], edx + mov edx, dword ptr [esp + 12] + mov dword ptr [eax + 12], edx + mov edx, dword ptr [esp + 16] ; Update this function's return address into permenent memory + mov dword ptr [eax + 16], edx + mov esp, eax ; From now, esp is pointed to permenent memory + + ; + ; Fixup the ebp point to permenent memory + ; + mov eax, ebp + sub eax, ebx + add eax, ecx + mov ebp, eax ; From now, ebp is pointed to permenent memory + + pop edx + pop ecx + pop ebx + pop eax + ret +SecSwitchStack ENDP + + END + diff --git a/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/PlatformInit.c b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/PlatformInit.c new file mode 100644 index 0000000000..d6aba92884 --- /dev/null +++ b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/PlatformInit.c @@ -0,0 +1,44 @@ +/** @file + Sample to provide platform init function. + + Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include + +/** + Platform initialization. + + @param[in] FspHobList HobList produced by FSP. + @param[in] StartOfRange Start of temporary RAM. + @param[in] EndOfRange End of temporary RAM. + +**/ +VOID +EFIAPI +PlatformInit ( + IN VOID *FspHobList, + IN VOID *StartOfRange, + IN VOID *EndOfRange + ) +{ + // + // Platform initialization + // Enable Serial port here + // + DEBUG ((DEBUG_INFO, "PrintPeiCoreEntryPointParam\n")); + DEBUG ((DEBUG_INFO, "FspHobList - 0x%x\n", FspHobList)); + DEBUG ((DEBUG_INFO, "StartOfRange - 0x%x\n", StartOfRange)); + DEBUG ((DEBUG_INFO, "EndOfRange - 0x%x\n", EndOfRange)); +} + diff --git a/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/SaveSecContext.c b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/SaveSecContext.c new file mode 100644 index 0000000000..8458b87aac --- /dev/null +++ b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/SaveSecContext.c @@ -0,0 +1,115 @@ +/** @file + Sample to provide SaveSecContext function. + + Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include + +#include +#include + +/** + Save BIST value before call FspInit. + + @param[in] Bist BIST value. + +**/ +VOID +AsmSaveBistValue ( + IN UINT32 Bist + ); + +/** + Save Ticker value before call FspInit. + + @param[in] Ticker Ticker value. + +**/ +VOID +AsmSaveTickerValue ( + IN UINT64 Ticker + ); + +/** + Save SEC context before call FspInit. + + @param[in] PeiServices Pointer to PEI Services Table. + +**/ +VOID +EFIAPI +SaveSecContext ( + IN CONST EFI_PEI_SERVICES **PeiServices + ) +{ + UINT32 *Bist; + UINT64 *Ticker; + UINT32 Size; + UINT32 Count; + UINT32 TopOfTemporaryRam; + VOID *TopOfTemporaryRamPpi; + EFI_STATUS Status; + + DEBUG ((DEBUG_INFO, "SaveSecContext - 0x%x\n", PeiServices)); + + Status = (*PeiServices)->LocatePpi ( + PeiServices, + &gTopOfTemporaryRamPpiGuid, + 0, + NULL, + (VOID **) &TopOfTemporaryRamPpi + ); + if (EFI_ERROR (Status)) { + return ; + } + + DEBUG ((DEBUG_INFO, "TopOfTemporaryRamPpi - 0x%x\n", TopOfTemporaryRamPpi)); + + // + // The entries of BIST information, together with the number of them, + // reside in the bottom of stack, left untouched by normal stack operation. + // This routine copies the BIST information to the buffer pointed by + // PlatformInformationRecord for output. + // + // |--------------| <- TopOfTemporaryRam + // |Number of BSPs| + // |--------------| + // | BIST | + // |--------------| + // | .... | + // |--------------| + // | TSC[63:32] | + // |--------------| + // | TSC[31:00] | + // |--------------| + // + + TopOfTemporaryRam = (UINT32) (UINTN) TopOfTemporaryRamPpi - sizeof (UINT32); + TopOfTemporaryRam -= sizeof (UINT32) * 2; + DEBUG ((DEBUG_INFO, "TopOfTemporaryRam - 0x%x\n", TopOfTemporaryRam)); + Count = *(UINT32 *) (UINTN) (TopOfTemporaryRam - sizeof (UINT32)); + DEBUG ((DEBUG_INFO, "Count - 0x%x\n", Count)); + Size = Count * sizeof (IA32_HANDOFF_STATUS); + DEBUG ((DEBUG_INFO, "Size - 0x%x\n", Size)); + + Bist = (UINT32 *) (UINTN) (TopOfTemporaryRam - sizeof (UINT32) - Size); + DEBUG ((DEBUG_INFO, "Bist - 0x%x\n", *Bist)); + Ticker = (UINT64 *) (UINTN) (TopOfTemporaryRam - sizeof (UINT32) - Size - sizeof (UINT64)); + DEBUG ((DEBUG_INFO, "Ticker - 0x%lx\n", *Ticker)); + + // Just need record BSP + AsmSaveBistValue (*Bist); + AsmSaveTickerValue (*Ticker); +} + diff --git a/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecGetPerformance.c b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecGetPerformance.c new file mode 100644 index 0000000000..9fe4793415 --- /dev/null +++ b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecGetPerformance.c @@ -0,0 +1,92 @@ +/** @file + Sample to provide SecGetPerformance function. + + Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include + +#include +#include + +#include +#include +#include + +/** + This interface conveys performance information out of the Security (SEC) phase into PEI. + + This service is published by the SEC phase. The SEC phase handoff has an optional + EFI_PEI_PPI_DESCRIPTOR list as its final argument when control is passed from SEC into the + PEI Foundation. As such, if the platform supports collecting performance data in SEC, + this information is encapsulated into the data structure abstracted by this service. + This information is collected for the boot-strap processor (BSP) on IA-32. + + @param[in] PeiServices The pointer to the PEI Services Table. + @param[in] This The pointer to this instance of the PEI_SEC_PERFORMANCE_PPI. + @param[out] Performance The pointer to performance data collected in SEC phase. + + @retval EFI_SUCCESS The data was successfully returned. + +**/ +EFI_STATUS +EFIAPI +SecGetPerformance ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN PEI_SEC_PERFORMANCE_PPI *This, + OUT FIRMWARE_SEC_PERFORMANCE *Performance + ) +{ + UINT32 Size; + UINT32 Count; + UINT32 TopOfTemporaryRam; + UINT64 Ticker; + VOID *TopOfTemporaryRamPpi; + EFI_STATUS Status; + + DEBUG ((DEBUG_INFO, "SecGetPerformance\n")); + + Status = (*PeiServices)->LocatePpi ( + PeiServices, + &gTopOfTemporaryRamPpiGuid, + 0, + NULL, + (VOID **) &TopOfTemporaryRamPpi + ); + if (EFI_ERROR (Status)) { + return EFI_NOT_FOUND; + } + + // + // |--------------| <- TopOfTemporaryRam + // |Number of BSPs| + // |--------------| + // | BIST | + // |--------------| + // | .... | + // |--------------| + // | TSC[63:32] | + // |--------------| + // | TSC[31:00] | + // |--------------| + // + TopOfTemporaryRam = (UINT32) (UINTN) TopOfTemporaryRamPpi - sizeof (UINT32); + TopOfTemporaryRam -= sizeof (UINT32) * 2; + Count = *(UINT32 *) (UINTN) (TopOfTemporaryRam - sizeof (UINT32)); + Size = Count * sizeof (UINT64); + + Ticker = *(UINT64 *) (UINTN) (TopOfTemporaryRam - sizeof (UINT32) - Size - sizeof (UINT32) * 2); + Performance->ResetEnd = GetTimeInNanoSecond (Ticker); + + return EFI_SUCCESS; +} + diff --git a/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecPeiFspPlatformSecLibSample.inf b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecPeiFspPlatformSecLibSample.inf new file mode 100644 index 0000000000..7dd8c1447f --- /dev/null +++ b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecPeiFspPlatformSecLibSample.inf @@ -0,0 +1,97 @@ +## @file +# Sample to provide FSP wrapper platform sec related function. +# +# Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +################################################################################ +# +# Defines Section - statements that will be processed to create a Makefile. +# +################################################################################ +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = SecPeiFspPlatformSecLibSample + FILE_GUID = 5B2B6493-BEBB-4d44-8278-35F40F5289BC + MODULE_UNI_FILE = SecPeiFspPlatformSecLibSample.uni + MODULE_TYPE = SEC + VERSION_STRING = 1.0 + LIBRARY_CLASS = FspPlatformSecLib + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +################################################################################ +# +# Sources Section - list of files that are required for the build to succeed. +# +################################################################################ + +[Sources] + FspPlatformSecLibSample.c + SecRamInitData.c + SaveSecContext.c + SecPlatformInformation.c + SecGetPerformance.c + SecTempRamSupport.c + PlatformInit.c + +[Sources.IA32] + Ia32/SecEntry.asm + Ia32/PeiCoreEntry.asm + Ia32/AsmSaveSecContext.asm + Ia32/Stack.asm + Ia32/Fsp.h + Ia32/SecEntry.S + Ia32/PeiCoreEntry.S + Ia32/AsmSaveSecContext.S + Ia32/Stack.S + +################################################################################ +# +# Package Dependency Section - list of Package files that are required for +# this module. +# +################################################################################ + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + UefiCpuPkg/UefiCpuPkg.dec + BroxtonFspPkg/BroxtonFspPkg.dec + IntelFsp2Pkg/IntelFsp2Pkg.dec + BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec #override + IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec + +[LibraryClasses] + LocalApicLib + +[Ppis] + gEfiSecPlatformInformationPpiGuid ## CONSUMES + gPeiSecPerformancePpiGuid ## CONSUMES + gEfiTemporaryRamSupportPpiGuid ## CONSUMES + +[Pcd] + gIntelFsp2WrapperTokenSpaceGuid.PcdPeiTemporaryRamStackSize ## CONSUMES + gIntelFsp2WrapperTokenSpaceGuid.PcdFlashFvFspBase ## CONSUMES + gIntelFsp2WrapperTokenSpaceGuid.PcdFlashFvFspSize ## CONSUMES + +[FixedPcd] + gIntelFsp2WrapperTokenSpaceGuid.PcdCpuMicrocodePatchAddress ## CONSUMES + gIntelFsp2WrapperTokenSpaceGuid.PcdCpuMicrocodePatchRegionSize ## CONSUMES + gIntelFsp2WrapperTokenSpaceGuid.PcdFlashMicroCodeOffset ## CONSUMES + gIntelFsp2WrapperTokenSpaceGuid.PcdFlashCodeCacheAddress ## CONSUMES + gIntelFsp2WrapperTokenSpaceGuid.PcdFlashCodeCacheSize ## CONSUMES + diff --git a/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecPeiFspPlatformSecLibSample.uni b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecPeiFspPlatformSecLibSample.uni new file mode 100644 index 0000000000..50dd05a11b Binary files /dev/null and b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecPeiFspPlatformSecLibSample.uni differ diff --git a/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecPlatformInformation.c b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecPlatformInformation.c new file mode 100644 index 0000000000..1ab1089054 --- /dev/null +++ b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecPlatformInformation.c @@ -0,0 +1,86 @@ +/** @file + Sample to provide SecPlatformInformation function. + + Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include + +#include +#include + +#include +#include + +/** + This interface conveys state information out of the Security (SEC) phase into PEI. + + @param[in] PeiServices Pointer to the PEI Services Table. + @param[in,out] StructureSize Pointer to the variable describing size of the input buffer. + @param[out] PlatformInformationRecord Pointer to the EFI_SEC_PLATFORM_INFORMATION_RECORD. + + @retval EFI_SUCCESS The data was successfully returned. + @retval EFI_BUFFER_TOO_SMALL The buffer was too small. + +**/ +EFI_STATUS +EFIAPI +SecPlatformInformation ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN OUT UINT64 *StructureSize, + OUT EFI_SEC_PLATFORM_INFORMATION_RECORD *PlatformInformationRecord + ) +{ + UINT32 *Bist; + UINT32 Size; + UINT32 Count; + UINT32 TopOfTemporaryRam; + VOID *TopOfTemporaryRamPpi; + EFI_STATUS Status; + + DEBUG ((DEBUG_INFO, "SecPlatformInformation\n")); + + Status = (*PeiServices)->LocatePpi ( + PeiServices, + &gTopOfTemporaryRamPpiGuid, + 0, + NULL, + (VOID **) &TopOfTemporaryRamPpi + ); + if (EFI_ERROR (Status)) { + return EFI_NOT_FOUND; + } + + // + // The entries of BIST information, together with the number of them, + // reside in the bottom of stack, left untouched by normal stack operation. + // This routine copies the BIST information to the buffer pointed by + // PlatformInformationRecord for output. + // + TopOfTemporaryRam = (UINT32) (UINTN) TopOfTemporaryRamPpi - sizeof (UINT32); + TopOfTemporaryRam -= sizeof (UINT32) * 2; + Count = *((UINT32 *) (UINTN) (TopOfTemporaryRam - sizeof (UINT32))); + Size = Count * sizeof (IA32_HANDOFF_STATUS); + + if ((*StructureSize) < (UINT64) Size) { + *StructureSize = Size; + return EFI_BUFFER_TOO_SMALL; + } + + *StructureSize = Size; + Bist = (UINT32 *) (TopOfTemporaryRam - sizeof (UINT32) - Size); + + CopyMem (PlatformInformationRecord, Bist, Size); + + return EFI_SUCCESS; +} + diff --git a/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecRamInitData.c b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecRamInitData.c new file mode 100644 index 0000000000..c5beee0d65 --- /dev/null +++ b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecRamInitData.c @@ -0,0 +1,24 @@ +/** @file + Sample to provide TempRamInitParams data. + + Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include + +GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT32 TempRamInitParams[4] = { + ((UINT32) FixedPcdGet64 (PcdCpuMicrocodePatchAddress) + FixedPcdGet32 (PcdFlashMicroCodeOffset)), + ((UINT32) FixedPcdGet64 (PcdCpuMicrocodePatchRegionSize) - FixedPcdGet32 (PcdFlashMicroCodeOffset)), + FixedPcdGet32 (PcdFlashCodeCacheAddress), + FixedPcdGet32 (PcdFlashCodeCacheSize) +}; + diff --git a/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecTempRamSupport.c b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecTempRamSupport.c new file mode 100644 index 0000000000..4bd8384cd4 --- /dev/null +++ b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecTempRamSupport.c @@ -0,0 +1,148 @@ +/** @file + Sample to provide SecTemporaryRamSupport function. + + Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include + +#include + +#include +#include +#include +#include + +/** + Switch the stack in the temporary memory to the one in the permanent memory. + + This function must be invoked after the memory migration immediately. The relative + position of the stack in the temporary and permanent memory is same. + + @param[in] TemporaryMemoryBase Base address of the temporary memory. + @param[in] PermenentMemoryBase Base address of the permanent memory. + +**/ +VOID +EFIAPI +SecSwitchStack ( + IN UINT32 TemporaryMemoryBase, + IN UINT32 PermenentMemoryBase + ); + +/** + This service of the TEMPORARY_RAM_SUPPORT_PPI that migrates temporary RAM into + permanent memory. + + @param[in] PeiServices Pointer to the PEI Services Table. + @param[in] TemporaryMemoryBase Source Address in temporary memory from which the SEC or PEIM will copy the + Temporary RAM contents. + @param[in] PermanentMemoryBase Destination Address in permanent memory into which the SEC or PEIM will copy the + Temporary RAM contents. + @param[in] CopySize Amount of memory to migrate from temporary to permanent memory. + + @retval EFI_SUCCESS The data was successfully returned. + @retval EFI_INVALID_PARAMETER PermanentMemoryBase + CopySize > TemporaryMemoryBase when + TemporaryMemoryBase > PermanentMemoryBase. + +**/ +EFI_STATUS +EFIAPI +SecTemporaryRamSupport ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase, + IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase, + IN UINTN CopySize + ) +{ + IA32_DESCRIPTOR IdtDescriptor; + VOID* OldHeap; + VOID* NewHeap; + VOID* OldStack; + VOID* NewStack; + DEBUG_AGENT_CONTEXT_POSTMEM_SEC DebugAgentContext; + BOOLEAN OldStatus; + UINTN PeiStackSize; + + PeiStackSize = (UINTN) PcdGet32 (PcdPeiTemporaryRamStackSize); + if (PeiStackSize == 0) { + PeiStackSize = (CopySize >> 1); + } + + ASSERT (PeiStackSize < CopySize); + + // + // |-------------------|----> + // | Stack | PeiStackSize + // |-------------------|----> + // | Heap | PeiTemporayRamSize + // |-------------------|----> TempRamBase + // + // |-------------------|----> + // | Heap | PeiTemporayRamSize + // |-------------------|----> + // | Stack | PeiStackSize + // |-------------------|----> PermanentMemoryBase + // + + OldHeap = (VOID *) (UINTN) TemporaryMemoryBase; + NewHeap = (VOID *) ((UINTN) PermanentMemoryBase + PeiStackSize); + + OldStack = (VOID *) ((UINTN) TemporaryMemoryBase + CopySize - PeiStackSize); + NewStack = (VOID *) (UINTN) PermanentMemoryBase; + + DebugAgentContext.HeapMigrateOffset = (UINTN) NewHeap - (UINTN) OldHeap; + DebugAgentContext.StackMigrateOffset = (UINTN) NewStack - (UINTN) OldStack; + + OldStatus = SaveAndSetDebugTimerInterrupt (FALSE); + // + // Initialize Debug Agent to support source level debug in PEI phase after memory ready. + // It will build HOB and fix up the pointer in IDT table. + // + InitializeDebugAgent (DEBUG_AGENT_INIT_POSTMEM_SEC, (VOID *) &DebugAgentContext, NULL); + + // + // Migrate Heap + // + CopyMem (NewHeap, OldHeap, CopySize - PeiStackSize); + + // + // Migrate Stack + // + CopyMem (NewStack, OldStack, PeiStackSize); + + // + // Rebase IDT table in permanent memory + // + AsmReadIdtr (&IdtDescriptor); + IdtDescriptor.Base = IdtDescriptor.Base - (UINTN) OldStack + (UINTN) NewStack; + + AsmWriteIdtr (&IdtDescriptor); + + // + // Program MTRR + // + // + // SecSwitchStack function must be invoked after the memory migration + // immediatly, also we need fixup the stack change caused by new call into + // permenent memory. + // + SecSwitchStack ( + (UINT32) (UINTN) OldStack, + (UINT32) (UINTN) NewStack + ); + + SaveAndSetDebugTimerInterrupt (OldStatus); + + return EFI_SUCCESS; +} + diff --git a/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Tools/fsptool.py b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Tools/fsptool.py new file mode 100644 index 0000000000..83e824d617 --- /dev/null +++ b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Tools/fsptool.py @@ -0,0 +1,365 @@ +## @file +# !/usr/bin/env python +# +# Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +import os +import sys +import uuid +import copy +import struct +import argparse +from ctypes import * + +""" +This utility supports some operations for Intel FSP image. +It supports: + - Split a FSP 2.0 compatibale image into individual FSP-T/M/S/C + and generate the mapping header file. +""" + +class c_uint24(Structure): + """Little-Endian 24-bit Unsigned Integer""" + _pack_ = 1 + _fields_ = [ + ('Data', (c_uint8 * 3)) + ] + + def __init__(self, val=0): + self.set_value(val) + + def __str__(self, indent=0): + return '0x%.6x' % self.value + + def get_value(self): + return ( + (self.Data[0] ) + + (self.Data[1] << 8) + + (self.Data[2] << 16) + ) + + def set_value(self, val): + self.Data[0] = (val ) & 0xff + self.Data[1] = (val >> 8) & 0xff + self.Data[2] = (val >> 16) & 0xff + + value = property(get_value, set_value) + +class EFI_FIRMWARE_VOLUME_HEADER(Structure): + _fields_ = [ + ('ZeroVector', ARRAY(c_uint8, 16)), + ('FileSystemGuid', ARRAY(c_char, 16)), + ('FvLength', c_uint64), + ('Signature', c_uint32), + ('Attributes', c_uint32), + ('HeaderLength', c_uint16), + ('Checksum', c_uint16), + ('ExtHeaderOffset', c_uint16), + ('Reserved', c_uint8), + ('Revision', c_uint8) + ] + +class EFI_FIRMWARE_VOLUME_EXT_HEADER(Structure): + _fields_ = [ + ('FvName', ARRAY(c_char, 16)), + ('ExtHeaderSize', c_uint32) + ] + +class EFI_FFS_INTEGRITY_CHECK(Structure): + _fields_ = [ + ('Header', c_uint8), + ('File', c_uint8) + ] + +class EFI_FFS_FILE_HEADER(Structure): + _fields_ = [ + ('Name', ARRAY(c_char, 16)), + ('IntegrityCheck', EFI_FFS_INTEGRITY_CHECK), + ('Type', c_uint8), + ('Attributes', c_uint8), + ('Size', c_uint24), + ('State', c_uint8) + ] + +class EFI_COMMON_SECTION_HEADER(Structure): + _fields_ = [ + ('Size', c_uint24), + ('Type', c_uint8) + ] + +class FSP_INFORMATION_HEADER(Structure): + _fields_ = [ + ('Signature', c_uint32), + ('HeaderLength', c_uint32), + ('Reserved1', ARRAY(c_uint8, 3)), + ('HeaderRevision', c_uint8), + ('ImageRevision', c_uint32), + ('ImageId', c_uint64), + ('ImageSize', c_uint32), + ('ImageBase', c_uint32), + ('ImageAttribute', c_uint32), + ('CfgRegionOffset', c_uint32), + ('CfgRegionSize', c_uint32), + ('ApiEntryNum', c_uint32), + ('NemInitEntry', c_uint32), + ('FspInitEntry', c_uint32), + ('NotifyPhaseEntry', c_uint32), + ('FspMemoryInitEntry', c_uint32), + ('TempRamExitEntry', c_uint32), + ('FspSiliconInitEntry', c_uint32) + ] + +class FspFv: + HeaderFile = """/* + * + * Automatically generated file; DO NOT EDIT. + * FSP mapping file + * + */ +""" + FspNameDict = { + "0" : "-C.Fv", + "1" : "-T.Fv", + "2" : "-M.Fv", + "3" : "-S.Fv", + } + + def __init__(self, FvBin): + self.FspFv = {} + self.FvList = [] + self.FspBin = FvBin + hfsp = open (self.FspBin, 'r+b') + self.FspDat = bytearray(hfsp.read()) + hfsp.close() + + def OutputStruct (self, obj, indent = 0): + max_key_len = 20 + pstr = (' ' * indent + '{0:<%d} = {1}\n') % max_key_len + if indent: + s = '' + else: + s = (' ' * indent + '<%s>:\n') % obj.__class__.__name__ + for field in obj._fields_: + key = field[0] + val = getattr(obj, key) + rep = '' + + if not isinstance(val, c_uint24) and isinstance(val, Structure): + s += pstr.format(key, val.__class__.__name__) + s += self.OutputStruct (val, indent + 1) + else: + if type(val) in (int, long): + rep = hex(val) + elif isinstance(val, str) and (len(val) == 16): + rep = str(uuid.UUID(bytes = val)) + elif isinstance(val, c_uint24): + rep = hex(val.get_value()) + elif 'c_ubyte_Array' in str(type(val)): + rep = str(list(bytearray(val))) + else: + rep = str(val) + s += pstr.format(key, rep) + return s + + def PrintFv (self): + print ("FV LIST:") + idx = 0 + for (fvh, fvhe, offset) in self.FvList: + guid = uuid.UUID(bytes = fvhe.FvName) + print ("FV%d FV GUID:%s Offset:0x%08X Length:0x%08X" % (idx, str(guid), offset, fvh.FvLength)) + idx = idx + 1 + print ("\nFSP LIST:") + for fsp in self.FspFv: + print "FSP%s contains FV%s" % (fsp, str(self.FspFv[fsp][1])) + print "\nFSP%s Info Header:" % fsp + fih = self.FspFv[fsp][0] + + def AlaignPtr (self, offset, alignment = 8): + return (offset + alignment - 1) & ~(alignment - 1) + + def GetFspInfoHdr (self, fvh, fvhe, fvoffset): + if fvhe: + offset = fvh.ExtHeaderOffset + fvhe.ExtHeaderSize + else: + offset = fvh.HeaderLength + offset = self.AlaignPtr(offset) + + # Now it should be 1st FFS + ffs = EFI_FFS_FILE_HEADER.from_buffer (self.FspDat, offset) + offset += sizeof(ffs) + offset = self.AlaignPtr(offset) + + # Now it should be 1st Section + sec = EFI_COMMON_SECTION_HEADER.from_buffer (self.FspDat, offset) + offset += sizeof(sec) + + # Now it should be FSP_INFO_HEADER + offset += fvoffset + fih = FSP_INFORMATION_HEADER.from_buffer (self.FspDat, offset) + if 'FSPH' != bytearray.fromhex('%08X' % fih.Signature)[::-1]: + return None + + return fih + + def GetFvHdr (self, offset): + fvh = EFI_FIRMWARE_VOLUME_HEADER.from_buffer (self.FspDat, offset) + if '_FVH' != bytearray.fromhex('%08X' % fvh.Signature)[::-1]: + return None, None + if fvh.ExtHeaderOffset > 0: + offset += fvh.ExtHeaderOffset + fvhe = EFI_FIRMWARE_VOLUME_EXT_HEADER.from_buffer (self.FspDat, offset) + else: + fvhe = None + return fvh, fvhe + + def GetFvData(self, idx): + (fvh, fvhe, offset) = self.FvList[idx] + return self.FspDat[offset:offset+fvh.FvLength] + + def CheckFsp (self): + if len(self.FspFv) == 0: + return + + fih = None + for fv in self.FspFv: + if not fih: + fih = self.FspFv[fv][0] + else: + newfih = self.FspFv[fv][0] + if (newfih.ImageId != fih.ImageId) or (newfih.ImageRevision != fih.ImageRevision): + raise Exception("Inconsistent FSP ImageId or ImageRevision detected !") + return + + def WriteFsp(self, dir, name): + if not name: + name = self.FspBin + fspname, ext = os.path.splitext(os.path.basename(name)) + for fv in self.FspFv: + filename = os.path.join(dir, fspname + fv + ext) + hfsp = open(filename, 'w+b') + for fvidx in self.FspFv[fv][1]: + hfsp.write (self.GetFvData(fvidx)) + hfsp.close() + + def WriteMap(self, dir, hfile): + if not hfile: + hfile = os.path.splitext(os.path.basename(self.FspBin))[0] + '.h' + fspname, ext = os.path.splitext(os.path.basename(hfile)) + filename = os.path.join(dir, fspname + ext) + hfsp = open(filename, 'w') + hfsp.write ('%s\n\n' % self.HeaderFile) + + firstfv = True + for fsp in self.FspFv: + fih = self.FspFv[fsp][0] + fvs = self.FspFv[fsp][1] + if firstfv: + IdStr = str(bytearray.fromhex('%016X' % fih.ImageId)[::-1]) + hfsp.write("#define FSP_IMAGE_ID 0x%016X /* '%s' */\n" % (fih.ImageId, IdStr)) + hfsp.write("#define FSP_IMAGE_REV 0x%08X \n\n" % fih.ImageRevision) + firstfv = False + hfsp.write ('#define FSP%s_BASE 0x%08X\n' % (fsp, fih.ImageBase)) + hfsp.write ('#define FSP%s_OFFSET 0x%08X\n' % (fsp, self.FvList[fvs[0]][-1])) + hfsp.write ('#define FSP%s_LENGTH 0x%08X\n\n' % (fsp, fih.ImageSize)) + hfsp.close() + + def ParseFsp (self): + self.FspFv = {} + flen = 0 + for (fvh, fvhe, offset) in self.FvList: + fih = self.GetFspInfoHdr (fvh, fvhe, offset) + if fih: + if flen != 0: + raise Exception("Incorrect FV size in image !") + ftype = str((fih.ImageAttribute >> 28) & 0xF) + if ftype not in self.FspNameDict: + raise Exception("Unknown Attribute in image !") + fname = self.FspNameDict[str(ftype)] + if fname in self.FspFv: + raise Exception("Multiple '%s' in image !" % fname) + self.FspFv[fname] = (copy.deepcopy(fih), []) + flen = fih.ImageSize + if flen > 0: + flen = flen - fvh.FvLength + if flen < 0: + raise Exception("Incorrect FV size in image !") + self.FspFv[fname][1].append(self.FvList.index((fvh, fvhe, offset))) + + def AddFv(self, offset): + fvh, fvhe = self.GetFvHdr (offset) + if fvh is None: + raise Exception('FV signature is not valid !') + fvitem = (copy.deepcopy(fvh), copy.deepcopy(fvhe), offset) + self.FvList.append(fvitem) + return fvh.FvLength + + def ParseFv(self): + offset = 0 + while (offset < len(self.FspDat)): + fv_len = self.AddFv (offset) + offset += fv_len + +def GenFspHdr (fspfile, outdir, hfile, show): + fsp_fv = FspFv(fspfile) + fsp_fv.ParseFv() + fsp_fv.ParseFsp() + fsp_fv.CheckFsp() + if show: + fsp_fv.PrintFv() + fsp_fv.WriteMap(outdir, hfile) + +def SplitFspBin (fspfile, outdir, nametemplate, show): + fsp_fv = FspFv(fspfile) + fsp_fv.ParseFv() + fsp_fv.ParseFsp() + if show: + fsp_fv.PrintFv() + fsp_fv.WriteFsp(outdir, nametemplate) + +def main (): + parser = argparse.ArgumentParser() + subparsers = parser.add_subparsers(title='commands') + + parser_split = subparsers.add_parser('split', help='split a FSP into multiple components') + parser_split.set_defaults(which='split') + parser_split.add_argument('-f', '--fspbin' , dest='FspBinary', type=str, help='FSP binary file path', required = True) + parser_split.add_argument('-o', '--outdir' , dest='OutputDir', type=str, help='Output directory path', default = '.') + parser_split.add_argument('-n', '--nametpl', dest='NameTemplate', type=str, help='Output name template', default = '') + parser_split.add_argument('-p', action='store_true', help='Print FSP FV information', default = False) + + parser_genhdr = subparsers.add_parser('genhdr', help='generate a header file for FSP binary') + parser_genhdr.set_defaults(which='genhdr') + parser_genhdr.add_argument('-f', '--fspbin' , dest='FspBinary', type=str, help='FSP binary file path', required = True) + parser_genhdr.add_argument('-o', '--outdir' , dest='OutputDir', type=str, help='Output directory path', default = '.') + parser_genhdr.add_argument('-n', '--hfile', dest='HFileName', type=str, help='Output header file name', default = '') + parser_genhdr.add_argument('-p', action='store_true', help='Print FSP FV information', default = False) + + args = parser.parse_args() + if args.which in ['split', 'genhdr']: + if not os.path.exists(args.FspBinary): + raise Exception ("Could not locate FSP binary file '%s' !" % args.FspBinary) + if not os.path.exists(args.OutputDir): + raise Exception ("Invalid output directory '%s' !" % args.OutputDir) + + if args.which == 'split': + SplitFspBin (args.FspBinary, args.OutputDir, args.NameTemplate, args.p) + elif args.which == 'genhdr': + GenFspHdr (args.FspBinary, args.OutputDir, args.HFileName, args.p) + else: + pass + + print 'Done!' + return 0 + +if __name__ == '__main__': + sys.exit(main()) -- cgit v1.2.3