/** Retrieves and returns a pointer to the entry point to a PE/COFF image that has been loaded into system memory with the PE/COFF Loader Library functions. Retrieves the entry point to the PE/COFF image specified by Pe32Data and returns this entry point in EntryPoint. If the entry point could not be retrieved from the PE/COFF image, then return RETURN_INVALID_PARAMETER. Otherwise return RETURN_SUCCESS. If Pe32Data is NULL, then ASSERT(). If EntryPoint is NULL, then ASSERT(). @param Pe32Data The pointer to the PE/COFF image that is loaded in system memory. @param EntryPoint The pointer to entry point to the PE/COFF image to return. @retval RETURN_SUCCESS EntryPoint was returned. @retval RETURN_INVALID_PARAMETER The entry point could not be found in the PE/COFF image. **/ RETURN_STATUS EFIAPI PeCoffLoaderGetEntryPoint ( IN VOID *Pe32Data, IN OUT VOID **EntryPoint ) { EMU_THUNK_PPI *ThunkPpi; EFI_STATUS Status; EMU_THUNK_PROTOCOL *Thunk; // // Locate EmuThunkPpi for retrieving standard output handle // Status = PeiServicesLocatePpi ( &gEmuThunkPpiGuid, 0, NULL, (VOID **) &ThunkPpi ); ASSERT_EFI_ERROR (Status); Thunk = (EMU_THUNK_PROTOCOL *)ThunkPpi->Thunk (); return Thunk->PeCoffGetEntryPoint (Pe32Data, EntryPoint); }
/*++ Routine Description: Arguments: FileHandle - Handle of the file being invoked. PeiServices - Describes the list of possible PEI Services. Returns: Status - EFI_SUCCESS if the boot mode could be set --*/ EFI_STATUS EFIAPI InitializeCpuPeim ( IN EFI_PEI_FILE_HANDLE FileHandle, IN CONST EFI_PEI_SERVICES **PeiServices ) { EFI_STATUS Status; ARM_MP_CORE_INFO_PPI *ArmMpCoreInfoPpi; UINTN ArmCoreCount; ARM_CORE_INFO *ArmCoreInfoTable; // Enable program flow prediction, if supported. ArmEnableBranchPrediction (); // Publish the CPU memory and io spaces sizes BuildCpuHob (PcdGet8 (PcdPrePiCpuMemorySize), PcdGet8 (PcdPrePiCpuIoSize)); // Only MP Core platform need to produce gArmMpCoreInfoPpiGuid Status = PeiServicesLocatePpi (&gArmMpCoreInfoPpiGuid, 0, NULL, (VOID**)&ArmMpCoreInfoPpi); if (!EFI_ERROR(Status)) { // Build the MP Core Info Table ArmCoreCount = 0; Status = ArmMpCoreInfoPpi->GetMpCoreInfo (&ArmCoreCount, &ArmCoreInfoTable); if (!EFI_ERROR(Status) && (ArmCoreCount > 0)) { // Build MPCore Info HOB BuildGuidDataHob (&gArmMpCoreInfoGuid, ArmCoreInfoTable, sizeof (ARM_CORE_INFO) * ArmCoreCount); } } return EFI_SUCCESS; }
/** Initialize OEM status code device . @return Always return EFI_SUCCESS. **/ EFI_STATUS EFIAPI OemHookStatusCodeInitialize ( VOID ) { PEI_NT_THUNK_PPI *NtThunkPpi; EFI_STATUS Status; // // Locate NtThunkPpi for retrieving standard output handle // Status = PeiServicesLocatePpi ( &gPeiNtThunkPpiGuid, 0, NULL, (VOID **) &NtThunkPpi ); ASSERT_EFI_ERROR (Status); mWinNt = (EFI_WIN_NT_THUNK_PROTOCOL *) NtThunkPpi->NtThunk (); // // Cache standard output handle. // mStdOut = mWinNt->GetStdHandle (STD_OUTPUT_HANDLE); return EFI_SUCCESS; }
/** Write data from buffer to serial device. Writes NumberOfBytes data bytes from Buffer to the serial device. The number of bytes actually written to the serial device is returned. If the return value is less than NumberOfBytes, then the write operation failed. If Buffer is NULL, then ASSERT(). If NumberOfBytes is zero, then return 0. @param Buffer The pointer to the data buffer to be written. @param NumberOfBytes The number of bytes to written to the serial device. @retval 0 NumberOfBytes is 0. @retval >0 The number of bytes written to the serial device. If this value is less than NumberOfBytes, then the read operation failed. **/ UINTN EFIAPI SerialPortWrite ( IN UINT8 *Buffer, IN UINTN NumberOfBytes ) { EMU_THUNK_PPI *ThunkPpi; EFI_STATUS Status; EMU_THUNK_PROTOCOL *Thunk; // // Locate EmuThunkPpi for retrieving standard output handle // Status = PeiServicesLocatePpi ( &gEmuThunkPpiGuid, 0, NULL, (VOID **) &ThunkPpi ); if (!EFI_ERROR (Status)) { Thunk = (EMU_THUNK_PROTOCOL *)ThunkPpi->Thunk (); return Thunk->WriteStdErr (Buffer, NumberOfBytes); } return 0; }
/** Worker function to retrieve the number of logical processor in the platform. @param[out] NumberOfCpus Pointer to the total number of logical processors in the system, including the BSP and disabled APs. @param[out] NumberOfEnabledProcessors Pointer to the number of enabled logical processors that exist in system, including the BSP. **/ VOID GetNumberOfProcessor ( OUT UINTN *NumberOfCpus, OUT UINTN *NumberOfEnabledProcessors ) { EFI_STATUS Status; EFI_PEI_MP_SERVICES_PPI *CpuMpPpi; // // Get MP Services Protocol // Status = PeiServicesLocatePpi ( &gEfiPeiMpServicesPpiGuid, 0, NULL, (VOID **)&CpuMpPpi ); ASSERT_EFI_ERROR (Status); // // Get the number of CPUs // Status = CpuMpPpi->GetNumberOfProcessors ( GetPeiServicesTablePointer (), CpuMpPpi, NumberOfCpus, NumberOfEnabledProcessors ); ASSERT_EFI_ERROR (Status); }
/** Worker function to execute a caller provided function on all enabled APs. @param[in] Procedure A pointer to the function to be run on enabled APs of the system. **/ VOID StartupAPsWorker ( IN EFI_AP_PROCEDURE Procedure ) { EFI_STATUS Status; EFI_PEI_MP_SERVICES_PPI *CpuMpPpi; // // Get MP Services Protocol // Status = PeiServicesLocatePpi ( &gEfiPeiMpServicesPpiGuid, 0, NULL, (VOID **)&CpuMpPpi ); ASSERT_EFI_ERROR (Status); // // Wakeup all APs for data collection. // Status = CpuMpPpi->StartupAllAPs ( GetPeiServicesTablePointer (), CpuMpPpi, Procedure, FALSE, 0, NULL ); ASSERT_EFI_ERROR (Status); }
/** The function caches the pointer of the Unix thunk functions It will ASSERT() if Unix thunk ppi is not installed. @retval EFI_SUCCESS WinNT thunk protocol is found and cached. **/ EFI_STATUS EFIAPI UnixPeCoffGetUnixThunkStucture ( ) { PEI_UNIX_THUNK_PPI *UnixThunkPpi; EFI_STATUS Status; // // Locate Unix ThunkPpi for retrieving standard output handle // Status = PeiServicesLocatePpi ( &gPeiUnixThunkPpiGuid, 0, NULL, (VOID **) &UnixThunkPpi ); ASSERT_EFI_ERROR (Status); mUnix = (EFI_UNIX_THUNK_PROTOCOL *) UnixThunkPpi->UnixThunk (); return EFI_SUCCESS; }
/** FSP notify phase PEI module entry point @param[in] FileHandle Not used. @param[in] PeiServices General purpose services available to every PEIM. @retval EFI_SUCCESS The function completes successfully @retval EFI_OUT_OF_RESOURCES Insufficient resources to create database **/ EFI_STATUS FspNotifyPhasePeimEntryPoint ( IN EFI_PEI_FILE_HANDLE FileHandle, IN CONST EFI_PEI_SERVICES **PeiServices ) { EFI_STATUS Status; VOID *OldDxeIplPpi; EFI_PEI_PPI_DESCRIPTOR *OldDescriptor; DEBUG ((DEBUG_INFO | DEBUG_INIT, "The entry of FspNotificationPeim\n")); // // Locate old DXE IPL PPI // Status = PeiServicesLocatePpi ( &gEfiDxeIplPpiGuid, 0, &OldDescriptor, &OldDxeIplPpi ); ASSERT_EFI_ERROR (Status); // // Re-install the DXE IPL PPI to wait for notify // Status = PeiServicesReInstallPpi (OldDescriptor, &mInstallDxeIplPpi); ASSERT_EFI_ERROR (Status); return EFI_SUCCESS; }
/** Core version of the Reset System @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. @retval EFI_NOT_AVAILABLE_YET PPI not available yet. @retval EFI_DEVICE_ERROR Did not reset system. Otherwise, resets the system. **/ EFI_STATUS EFIAPI PeiResetSystem ( IN CONST EFI_PEI_SERVICES **PeiServices ) { EFI_STATUS Status; EFI_PEI_RESET_PPI *ResetPpi; Status = PeiServicesLocatePpi ( &gEfiPeiResetPpiGuid, 0, NULL, (VOID **)&ResetPpi ); // // LocatePpi returns EFI_NOT_FOUND on error // if (!EFI_ERROR (Status)) { return ResetPpi->ResetSystem (PeiServices); } // // Report Status Code that Reset PPI is not available // REPORT_STATUS_CODE ( EFI_ERROR_CODE | EFI_ERROR_MINOR, (EFI_SOFTWARE_PEI_CORE | EFI_SW_PS_EC_RESET_NOT_AVAILABLE) ); return EFI_NOT_AVAILABLE_YET; }
/** Do measurement after memory is ready. @param[in] PeiServices Describes the list of possible PEI Services. @retval EFI_SUCCESS Operation completed successfully. @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event. @retval EFI_DEVICE_ERROR The command was unsuccessful. **/ EFI_STATUS PeimEntryMP ( IN EFI_PEI_SERVICES **PeiServices ) { EFI_STATUS Status; Status = PeiServicesLocatePpi ( &gEfiPeiFirmwareVolumeInfoMeasurementExcludedPpiGuid, 0, NULL, (VOID**)&mMeasurementExcludedFvPpi ); // Do not check status, because it is optional if (PcdGet8 (PcdTpm2ScrtmPolicy) == 1) { Status = MeasureCRTMVersion (); ASSERT_EFI_ERROR (Status); } Status = MeasureMainBios (); // // Post callbacks: // for the FvInfoPpi services to measure and record // the additional Fvs to TPM // Status = PeiServicesNotifyPpi (&mNotifyList[0]); ASSERT_EFI_ERROR (Status); return Status; }
/** Worker function to switch the requested AP to be the BSP from that point onward. @param[in] ProcessorNumber The handle number of AP that is to become the new BSP. **/ VOID SwitchNewBsp ( IN UINTN ProcessorNumber ) { EFI_STATUS Status; EFI_PEI_MP_SERVICES_PPI *CpuMpPpi; // // Get MP Services Protocol // Status = PeiServicesLocatePpi ( &gEfiPeiMpServicesPpiGuid, 0, NULL, (VOID **)&CpuMpPpi ); ASSERT_EFI_ERROR (Status); // // Wakeup all APs for data collection. // Status = CpuMpPpi->SwitchBSP ( GetPeiServicesTablePointer (), CpuMpPpi, ProcessorNumber, TRUE ); ASSERT_EFI_ERROR (Status); }
/** Internal worker function to read a PCI configuration register. This function wraps EFI_PEI_PCI_CFG2_PPI.Read() service. It reads and returns the PCI configuration register specified by Address, the width of data is specified by Width. @param Address The address that encodes the PCI Bus, Device, Function and Register. @param Width The width of data to read @return The value read from the PCI configuration register. **/ UINT32 PeiPciLibPciCfg2ReadWorker ( IN UINTN Address, IN EFI_PEI_PCI_CFG_PPI_WIDTH Width ) { EFI_STATUS Status; UINT32 Data; CONST EFI_PEI_PCI_CFG2_PPI *PciCfg2Ppi; UINT64 PciCfg2Address; Status = PeiServicesLocatePpi (&gEfiPciCfg2PpiGuid, 0, NULL, (VOID **) &PciCfg2Ppi); ASSERT_EFI_ERROR (Status); ASSERT (PciCfg2Ppi != NULL); PciCfg2Address = PCI_TO_PCICFG2_ADDRESS (Address); PciCfg2Ppi->Read ( GetPeiServicesTablePointer (), PciCfg2Ppi, Width, PciCfg2Address, &Data ); return Data; }
/** Gets PCI CFG2 PPI. This internal function retrieves PCI CFG2 PPI from PPI database. @param Address The address that encodes the PCI Segment, Bus, Device, Function and Register. @return The pointer to PCI CFG2 PPI. **/ EFI_PEI_PCI_CFG2_PPI * InternalGetPciCfg2Ppi ( IN UINT64 Address ) { EFI_STATUS Status; UINTN Instance; EFI_PEI_PCI_CFG2_PPI *PciCfg2Ppi; UINT64 SegmentNumber; Instance = 0; PciCfg2Ppi = NULL; SegmentNumber = BitFieldRead64 (Address, 32, 63); // // Loop through all instances of the PPI and match segment number // do { Status = PeiServicesLocatePpi( &gEfiPciCfg2PpiGuid, Instance, NULL, (VOID**) &PciCfg2Ppi ); ASSERT_EFI_ERROR (Status); Instance++; } while (PciCfg2Ppi->Segment != SegmentNumber); return PciCfg2Ppi; }
/** Wrap the call to PI's EFI_PEI_LOAD_FILE_PPI. @param This A pointer to EFI_PEI_FV_FILE_LOADER_PPI. @param FfsHeader The pointer to the file header to be loaded by the Pe/Coff loader. @param ImageAddress The loaded address of the Image. @param ImageSize Pointer to the size of the loaded image. @param EntryPoint Pointer to the entry point of the image. @retval EFI_SUCCESS The image was loaded successfully. @retval EFI_OUT_OF_RESOURCE There was not enought memory. @retval EFI_INVALID_PARAMETER The contents of the FFS file did not contain a valid PE/COFF image that could be loaded. **/ EFI_STATUS EFIAPI FrameworkLoadFile ( IN EFI_PEI_FV_FILE_LOADER_PPI *This, IN EFI_FFS_FILE_HEADER *FfsHeader, OUT EFI_PHYSICAL_ADDRESS *ImageAddress, OUT UINT64 *ImageSize, OUT EFI_PHYSICAL_ADDRESS *EntryPoint ) { EFI_STATUS Status; EFI_PEI_LOAD_FILE_PPI *PiLoadFile; UINT32 AuthenticationState; Status = PeiServicesLocatePpi ( &gEfiPeiLoadFilePpiGuid, 0, NULL, (VOID **) &PiLoadFile ); ASSERT_EFI_ERROR (Status); return PiLoadFile->LoadFile ( PiLoadFile, (EFI_PEI_FILE_HANDLE) FfsHeader, ImageAddress, ImageSize, EntryPoint, &AuthenticationState ); }
/** Measure and record the Firmware Volum Information once FvInfoPPI install. @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. @param[in] NotifyDescriptor Address of the notification descriptor data structure. @param[in] Ppi Address of the PPI that was installed. @retval EFI_SUCCESS The FV Info is measured and recorded to TPM. @return Others Fail to measure FV. **/ EFI_STATUS EFIAPI FirmwareVolmeInfoPpiNotifyCallback ( IN EFI_PEI_SERVICES **PeiServices, IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, IN VOID *Ppi ) { EFI_PEI_FIRMWARE_VOLUME_INFO_PPI *Fv; EFI_STATUS Status; EFI_PEI_FIRMWARE_VOLUME_PPI *FvPpi; UINTN Index; Fv = (EFI_PEI_FIRMWARE_VOLUME_INFO_PPI *) Ppi; // // The PEI Core can not dispatch or load files from memory mapped FVs that do not support FvPpi. // Status = PeiServicesLocatePpi ( &Fv->FvFormat, 0, NULL, (VOID**)&FvPpi ); if (EFI_ERROR (Status)) { return EFI_SUCCESS; } // // This is an FV from an FFS file, and the parent FV must have already been measured, // No need to measure twice, so just record the FV and return // if (Fv->ParentFvName != NULL || Fv->ParentFileName != NULL ) { if (mMeasuredChildFvIndex >= mMeasuredMaxChildFvIndex) { mMeasuredChildFvInfo = ReallocatePool ( sizeof (EFI_PLATFORM_FIRMWARE_BLOB) * mMeasuredMaxChildFvIndex, sizeof (EFI_PLATFORM_FIRMWARE_BLOB) * (mMeasuredMaxChildFvIndex + FIRMWARE_BLOB_GROWTH_STEP), mMeasuredChildFvInfo ); ASSERT (mMeasuredChildFvInfo != NULL); mMeasuredMaxChildFvIndex = mMeasuredMaxChildFvIndex + FIRMWARE_BLOB_GROWTH_STEP; } // // Check whether FV is in the measured child FV list. // for (Index = 0; Index < mMeasuredChildFvIndex; Index++) { if (mMeasuredChildFvInfo[Index].BlobBase == (EFI_PHYSICAL_ADDRESS) (UINTN) Fv->FvInfo) { return EFI_SUCCESS; } } mMeasuredChildFvInfo[mMeasuredChildFvIndex].BlobBase = (EFI_PHYSICAL_ADDRESS) (UINTN) Fv->FvInfo; mMeasuredChildFvInfo[mMeasuredChildFvIndex].BlobLength = Fv->FvInfoSize; mMeasuredChildFvIndex++; return EFI_SUCCESS; } return MeasureFvImage ((EFI_PHYSICAL_ADDRESS) (UINTN) Fv->FvInfo, Fv->FvInfoSize); }
/** Worker function to get CPUs' BIST by calling SecPlatformInformationPpi or SecPlatformInformation2Ppi. @param PeiServices Pointer to PEI Services Table @param Guid PPI Guid @param PpiDescriptor Return a pointer to instance of the EFI_PEI_PPI_DESCRIPTOR @param BistInformationData Pointer to BIST information data @retval EFI_SUCCESS Retrieve of the BIST data successfully @retval EFI_NOT_FOUND No sec platform information(2) ppi export @retval EFI_DEVICE_ERROR Failed to get CPU Information **/ EFI_STATUS GetBistInfoFromPpi ( IN CONST EFI_PEI_SERVICES **PeiServices, IN CONST EFI_GUID *Guid, OUT EFI_PEI_PPI_DESCRIPTOR **PpiDescriptor, OUT VOID **BistInformationData ) { EFI_STATUS Status; EFI_SEC_PLATFORM_INFORMATION2_PPI *SecPlatformInformation2Ppi; EFI_SEC_PLATFORM_INFORMATION_RECORD2 *SecPlatformInformation2; UINT64 InformationSize; Status = PeiServicesLocatePpi ( Guid, // GUID 0, // INSTANCE PpiDescriptor, // EFI_PEI_PPI_DESCRIPTOR (VOID **)&SecPlatformInformation2Ppi // PPI ); if (Status == EFI_NOT_FOUND) { return EFI_NOT_FOUND; } if (Status == EFI_SUCCESS) { // // Get the size of the sec platform information2(BSP/APs' BIST data) // InformationSize = 0; SecPlatformInformation2 = NULL; Status = SecPlatformInformation2Ppi->PlatformInformation2 ( PeiServices, &InformationSize, SecPlatformInformation2 ); if (Status == EFI_BUFFER_TOO_SMALL) { Status = PeiServicesAllocatePool ( (UINTN) InformationSize, (VOID **) &SecPlatformInformation2 ); if (Status == EFI_SUCCESS) { // // Retrieve BIST data // Status = SecPlatformInformation2Ppi->PlatformInformation2 ( PeiServices, &InformationSize, SecPlatformInformation2 ); if (Status == EFI_SUCCESS) { *BistInformationData = SecPlatformInformation2; return EFI_SUCCESS; } } } } return EFI_DEVICE_ERROR; }
RETURN_STATUS EFIAPI PeCoffLoaderGetEntryPoint ( IN VOID *Pe32Data, IN OUT VOID **EntryPoint ) /*++ Routine Description: Loads a PE/COFF image into memory, this is not follow the original purpose of PeCoffGetEntryPoint library class. But it's ok that Unix package not run on a real platform and this is for source level debug. Arguments: Pe32Data - Pointer to a PE/COFF Image EntryPoint - Pointer to the entry point of the PE/COFF image Returns: EFI_SUCCESS if the EntryPoint was returned EFI_INVALID_PARAMETER if the EntryPoint could not be found from Pe32Data --*/ { EFI_STATUS Status; EFI_PEI_PPI_DESCRIPTOR *PpiDescriptor; NT_PEI_LOAD_FILE_PPI *PeiNtService; EFI_PHYSICAL_ADDRESS ImageAddress; UINT64 ImageSize; EFI_PHYSICAL_ADDRESS ImageEntryPoint; ASSERT (Pe32Data != NULL); ASSERT (EntryPoint != NULL); Status = PeiServicesLocatePpi ( &gNtPeiLoadFilePpiGuid, 0, &PpiDescriptor, (VOID**)&PeiNtService ); ASSERT_EFI_ERROR (Status); Status = PeiNtService->PeiLoadFileService ( Pe32Data, &ImageAddress, &ImageSize, &ImageEntryPoint ); if (EFI_ERROR (Status)) { return Status; } *EntryPoint = (VOID*)(UINTN)ImageEntryPoint; return Status; }
EFI_STATUS EFIAPI PeimInitializeFlashMap ( IN EFI_FFS_FILE_HEADER *FfsHeader, IN EFI_PEI_SERVICES **PeiServices ) /*++ Routine Description: Build GUIDed HOBs for platform specific flash map Arguments: FfsHeader - A pointer to the EFI_FFS_FILE_HEADER structure. PeiServices - General purpose services available to every PEIM. Returns: EFI_STATUS --*/ // TODO: EFI_SUCCESS - add return value to function comment { EFI_STATUS Status; NT_FWH_PPI *NtFwhPpi; EFI_PHYSICAL_ADDRESS FdBase; UINT64 FdSize; EFI_PEI_PPI_DESCRIPTOR *PpiDescriptor; DEBUG ((EFI_D_ERROR, "NT 32 Flash Map PEIM Loaded\n")); // // Get the Fwh Information PPI // Status = PeiServicesLocatePpi ( &gNtFwhPpiGuid, // GUID 0, // INSTANCE &PpiDescriptor, // EFI_PEI_PPI_DESCRIPTOR (VOID**)&NtFwhPpi // PPI ); ASSERT_EFI_ERROR (Status); // // Assume that FD0 contains the Flash map. // Status = NtFwhPpi->NtFwh (0, &FdBase, &FdSize); if (EFI_ERROR (Status)) { return Status; } // // Relocate the base of FV region // PcdSet32 (PcdFlashNvStorageVariableBase, PcdGet32 (PcdWinNtFlashNvStorageVariableBase) + (UINT32) FdBase); PcdSet32 (PcdFlashNvStorageFtwWorkingBase, PcdGet32 (PcdWinNtFlashNvStorageFtwWorkingBase) + (UINT32) FdBase); PcdSet32 (PcdFlashNvStorageFtwSpareBase, PcdGet32 (PcdWinNtFlashNvStorageFtwSpareBase) + (UINT32) FdBase); return EFI_SUCCESS; }
/** Publish Memory Type Information. @param None @retval EFI_SUCCESS Success. @retval Others Errors have occurred. **/ EFI_STATUS EFIAPI PublishMemoryTypeInfo ( void ) { EFI_STATUS Status; EFI_PEI_READ_ONLY_VARIABLE2_PPI *Variable; UINTN DataSize; EFI_MEMORY_TYPE_INFORMATION MemoryData[EfiMaxMemoryType + 1]; Status = PeiServicesLocatePpi ( &gEfiPeiReadOnlyVariable2PpiGuid, 0, NULL, &Variable ); if (EFI_ERROR (Status)) { DEBUG((EFI_D_ERROR, "WARNING: Locating Pei variable failed 0x%x \n", Status)); DEBUG((EFI_D_ERROR, "Build Hob from default\n")); // // Build the default GUID'd HOB for DXE // BuildGuidDataHob (&gEfiMemoryTypeInformationGuid, mDefaultMemoryTypeInformation, sizeof (mDefaultMemoryTypeInformation) ); return Status; } DataSize = sizeof (MemoryData); // // This variable is saved in BDS stage. Now read it back // Status = Variable->GetVariable ( Variable, EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME, &gEfiMemoryTypeInformationGuid, NULL, &DataSize, &MemoryData ); if (EFI_ERROR (Status)) { // // build default // DEBUG((EFI_D_ERROR, "Build Hob from default\n")); BuildGuidDataHob (&gEfiMemoryTypeInformationGuid, mDefaultMemoryTypeInformation, sizeof (mDefaultMemoryTypeInformation) ); } else { // // Build the GUID'd HOB for DXE from variable // DEBUG((EFI_D_ERROR, "Build Hob from variable \n")); BuildGuidDataHob (&gEfiMemoryTypeInformationGuid, MemoryData, DataSize); } return Status; }
/** This is the entrypoint of PEIM @param[in] FileHandle Handle of the file being invoked. @param[in] PeiServices Describes the list of possible PEI Services. @retval EFI_SUCCESS if it completed successfully. **/ EFI_STATUS EFIAPI 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; }
EFI_STATUS EFIAPI PeimInitializeFlashMap ( IN EFI_PEI_FILE_HANDLE FileHandle, IN CONST EFI_PEI_SERVICES **PeiServices ) /*++ Routine Description: Build GUIDed HOBs for platform specific flash map Arguments: FfsHeader - A pointer to the EFI_FFS_FILE_HEADER structure. PeiServices - General purpose services available to every PEIM. Returns: EFI_STATUS **/ { EFI_STATUS Status; EMU_THUNK_PPI *Thunk; EFI_PEI_PPI_DESCRIPTOR *PpiDescriptor; EFI_PHYSICAL_ADDRESS FdBase; EFI_PHYSICAL_ADDRESS FdFixUp; UINT64 FdSize; DEBUG ((EFI_D_ERROR, "EmulatorPkg Flash Map PEIM Loaded\n")); // // Get the Fwh Information PPI // Status = PeiServicesLocatePpi ( &gEmuThunkPpiGuid, // GUID 0, // INSTANCE &PpiDescriptor, // EFI_PEI_PPI_DESCRIPTOR (VOID **)&Thunk // PPI ); ASSERT_EFI_ERROR (Status); // // Assume that FD0 contains the Flash map. // Status = Thunk->FirmwareDevices (0, &FdBase, &FdSize, &FdFixUp); if (EFI_ERROR (Status)) { return Status; } PcdSet64 (PcdFlashNvStorageVariableBase64, PcdGet64 (PcdEmuFlashNvStorageVariableBase) + FdFixUp); PcdSet64 (PcdFlashNvStorageFtwWorkingBase64, PcdGet64 (PcdEmuFlashNvStorageFtwWorkingBase) + FdFixUp); PcdSet64 (PcdFlashNvStorageFtwSpareBase64, PcdGet64 (PcdEmuFlashNvStorageFtwSpareBase) + FdFixUp); return EFI_SUCCESS; }
/** Initialize IOMMU. **/ VOID IoMmuInit ( VOID ) { PeiServicesLocatePpi ( &gEdkiiIoMmuPpiGuid, 0, NULL, (VOID **)&mIoMmu ); }
/** This interface returns whether TPM physical presence needs be locked or not. @param[in] PeiServices The pointer to the PEI Services Table. @retval TRUE The TPM physical presence should be locked. @retval FALSE The TPM physical presence cannot be locked. **/ BOOLEAN EFIAPI LockTpmPhysicalPresence ( IN CONST EFI_PEI_SERVICES **PeiServices ) { EFI_STATUS Status; EFI_PEI_READ_ONLY_VARIABLE2_PPI *Variable; UINTN DataSize; EFI_PHYSICAL_PRESENCE TcgPpData; // // The CRTM has sensed the physical presence assertion of the user. For example, // the user has pressed the startup button or inserted a USB dongle. The details // of the implementation are vendor-specific. Here we read a PCD value to indicate // whether operator physical presence. // if (!PcdGetBool (PcdTpmPhysicalPresence)) { return TRUE; } // // Check the pending TPM requests. Lock TPM physical presence if there is no TPM // request. // Status = PeiServicesLocatePpi ( &gEfiPeiReadOnlyVariable2PpiGuid, 0, NULL, (VOID **)&Variable ); if (!EFI_ERROR (Status)) { DataSize = sizeof (EFI_PHYSICAL_PRESENCE); Status = Variable->GetVariable ( Variable, PHYSICAL_PRESENCE_VARIABLE, &gEfiPhysicalPresenceGuid, NULL, &DataSize, &TcgPpData ); if (!EFI_ERROR (Status)) { if (TcgPpData.PPRequest != 0) { return FALSE; } } } // // Lock TPM physical presence by default. // return TRUE; }
/** Retrieve the pointer of EFI_PEI_PCD_PPI defined in PI 1.2 Vol 3. This function is to locate EFI_PEI_PCD_PPI PPI via PeiService. If fail to locate EFI_PEI_PCD_PPI, then ASSERT_EFI_ERROR(). @retval EFI_PEI_PCD_PPI * The pointer to the EFI_PEI_PCD_PPI. **/ EFI_PEI_PCD_PPI * GetPiPcdPpiPointer ( VOID ) { EFI_STATUS Status; EFI_PEI_PCD_PPI *PiPcdPpi; Status = PeiServicesLocatePpi (&gEfiPeiPcdPpiGuid, 0, NULL, (VOID **)&PiPcdPpi); ASSERT_EFI_ERROR (Status); return PiPcdPpi; }
/** Retrieve the GET_PCD_INFO_PPI pointer. This function is to locate GET_PCD_INFO_PPI PPI via PeiService. If fail to locate GET_PCD_INFO_PPI, then ASSERT_EFI_ERROR(). @retval GET_PCD_INFO_PPI * The pointer to the GET_PCD_INFO_PPI. **/ GET_PCD_INFO_PPI * GetPcdInfoPpiPointer ( VOID ) { EFI_STATUS Status; GET_PCD_INFO_PPI *PcdInfoPpi; Status = PeiServicesLocatePpi (&gGetPcdInfoPpiGuid, 0, NULL, (VOID **)&PcdInfoPpi); ASSERT_EFI_ERROR (Status); return PcdInfoPpi; }
/** Do FSP initialization based on FspApi version 1. @param[in] FspHeader FSP header pointer. @return FSP initialization status. **/ EFI_STATUS PeiFspInitV1 ( IN FSP_INFO_HEADER *FspHeader ) { EFI_STATUS Status; FSP_INIT_DONE_PPI *FspInitDone; VOID *FspHobList; EFI_BOOT_MODE BootMode; Status = PeiServicesLocatePpi ( &gFspInitDonePpiGuid, 0, NULL, (VOID **) &FspInitDone ); if (EFI_ERROR (Status)) { // // 1st entry // DEBUG ((DEBUG_INFO, "1st entry\n")); PeiFspInit (FspHeader); // // Never return here, for FspApi version 1. // CpuDeadLoop (); } else { // // 2nd entry for FspApi version 1 only. // DEBUG ((DEBUG_INFO, "2nd entry\n")); Status = FspInitDone->GetFspHobList (GetPeiServicesTablePointer (), FspInitDone, &FspHobList); ASSERT_EFI_ERROR (Status); DEBUG ((DEBUG_INFO, "FspHobList - 0x%x\n", FspHobList)); FspHobProcess (FspHobList); // // Register EndOfPei Notify for S3 to run FspNotifyPhase // PeiServicesGetBootMode (&BootMode); if (BootMode == BOOT_ON_S3_RESUME) { Status = PeiServicesNotifyPpi (&mS3EndOfPeiNotifyDesc); ASSERT_EFI_ERROR (Status); } } return EFI_SUCCESS; }
/** Gets Smbus PPIs. This internal function retrieves Smbus PPI from PPI database. @param VOID @return The pointer to Smbus PPI. **/ EFI_PEI_SMBUS2_PPI * InternalGetSmbusPpi ( VOID ) { EFI_STATUS Status; EFI_PEI_SMBUS2_PPI *SmbusPpi; Status = PeiServicesLocatePpi (&gEfiPeiSmbus2PpiGuid, 0, NULL, (VOID **) &SmbusPpi); ASSERT_EFI_ERROR (Status); ASSERT (SmbusPpi != NULL); return SmbusPpi; }
EFI_STATUS EFIAPI BoardDetectionCallback ( IN CONST EFI_PEI_SERVICES **PeiServices, IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, IN VOID *Ppi ) { EFI_STATUS Status; VOID *Instance; DEBUG ((EFI_D_INFO, "Detecting Galileo ...\n")); // // Check if board detection is finished. // Status = PeiServicesLocatePpi ( &gBoardDetectedPpiGuid, 0, NULL, &Instance ); if (!EFI_ERROR(Status)) { return EFI_SUCCESS; } // // In most real platform, here should be the code to detect board type. // // For galileo, we only support build time board selection, so use PCD to do the fake detection. // if (PcdGet16(PcdPlatformType) != Galileo) { return EFI_UNSUPPORTED; } DEBUG ((EFI_D_INFO, "Detected Galileo!\n")); Status = PcdSet64S (PcdBoardInitPreMem, (UINT64)(UINTN)BoarInitPreMem); ASSERT_EFI_ERROR(Status); Status = PcdSet64S (PcdBoardInitPostMem, (UINT64)(UINTN)BoarInitPostMem); ASSERT_EFI_ERROR(Status); Status = PcdSet32S (PcdPciExpPerstResumeWellGpio, PCIEXP_PERST_RESUMEWELL_GPIO); ASSERT_EFI_ERROR(Status); Status = PcdSet32S (PcdFlashUpdateLedResumeWellGpio, GALILEO_FLASH_UPDATE_LED_RESUMEWELL_GPIO); ASSERT_EFI_ERROR(Status); Status = PeiServicesInstallPpi(&mDetectedPpi); ASSERT_EFI_ERROR(Status); return Status; }
/** The constructor function caches the pointer to PEI services. The constructor function caches the pointer to PEI services. It will always return EFI_SUCCESS. @param FfsHeader Pointer to FFS header the loaded driver. @param PeiServices Pointer to the PEI services. @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS. **/ EFI_STATUS EFIAPI Tpm2DeviceLibConstructor ( VOID ) { EFI_STATUS Status = EFI_SUCCESS; Status = PeiServicesLocatePpi (&gPttPassThruPpiGuid, 0, NULL, (VOID **) &SecPttPassThruPpi); if (EFI_ERROR (Status)) { // Locate the PPI failed SecPttPassThruPpi = NULL; } return Status; }
/** The function is provided by PCD PEIM and PCD DXE driver to do the work of reading a HII variable from variable service. @param VariableGuid The Variable GUID. @param VariableName The Variable Name. @param VariableData The output data. @param VariableSize The size of the variable. @retval EFI_SUCCESS Operation successful. @retval EFI_NOT_FOUND Variablel not found. **/ EFI_STATUS GetHiiVariable ( IN CONST EFI_GUID *VariableGuid, IN UINT16 *VariableName, OUT VOID **VariableData, OUT UINTN *VariableSize ) { UINTN Size; EFI_STATUS Status; VOID *Buffer; EFI_PEI_READ_ONLY_VARIABLE2_PPI *VariablePpi; Status = PeiServicesLocatePpi (&gEfiPeiReadOnlyVariable2PpiGuid, 0, NULL, (VOID **) &VariablePpi); ASSERT_EFI_ERROR (Status); Size = 0; Status = VariablePpi->GetVariable ( VariablePpi, VariableName, (EFI_GUID *) VariableGuid, NULL, &Size, NULL ); if (Status == EFI_BUFFER_TOO_SMALL) { Status = PeiServicesAllocatePool (Size, &Buffer); ASSERT_EFI_ERROR (Status); Status = VariablePpi->GetVariable ( VariablePpi, (UINT16 *) VariableName, (EFI_GUID *) VariableGuid, NULL, &Size, Buffer ); ASSERT_EFI_ERROR (Status); *VariableSize = Size; *VariableData = Buffer; return EFI_SUCCESS; } return EFI_NOT_FOUND; }