From: jyao1 Date: Thu, 24 Jul 2014 06:52:43 +0000 (+0000) Subject: Add IntelFspWrapper to support boot EDKII on FSP bin. X-Git-Tag: edk2-stable201903~11317 X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=commitdiff_plain;h=a33a2f62218e6e49a25d63474b7fe423d8ee4b71 Add IntelFspWrapper to support boot EDKII on FSP bin. Contributed-under: TianoCore Contribution Agreement 1.0 Signed off by: Jiewen Yao Reviewed by: Ravi Rangarajan Reviewed by: Maurice Ma Reviewed by: Giri Mudusuru Reviewed by: Liming Gao git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15676 6f19259b-4bc3-4df7-8a09-765794883524 --- diff --git a/IntelFspPkg/Include/FspApi.h b/IntelFspPkg/Include/FspApi.h new file mode 100644 index 0000000000..934a5766c3 --- /dev/null +++ b/IntelFspPkg/Include/FspApi.h @@ -0,0 +1,209 @@ +/** @file + Intel FSP API definition from Intel Firmware Support Package External + Architecture Specification, April 2014, revision 001. + + Copyright (c) 2014, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef _FSP_API_H_ +#define _FSP_API_H_ + +typedef UINT32 FSP_STATUS; +#define FSPAPI EFIAPI + +/** + FSP Init continuation function prototype. + Control will be returned to this callback function after FspInit API call. + + @param[in] Status Status of the FSP INIT API. + @param[in] HobBufferPtr Pointer to the HOB data structure defined in the PI specification. +**/ +typedef +VOID +(* CONTINUATION_PROC) ( + IN FSP_STATUS Status, + IN VOID *HobListPtr + ); + +#pragma pack(1) + +typedef struct { + /// + /// Base address of the microcode region. + /// + UINT32 MicrocodeRegionBase; + /// + /// Length of the microcode region. + /// + UINT32 MicrocodeRegionLength; + /// + /// Base address of the cacheable flash region. + /// + UINT32 CodeRegionBase; + /// + /// Length of the cacheable flash region. + /// + UINT32 CodeRegionLength; +} FSP_TEMP_RAM_INIT_PARAMS; + +typedef struct { + /// + /// Non-volatile storage buffer pointer. + /// + VOID *NvsBufferPtr; + /// + /// Runtime buffer pointer + /// + VOID *RtBufferPtr; + /// + /// Continuation function address + /// + CONTINUATION_PROC ContinuationFunc; +} FSP_INIT_PARAMS; + +typedef struct { + /// + /// Stack top pointer used by the bootloader. + /// The new stack frame will be set up at this location after FspInit API call. + /// + UINT32 *StackTop; + /// + /// Current system boot mode. + /// + UINT32 BootMode; + /// + /// User platform configuraiton data region pointer. + /// + VOID *UpdDataRgnPtr; + /// + /// Reserved + /// + UINT32 Reserved[7]; +} FSP_INIT_RT_COMMON_BUFFER; + +typedef enum { + /// + /// Notification code for post PCI enuermation + /// + EnumInitPhaseAfterPciEnumeration = 0x20, + /// + /// Notification code before transfering control to the payload + /// + EnumInitPhaseReadyToBoot = 0x40 +} FSP_INIT_PHASE; + +typedef struct { + /// + /// Notification phase used for NotifyPhase API + /// + FSP_INIT_PHASE Phase; +} NOTIFY_PHASE_PARAMS; + +#pragma pack() + +/** + This FSP API is called soon after coming out of reset and before memory and stack is + available. This FSP API will load the microcode update, enable code caching for the + region specified by the boot loader and also setup a temporary stack to be used until + main memory is initialized. + + A hardcoded stack can be set up with the following values, and the "esp" register + initialized to point to this hardcoded stack. + 1. The return address where the FSP will return control after setting up a temporary + stack. + 2. A pointer to the input parameter structure + + However, since the stack is in ROM and not writeable, this FSP API cannot be called + using the "call" instruction, but needs to be jumped to. + + @param[in] TempRaminitParamPtr Address pointer to the FSP_TEMP_RAM_INIT_PARAMS structure. + + @retval FSP_SUCCESS Temp RAM was initialized successfully. + @retval FSP_INVALID_PARAMETER Input parameters are invalid.. + @retval FSP_NOT_FOUND No valid microcode was found in the microcode region. + @retval FSP_UNSUPPORTED The FSP calling conditions were not met. + @retval FSP_DEVICE_ERROR Temp RAM initialization failed. + + If this function is successful, the FSP initializes the ECX and EDX registers to point to + a temporary but writeable memory range available to the boot loader and returns with + FSP_SUCCESS in register EAX. Register ECX points to the start of this temporary + memory range and EDX points to the end of the range. Boot loader is free to use the + whole range described. Typically the boot loader can reload the ESP register to point + to the end of this returned range so that it can be used as a standard stack. +**/ +typedef +FSP_STATUS +(FSPAPI *FSP_TEMP_RAM_INIT) ( + IN FSP_TEMP_RAM_INIT_PARAMS *FspTempRamInitPtr + ); + +/** + This FSP API is called after TempRamInitEntry. This FSP API initializes the memory, + the CPU and the chipset to enable normal operation of these devices. This FSP API + accepts a pointer to a data structure that will be platform dependent and defined for + each FSP binary. This will be documented in the Integration Guide for each FSP + release. + The boot loader provides a continuation function as a parameter when calling FspInit. + After FspInit completes its execution, it does not return to the boot loader from where + it was called but instead returns control to the boot loader by calling the continuation + function which is passed to FspInit as an argument. + + @param[in] FspInitParamPtr Address pointer to the FSP_INIT_PARAMS structure. + + @retval FSP_SUCCESS FSP execution environment was initialized successfully. + @retval FSP_INVALID_PARAMETER Input parameters are invalid. + @retval FSP_UNSUPPORTED The FSP calling conditions were not met. + @retval FSP_DEVICE_ERROR FSP initialization failed. +**/ +typedef +FSP_STATUS +(FSPAPI *FSP_FSP_INIT) ( + IN OUT FSP_INIT_PARAMS *FspInitParamPtr + ); + +/** + This FSP API is used to notify the FSP about the different phases in the boot process. + This allows the FSP to take appropriate actions as needed during different initialization + phases. The phases will be platform dependent and will be documented with the FSP + release. The current FSP supports two notify phases: + Post PCI enumeration + Ready To Boot + + @param[in] NotifyPhaseParamPtr Address pointer to the NOTIFY_PHASE_PRAMS + + @retval FSP_SUCCESS The notification was handled successfully. + @retval FSP_UNSUPPORTED The notification was not called in the proper order. + @retval FSP_INVALID_PARAMETER The notification code is invalid. +**/ +typedef +FSP_STATUS +(FSPAPI *FSP_NOTFY_PHASE) ( + IN NOTIFY_PHASE_PARAMS *NotifyPhaseParamPtr + ); + +/// +/// FSP API Return Status Code +/// +#define FSP_SUCCESS 0x00000000 +#define FSP_INVALID_PARAMETER 0x80000002 +#define FSP_UNSUPPORTED 0x80000003 +#define FSP_NOT_READY 0x80000006 +#define FSP_DEVICE_ERROR 0x80000007 +#define FSP_OUT_OF_RESOURCES 0x80000009 +#define FSP_VOLUME_CORRUPTED 0x8000000A +#define FSP_NOT_FOUND 0x8000000E +#define FSP_TIMEOUT 0x80000012 +#define FSP_ABORTED 0x80000015 +#define FSP_INCOMPATIBLE_VERSION 0x80000010 +#define FSP_SECURITY_VIOLATION 0x8000001A +#define FSP_CRC_ERROR 0x8000001B + +#endif diff --git a/IntelFspPkg/Include/FspInfoHeader.h b/IntelFspPkg/Include/FspInfoHeader.h new file mode 100644 index 0000000000..cde7b599c9 --- /dev/null +++ b/IntelFspPkg/Include/FspInfoHeader.h @@ -0,0 +1,105 @@ +/** @file + Intel FSP Info Header definition from Intel Firmware Support Package External + Architecture Specification, April 2014, revision 001. + + Copyright (c) 2014, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef _FSP_INFO_HEADER_H_ +#define _FSP_INFO_HEADER_H_ + +/// +/// Fixed FSP header offset in the FSP image +/// +#define FSP_INFO_HEADER_OFF 0x94 + +#define OFFSET_IN_FSP_INFO_HEADER(x) (UINT32)&((FSP_INFO_HEADER *)(UINTN)0)->x + +#pragma pack(1) + +typedef struct { + /// + /// Signature ('FSPH') for the FSP Information Header + /// + UINT32 Signature; + /// + /// Length of the FSP Information Header + /// + UINT32 HeaderLength; + /// + /// Reserved + /// + UINT8 Reserved1[3]; + /// + /// Revision of the FSP Information Header + /// + UINT8 HeaderRevision; + /// + /// Revision of the FSP binary + /// + UINT32 ImageRevision; + + + /// + /// Signature string that will help match the FSP Binary to a supported + /// hardware configuration. + /// + CHAR8 ImageId[8]; + /// + /// Size of the entire FSP binary + /// + UINT32 ImageSize; + /// + /// FSP binary preferred base address + /// + UINT32 ImageBase; + + + /// + /// Attribute for the FSP binary + /// + UINT32 ImageAttribute; + /// + /// Offset of the FSP configuration region + /// + UINT32 CfgRegionOffset; + /// + /// Size of the FSP configuration region + /// + UINT32 CfgRegionSize; + /// + /// Number of API entries this FSP supports + /// + UINT32 ApiEntryNum; + + + /// + /// TempRamInit API entry offset + /// + UINT32 TempRamInitEntryOffset; + /// + /// FspInit API entry offset + /// + UINT32 FspInitEntryOffset; + /// + /// NotifyPhase API entry offset + /// + UINT32 NotifyPhaseEntryOffset; + /// + /// Reserved + /// + UINT32 Reserved2; + +} FSP_INFO_HEADER; + +#pragma pack() + +#endif diff --git a/IntelFspPkg/Include/Guid/FspHeaderFile.h b/IntelFspPkg/Include/Guid/FspHeaderFile.h new file mode 100644 index 0000000000..9902395935 --- /dev/null +++ b/IntelFspPkg/Include/Guid/FspHeaderFile.h @@ -0,0 +1,21 @@ +/** @file + Intel FSP Header File Guid definition from Intel Firmware Support Package External + Architecture Specification, April 2014, revision 001. + + Copyright (c) 2014, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef __FSP_HEADER_FILE_GUID__ +#define __FSP_HEADER_FILE_GUID__ + +extern EFI_GUID gFspHeaderFileGuid; + +#endif diff --git a/IntelFspPkg/Include/Guid/GuidHobFspEas.h b/IntelFspPkg/Include/Guid/GuidHobFspEas.h new file mode 100644 index 0000000000..07685dda7a --- /dev/null +++ b/IntelFspPkg/Include/Guid/GuidHobFspEas.h @@ -0,0 +1,23 @@ +/** @file + Intel FSP Hob Guid definition from Intel Firmware Support Package External + Architecture Specification, April 2014, revision 001. + + Copyright (c) 2014, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef __GUID_HOB_FSP_EAS_GUID__ +#define __GUID_HOB_FSP_EAS_GUID__ + +extern EFI_GUID gFspBootLoaderTemporaryMemoryGuid; +extern EFI_GUID gFspReservedMemoryResourceHobGuid; +extern EFI_GUID gFspNonVolatileStorageHobGuid; + +#endif diff --git a/IntelFspPkg/IntelFspPkg.dec b/IntelFspPkg/IntelFspPkg.dec new file mode 100644 index 0000000000..ef942a7ac4 --- /dev/null +++ b/IntelFspPkg/IntelFspPkg.dec @@ -0,0 +1,31 @@ +## @file +# +# Provides driver and definitions to build fsp in EDKII bios. +# +# Copyright (c) 2014, Intel Corporation. All rights reserved.
+# This program and the accompanying materials are licensed and made available under +# the terms and conditions of the BSD License that accompanies this distribution. +# The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +[Defines] + DEC_SPECIFICATION = 0x00010005 + PACKAGE_NAME = IntelFspPkg + PACKAGE_GUID = 444C6CDF-55BD-4744-8F74-AE98B003B955 + PACKAGE_VERSION = 0.1 + +[Includes] + Include + +[Guids] + # Guid define in FSP EAS + gFspHeaderFileGuid = { 0x912740BE, 0x2284, 0x4734, { 0xB9, 0x71, 0x84, 0xB0, 0x27, 0x35, 0x3F, 0x0C } } + gFspBootLoaderTemporaryMemoryGuid = { 0xbbcff46c, 0xc8d3, 0x4113, { 0x89, 0x85, 0xb9, 0xd4, 0xf3, 0xb3, 0xf6, 0x4e } } + gFspReservedMemoryResourceHobGuid = { 0x69a79759, 0x1373, 0x4367, { 0xa6, 0xc4, 0xc7, 0xf5, 0x9e, 0xfd, 0x98, 0x6e } } + gFspNonVolatileStorageHobGuid = { 0x721acf02, 0x4d77, 0x4c2a, { 0xb3, 0xdc, 0x27, 0x0b, 0x7b, 0xa9, 0xe4, 0xb0 } } + diff --git a/IntelFspWrapperPkg/FspInitPei/FindPeiCore.c b/IntelFspWrapperPkg/FspInitPei/FindPeiCore.c new file mode 100644 index 0000000000..ce003d056f --- /dev/null +++ b/IntelFspWrapperPkg/FspInitPei/FindPeiCore.c @@ -0,0 +1,199 @@ +/** @file + Locate the entry point for the PEI Core + + Copyright (c) 2014, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include +#include + +#include "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/IntelFspWrapperPkg/FspInitPei/FspInitPei.c b/IntelFspWrapperPkg/FspInitPei/FspInitPei.c new file mode 100644 index 0000000000..823f1bbef8 --- /dev/null +++ b/IntelFspWrapperPkg/FspInitPei/FspInitPei.c @@ -0,0 +1,188 @@ +/** @file + This PEIM will be invoked twice by pei core. In 1st entry, it will call FspInit API. + In 2nd entry, it will parse the hoblist from fsp and report them into pei core. + This file contains the main entrypoint of the PEIM. + + Copyright (c) 2014, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + + +#include "FspInitPei.h" + +/** + FSP Init continuation function. + Control will be returned to this callback function after FspInit API call. + + @param[in] Status Status of the FSP INIT API + @param[in] HobListPtr Pointer to the HOB data structure defined in the PI specification. + +**/ +VOID +ContinuationFunc ( + IN FSP_STATUS Status, + IN VOID *HobListPtr + ) +{ + EFI_BOOT_MODE BootMode; + UINT64 StackSize; + EFI_PHYSICAL_ADDRESS StackBase; + + DEBUG ((DEBUG_INFO, "ContinuationFunc - %r\n", Status)); + DEBUG ((DEBUG_INFO, "HobListPtr - 0x%x\n", HobListPtr)); + + if (Status != FSP_SUCCESS) { + CpuDeadLoop (); + } + + // + // Can not call any PeiServices + // + BootMode = GetBootMode (); + + GetStackInfo (BootMode, TRUE, &StackBase, &StackSize); + DEBUG ((DEBUG_INFO, "StackBase - 0x%x\n", StackBase)); + DEBUG ((DEBUG_INFO, "StackSize - 0x%x\n", StackSize)); + CallPeiCoreEntryPoint ( + HobListPtr, + (VOID *)(UINTN)StackBase, + (VOID *)(UINTN)(StackBase + StackSize) + ); +} + +/** + Call FspInit API. + + @param[in] FspHeader FSP header pointer. +**/ +VOID +SecFspInit ( + IN FSP_INFO_HEADER *FspHeader + ) +{ + FSP_INIT_PARAMS FspInitParams; + FSP_INIT_RT_COMMON_BUFFER FspRtBuffer; + UINT8 FspUpdRgn[FixedPcdGet32 (PcdMaxUpdRegionSize)]; + UINT32 UpdRegionSize; + EFI_BOOT_MODE BootMode; + UINT64 StackSize; + EFI_PHYSICAL_ADDRESS StackBase; + FSP_STATUS FspStatus; + + DEBUG ((DEBUG_INFO, "SecFspInit enter\n")); + + PeiServicesGetBootMode (&BootMode); + DEBUG ((DEBUG_INFO, "BootMode - 0x%x\n", BootMode)); + + GetStackInfo (BootMode, FALSE, &StackBase, &StackSize); + DEBUG ((DEBUG_INFO, "StackBase - 0x%x\n", StackBase)); + DEBUG ((DEBUG_INFO, "StackSize - 0x%x\n", StackSize)); + + ZeroMem (&FspRtBuffer, sizeof(FspRtBuffer)); + FspRtBuffer.StackTop = (UINT32 *)(UINTN)(StackBase + StackSize); + + FspRtBuffer.BootMode = BootMode; + + /* Platform override any UPD configs */ + UpdRegionSize = GetUpdRegionSize(); + DEBUG ((DEBUG_INFO, "UpdRegionSize - 0x%x\n", UpdRegionSize)); + DEBUG ((DEBUG_INFO, "sizeof(FspUpdRgn) - 0x%x\n", sizeof(FspUpdRgn))); + ASSERT(sizeof(FspUpdRgn) >= UpdRegionSize); + ZeroMem (FspUpdRgn, UpdRegionSize); + FspRtBuffer.UpdDataRgnPtr = UpdateFspUpdConfigs (FspUpdRgn); + + ZeroMem (&FspInitParams, sizeof(FspInitParams)); + FspInitParams.NvsBufferPtr = GetNvsBuffer (); + DEBUG ((DEBUG_INFO, "NvsBufferPtr - 0x%x\n", FspInitParams.NvsBufferPtr)); + FspInitParams.RtBufferPtr = (VOID *)&FspRtBuffer; + FspInitParams.ContinuationFunc = (CONTINUATION_PROC)ContinuationFunc; + + SaveSecContext (GetPeiServicesTablePointer ()); + + DEBUG ((DEBUG_INFO, "FspInitParams - 0x%x\n", &FspInitParams)); + DEBUG ((DEBUG_INFO, " NvsBufferPtr - 0x%x\n", FspInitParams.NvsBufferPtr)); + DEBUG ((DEBUG_INFO, " RtBufferPtr - 0x%x\n", FspInitParams.RtBufferPtr)); + DEBUG ((DEBUG_INFO, " StackTop - 0x%x\n", FspRtBuffer.StackTop)); + DEBUG ((DEBUG_INFO, " BootMode - 0x%x\n", FspRtBuffer.BootMode)); + DEBUG ((DEBUG_INFO, " UpdDataRgnPtr - 0x%x\n", FspRtBuffer.UpdDataRgnPtr)); + DEBUG ((DEBUG_INFO, " ContinuationFunc - 0x%x\n", FspInitParams.ContinuationFunc)); + + FspStatus = CallFspInit (FspHeader, &FspInitParams); + // + // Should never return + // + DEBUG((DEBUG_ERROR, "FSP Init failed, status: 0x%x\n", FspStatus)); + CpuDeadLoop (); +} + +/** + 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 +FspPeiEntryPoint ( + IN EFI_PEI_FILE_HANDLE FileHandle, + IN CONST EFI_PEI_SERVICES **PeiServices + ) +{ + FSP_INFO_HEADER *FspHeader; + EFI_STATUS Status; + FSP_INIT_DONE_PPI *FspInitDone; + VOID *FspHobList; + EFI_BOOT_MODE BootMode; + + DEBUG ((DEBUG_INFO, "FspPeiEntryPoint\n")); + + Status = PeiServicesLocatePpi ( + &gFspInitDonePpiGuid, + 0, + NULL, + (VOID **) &FspInitDone + ); + if (EFI_ERROR (Status)) { + // + // 1st entry + // + DEBUG ((DEBUG_INFO, "1st entry\n")); + FspHeader = FspFindFspHeader (PcdGet32 (PcdFlashFvFspBase)); + DEBUG ((DEBUG_INFO, "FspHeader - 0x%x\n", FspHeader)); + if (FspHeader == NULL) { + return EFI_DEVICE_ERROR; + } + + SecFspInit (FspHeader); + + // + // Never return here + // + CpuDeadLoop (); + } else { + // + // 2nd entry + // + DEBUG ((DEBUG_INFO, "2nd entry\n")); + Status = FspInitDone->GetFspHobList (PeiServices, FspInitDone, &FspHobList); + DEBUG ((DEBUG_INFO, "FspHobList - 0x%x\n", FspHobList)); + FspHobProcess (FspHobList); + + PeiServicesGetBootMode (&BootMode); + if (BootMode == BOOT_ON_S3_RESUME) { + Status = PeiServicesNotifyPpi (&mS3EndOfPeiNotifyDesc); + ASSERT_EFI_ERROR (Status); + } + } + + return EFI_SUCCESS; +} diff --git a/IntelFspWrapperPkg/FspInitPei/FspInitPei.h b/IntelFspWrapperPkg/FspInitPei/FspInitPei.h new file mode 100644 index 0000000000..5118cd04e3 --- /dev/null +++ b/IntelFspWrapperPkg/FspInitPei/FspInitPei.h @@ -0,0 +1,38 @@ +/** @file + This is PEIM header file. + + Copyright (c) 2014, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef _FSP_INIT_PEI_H_ +#define _FSP_INIT_PEI_H_ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +extern EFI_PEI_NOTIFY_DESCRIPTOR mS3EndOfPeiNotifyDesc; + +#endif diff --git a/IntelFspWrapperPkg/FspInitPei/FspInitPei.inf b/IntelFspWrapperPkg/FspInitPei/FspInitPei.inf new file mode 100644 index 0000000000..0efcf5e542 --- /dev/null +++ b/IntelFspWrapperPkg/FspInitPei/FspInitPei.inf @@ -0,0 +1,81 @@ +## @file +# FSP PEI Module +# +# This PEIM will be invoked twice by pei core. In 1st entry, it will call FspInit API. +# In 2nd entry, it will parse the hoblist from fsp and report them into pei core. +# including install the memory as required. +# +# Copyright (c) 2014, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = FspInitPeim + FILE_GUID = BC59E2E1-7492-4031-806E-C48DCCC3A026 + MODULE_TYPE = PEIM + VERSION_STRING = 1.0 + ENTRY_POINT = FspPeiEntryPoint + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 +# + +[Sources] + FspInitPei.c + FspInitPei.h + FspNotifyS3.c + SecMain.c + SecMain.h + FindPeiCore.c + SecFspInitDone.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + UefiCpuPkg/UefiCpuPkg.dec + IntelFspPkg/IntelFspPkg.dec + IntelFspWrapperPkg/IntelFspWrapperPkg.dec + +[LibraryClasses] + PeimEntryPoint + PeiServicesLib + PeiServicesTablePointerLib + BaseLib + BaseMemoryLib + DebugLib + HobLib + FspPlatformInfoLib + FspHobProcessLib + FspPlatformSecLib + DebugAgentLib + UefiCpuLib + PeCoffGetEntryPointLib + PeCoffExtraActionLib + FspApiLib + +[Ppis] + gTopOfTemporaryRamPpiGuid + gFspInitDonePpiGuid + gEfiEndOfPeiSignalPpiGuid + +[FixedPcd] + gFspWrapperTokenSpaceGuid.PcdSecCoreMaxPpiSupported + +[Pcd] + gFspWrapperTokenSpaceGuid.PcdPeiTemporaryRamStackSize + gFspWrapperTokenSpaceGuid.PcdFlashFvFspBase + gFspWrapperTokenSpaceGuid.PcdFlashFvFspSize + gFspWrapperTokenSpaceGuid.PcdMaxUpdRegionSize + +[Depex] + gEfiPeiMasterBootModePpiGuid diff --git a/IntelFspWrapperPkg/FspInitPei/FspNotifyS3.c b/IntelFspWrapperPkg/FspInitPei/FspNotifyS3.c new file mode 100644 index 0000000000..6fd2b77588 --- /dev/null +++ b/IntelFspWrapperPkg/FspInitPei/FspNotifyS3.c @@ -0,0 +1,86 @@ +/** @file + In EndOfPei notify, it will call FspNotifyPhase API. + + Copyright (c) 2014, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + + +#include "FspInitPei.h" + +/** + 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; + FSP_STATUS FspStatus; + FSP_INFO_HEADER *FspHeader; + + FspHeader = FspFindFspHeader (PcdGet32 (PcdFlashFvFspBase)); + if (FspHeader == NULL) { + return EFI_DEVICE_ERROR; + } + + NotifyPhaseParams.Phase = EnumInitPhaseAfterPciEnumeration; + FspStatus = CallFspNotifyPhase (FspHeader, &NotifyPhaseParams); + if (FspStatus != FSP_SUCCESS) { + DEBUG((DEBUG_ERROR, "FSP S3NotifyPhase AfterPciEnumeration failed, status: 0x%x\n", FspStatus)); + } else { + DEBUG((DEBUG_INFO, "FSP S3NotifyPhase AfterPciEnumeration Success.\n")); + } + + NotifyPhaseParams.Phase = EnumInitPhaseReadyToBoot; + FspStatus = CallFspNotifyPhase (FspHeader, &NotifyPhaseParams); + if (FspStatus != FSP_SUCCESS) { + DEBUG((DEBUG_ERROR, "FSP S3NotifyPhase ReadyToBoot failed, status: 0x%x\n", FspStatus)); + } else { + DEBUG((DEBUG_INFO, "FSP S3NotifyPhase ReadyToBoot Success.\n")); + } + + return EFI_SUCCESS; +} diff --git a/IntelFspWrapperPkg/FspInitPei/SecFspInitDone.c b/IntelFspWrapperPkg/FspInitPei/SecFspInitDone.c new file mode 100644 index 0000000000..e109694062 --- /dev/null +++ b/IntelFspWrapperPkg/FspInitPei/SecFspInitDone.c @@ -0,0 +1,57 @@ +/** @file + Install FspInitDone PPI and GetFspHobList API. + + Copyright (c) 2014, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + + +#include "SecMain.h" + +FSP_INIT_DONE_PPI gFspInitDonePpi = { + FspInitDoneGetFspHobList +}; + +/** + 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 +FspInitDoneGetFspHobList ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN FSP_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/IntelFspWrapperPkg/FspInitPei/SecMain.c b/IntelFspWrapperPkg/FspInitPei/SecMain.c new file mode 100644 index 0000000000..10550e74de --- /dev/null +++ b/IntelFspWrapperPkg/FspInitPei/SecMain.c @@ -0,0 +1,269 @@ +/** @file + C functions in SEC + + Copyright (c) 2014, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + + +#include "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, + &gFspInitDonePpiGuid, + &gFspInitDonePpi + }, +}; + +// +// 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, "BootFirmwareVolumeBase - 0x%x\n", SecCoreData.BootFirmwareVolumeBase)); + DEBUG ((DEBUG_INFO, "BootFirmwareVolumeSize - 0x%x\n", SecCoreData.BootFirmwareVolumeSize)); + DEBUG ((DEBUG_INFO, "TemporaryRamBase - 0x%x\n", SecCoreData.TemporaryRamBase)); + DEBUG ((DEBUG_INFO, "TemporaryRamSize - 0x%x\n", SecCoreData.TemporaryRamSize)); + DEBUG ((DEBUG_INFO, "PeiTemporaryRamBase - 0x%x\n", SecCoreData.PeiTemporaryRamBase)); + DEBUG ((DEBUG_INFO, "PeiTemporaryRamSize - 0x%x\n", SecCoreData.PeiTemporaryRamSize)); + DEBUG ((DEBUG_INFO, "StackBase - 0x%x\n", SecCoreData.StackBase)); + DEBUG ((DEBUG_INFO, "StackSize - 0x%x\n", SecCoreData.StackSize)); + + // + // 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 ; +} diff --git a/IntelFspWrapperPkg/FspInitPei/SecMain.h b/IntelFspWrapperPkg/FspInitPei/SecMain.h new file mode 100644 index 0000000000..fc203973da --- /dev/null +++ b/IntelFspWrapperPkg/FspInitPei/SecMain.h @@ -0,0 +1,116 @@ +/** @file + Master header file for SecCore. + + Copyright (c) 2014, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef _SEC_CORE_H_ +#define _SEC_CORE_H_ + + +#include + +#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 +FspInitDoneGetFspHobList ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN FSP_INIT_DONE_PPI *This, + OUT VOID **FspHobList + ); + +extern FSP_INIT_DONE_PPI gFspInitDonePpi; + +#endif diff --git a/IntelFspWrapperPkg/FspNotifyDxe/FspNotifyDxe.c b/IntelFspWrapperPkg/FspNotifyDxe/FspNotifyDxe.c new file mode 100644 index 0000000000..7beedc458a --- /dev/null +++ b/IntelFspWrapperPkg/FspNotifyDxe/FspNotifyDxe.c @@ -0,0 +1,149 @@ +/** @file + This driver will register two callbacks to call fsp's notifies. + + Copyright (c) 2014, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include + +#include + +#include +#include +#include +#include +#include +#include + +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 + ) +{ + NOTIFY_PHASE_PARAMS NotifyPhaseParams; + EFI_STATUS Status; + FSP_STATUS FspStatus; + VOID *Interface; + + // + // Try to locate it because gEfiPciEnumerationCompleteProtocolGuid will trigger it once when registration. + // Just return if it is not found. + // + Status = gBS->LocateProtocol ( + &gEfiPciEnumerationCompleteProtocolGuid, + NULL, + &Interface + ); + if (EFI_ERROR (Status)) { + return ; + } + + NotifyPhaseParams.Phase = EnumInitPhaseAfterPciEnumeration; + FspStatus = CallFspNotifyPhase (mFspHeader, &NotifyPhaseParams); + if (FspStatus != FSP_SUCCESS) { + DEBUG((DEBUG_ERROR, "FSP NotifyPhase AfterPciEnumeration failed, status: 0x%x\n", FspStatus)); + } else { + DEBUG((DEBUG_INFO, "FSP NotifyPhase AfterPciEnumeration Success.\n")); + } +} + +/** + Notification function of EVT_GROUP_READY_TO_BOOT event group. + + This is a notification function registered on EVT_GROUP_READY_TO_BOOT event group. + When the Boot Manager is about to load and execute a boot option, it reclaims variable + storage if free size is below the threshold. + + @param[in] Event Event whose notification function is being invoked. + @param[in] Context Pointer to the notification function's context. + +**/ +VOID +EFIAPI +OnReadyToBoot ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + NOTIFY_PHASE_PARAMS NotifyPhaseParams; + FSP_STATUS FspStatus; + + gBS->CloseEvent (Event); + + NotifyPhaseParams.Phase = EnumInitPhaseReadyToBoot; + FspStatus = CallFspNotifyPhase (mFspHeader, &NotifyPhaseParams); + if (FspStatus != FSP_SUCCESS) { + DEBUG((DEBUG_ERROR, "FSP NotifyPhase ReadyToBoot failed, status: 0x%x\n", FspStatus)); + } else { + DEBUG((DEBUG_INFO, "FSP NotifyPhase ReadyToBoot 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; + + mFspHeader = FspFindFspHeader (PcdGet32 (PcdFlashFvFspBase)); + DEBUG ((DEBUG_INFO, "FspHeader - 0x%x\n", mFspHeader)); + if (mFspHeader == NULL) { + return EFI_DEVICE_ERROR; + } + + ProtocolNotifyEvent = EfiCreateProtocolNotifyEvent ( + &gEfiPciEnumerationCompleteProtocolGuid, + TPL_CALLBACK, + OnPciEnumerationComplete, + NULL, + &Registration + ); + ASSERT (ProtocolNotifyEvent != NULL); + + Status = EfiCreateEventReadyToBootEx ( + TPL_CALLBACK, + OnReadyToBoot, + NULL, + &ReadyToBootEvent + ); + ASSERT_EFI_ERROR (Status); + + return EFI_SUCCESS; +} + diff --git a/IntelFspWrapperPkg/FspNotifyDxe/FspNotifyDxe.inf b/IntelFspWrapperPkg/FspNotifyDxe/FspNotifyDxe.inf new file mode 100644 index 0000000000..5138bb98a0 --- /dev/null +++ b/IntelFspWrapperPkg/FspNotifyDxe/FspNotifyDxe.inf @@ -0,0 +1,55 @@ +## @file +# FSP DXE Module +# +# This driver will register two callbacks to call fsp's notifies. +# +# Copyright (c) 2014, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = FspNotifyDxe + FILE_GUID = 8714C537-6D4B-4247-AA6C-29E8495F9100 + 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 + +[Packages] + MdePkg/MdePkg.dec + IntelFspPkg/IntelFspPkg.dec + IntelFspWrapperPkg/IntelFspWrapperPkg.dec + +[LibraryClasses] + UefiDriverEntryPoint + UefiBootServicesTableLib + DebugLib + BaseMemoryLib + UefiLib + FspApiLib + +[Protocols] + gEfiPciEnumerationCompleteProtocolGuid + +[Pcd] + gFspWrapperTokenSpaceGuid.PcdFlashFvFspBase + gFspWrapperTokenSpaceGuid.PcdFlashFvFspSize + +[Depex] + TRUE diff --git a/IntelFspWrapperPkg/FspWrapperSecCore/FindPeiCore.c b/IntelFspWrapperPkg/FspWrapperSecCore/FindPeiCore.c new file mode 100644 index 0000000000..ce003d056f --- /dev/null +++ b/IntelFspWrapperPkg/FspWrapperSecCore/FindPeiCore.c @@ -0,0 +1,199 @@ +/** @file + Locate the entry point for the PEI Core + + Copyright (c) 2014, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include +#include + +#include "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/IntelFspWrapperPkg/FspWrapperSecCore/FspWrapperSecCore.inf b/IntelFspWrapperPkg/FspWrapperSecCore/FspWrapperSecCore.inf new file mode 100644 index 0000000000..fc221fc856 --- /dev/null +++ b/IntelFspWrapperPkg/FspWrapperSecCore/FspWrapperSecCore.inf @@ -0,0 +1,66 @@ +## @file +# This is the first module taking control of the platform upon power-on/reset. +# +# Copyright (c) 2014, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = FspWrapperSecCore + FILE_GUID = 1BA0062E-C779-4582-8566-336AE8F78F09 + MODULE_TYPE = SEC + VERSION_STRING = 1.0 + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 +# + +[Sources] + SecMain.c + SecMain.h + FindPeiCore.c + +[Sources.IA32] + Ia32/ResetVec.asm16 | MSFT + Ia32/ResetVec.asm16 | INTEL + Ia32/Dummy.asm + +[Binaries.Ia32] + RAW|Vtf0/Bin/ResetVec.ia32.raw |GCC + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + UefiCpuPkg/UefiCpuPkg.dec + IntelFspPkg/IntelFspPkg.dec + IntelFspWrapperPkg/IntelFspWrapperPkg.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + DebugLib + FspPlatformInfoLib + FspPlatformSecLib + DebugAgentLib + UefiCpuLib + PeCoffGetEntryPointLib + PeCoffExtraActionLib + +[Ppis] + gTopOfTemporaryRamPpiGuid + +[FixedPcd] + gFspWrapperTokenSpaceGuid.PcdSecCoreMaxPpiSupported + +[Pcd] + gFspWrapperTokenSpaceGuid.PcdPeiTemporaryRamStackSize diff --git a/IntelFspWrapperPkg/FspWrapperSecCore/Ia32/Dummy.asm b/IntelFspWrapperPkg/FspWrapperSecCore/Ia32/Dummy.asm new file mode 100644 index 0000000000..16438e26e3 --- /dev/null +++ b/IntelFspWrapperPkg/FspWrapperSecCore/Ia32/Dummy.asm @@ -0,0 +1,26 @@ +;------------------------------------------------------------------------------ +; +; Copyright (c) 2014, Intel Corporation. All rights reserved.
+; This program and the accompanying materials +; are licensed and made available under the terms and conditions of the BSD License +; which accompanies this distribution. The full text of the license may be found at +; http://opensource.org/licenses/bsd-license.php. +; +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +; +; Module Name: +; +; Dummy.asm +; +; Abstract: +; +; To pass build +; +;------------------------------------------------------------------------------ + + .586p + .model flat,C + .code + + END diff --git a/IntelFspWrapperPkg/FspWrapperSecCore/Ia32/ResetVec.asm16 b/IntelFspWrapperPkg/FspWrapperSecCore/Ia32/ResetVec.asm16 new file mode 100644 index 0000000000..93de20e530 --- /dev/null +++ b/IntelFspWrapperPkg/FspWrapperSecCore/Ia32/ResetVec.asm16 @@ -0,0 +1,106 @@ +;------------------------------------------------------------------------------ +; +; Copyright (c) 2014, Intel Corporation. All rights reserved.
+; This program and the accompanying materials +; are licensed and made available under the terms and conditions of the BSD License +; which accompanies this distribution. The full text of the license may be found at +; http://opensource.org/licenses/bsd-license.php. +; +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +; +; Module Name: +; +; ResetVec.asm +; +; Abstract: +; +; Reset Vector Data structure +; This structure is located at 0xFFFFFFC0 +; +;------------------------------------------------------------------------------ + + .model tiny + .686p + .stack 0h + .code + +; +; The layout of this file is fixed. The build tool makes assumption of the layout. +; + + ORG 0h +; +; Reserved +; +ReservedData DD 0eeeeeeeeh, 0eeeeeeeeh + + ORG 10h +; +; This is located at 0xFFFFFFD0h +; + mov di, "AP" + jmp ApStartup + + ORG 20h +; +; Pointer to the entry point of the PEI core +; It is located at 0xFFFFFFE0, and is fixed up by some build tool +; So if the value 8..1 appears in the final FD image, tool failure occurs. +; +PeiCoreEntryPoint DD 87654321h + +; +; This is the handler for all kinds of exceptions. Since it's for debugging +; purpose only, nothing except a deadloop would be done here. Developers could +; analyze the cause of the exception if a debugger had been attached. +; +InterruptHandler PROC + jmp $ + iret +InterruptHandler ENDP + + ORG 30h +; +; For IA32, the reset vector must be at 0xFFFFFFF0, i.e., 4G-16 byte +; Execution starts here upon power-on/platform-reset. +; +ResetHandler: + nop + nop +ApStartup: + ; + ; Jmp Rel16 instruction + ; Use machine code directly in case of the assembler optimization + ; SEC entry point relatvie address will be fixed up by some build tool. + ; + ; Typically, SEC entry point is the function _ModuleEntryPoint() defined in + ; SecEntry.asm + ; + DB 0e9h + DW -3 + + + ORG 38h +; +; Ap reset vector segment address is at 0xFFFFFFF8 +; This will be fixed up by some build tool, +; so if the value 1..8 appears in the final FD image, +; tool failure occurs +; +ApSegAddress dd 12345678h + + ORG 3ch +; +; BFV Base is at 0xFFFFFFFC +; This will be fixed up by some build tool, +; so if the value 1..8 appears in the final FD image, +; tool failure occurs. +; +BfvBase DD 12345678h + +; +; Nothing can go here, otherwise the layout of this file would change. +; + + END diff --git a/IntelFspWrapperPkg/FspWrapperSecCore/SecMain.c b/IntelFspWrapperPkg/FspWrapperSecCore/SecMain.c new file mode 100644 index 0000000000..f441725c6c --- /dev/null +++ b/IntelFspWrapperPkg/FspWrapperSecCore/SecMain.c @@ -0,0 +1,264 @@ +/** @file + C functions in SEC + + Copyright (c) 2014, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + + +#include "SecMain.h" + +EFI_PEI_PPI_DESCRIPTOR mPeiSecMainPpi[] = { + { + EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST, + &gTopOfTemporaryRamPpiGuid, + NULL // To be patched later. + }, +}; + +// +// 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, "SecCore - 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, "BootFirmwareVolumeBase - 0x%x\n", SecCoreData.BootFirmwareVolumeBase)); + DEBUG ((DEBUG_INFO, "BootFirmwareVolumeSize - 0x%x\n", SecCoreData.BootFirmwareVolumeSize)); + DEBUG ((DEBUG_INFO, "TemporaryRamBase - 0x%x\n", SecCoreData.TemporaryRamBase)); + DEBUG ((DEBUG_INFO, "TemporaryRamSize - 0x%x\n", SecCoreData.TemporaryRamSize)); + DEBUG ((DEBUG_INFO, "PeiTemporaryRamBase - 0x%x\n", SecCoreData.PeiTemporaryRamBase)); + DEBUG ((DEBUG_INFO, "PeiTemporaryRamSize - 0x%x\n", SecCoreData.PeiTemporaryRamSize)); + DEBUG ((DEBUG_INFO, "StackBase - 0x%x\n", SecCoreData.StackBase)); + DEBUG ((DEBUG_INFO, "StackSize - 0x%x\n", SecCoreData.StackSize)); + + // + // 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 CAR. + +**/ +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 ; +} diff --git a/IntelFspWrapperPkg/FspWrapperSecCore/SecMain.h b/IntelFspWrapperPkg/FspWrapperSecCore/SecMain.h new file mode 100644 index 0000000000..afaadfe895 --- /dev/null +++ b/IntelFspWrapperPkg/FspWrapperSecCore/SecMain.h @@ -0,0 +1,96 @@ +/** @file + Master header file for SecCore. + + Copyright (c) 2014, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef _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 + ); + +#endif diff --git a/IntelFspWrapperPkg/FspWrapperSecCore/Vtf0/Bin/ResetVec.ia32.raw b/IntelFspWrapperPkg/FspWrapperSecCore/Vtf0/Bin/ResetVec.ia32.raw new file mode 100644 index 0000000000..2dc9f178d3 Binary files /dev/null and b/IntelFspWrapperPkg/FspWrapperSecCore/Vtf0/Bin/ResetVec.ia32.raw differ diff --git a/IntelFspWrapperPkg/FspWrapperSecCore/Vtf0/Build.py b/IntelFspWrapperPkg/FspWrapperSecCore/Vtf0/Build.py new file mode 100644 index 0000000000..3018391445 --- /dev/null +++ b/IntelFspWrapperPkg/FspWrapperSecCore/Vtf0/Build.py @@ -0,0 +1,53 @@ +## @file +# Automate the process of building the various reset vector types +# +# Copyright (c) 2014, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# + +import glob +import os +import subprocess +import sys + +def RunCommand(commandLine): + #print ' '.join(commandLine) + return subprocess.call(commandLine) + +for filename in glob.glob(os.path.join('Bin', '*.raw')): + os.remove(filename) + +arch = 'ia32' +debugType = None +output = os.path.join('Bin', 'ResetVec') +output += '.' + arch +if debugType is not None: + output += '.' + debugType +output += '.raw' +commandLine = ( + 'nasm', + '-D', 'ARCH_%s' % arch.upper(), + '-D', 'DEBUG_%s' % str(debugType).upper(), + '-o', output, + 'ResetVectorCode.asm', + ) +ret = RunCommand(commandLine) +print '\tASM\t' + output +if ret != 0: sys.exit(ret) + +commandLine = ( + 'python', + 'Tools/FixupForRawSection.py', + output, + ) +print '\tFIXUP\t' + output +ret = RunCommand(commandLine) +if ret != 0: sys.exit(ret) + diff --git a/IntelFspWrapperPkg/FspWrapperSecCore/Vtf0/Ia16/ResetVec.asm16 b/IntelFspWrapperPkg/FspWrapperSecCore/Vtf0/Ia16/ResetVec.asm16 new file mode 100644 index 0000000000..585876fa86 --- /dev/null +++ b/IntelFspWrapperPkg/FspWrapperSecCore/Vtf0/Ia16/ResetVec.asm16 @@ -0,0 +1,103 @@ +;; @file +; Reset Vector Data structure +; This structure is located at 0xFFFFFFC0 +; +; Copyright (c) 2014, Intel Corporation. All rights reserved.
+; This program and the accompanying materials +; are licensed and made available under the terms and conditions of the BSD License +; which accompanies this distribution. The full text of the license may be found at +; http://opensource.org/licenses/bsd-license.php. +; +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +; +;; + +BITS 16 + + +; +; The layout of this file is fixed. The build tool makes assumption of the layout. +; + +ORG 0x0 +; +; Reserved +; +ReservedData: DD 0eeeeeeeeh, 0eeeeeeeeh + + ; ORG 0x10 + TIMES 0x10-($-$$) DB 0 +; +; This is located at 0xFFFFFFD0h +; + mov di, "AP" + jmp ApStartup + + ; ORG 0x20 + + TIMES 0x20-($-$$) DB 0 + +; Pointer to the entry point of the PEI core +; It is located at 0xFFFFFFE0, and is fixed up by some build tool +; So if the value 8..1 appears in the final FD image, tool failure occurs. +; +PeiCoreEntryPoint: DD 0x12345678 + +; +; This is the handler for all kinds of exceptions. Since it's for debugging +; purpose only, nothing except a deadloop would be done here. Developers could +; analyze the cause of the exception if a debugger had been attached. +; +InterruptHandler: + jmp $ + iret + + ; ORG 0x30 + TIMES 0x30-($-$$) DB 0 +; +; For IA32, the reset vector must be at 0xFFFFFFF0, i.e., 4G-16 byte +; Execution starts here upon power-on/platform-reset. +; +ResetHandler: + nop + nop + +ApStartup: + ; + ; Jmp Rel16 instruction + ; Use machine code directly in case of the assembler optimization + ; SEC entry point relatvie address will be fixed up by some build tool. + ; + ; Typically, SEC entry point is the function _ModuleEntryPoint() defined in + ; SecEntry.asm + ; + DB 0x0e9 + DW -3 + + ; ORG 0x38 + + TIMES 0x38-($-$$) DB 0 +; +; Ap reset vector segment address is at 0xFFFFFFF8 +; This will be fixed up by some build tool, +; so if the value 1..8 appears in the final FD image, +; tool failure occurs +; +ApSegAddress: dd 0x12345678 + + ; ORG 0x3c + TIMES 0x3c-($-$$) DB 0 +; +; BFV Base is at 0xFFFFFFFC +; This will be fixed up by some build tool, +; so if the value 1..8 appears in the final FD image, +; tool failure occurs. +; +BfvBase: DD 0x12345678 + +; +; Nothing can go here, otherwise the layout of this file would change. +; + + ; END diff --git a/IntelFspWrapperPkg/FspWrapperSecCore/Vtf0/ResetVectorCode.asm b/IntelFspWrapperPkg/FspWrapperSecCore/Vtf0/ResetVectorCode.asm new file mode 100644 index 0000000000..72b252491f --- /dev/null +++ b/IntelFspWrapperPkg/FspWrapperSecCore/Vtf0/ResetVectorCode.asm @@ -0,0 +1,17 @@ +;------------------------------------------------------------------------------ +; @file +; This file includes all other code files to assemble the reset vector code +; +; Copyright (c) 2014, Intel Corporation. All rights reserved.
+; This program and the accompanying materials +; are licensed and made available under the terms and conditions of the BSD License +; which accompanies this distribution. The full text of the license may be found at +; http://opensource.org/licenses/bsd-license.php +; +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +; +;------------------------------------------------------------------------------ + + +%include "Ia16/ResetVec.asm16" diff --git a/IntelFspWrapperPkg/FspWrapperSecCore/Vtf0/Tools/FixupForRawSection.py b/IntelFspWrapperPkg/FspWrapperSecCore/Vtf0/Tools/FixupForRawSection.py new file mode 100644 index 0000000000..8e7c20b401 --- /dev/null +++ b/IntelFspWrapperPkg/FspWrapperSecCore/Vtf0/Tools/FixupForRawSection.py @@ -0,0 +1,110 @@ +## @file +# Apply fixup to VTF binary image for FFS Raw section +# +# Copyright (c) 2014, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# + +import sys + +filename = sys.argv[1] + +if filename.lower().find('ia32') >= 0: + d = open(sys.argv[1], 'rb').read() + c = ((len(d) + 4 + 7) & ~7) - 4 + if c > len(d): + c -= len(d) + f = open(sys.argv[1], 'wb') + f.write('\x90' * c) + f.write(d) + f.close() +else: + from struct import pack + + PAGE_PRESENT = 0x01 + PAGE_READ_WRITE = 0x02 + PAGE_USER_SUPERVISOR = 0x04 + PAGE_WRITE_THROUGH = 0x08 + PAGE_CACHE_DISABLE = 0x010 + PAGE_ACCESSED = 0x020 + PAGE_DIRTY = 0x040 + PAGE_PAT = 0x080 + PAGE_GLOBAL = 0x0100 + PAGE_2M_MBO = 0x080 + PAGE_2M_PAT = 0x01000 + + def NopAlign4k(s): + c = ((len(s) + 0xfff) & ~0xfff) - len(s) + return ('\x90' * c) + s + + def PageDirectoryEntries4GbOf2MbPages(baseAddress): + + s = '' + for i in range(0x800): + i = ( + baseAddress + long(i << 21) + + PAGE_2M_MBO + + PAGE_CACHE_DISABLE + + PAGE_ACCESSED + + PAGE_DIRTY + + PAGE_READ_WRITE + + PAGE_PRESENT + ) + s += pack('Q', i) + return s + + def PageDirectoryPointerTable4GbOf2MbPages(pdeBase): + s = '' + for i in range(0x200): + i = ( + pdeBase + + (min(i, 3) << 12) + + PAGE_CACHE_DISABLE + + PAGE_ACCESSED + + PAGE_READ_WRITE + + PAGE_PRESENT + ) + s += pack('Q', i) + return s + + def PageMapLevel4Table4GbOf2MbPages(pdptBase): + s = '' + for i in range(0x200): + i = ( + pdptBase + + (min(i, 0) << 12) + + PAGE_CACHE_DISABLE + + PAGE_ACCESSED + + PAGE_READ_WRITE + + PAGE_PRESENT + ) + s += pack('Q', i) + return s + + def First4GbPageEntries(topAddress): + PDE = PageDirectoryEntries4GbOf2MbPages(0L) + pml4tBase = topAddress - 0x1000 + pdptBase = pml4tBase - 0x1000 + pdeBase = pdptBase - len(PDE) + PDPT = PageDirectoryPointerTable4GbOf2MbPages(pdeBase) + PML4T = PageMapLevel4Table4GbOf2MbPages(pdptBase) + return PDE + PDPT + PML4T + + def AlignAndAddPageTables(): + d = open(sys.argv[1], 'rb').read() + code = NopAlign4k(d) + topAddress = 0x100000000 - len(code) + d = ('\x90' * 4) + First4GbPageEntries(topAddress) + code + f = open(sys.argv[1], 'wb') + f.write(d) + f.close() + + AlignAndAddPageTables() + diff --git a/IntelFspWrapperPkg/Include/Library/FspApiLib.h b/IntelFspWrapperPkg/Include/Library/FspApiLib.h new file mode 100644 index 0000000000..fc0104d28c --- /dev/null +++ b/IntelFspWrapperPkg/Include/Library/FspApiLib.h @@ -0,0 +1,64 @@ +/** @file + Provide FSP API related function. + + Copyright (c) 2014, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef __FSP_API_LIB_H__ +#define __FSP_API_LIB_H__ + +#include +#include + +/** + Find FSP header pointer. + + @param[in] FlashFvFspBase Flash address of FSP FV. + + @return FSP header pointer. +**/ +FSP_INFO_HEADER * +EFIAPI +FspFindFspHeader ( + IN EFI_PHYSICAL_ADDRESS FlashFvFspBase + ); + +/** + Call FSP API - FspInit. + + @param[in] FspHeader FSP header pointer. + @param[in] FspInitParams Address pointer to the FSP_INIT_PARAMS structure. + + @return FSP status returned by FspInit API. +**/ +FSP_STATUS +EFIAPI +CallFspInit ( + IN FSP_INFO_HEADER *FspHeader, + IN FSP_INIT_PARAMS *FspInitParams + ); + +/** + Call FSP API - FspNotifyPhase. + + @param[in] FspHeader FSP header pointer. + @param[in] NotifyPhaseParams Address pointer to the NOTIFY_PHASE_PARAMS structure. + + @return FSP status returned by FspNotifyPhase API. +**/ +FSP_STATUS +EFIAPI +CallFspNotifyPhase ( + IN FSP_INFO_HEADER *FspHeader, + IN NOTIFY_PHASE_PARAMS *NotifyPhaseParams + ); + +#endif diff --git a/IntelFspWrapperPkg/Include/Library/FspHobProcessLib.h b/IntelFspWrapperPkg/Include/Library/FspHobProcessLib.h new file mode 100644 index 0000000000..32ce987b92 --- /dev/null +++ b/IntelFspWrapperPkg/Include/Library/FspHobProcessLib.h @@ -0,0 +1,31 @@ +/** @file + Provide FSP hob process related function. + + Copyright (c) 2014, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#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 + ); + +#endif diff --git a/IntelFspWrapperPkg/Include/Library/FspPlatformInfoLib.h b/IntelFspWrapperPkg/Include/Library/FspPlatformInfoLib.h new file mode 100644 index 0000000000..ebbe9a7eaf --- /dev/null +++ b/IntelFspWrapperPkg/Include/Library/FspPlatformInfoLib.h @@ -0,0 +1,116 @@ +/** @file + Provide FSP platform information related function. + + Copyright (c) 2014, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#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 + ); + +/** + Get UPD region size. + + @note At this point, memory is NOT ready, PeiServices are available to use. + + @return UPD region size. +**/ +UINT32 +EFIAPI +GetUpdRegionSize ( + VOID + ); + +/** + This function overrides the default configurations in the UPD data region. + + @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 OUT VOID *FspUpdRgnPtr + ); + +/** + 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 + ); + +#endif diff --git a/IntelFspWrapperPkg/Include/Library/FspPlatformSecLib.h b/IntelFspWrapperPkg/Include/Library/FspPlatformSecLib.h new file mode 100644 index 0000000000..58447a6e8f --- /dev/null +++ b/IntelFspWrapperPkg/Include/Library/FspPlatformSecLib.h @@ -0,0 +1,67 @@ +/** @file + Provide FSP wrapper platform sec related function. + + Copyright (c) 2014, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#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/IntelFspWrapperPkg/Include/Ppi/FspInitDone.h b/IntelFspWrapperPkg/Include/Ppi/FspInitDone.h new file mode 100644 index 0000000000..6acbf2d18a --- /dev/null +++ b/IntelFspWrapperPkg/Include/Ppi/FspInitDone.h @@ -0,0 +1,43 @@ +/** @file + Provides the services to return FSP hob list. + + Copyright (c) 2014, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef _FSP_INIT_DONE_H_ +#define _FSP_INIT_DONE_H_ + +typedef struct _FSP_INIT_DONE_PPI FSP_INIT_DONE_PPI; + +/** + Return Hob list produced by FSP. + + @param[in] PeiServices The pointer to the PEI Services Table. + @param[in] This The pointer to this instance of this PPI. + @param[out] FspHobList The pointer to Hob list produced by FSP. + + @return EFI_SUCCESS FReturn Hob list produced by FSP successfully. +**/ +typedef +EFI_STATUS +(EFIAPI *FSP_INIT_DONE_GET_FSP_HOB_LIST)( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN FSP_INIT_DONE_PPI *This, + OUT VOID **FspHobList + ); + +struct _FSP_INIT_DONE_PPI { + FSP_INIT_DONE_GET_FSP_HOB_LIST GetFspHobList; +}; + +extern EFI_GUID gFspInitDonePpiGuid; + +#endif diff --git a/IntelFspWrapperPkg/Include/Ppi/TopOfTemporaryRam.h b/IntelFspWrapperPkg/Include/Ppi/TopOfTemporaryRam.h new file mode 100644 index 0000000000..c25c4fa802 --- /dev/null +++ b/IntelFspWrapperPkg/Include/Ppi/TopOfTemporaryRam.h @@ -0,0 +1,20 @@ +/** @file + Provides the pointer to top of temporary ram. + + Copyright (c) 2014, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef _TOP_OF_TEMPORARY_RAM_H_ +#define _TOP_OF_TEMPORARY_RAM_H_ + +extern EFI_GUID gTopOfTemporaryRamPpiGuid; + +#endif diff --git a/IntelFspWrapperPkg/IntelFspWrapperPkg.dec b/IntelFspWrapperPkg/IntelFspWrapperPkg.dec new file mode 100644 index 0000000000..0fea5f2269 --- /dev/null +++ b/IntelFspWrapperPkg/IntelFspWrapperPkg.dec @@ -0,0 +1,88 @@ +## @file +# +# Provides drivers and definitions to support fsp in EDKII bios. +# +# Copyright (c) 2014, Intel Corporation. All rights reserved.
+# This program and the accompanying materials are licensed and made available under +# the terms and conditions of the BSD License that accompanies this distribution. +# The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +[Defines] + DEC_SPECIFICATION = 0x00010005 + PACKAGE_NAME = IntelFspWrapperPkg + PACKAGE_GUID = 99101BB6-6DE1-4537-85A3-FD6B594F7468 + PACKAGE_VERSION = 0.1 + +[Includes] + Include + +[LibraryClasses] + +[Guids] + # + # GUID defined in package + # + gFspWrapperTokenSpaceGuid = {0x2bc1c74a, 0x122f, 0x40b2, { 0xb2, 0x23, 0x8, 0x2b, 0x74, 0x65, 0x22, 0x5d } } + + # Guid define in FSP EAS + gFspHeaderFileGuid = { 0x912740BE, 0x2284, 0x4734, { 0xB9, 0x71, 0x84, 0xB0, 0x27, 0x35, 0x3F, 0x0C } } + gFspBootLoaderTemporaryMemoryGuid = { 0xbbcff46c, 0xc8d3, 0x4113, { 0x89, 0x85, 0xb9, 0xd4, 0xf3, 0xb3, 0xf6, 0x4e } } + gFspReservedMemoryResourceHobGuid = { 0x69a79759, 0x1373, 0x4367, { 0xa6, 0xc4, 0xc7, 0xf5, 0x9e, 0xfd, 0x98, 0x6e } } + gFspNonVolatileStorageHobGuid = { 0x721acf02, 0x4d77, 0x4c2a, { 0xb3, 0xdc, 0x27, 0x0b, 0x7b, 0xa9, 0xe4, 0xb0 } } + +[Ppis] + gFspInitDonePpiGuid = { 0xf5ef05e4, 0xd538, 0x4774, 0x8f, 0x1b, 0xe9, 0x77, 0x30, 0x11, 0xe0, 0x38 } + 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. + gFspWrapperTokenSpaceGuid.PcdFlashCodeCacheAddress|0xFFE00000|UINT32|0x10000001 + ## Provides the size of the BIOS Flash Device. + gFspWrapperTokenSpaceGuid.PcdFlashCodeCacheSize|0x00200000|UINT32|0x10000002 + + ## Indicates the base address of the FSP binary. + gFspWrapperTokenSpaceGuid.PcdFlashFvFspBase|0xFFF80000|UINT32|0x10000003 + ## Provides the size of the FSP binary. + gFspWrapperTokenSpaceGuid.PcdFlashFvFspSize|0x00048000|UINT32|0x10000004 + + ## Indicates the base address of the first Microcode Patch in the Microcode Region + gFspWrapperTokenSpaceGuid.PcdCpuMicrocodePatchAddress|0x0|UINT64|0x10000005 + gFspWrapperTokenSpaceGuid.PcdCpuMicrocodePatchRegionSize|0x0|UINT64|0x10000006 + ## Indicates the offset of the Cpu Microcode. + gFspWrapperTokenSpaceGuid.PcdFlashMicroCodeOffset|0x90|UINT32|0x10000007 + + ## + # Maximum number of Ppi is provided by SecCore. + ## + gFspWrapperTokenSpaceGuid.PcdSecCoreMaxPpiSupported|0x6|UINT32|0x20000001 + + # This is MAX UPD region size + gFspWrapperTokenSpaceGuid.PcdMaxUpdRegionSize|0x200|UINT32|0x30000001 + + ## Stack size in the temporary RAM. + # 0 means half of TemporaryRamSize. + gFspWrapperTokenSpaceGuid.PcdPeiTemporaryRamStackSize|0|UINT32|0x40000001 + + # This is temporary DRAM base and size for StackTop in FspInit + gFspWrapperTokenSpaceGuid.PcdTemporaryRamBase|0x00080000|UINT32|0x40000002 + gFspWrapperTokenSpaceGuid.PcdTemporaryRamSize|0x00010000|UINT32|0x40000003 + + ## Indicate the PEI memory size platform want to report + gFspWrapperTokenSpaceGuid.PcdPeiMinMemSize|0x1800000|UINT32|0x40000004 + ## Indicate the PEI memory size platform want to report + gFspWrapperTokenSpaceGuid.PcdPeiRecoveryMinMemSize|0x3000000|UINT32|0x40000005 diff --git a/IntelFspWrapperPkg/IntelFspWrapperPkg.dsc b/IntelFspWrapperPkg/IntelFspWrapperPkg.dsc new file mode 100644 index 0000000000..c93512aacb --- /dev/null +++ b/IntelFspWrapperPkg/IntelFspWrapperPkg.dsc @@ -0,0 +1,84 @@ +## @file +# +# Provides drivers and definitions to support fsp in EDKII bios. +# +# Copyright (c) 2014, Intel Corporation. All rights reserved.
+# This program and the accompanying materials are licensed and made available under +# the terms and conditions of the BSD License that accompanies this distribution. +# The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +[Defines] + PLATFORM_NAME = IntelFspWrapperPkg + PLATFORM_GUID = BC1EC7D4-8550-4a64-B7F5-8E0EF864FFA2 + PLATFORM_VERSION = 0.1 + DSC_SPECIFICATION = 0x00010005 + OUTPUT_DIRECTORY = Build/IntelFspWrapperPkg + SUPPORTED_ARCHITECTURES = IA32|X64 + BUILD_TARGETS = DEBUG|RELEASE + SKUID_IDENTIFIER = DEFAULT + +[LibraryClasses] + BaseLib|MdePkg/Library/BaseLib/BaseLib.inf + BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf + PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf + PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf + DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf + DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf + PciCf8Lib|MdePkg/Library/BasePciCf8Lib/BasePciCf8Lib.inf + IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf + PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf + PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf + PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf + + # Dummy - test build only + SerialPortLib|MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.inf + ReportStatusCodeLib|MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.inf + TimerLib|MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplate.inf + + # MdeModulePkg + DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf + + # UefiCpuPkg + UefiCpuLib|UefiCpuPkg/Library/BaseUefiCpuLib/BaseUefiCpuLib.inf + LocalApicLib|UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.inf + + # FSP lib + FspApiLib|IntelFspWrapperPkg/Library/BaseFspApiLib/BaseFspApiLib.inf + + # FSP platform sample + FspPlatformInfoLib|IntelFspWrapperPkg/Library/BaseFspPlatformInfoLibSample/BaseFspPlatformInfoLibSample.inf + FspPlatformSecLib|IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecPeiFspPlatformSecLibSample.inf + FspHobProcessLib|IntelFspWrapperPkg/Library/PeiFspHobProcessLibSample/PeiFspHobProcessLibSample.inf + +[LibraryClasses.common.PEIM,LibraryClasses.common.PEI_CORE] + PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf + PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf + PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf + MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf + HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf + +[LibraryClasses.common.DXE_DRIVER] + UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf + UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf + UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf + UefiLib|MdePkg/Library/UefiLib/UefiLib.inf + MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf + DevicePathLib|MdePkg/Library/UefiDevicePathLibDevicePathProtocol/UefiDevicePathLibDevicePathProtocol.inf + +[Components.Ia32] + IntelFspWrapperPkg/FspWrapperSecCore/FspWrapperSecCore.inf + IntelFspWrapperPkg/FspInitPei/FspInitPei.inf + +[Components.IA32, Components.X64] + IntelFspWrapperPkg/FspNotifyDxe/FspNotifyDxe.inf + +[PcdsFixedAtBuild.common] + gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x1f + gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80080046 + gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x07 diff --git a/IntelFspWrapperPkg/Library/BaseFspApiLib/BaseFspApiLib.inf b/IntelFspWrapperPkg/Library/BaseFspApiLib/BaseFspApiLib.inf new file mode 100644 index 0000000000..451698d8d0 --- /dev/null +++ b/IntelFspWrapperPkg/Library/BaseFspApiLib/BaseFspApiLib.inf @@ -0,0 +1,66 @@ +## @file +# Provide FSP API related function. +# +# Copyright (c) 2014, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +################################################################################ +# +# Defines Section - statements that will be processed to create a Makefile. +# +################################################################################ +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = BaseFspApiLib + FILE_GUID = 6E4CB8C5-6144-4ae3-BA52-B6AFBCB2B2F5 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = FspApiLib + +# +# 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] + FspApiLib.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 + IntelFspPkg/IntelFspPkg.dec + IntelFspWrapperPkg/IntelFspWrapperPkg.dec + +[LibraryClasses] + +[Guids] + gFspHeaderFileGuid diff --git a/IntelFspWrapperPkg/Library/BaseFspApiLib/FspApiLib.c b/IntelFspWrapperPkg/Library/BaseFspApiLib/FspApiLib.c new file mode 100644 index 0000000000..590238e391 --- /dev/null +++ b/IntelFspWrapperPkg/Library/BaseFspApiLib/FspApiLib.c @@ -0,0 +1,127 @@ +/** @file + Provide FSP API related function. + + Copyright (c) 2014, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include + +#include + +#include +#include + +/** + 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 FSP_STATUS. +**/ +FSP_STATUS +Execute32BitCode ( + IN UINT64 Function, + IN UINT64 Param1 + ); + +/** + Find FSP header pointer. + + @param[in] FlashFvFspBase Flash address of FSP FV. + + @return FSP header pointer. +**/ +FSP_INFO_HEADER * +EFIAPI +FspFindFspHeader ( + IN EFI_PHYSICAL_ADDRESS FlashFvFspBase + ) +{ + UINT8 *CheckPointer; + + CheckPointer = (UINT8 *) (UINTN) FlashFvFspBase; + + if (((EFI_FIRMWARE_VOLUME_HEADER *)CheckPointer)->Signature != EFI_FVH_SIGNATURE) { + return NULL; + } + + if (((EFI_FIRMWARE_VOLUME_HEADER *)CheckPointer)->ExtHeaderOffset != 0) { + CheckPointer = CheckPointer + ((EFI_FIRMWARE_VOLUME_HEADER *)CheckPointer)->ExtHeaderOffset; + CheckPointer = CheckPointer + ((EFI_FIRMWARE_VOLUME_EXT_HEADER *)CheckPointer)->ExtHeaderSize; + CheckPointer = (UINT8 *) ALIGN_POINTER (CheckPointer, 8); + } else { + CheckPointer = CheckPointer + ((EFI_FIRMWARE_VOLUME_HEADER *)CheckPointer)->HeaderLength; + } + + if (!CompareGuid (&((EFI_FFS_FILE_HEADER *)CheckPointer)->Name, &gFspHeaderFileGuid)) { + return NULL; + } + + CheckPointer = CheckPointer + sizeof (EFI_FFS_FILE_HEADER); + + if (((EFI_RAW_SECTION *)CheckPointer)->Type != EFI_SECTION_RAW) { + return NULL; + } + + CheckPointer = CheckPointer + sizeof (EFI_RAW_SECTION); + + return (FSP_INFO_HEADER *)CheckPointer; +} + +/** + Call FSP API - FspInit. + + @param[in] FspHeader FSP header pointer. + @param[in] FspInitParams Address pointer to the FSP_INIT_PARAMS structure. + + @return FSP status returned by FspInit API. +**/ +FSP_STATUS +EFIAPI +CallFspInit ( + IN FSP_INFO_HEADER *FspHeader, + IN FSP_INIT_PARAMS *FspInitParams + ) +{ + FSP_FSP_INIT FspInitApi; + FSP_STATUS FspStatus; + + FspInitApi = (FSP_FSP_INIT)(UINTN)(FspHeader->ImageBase + FspHeader->FspInitEntryOffset); + FspStatus = Execute32BitCode ((UINTN)FspInitApi, (UINTN)FspInitParams); + + return FspStatus; +} + +/** + Call FSP API - FspNotifyPhase. + + @param[in] FspHeader FSP header pointer. + @param[in] NotifyPhaseParams Address pointer to the NOTIFY_PHASE_PARAMS structure. + + @return FSP status returned by FspNotifyPhase API. +**/ +FSP_STATUS +EFIAPI +CallFspNotifyPhase ( + IN FSP_INFO_HEADER *FspHeader, + IN NOTIFY_PHASE_PARAMS *NotifyPhaseParams + ) +{ + FSP_NOTFY_PHASE NotifyPhaseApi; + FSP_STATUS FspStatus; + + NotifyPhaseApi = (FSP_NOTFY_PHASE)(UINTN)(FspHeader->ImageBase + FspHeader->NotifyPhaseEntryOffset); + FspStatus = Execute32BitCode ((UINTN)NotifyPhaseApi, (UINTN)NotifyPhaseParams); + + return FspStatus; +} diff --git a/IntelFspWrapperPkg/Library/BaseFspApiLib/IA32/DispatchExecute.c b/IntelFspWrapperPkg/Library/BaseFspApiLib/IA32/DispatchExecute.c new file mode 100644 index 0000000000..15d0a023b8 --- /dev/null +++ b/IntelFspWrapperPkg/Library/BaseFspApiLib/IA32/DispatchExecute.c @@ -0,0 +1,47 @@ +/** @file + Execute 32-bit code in Protected Mode. + + Copyright (c) 2014, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include + +typedef +FSP_STATUS +(FSPAPI *FSP_FUNCTION) ( + IN VOID *Param1 + ); + +/** + 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 FSP_STATUS. +**/ +FSP_STATUS +Execute32BitCode ( + IN UINT64 Function, + IN UINT64 Param1 + ) +{ + FSP_FUNCTION EntryFunc; + FSP_STATUS Status; + + EntryFunc = (FSP_FUNCTION) (UINTN) (Function); + Status = EntryFunc ((VOID *)(UINTN)Param1); + + return Status; +} + diff --git a/IntelFspWrapperPkg/Library/BaseFspApiLib/X64/DispatchExecute.c b/IntelFspWrapperPkg/Library/BaseFspApiLib/X64/DispatchExecute.c new file mode 100644 index 0000000000..17a9ebc8b5 --- /dev/null +++ b/IntelFspWrapperPkg/Library/BaseFspApiLib/X64/DispatchExecute.c @@ -0,0 +1,94 @@ +/** @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, 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. + + @return FSP_STATUS. +**/ +FSP_STATUS +Execute32BitCode ( + IN UINT64 Function, + IN UINT64 Param1 + ) +{ + return AsmExecute32BitCode (Function, Param1, 0, &mGdt); +} + diff --git a/IntelFspWrapperPkg/Library/BaseFspApiLib/X64/Thunk64To32.S b/IntelFspWrapperPkg/Library/BaseFspApiLib/X64/Thunk64To32.S new file mode 100644 index 0000000000..b6b5c1aca8 --- /dev/null +++ b/IntelFspWrapperPkg/Library/BaseFspApiLib/X64/Thunk64To32.S @@ -0,0 +1,230 @@ +# +# Copyright (c) 2014, Intel Corporation. All rights reserved.
+# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +# +# Module Name: +# +# Thunk64To32.asm +# +# Abstract: +# +# This is the assembly code to transition from long mode to compatibility mode to execute 32-bit code and then +# transit back to long mode. +# +#------------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Procedure: AsmExecute32BitCode +# +# Input: None +# +# Output: None +# +# Prototype: UINT32 +# AsmExecute32BitCode ( +# IN UINT64 Function, +# IN UINT64 Param1, +# IN UINT64 Param2, +# IN IA32_DESCRIPTOR *InternalGdtr +# ); +# +# +# Description: A thunk function to execute 32-bit code in long mode. +# +#---------------------------------------------------------------------------- + +ASM_GLOBAL ASM_PFX(AsmExecute32BitCode) +ASM_PFX(AsmExecute32BitCode): + # + # save IFLAG and disable it + # + pushfq + cli + + # + # save orignal GDTR and CS + # + movl %ds, %eax + push %rax + movl %cs, %eax + push %rax + subq $0x10, %rsp + sgdt (%rsp) + # + # load internal GDT + # + lgdt (%r9) + # + # Save general purpose register and rflag register + # + pushfq + push %rdi + push %rsi + push %rbp + push %rbx + + # + # save CR3 + # + movq %cr3, %rax + movq %rax, %rbp + + # + # Prepare the CS and return address for the transition from 32-bit to 64-bit mode + # + movq $0x10, %rax # load long mode selector + shl $32, %rax + lea ReloadCS(%rip), %r9 #Assume the ReloadCS is under 4G + orq %r9, %rax + push %rax + # + # Save parameters for 32-bit function call + # + movq %r8, %rax + shl $32, %rax + orq %rdx, %rax + push %rax + # + # save the 32-bit function entry and the return address into stack which will be + # retrieve in compatibility mode. + # + lea ReturnBack(%rip), %rax #Assume the ReloadCS is under 4G + shl $32, %rax + orq %rcx, %rax + push %rax + + # + # let rax save DS + # + movq $0x18, %rax + + # + # Change to Compatible Segment + # + movq $8, %rcx # load compatible mode selector + shl $32, %rcx + lea Compatible(%rip), %rdx # assume address < 4G + orq %rdx, %rcx + push %rcx + .byte 0xcb # retf + +Compatible: + # reload DS/ES/SS to make sure they are correct referred to current GDT + movw %ax, %ds + movw %ax, %es + movw %ax, %ss + + # + # Disable paging + # + movq %cr0, %rcx + btc $31, %ecx + movq %rcx, %cr0 + # + # Clear EFER.LME + # + movl $0xC0000080, %ecx + rdmsr + btc $8, %eax + wrmsr + +# Now we are in protected mode + # + # Call 32-bit function. Assume the function entry address and parameter value is less than 4G + # + pop %rax # Here is the function entry + # + # Now the parameter is at the bottom of the stack, then call in to IA32 function. + # + jmp *%rax +ReturnBack: + movl %eax, %ebx # save return status + pop %rcx # drop param1 + pop %rcx # drop param2 + + # + # restore CR4 + # + movq %cr4, %rax + bts $5, %eax + movq %rax, %cr4 + + # + # restore CR3 + # + movl %ebp, %eax + movq %rax, %cr3 + + # + # Set EFER.LME to re-enable ia32-e + # + movl $0xC0000080, %ecx + rdmsr + bts $8, %eax + wrmsr + # + # Enable paging + # + movq %cr0, %rax + bts $31, %eax + mov %rax, %cr0 +# Now we are in compatible mode + + # + # Reload cs register + # + .byte 0xcb # retf +ReloadCS: + # + # Now we're in Long Mode + # + # + # Restore C register and eax hold the return status from 32-bit function. + # Note: Do not touch rax from now which hold the return value from IA32 function + # + movl %ebx, %eax # put return status to EAX + pop %rbx + pop %rbp + pop %rsi + pop %rdi + popfq + # + # Switch to orignal GDT and CS. here rsp is pointer to the orignal GDT descriptor. + # + lgdt (%rsp) + # + # drop GDT descriptor in stack + # + addq $0x10, %rsp + # + # switch to orignal CS and GDTR + # + pop %r9 # get CS + shl $32, %r9 # rcx[32..47] <- Cs + lea ReturnToLongMode(%rip), %rcx + orq %r9, %rcx + push %rcx + .byte 0xcb # retf +ReturnToLongMode: + # + # Reload original DS/ES/SS + # + pop %rcx + movl %ecx, %ds + movl %ecx, %es + movl %ecx, %ss + + # + # Restore IFLAG + # + popfq + + ret + diff --git a/IntelFspWrapperPkg/Library/BaseFspApiLib/X64/Thunk64To32.asm b/IntelFspWrapperPkg/Library/BaseFspApiLib/X64/Thunk64To32.asm new file mode 100644 index 0000000000..70e7b5f408 --- /dev/null +++ b/IntelFspWrapperPkg/Library/BaseFspApiLib/X64/Thunk64To32.asm @@ -0,0 +1,230 @@ +; +; Copyright (c) 2014, Intel Corporation. All rights reserved.
+; This program and the accompanying materials +; are licensed and made available under the terms and conditions of the BSD License +; which accompanies this distribution. The full text of the license may be found at +; http://opensource.org/licenses/bsd-license.php. +; +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +; +; +; Module Name: +; +; Thunk64To32.asm +; +; Abstract: +; +; This is the assembly code to transition from long mode to compatibility mode to execute 32-bit code and then +; transit back to long mode. +; +;------------------------------------------------------------------------------- + .code +;---------------------------------------------------------------------------- +; Procedure: AsmExecute32BitCode +; +; Input: None +; +; Output: None +; +; Prototype: UINT32 +; AsmExecute32BitCode ( +; IN UINT64 Function, +; IN UINT64 Param1, +; IN UINT64 Param2, +; IN IA32_DESCRIPTOR *InternalGdtr +; ); +; +; +; Description: A thunk function to execute 32-bit code in long mode. +; +;---------------------------------------------------------------------------- +AsmExecute32BitCode PROC + ; + ; save IFLAG and disable it + ; + pushfq + cli + + ; + ; save orignal GDTR and CS + ; + mov rax, ds + push rax + mov rax, cs + push rax + sub rsp, 10h + sgdt fword ptr [rsp] + ; + ; load internal GDT + ; + lgdt fword ptr [r9] + ; + ; Save general purpose register and rflag register + ; + pushfq + push rdi + push rsi + push rbp + push rbx + + ; + ; save CR3 + ; + mov rax, cr3 + mov rbp, rax + + ; + ; Prepare the CS and return address for the transition from 32-bit to 64-bit mode + ; + mov rax, 10h ; load long mode selector + shl rax, 32 + mov r9, OFFSET ReloadCS ;Assume the ReloadCS is under 4G + or rax, r9 + push rax + ; + ; Save parameters for 32-bit function call + ; + mov rax, r8 + shl rax, 32 + or rax, rdx + push rax + ; + ; save the 32-bit function entry and the return address into stack which will be + ; retrieve in compatibility mode. + ; + mov rax, OFFSET ReturnBack ;Assume the ReloadCS is under 4G + shl rax, 32 + or rax, rcx + push rax + + ; + ; let rax save DS + ; + mov rax, 018h + + ; + ; Change to Compatible Segment + ; + mov rcx, 08h ; load compatible mode selector + shl rcx, 32 + mov rdx, OFFSET Compatible ; assume address < 4G + or rcx, rdx + push rcx + retf + +Compatible: + ; reload DS/ES/SS to make sure they are correct referred to current GDT + mov ds, ax + mov es, ax + mov ss, ax + + ; + ; Disable paging + ; + mov rcx, cr0 + btc ecx, 31 + mov cr0, rcx + ; + ; Clear EFER.LME + ; + mov ecx, 0C0000080h + rdmsr + btc eax, 8 + wrmsr + +; Now we are in protected mode + ; + ; Call 32-bit function. Assume the function entry address and parameter value is less than 4G + ; + pop rax ; Here is the function entry + ; + ; Now the parameter is at the bottom of the stack, then call in to IA32 function. + ; + jmp rax +ReturnBack: + mov ebx, eax ; save return status + pop rcx ; drop param1 + pop rcx ; drop param2 + + ; + ; restore CR4 + ; + mov rax, cr4 + bts eax, 5 + mov cr4, rax + + ; + ; restore CR3 + ; + mov eax, ebp + mov cr3, rax + + ; + ; Set EFER.LME to re-enable ia32-e + ; + mov ecx, 0C0000080h + rdmsr + bts eax, 8 + wrmsr + ; + ; Enable paging + ; + mov rax, cr0 + bts eax, 31 + mov cr0, rax +; Now we are in compatible mode + + ; + ; Reload cs register + ; + retf +ReloadCS: + ; + ; Now we're in Long Mode + ; + ; + ; Restore C register and eax hold the return status from 32-bit function. + ; Note: Do not touch rax from now which hold the return value from IA32 function + ; + mov eax, ebx ; put return status to EAX + pop rbx + pop rbp + pop rsi + pop rdi + popfq + ; + ; Switch to orignal GDT and CS. here rsp is pointer to the orignal GDT descriptor. + ; + lgdt fword ptr[rsp] + ; + ; drop GDT descriptor in stack + ; + add rsp, 10h + ; + ; switch to orignal CS and GDTR + ; + pop r9 ; get CS + shl r9, 32 ; rcx[32..47] <- Cs + mov rcx, OFFSET @F + or rcx, r9 + push rcx + retf +@@: + ; + ; Reload original DS/ES/SS + ; + pop rcx + mov ds, rcx + mov es, rcx + mov ss, rcx + + ; + ; Restore IFLAG + ; + popfq + + ret +AsmExecute32BitCode ENDP + + END diff --git a/IntelFspWrapperPkg/Library/BaseFspPlatformInfoLibSample/BaseFspPlatformInfoLibSample.inf b/IntelFspWrapperPkg/Library/BaseFspPlatformInfoLibSample/BaseFspPlatformInfoLibSample.inf new file mode 100644 index 0000000000..68cd9a9a56 --- /dev/null +++ b/IntelFspWrapperPkg/Library/BaseFspPlatformInfoLibSample/BaseFspPlatformInfoLibSample.inf @@ -0,0 +1,61 @@ +## @file +# Sample to provide FSP platform information related function. +# +# Copyright (c) 2014, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +################################################################################ +# +# Defines Section - statements that will be processed to create a Makefile. +# +################################################################################ +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = BaseFspPlatformInfoLibSample + FILE_GUID = 24C6F3E2-6ACD-436b-A604-56A5CF742A55 + MODULE_TYPE = SEC + VERSION_STRING = 1.0 + LIBRARY_CLASS = FspPlatformInfoLib + + +# +# 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] + FspPlatformInfoLibSample.c + + +################################################################################ +# +# Package Dependency Section - list of Package files that are required for +# this module. +# +################################################################################ + +[Packages] + MdePkg/MdePkg.dec + IntelFspPkg/IntelFspPkg.dec + IntelFspWrapperPkg/IntelFspWrapperPkg.dec + +[LibraryClasses] + +[Pcd] + gFspWrapperTokenSpaceGuid.PcdTemporaryRamBase + gFspWrapperTokenSpaceGuid.PcdTemporaryRamSize diff --git a/IntelFspWrapperPkg/Library/BaseFspPlatformInfoLibSample/FspPlatformInfoLibSample.c b/IntelFspWrapperPkg/Library/BaseFspPlatformInfoLibSample/FspPlatformInfoLibSample.c new file mode 100644 index 0000000000..7c57e7bb46 --- /dev/null +++ b/IntelFspWrapperPkg/Library/BaseFspPlatformInfoLibSample/FspPlatformInfoLibSample.c @@ -0,0 +1,147 @@ +/** @file + Sample to provide FSP platform information related function. + + Copyright (c) 2014, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include + +/** + 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 + ) +{ + return BOOT_WITH_FULL_CONFIGURATION; +} + +/** + 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 + ) +{ + return NULL; +} + +/** + Get UPD region size. + + @note At this point, memory is NOT ready, PeiServices are available to use. + + @return UPD region size. +**/ +UINT32 +EFIAPI +GetUpdRegionSize ( + VOID + ) +{ + return 0; +} + +/** + This function overrides the default configurations in the UPD data region. + + @note At this point, memory is NOT ready, PeiServices are available to use. + + @param[in,out] FspUpdRgnPtr A pointer to the UPD data region data strcture. + + @return FspUpdRgnPtr A pointer to the UPD data region data strcture. +**/ +VOID * +EFIAPI +UpdateFspUpdConfigs ( + IN OUT VOID *FspUpdRgnPtr + ) +{ + return NULL; +} + +/** + Get S3 PEI memory information. + + @note At this point, memory is ready, and PeiServices are available to use. + Platform can get some data from SMRAM directly. + + @param[out] S3PeiMemSize PEI memory size to be installed in S3 phase. + @param[out] S3PeiMemBase PEI memory base to be installed in S3 phase. + + @return If S3 PEI memory information is got successfully. +**/ +EFI_STATUS +EFIAPI +GetS3MemoryInfo ( + OUT UINT64 *S3PeiMemSize, + OUT EFI_PHYSICAL_ADDRESS *S3PeiMemBase + ) +{ + return EFI_UNSUPPORTED; +} + +/** + 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 + ) +{ + *StackBase = PcdGet32 (PcdTemporaryRamBase); + *StackSize = PcdGet32 (PcdTemporaryRamSize); + + if (BootMode == BOOT_ON_S3_RESUME) { + if (!FspInitDone) { + } else { + } + } else if (BootMode == BOOT_ON_FLASH_UPDATE) { + if (!FspInitDone) { + } else { + } + } + + return EFI_SUCCESS; +} diff --git a/IntelFspWrapperPkg/Library/PeiFspHobProcessLibSample/FspHobProcessLibSample.c b/IntelFspWrapperPkg/Library/PeiFspHobProcessLibSample/FspHobProcessLibSample.c new file mode 100644 index 0000000000..f293dc8be8 --- /dev/null +++ b/IntelFspWrapperPkg/Library/PeiFspHobProcessLibSample/FspHobProcessLibSample.c @@ -0,0 +1,337 @@ +/** @file + Sample to provide FSP hob process related function. + + Copyright (c) 2014, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +// +// Additional pages are used by DXE memory manager. +// It should be consistent between RetrieveRequiredMemorySize() and GetPeiMemSize() +// +#define PEI_ADDITIONAL_MEMORY_SIZE (16 * EFI_PAGE_SIZE) + +/** + Get the mem size in memory type infromation table. + + @param[in] PeiServices PEI Services table. + + @return the mem size in memory type infromation table. +**/ +UINT64 +GetMemorySizeInMemoryTypeInformation ( + IN EFI_PEI_SERVICES **PeiServices + ) +{ + EFI_STATUS Status; + EFI_PEI_HOB_POINTERS Hob; + EFI_MEMORY_TYPE_INFORMATION *MemoryData; + UINT8 Index; + UINTN TempPageNum; + + MemoryData = NULL; + Status = (*PeiServices)->GetHobList ((CONST EFI_PEI_SERVICES**)PeiServices, (VOID **) &Hob.Raw); + while (!END_OF_HOB_LIST (Hob)) { + if (Hob.Header->HobType == EFI_HOB_TYPE_GUID_EXTENSION && + CompareGuid (&Hob.Guid->Name, &gEfiMemoryTypeInformationGuid)) { + MemoryData = (EFI_MEMORY_TYPE_INFORMATION *) (Hob.Raw + sizeof (EFI_HOB_GENERIC_HEADER) + sizeof (EFI_GUID)); + break; + } + + Hob.Raw = GET_NEXT_HOB (Hob); + } + + if (MemoryData == NULL) { + return 0; + } + + TempPageNum = 0; + for (Index = 0; MemoryData[Index].Type != EfiMaxMemoryType; Index++) { + // + // Accumulate default memory size requirements + // + TempPageNum += MemoryData[Index].NumberOfPages; + } + + return TempPageNum * EFI_PAGE_SIZE; +} + +/** + Get the mem size need to be reserved in PEI phase. + + @param[in] PeiServices PEI Services table. + + @return the mem size need to be reserved in PEI phase. +**/ +UINT64 +RetrieveRequiredMemorySize ( + IN EFI_PEI_SERVICES **PeiServices + ) +{ + UINT64 Size; + + Size = GetMemorySizeInMemoryTypeInformation (PeiServices); + return Size + PEI_ADDITIONAL_MEMORY_SIZE; +} + +/** + Get the mem size need to be consumed and reserved in PEI phase. + + @param[in] PeiServices PEI Services table. + @param[in] BootMode Current boot mode. + + @return the mem size need to be consumed and reserved in PEI phase. +**/ +UINT64 +GetPeiMemSize ( + IN EFI_PEI_SERVICES **PeiServices, + IN UINT32 BootMode + ) +{ + UINT64 Size; + UINT64 MinSize; + + if (BootMode == BOOT_IN_RECOVERY_MODE) { + return PcdGet32 (PcdPeiRecoveryMinMemSize); + } + + Size = GetMemorySizeInMemoryTypeInformation (PeiServices); + + if (BootMode == BOOT_ON_FLASH_UPDATE) { + // + // Maybe more size when in CapsuleUpdate phase ? + // + MinSize = PcdGet32 (PcdPeiMinMemSize); + } else { + MinSize = PcdGet32 (PcdPeiMinMemSize); + } + + return MinSize + Size + PEI_ADDITIONAL_MEMORY_SIZE; +} + +/** + 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 + ) +{ + EFI_PEI_HOB_POINTERS Hob; + UINT64 LowMemorySize; + UINT64 FspMemorySize; + EFI_PHYSICAL_ADDRESS FspMemoryBase; + UINT64 PeiMemSize; + EFI_PHYSICAL_ADDRESS PeiMemBase; + UINT64 S3PeiMemSize; + EFI_PHYSICAL_ADDRESS S3PeiMemBase; + BOOLEAN FoundFspMemHob; + EFI_STATUS Status; + EFI_BOOT_MODE BootMode; + PEI_CAPSULE_PPI *Capsule; + VOID *CapsuleBuffer; + UINTN CapsuleBufferLength; + UINT64 RequiredMemSize; + EFI_PEI_SERVICES **PeiServices; + + PeiServices = (EFI_PEI_SERVICES **)GetPeiServicesTablePointer (); + + PeiServicesGetBootMode (&BootMode); + + PeiMemBase = 0; + LowMemorySize = 0; + FspMemorySize = 0; + FspMemoryBase = 0; + FoundFspMemHob = FALSE; + + // + // Parse the hob list from fsp + // Report all the resource hob except the memory between 1M and 4G + // + Hob.Raw = (UINT8 *)(UINTN)FspHobList; + DEBUG((DEBUG_INFO, "FspHobList - 0x%x\n", FspHobList)); + + while ((Hob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, Hob.Raw)) != NULL) { + DEBUG((DEBUG_INFO, "\nResourceType: 0x%x\n", Hob.ResourceDescriptor->ResourceType)); + if ((Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) || + (Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_MEMORY_RESERVED)) { + DEBUG((DEBUG_INFO, "ResourceAttribute: 0x%x\n", Hob.ResourceDescriptor->ResourceAttribute)); + DEBUG((DEBUG_INFO, "PhysicalStart: 0x%x\n", Hob.ResourceDescriptor->PhysicalStart)); + DEBUG((DEBUG_INFO, "ResourceLength: 0x%x\n", Hob.ResourceDescriptor->ResourceLength)); + DEBUG((DEBUG_INFO, "Owner: %g\n\n", &Hob.ResourceDescriptor->Owner)); + } + + if ((Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) // Found the low memory length below 4G + && (Hob.ResourceDescriptor->PhysicalStart >= BASE_1MB) + && (Hob.ResourceDescriptor->PhysicalStart + Hob.ResourceDescriptor->ResourceLength <= BASE_4GB)) { + LowMemorySize += Hob.ResourceDescriptor->ResourceLength; + Hob.Raw = GET_NEXT_HOB (Hob); + continue; + } + + if ((Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_MEMORY_RESERVED) // Found the low memory length below 4G + && (Hob.ResourceDescriptor->PhysicalStart >= BASE_1MB) + && (Hob.ResourceDescriptor->PhysicalStart + Hob.ResourceDescriptor->ResourceLength <= BASE_4GB) + && (CompareGuid (&Hob.ResourceDescriptor->Owner, &gFspReservedMemoryResourceHobGuid))) { + FoundFspMemHob = TRUE; + FspMemoryBase = Hob.ResourceDescriptor->PhysicalStart; + FspMemorySize = Hob.ResourceDescriptor->ResourceLength; + DEBUG((DEBUG_INFO, "Find fsp mem hob, base 0x%x, len 0x%x\n", FspMemoryBase, FspMemorySize)); + } + + // + // Report the resource hob + // + BuildResourceDescriptorHob ( + Hob.ResourceDescriptor->ResourceType, + Hob.ResourceDescriptor->ResourceAttribute, + Hob.ResourceDescriptor->PhysicalStart, + Hob.ResourceDescriptor->ResourceLength + ); + + Hob.Raw = GET_NEXT_HOB (Hob); + } + + if (!FoundFspMemHob) { + DEBUG((DEBUG_INFO, "Didn't find the fsp used memory information.\n")); + //ASSERT(FALSE); + } + + DEBUG((DEBUG_INFO, "LowMemorySize: 0x%x.\n", LowMemorySize)); + DEBUG((DEBUG_INFO, "FspMemoryBase: 0x%x.\n", FspMemoryBase)); + DEBUG((DEBUG_INFO, "FspMemorySize: 0x%x.\n", FspMemorySize)); + + if (BootMode == BOOT_ON_S3_RESUME) { + BuildResourceDescriptorHob ( + EFI_RESOURCE_SYSTEM_MEMORY, + ( + EFI_RESOURCE_ATTRIBUTE_PRESENT | + EFI_RESOURCE_ATTRIBUTE_INITIALIZED | + // EFI_RESOURCE_ATTRIBUTE_TESTED | + EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE | + EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE | + EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE | + EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE + ), + BASE_1MB, + LowMemorySize + ); + + Status = GetS3MemoryInfo (&S3PeiMemBase, &S3PeiMemSize); + ASSERT_EFI_ERROR (Status); + DEBUG((DEBUG_INFO, "S3 memory %Xh - %Xh bytes\n", S3PeiMemBase, S3PeiMemSize)); + + // + // Make sure Stack and PeiMemory are not overlap - JYAO1 + // + + Status = PeiServicesInstallPeiMemory ( + S3PeiMemBase, + S3PeiMemSize + ); + ASSERT_EFI_ERROR (Status); + } else { + PeiMemSize = GetPeiMemSize (PeiServices, BootMode); + DEBUG((DEBUG_INFO, "PEI memory size = %Xh bytes\n", PeiMemSize)); + + // + // Capsule mode + // + Capsule = NULL; + CapsuleBuffer = NULL; + CapsuleBufferLength = 0; + if (BootMode == BOOT_ON_FLASH_UPDATE) { + Status = PeiServicesLocatePpi ( + &gPeiCapsulePpiGuid, + 0, + NULL, + (VOID **) &Capsule + ); + ASSERT_EFI_ERROR (Status); + + if (Status == EFI_SUCCESS) { + // + // Make sure Stack and CapsuleBuffer are not overlap - JYAO1 + // + CapsuleBuffer = (VOID *)(UINTN)BASE_1MB; + CapsuleBufferLength = (UINTN)(LowMemorySize - PeiMemSize); + // + // Call the Capsule PPI Coalesce function to coalesce the capsule data. + // + Status = Capsule->Coalesce (PeiServices, &CapsuleBuffer, &CapsuleBufferLength); + } + } + + RequiredMemSize = RetrieveRequiredMemorySize (PeiServices); + DEBUG((DEBUG_INFO, "Required memory size = %Xh bytes\n", RequiredMemSize)); + + // + // Report the main memory + // + BuildResourceDescriptorHob ( + EFI_RESOURCE_SYSTEM_MEMORY, + ( + EFI_RESOURCE_ATTRIBUTE_PRESENT | + EFI_RESOURCE_ATTRIBUTE_INITIALIZED | + EFI_RESOURCE_ATTRIBUTE_TESTED | + EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE | + EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE | + EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE | + EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE + ), + BASE_1MB, + LowMemorySize + ); + + // + // Make sure Stack and CapsuleBuffer are not overlap - JYAO1 + // + + // + // Install efi memory + // + PeiMemBase = BASE_1MB + LowMemorySize - PeiMemSize; + Status = PeiServicesInstallPeiMemory ( + PeiMemBase, + PeiMemSize - RequiredMemSize + ); + ASSERT_EFI_ERROR (Status); + + if (Capsule != NULL) { + Status = Capsule->CreateState (PeiServices, CapsuleBuffer, CapsuleBufferLength); + } + } + + // + // NV Storage Hob + // + + return EFI_SUCCESS; +} diff --git a/IntelFspWrapperPkg/Library/PeiFspHobProcessLibSample/PeiFspHobProcessLibSample.inf b/IntelFspWrapperPkg/Library/PeiFspHobProcessLibSample/PeiFspHobProcessLibSample.inf new file mode 100644 index 0000000000..cbba3d41f6 --- /dev/null +++ b/IntelFspWrapperPkg/Library/PeiFspHobProcessLibSample/PeiFspHobProcessLibSample.inf @@ -0,0 +1,75 @@ +## @file +# Sample to provide FSP hob process related function. +# +# Copyright (c) 2014, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +################################################################################ +# +# Defines Section - statements that will be processed to create a Makefile. +# +################################################################################ +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = PeiFspHobProcessLibSample + FILE_GUID = C7B7070B-E5A8-4b86-9110-BDCA1095F496 + MODULE_TYPE = SEC + VERSION_STRING = 1.0 + LIBRARY_CLASS = FspHobProcessLib + +# +# 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] + FspHobProcessLibSample.c + + +################################################################################ +# +# Package Dependency Section - list of Package files that are required for +# this module. +# +################################################################################ + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + IntelFspPkg/IntelFspPkg.dec + IntelFspWrapperPkg/IntelFspWrapperPkg.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + HobLib + DebugLib + FspPlatformInfoLib + PeiServicesLib + PeiServicesTablePointerLib + +[Pcd] + gFspWrapperTokenSpaceGuid.PcdPeiMinMemSize + gFspWrapperTokenSpaceGuid.PcdPeiRecoveryMinMemSize + +[Guids] + gFspReservedMemoryResourceHobGuid + gEfiMemoryTypeInformationGuid + +[Ppis] + gPeiCapsulePpiGuid diff --git a/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/FspPlatformSecLibSample.c b/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/FspPlatformSecLibSample.c new file mode 100644 index 0000000000..6bf2e8662d --- /dev/null +++ b/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/FspPlatformSecLibSample.c @@ -0,0 +1,151 @@ +/** @file + Sample to provide FSP wrapper platform sec related function. + + Copyright (c) 2014, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include + +#include +#include +#include + +#include + +/** + This interface conveys state information out of the Security (SEC) phase into PEI. + + @param[in] PeiServices Pointer to the PEI Services Table. + @param[in,out] StructureSize Pointer to the variable describing size of the input buffer. + @param[out] PlatformInformationRecord Pointer to the EFI_SEC_PLATFORM_INFORMATION_RECORD. + + @retval EFI_SUCCESS The data was successfully returned. + @retval EFI_BUFFER_TOO_SMALL The buffer was too small. + +**/ +EFI_STATUS +EFIAPI +SecPlatformInformation ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN OUT UINT64 *StructureSize, + OUT EFI_SEC_PLATFORM_INFORMATION_RECORD *PlatformInformationRecord + ); + +/** + 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/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/AsmSaveSecContext.S b/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/AsmSaveSecContext.S new file mode 100644 index 0000000000..3838cc8292 --- /dev/null +++ b/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/AsmSaveSecContext.S @@ -0,0 +1,43 @@ +#------------------------------------------------------------------------------ +# +# Copyright (c) 2014, Intel Corporation. All rights reserved.
+# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +# Module Name: +# +# AsmSaveSecContext.S +# +# Abstract: +# +# Save Sec Conext before call FspInit API +# +#------------------------------------------------------------------------------ + +#---------------------------------------------------------------------------- +# 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/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/AsmSaveSecContext.asm b/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/AsmSaveSecContext.asm new file mode 100644 index 0000000000..bb147a93db --- /dev/null +++ b/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/AsmSaveSecContext.asm @@ -0,0 +1,50 @@ +;------------------------------------------------------------------------------ +; +; Copyright (c) 2014, Intel Corporation. All rights reserved.
+; This program and the accompanying materials +; are licensed and made available under the terms and conditions of the BSD License +; which accompanies this distribution. The full text of the license may be found at +; http://opensource.org/licenses/bsd-license.php. +; +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +; +; Module Name: +; +; AsmSaveSecContext.asm +; +; Abstract: +; +; Save Sec Conext before call FspInit API +; +;------------------------------------------------------------------------------ + +.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/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/Fsp.h b/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/Fsp.h new file mode 100644 index 0000000000..289d6638b0 --- /dev/null +++ b/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/Fsp.h @@ -0,0 +1,43 @@ +/** @file + Fsp related definitions + + Copyright (c) 2014, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +// +// 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 diff --git a/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/PeiCoreEntry.S b/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/PeiCoreEntry.S new file mode 100644 index 0000000000..c35f02b77e --- /dev/null +++ b/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/PeiCoreEntry.S @@ -0,0 +1,130 @@ +#------------------------------------------------------------------------------ +# +# Copyright (c) 2014, Intel Corporation. All rights reserved.
+# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +# Module Name: +# +# PeiCoreEntry.S +# +# Abstract: +# +# Find and call SecStartup +# +#------------------------------------------------------------------------------ + +ASM_GLOBAL ASM_PFX(CallPeiCoreEntryPoint) +ASM_PFX(CallPeiCoreEntryPoint): + # + # Obtain the hob list pointer + # + movl 0x4(%esp), %eax + # + # Obtain the stack information + # ECX: start of range + # EDX: end of range + # + movl 0x8(%esp), %ecx + movl 0xC(%esp), %edx + + # + # Platform init + # + pushal + pushl %edx + pushl %ecx + pushl %eax + call ASM_PFX(PlatformInit) + popl %eax + popl %eax + popl %eax + popal + + # + # Set stack top pointer + # + movl %edx, %esp + + # + # Push the hob list pointer + # + pushl %eax + + # + # Save the value + # ECX: start of range + # EDX: end of range + # + movl %esp, %ebp + pushl %ecx + pushl %edx + + # + # Push processor count to stack first, then BIST status (AP then BSP) + # + movl $1, %eax + cpuid + shr $16, %ebx + andl $0x000000FF, %ebx + cmp $1, %bl + jae PushProcessorCount + + # + # Some processors report 0 logical processors. Effectively 0 = 1. + # So we fix up the processor count + # + inc %ebx + +PushProcessorCount: + pushl %ebx + + # + # We need to implement a long-term solution for BIST capture. For now, we just copy BSP BIST + # for all processor threads + # + xorl %ecx, %ecx + movb %bl, %cl +PushBist: + movd %mm0, %eax + pushl %eax + loop PushBist + + # Save Time-Stamp Counter + movd %mm5, %eax + pushl %eax + + movd %mm6, %eax + pushl %eax + + # + # Pass entry point of the PEI core + # + movl $0xFFFFFFE0, %edi + pushl %ds:(%edi) + + # + # Pass BFV into the PEI Core + # + movl $0xFFFFFFFC, %edi + pushl %ds:(%edi) + + # + # Pass stack size into the PEI Core + # + movl -4(%ebp), %ecx + movl -8(%ebp), %edx + pushl %ecx # RamBase + + subl %ecx, %edx + pushl %edx # RamSize + + # + # Pass Control into the PEI Core + # + call ASM_PFX(SecStartup) diff --git a/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/PeiCoreEntry.asm b/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/PeiCoreEntry.asm new file mode 100644 index 0000000000..cd1c7b8c5d --- /dev/null +++ b/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/PeiCoreEntry.asm @@ -0,0 +1,140 @@ +;------------------------------------------------------------------------------ +; +; Copyright (c) 2014, Intel Corporation. All rights reserved.
+; This program and the accompanying materials +; are licensed and made available under the terms and conditions of the BSD License +; which accompanies this distribution. The full text of the license may be found at +; http://opensource.org/licenses/bsd-license.php. +; +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +; +; Module Name: +; +; PeiCoreEntry.asm +; +; Abstract: +; +; Find and call SecStartup +; +;------------------------------------------------------------------------------ + +.686p +.xmm +.model flat, c +.code + +EXTRN SecStartup:NEAR +EXTRN PlatformInit:NEAR + +CallPeiCoreEntryPoint PROC PUBLIC + ; + ; Obtain the hob list pointer + ; + mov eax, [esp+4] + ; + ; Obtain the stack information + ; ECX: start of range + ; EDX: end of range + ; + mov ecx, [esp+8] + mov edx, [esp+0Ch] + + ; + ; Platform init + ; + pushad + push edx + push ecx + push eax + call PlatformInit + pop eax + pop eax + pop eax + popad + + ; + ; Set stack top pointer + ; + mov esp, edx + + ; + ; Push the hob list pointer + ; + push eax + + ; + ; Save the value + ; ECX: start of range + ; EDX: end of range + ; + mov ebp, esp + push ecx + push edx + + ; + ; Push processor count to stack first, then BIST status (AP then BSP) + ; + mov eax, 1 + cpuid + shr ebx, 16 + and ebx, 0000000FFh + cmp bl, 1 + jae PushProcessorCount + + ; + ; Some processors report 0 logical processors. Effectively 0 = 1. + ; So we fix up the processor count + ; + inc ebx + +PushProcessorCount: + push ebx + + ; + ; We need to implement a long-term solution for BIST capture. For now, we just copy BSP BIST + ; for all processor threads + ; + xor ecx, ecx + mov cl, bl +PushBist: + movd eax, mm0 + push eax + loop PushBist + + ; Save Time-Stamp Counter + movd eax, mm5 + push eax + + movd eax, mm6 + push eax + + ; + ; Pass entry point of the PEI core + ; + mov edi, 0FFFFFFE0h + push DWORD PTR ds:[edi] + + ; + ; Pass BFV into the PEI Core + ; + mov edi, 0FFFFFFFCh + push DWORD PTR ds:[edi] + + ; + ; Pass stack size into the PEI Core + ; + mov ecx, [ebp - 4] + mov edx, [ebp - 8] + push ecx ; RamBase + + sub edx, ecx + push edx ; RamSize + + ; + ; Pass Control into the PEI Core + ; + call SecStartup +CallPeiCoreEntryPoint ENDP + +END diff --git a/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/SecEntry.S b/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/SecEntry.S new file mode 100644 index 0000000000..3145a484a3 --- /dev/null +++ b/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/SecEntry.S @@ -0,0 +1,325 @@ +#------------------------------------------------------------------------------ +# +# Copyright (c) 2014, Intel Corporation. All rights reserved.
+# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +# Module Name: +# +# SecEntry.S +# +# Abstract: +# +# This is the code that goes from real-mode to protected mode. +# It consumes the reset vector, calls TempRamInit API from FSP binary. +# +#------------------------------------------------------------------------------ + +#include "Fsp.h" + +ASM_GLOBAL ASM_PFX(_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 $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 PcdGet32 (PcdFlashFvFspBase), %edi + movl PcdGet32 (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 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 ProtectedModeEntryPoint # Offset of our 32 bit code + .word LINEAR_CODE_SEL diff --git a/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/SecEntry.asm b/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/SecEntry.asm new file mode 100644 index 0000000000..0e0c5c5883 --- /dev/null +++ b/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/SecEntry.asm @@ -0,0 +1,345 @@ +;------------------------------------------------------------------------------ +; +; Copyright (c) 2014, Intel Corporation. All rights reserved.
+; This program and the accompanying materials +; are licensed and made available under the terms and conditions of the BSD License +; which accompanies this distribution. The full text of the license may be found at +; http://opensource.org/licenses/bsd-license.php. +; +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +; +; Module Name: +; +; SecEntry.asm +; +; Abstract: +; +; This is the code that goes from real-mode to protected mode. +; It consumes the reset vector, calls TempRamInit API from FSP binary. +; +;------------------------------------------------------------------------------ + +#include "Fsp.h" + +.686p +.xmm +.model small, c + +EXTRN CallPeiCoreEntryPoint:NEAR +EXTRN 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/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/Stack.S b/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/Stack.S new file mode 100644 index 0000000000..950b3a1f0a --- /dev/null +++ b/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/Stack.S @@ -0,0 +1,77 @@ +#------------------------------------------------------------------------------ +# +# Copyright (c) 2014, Intel Corporation. All rights reserved.
+# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +# Abstract: +# +# Switch the stack from temporary memory to permenent memory. +# +#------------------------------------------------------------------------------ + + +#------------------------------------------------------------------------------ +# VOID +# EFIAPI +# SecSwitchStack ( +# UINT32 TemporaryMemoryBase, +# UINT32 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/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/Stack.asm b/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/Stack.asm new file mode 100644 index 0000000000..f96a55f040 --- /dev/null +++ b/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/Stack.asm @@ -0,0 +1,82 @@ +;------------------------------------------------------------------------------ +; +; Copyright (c) 2014, Intel Corporation. All rights reserved.
+; This program and the accompanying materials +; are licensed and made available under the terms and conditions of the BSD License +; which accompanies this distribution. The full text of the license may be found at +; http://opensource.org/licenses/bsd-license.php. +; +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +; +; Abstract: +; +; Switch the stack from temporary memory to permenent memory. +; +;------------------------------------------------------------------------------ + + .586p + .model flat,C + .code + +;------------------------------------------------------------------------------ +; VOID +; EFIAPI +; SecSwitchStack ( +; UINT32 TemporaryMemoryBase, +; UINT32 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/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/PlatformInit.c b/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/PlatformInit.c new file mode 100644 index 0000000000..e8b71667de --- /dev/null +++ b/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/PlatformInit.c @@ -0,0 +1,43 @@ +/** @file + Sample to provide platform init function. + + Copyright (c) 2014, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + + +#include +#include + +/** + 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/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SaveSecContext.c b/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SaveSecContext.c new file mode 100644 index 0000000000..3d37441183 --- /dev/null +++ b/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SaveSecContext.c @@ -0,0 +1,111 @@ +/** @file + Sample to provide SaveSecContext function. + + Copyright (c) 2014, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + + +#include +#include + +#include +#include + +/** + 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/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecGetPerformance.c b/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecGetPerformance.c new file mode 100644 index 0000000000..e2d6b3da57 --- /dev/null +++ b/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecGetPerformance.c @@ -0,0 +1,90 @@ +/** @file + Sample to provide SecGetPerformance function. + + Copyright (c) 2014, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include + +#include +#include + +#include +#include +#include + +/** + This interface conveys performance information out of the Security (SEC) phase into PEI. + + This service is published by the SEC phase. The SEC phase handoff has an optional + EFI_PEI_PPI_DESCRIPTOR list as its final argument when control is passed from SEC into the + PEI Foundation. As such, if the platform supports collecting performance data in SEC, + this information is encapsulated into the data structure abstracted by this service. + This information is collected for the boot-strap processor (BSP) on IA-32. + + @param[in] PeiServices The pointer to the PEI Services Table. + @param[in] This The pointer to this instance of the PEI_SEC_PERFORMANCE_PPI. + @param[out] Performance The pointer to performance data collected in SEC phase. + + @retval EFI_SUCCESS The data was successfully returned. + +**/ +EFI_STATUS +EFIAPI +SecGetPerformance ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN PEI_SEC_PERFORMANCE_PPI *This, + OUT FIRMWARE_SEC_PERFORMANCE *Performance + ) +{ + UINT32 Size; + UINT32 Count; + UINT32 TopOfTemporaryRam; + UINT64 Ticker; + VOID *TopOfTemporaryRamPpi; + EFI_STATUS Status; + + DEBUG ((DEBUG_INFO, "SecGetPerformance\n")); + + Status = (*PeiServices)->LocatePpi ( + PeiServices, + &gTopOfTemporaryRamPpiGuid, + 0, + NULL, + (VOID **) &TopOfTemporaryRamPpi + ); + if (EFI_ERROR (Status)) { + return EFI_NOT_FOUND; + } + + // + // |--------------| <- TopOfTemporaryRam + // |Number of BSPs| + // |--------------| + // | BIST | + // |--------------| + // | .... | + // |--------------| + // | TSC[63:32] | + // |--------------| + // | TSC[31:00] | + // |--------------| + // + TopOfTemporaryRam = (UINT32)(UINTN)TopOfTemporaryRamPpi - sizeof(UINT32); + TopOfTemporaryRam -= sizeof(UINT32) * 2; + Count = *(UINT32 *) (UINTN) (TopOfTemporaryRam - sizeof (UINT32)); + Size = Count * sizeof (UINT64); + + Ticker = *(UINT64 *) (UINTN) (TopOfTemporaryRam - sizeof (UINT32) - Size - sizeof (UINT32) * 2); + Performance->ResetEnd = GetTimeInNanoSecond (Ticker); + + return EFI_SUCCESS; +} diff --git a/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecPeiFspPlatformSecLibSample.inf b/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecPeiFspPlatformSecLibSample.inf new file mode 100644 index 0000000000..09b8036918 --- /dev/null +++ b/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecPeiFspPlatformSecLibSample.inf @@ -0,0 +1,93 @@ +## @file +# Sample to provide FSP wrapper platform sec related function. +# +# Copyright (c) 2014, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +################################################################################ +# +# Defines Section - statements that will be processed to create a Makefile. +# +################################################################################ +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = SecPeiFspPlatformSecLibSample + FILE_GUID = 4E1C4F95-90EA-47de-9ACC-B8920189A1F5 + 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/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 + IntelFspPkg/IntelFspPkg.dec + IntelFspWrapperPkg/IntelFspWrapperPkg.dec + +[LibraryClasses] + LocalApicLib + +[Ppis] + gEfiSecPlatformInformationPpiGuid + gPeiSecPerformancePpiGuid + gEfiTemporaryRamSupportPpiGuid + +[Pcd] + gFspWrapperTokenSpaceGuid.PcdPeiTemporaryRamStackSize + gFspWrapperTokenSpaceGuid.PcdFlashFvFspBase + gFspWrapperTokenSpaceGuid.PcdFlashFvFspSize + +[FixedPcd] + gFspWrapperTokenSpaceGuid.PcdCpuMicrocodePatchAddress + gFspWrapperTokenSpaceGuid.PcdCpuMicrocodePatchRegionSize + gFspWrapperTokenSpaceGuid.PcdFlashMicroCodeOffset + gFspWrapperTokenSpaceGuid.PcdFlashCodeCacheAddress + gFspWrapperTokenSpaceGuid.PcdFlashCodeCacheSize diff --git a/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecPlatformInformation.c b/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecPlatformInformation.c new file mode 100644 index 0000000000..b879080dfa --- /dev/null +++ b/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecPlatformInformation.c @@ -0,0 +1,84 @@ +/** @file + Sample to provide SecPlatformInformation function. + + Copyright (c) 2014, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include + +#include +#include + +#include +#include + +/** + This interface conveys state information out of the Security (SEC) phase into PEI. + + @param[in] PeiServices Pointer to the PEI Services Table. + @param[in,out] StructureSize Pointer to the variable describing size of the input buffer. + @param[out] PlatformInformationRecord Pointer to the EFI_SEC_PLATFORM_INFORMATION_RECORD. + + @retval EFI_SUCCESS The data was successfully returned. + @retval EFI_BUFFER_TOO_SMALL The buffer was too small. + +**/ +EFI_STATUS +EFIAPI +SecPlatformInformation ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN OUT UINT64 *StructureSize, + OUT EFI_SEC_PLATFORM_INFORMATION_RECORD *PlatformInformationRecord + ) +{ + UINT32 *Bist; + UINT32 Size; + UINT32 Count; + UINT32 TopOfTemporaryRam; + VOID *TopOfTemporaryRamPpi; + EFI_STATUS Status; + + DEBUG ((DEBUG_INFO, "SecPlatformInformation\n")); + + Status = (*PeiServices)->LocatePpi ( + PeiServices, + &gTopOfTemporaryRamPpiGuid, + 0, + NULL, + (VOID **) &TopOfTemporaryRamPpi + ); + if (EFI_ERROR (Status)) { + return EFI_NOT_FOUND; + } + + // + // The entries of BIST information, together with the number of them, + // reside in the bottom of stack, left untouched by normal stack operation. + // This routine copies the BIST information to the buffer pointed by + // PlatformInformationRecord for output. + // + TopOfTemporaryRam = (UINT32)(UINTN)TopOfTemporaryRamPpi - sizeof (UINT32); + TopOfTemporaryRam -= sizeof(UINT32) * 2; + Count = *((UINT32 *)(UINTN) (TopOfTemporaryRam - sizeof (UINT32))); + Size = Count * sizeof (IA32_HANDOFF_STATUS); + + if ((*StructureSize) < (UINT64) Size) { + *StructureSize = Size; + return EFI_BUFFER_TOO_SMALL; + } + + *StructureSize = Size; + Bist = (UINT32 *) (TopOfTemporaryRam - sizeof (UINT32) - Size); + + CopyMem (PlatformInformationRecord, Bist, Size); + + return EFI_SUCCESS; +} diff --git a/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecRamInitData.c b/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecRamInitData.c new file mode 100644 index 0000000000..0c7da4447b --- /dev/null +++ b/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecRamInitData.c @@ -0,0 +1,22 @@ +/** @file + Sample to provide TempRamInitParams data. + + Copyright (c) 2014, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include + +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/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecTempRamSupport.c b/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecTempRamSupport.c new file mode 100644 index 0000000000..7f7a6af0bd --- /dev/null +++ b/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecTempRamSupport.c @@ -0,0 +1,154 @@ +/** @file + Sample to provide SecTemporaryRamSupport function. + + Copyright (c) 2014, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include + +#include + +#include +#include +#include +#include + +/** + 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); + + + // + // We need *not* fix the return address because currently, + // The PeiCore is executed in flash. + // + + // + // Rebase IDT table in permanent memory + // + AsmReadIdtr (&IdtDescriptor); + IdtDescriptor.Base = IdtDescriptor.Base - (UINTN)OldStack + (UINTN)NewStack; + + AsmWriteIdtr (&IdtDescriptor); + + + // + // 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; +} +