/** 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 ) { VOID *Hob; VTD_INFO *VTdInfo; UINT64 EngineMask; DEBUG((DEBUG_INFO, "VTdPmr S3EndOfPeiNotify\n")); if ((PcdGet8(PcdVTdPolicyPropertyMask) & BIT1) == 0) { Hob = GetFirstGuidHob (&mVTdInfoGuid); if (Hob == NULL) { return EFI_SUCCESS; } VTdInfo = GET_GUID_HOB_DATA(Hob); EngineMask = LShiftU64 (1, VTdInfo->VTdEngineCount) - 1; DisableDmaProtection (VTdInfo, EngineMask); } return EFI_SUCCESS; }
/** Initializes the Intel VTd PMR for DMA buffer. @retval EFI_SUCCESS Usb bot driver is successfully initialized. @retval EFI_OUT_OF_RESOURCES Can't initialize the driver. **/ EFI_STATUS InitVTdPmrForDma ( VOID ) { EFI_STATUS Status; VOID *Hob; VTD_INFO *VTdInfo; Hob = GetFirstGuidHob (&mVTdInfoGuid); VTdInfo = GET_GUID_HOB_DATA(Hob); // // If there is RMRR memory, parse it here. // ParseDmarAcpiTableRmrr (VTdInfo); // // Allocate a range in PEI memory as DMA buffer // Mark others to be DMA protected. // Status = InitDmaProtection (VTdInfo); return Status; }
/** Initializes the Intel VTd PMR for all memory. @retval EFI_SUCCESS Usb bot driver is successfully initialized. @retval EFI_OUT_OF_RESOURCES Can't initialize the driver. **/ EFI_STATUS InitVTdPmrForAll ( VOID ) { EFI_STATUS Status; VOID *Hob; VTD_INFO *VTdInfo; UINTN LowBottom; UINTN LowTop; UINTN HighBottom; UINT64 HighTop; Hob = GetFirstGuidHob (&mVTdInfoGuid); VTdInfo = GET_GUID_HOB_DATA(Hob); LowBottom = 0; LowTop = 0; HighBottom = 0; HighTop = LShiftU64 (1, VTdInfo->HostAddressWidth + 1); Status = SetDmaProtectedRange ( VTdInfo, VTdInfo->EngineMask, (UINT32)LowBottom, (UINT32)(LowTop - LowBottom), HighBottom, HighTop - HighBottom ); return Status; }
/** Frees memory that was allocated with AllocateBuffer(). @param This The PPI instance pointer. @param Pages The number of pages to free. @param HostAddress The base system memory address of the allocated range. @retval EFI_SUCCESS The requested memory pages were freed. @retval EFI_INVALID_PARAMETER The memory range specified by HostAddress and Pages was not allocated with AllocateBuffer(). @retval EFI_NOT_AVAILABLE_YET DMA protection has been enabled, but DMA buffer are not available to be allocated yet. **/ EFI_STATUS EFIAPI PeiIoMmuFreeBuffer ( IN EDKII_IOMMU_PPI *This, IN UINTN Pages, IN VOID *HostAddress ) { UINTN Length; VOID *Hob; DMA_BUFFER_INFO *DmaBufferInfo; Hob = GetFirstGuidHob (&mDmaBufferInfoGuid); DmaBufferInfo = GET_GUID_HOB_DATA(Hob); DEBUG ((DEBUG_VERBOSE, "PeiIoMmuFreeBuffer - page - %x, HostAddr - %x\n", Pages, HostAddress)); DEBUG ((DEBUG_VERBOSE, " DmaBufferCurrentTop - %x\n", DmaBufferInfo->DmaBufferCurrentTop)); DEBUG ((DEBUG_VERBOSE, " DmaBufferCurrentBottom - %x\n", DmaBufferInfo->DmaBufferCurrentBottom)); if (DmaBufferInfo->DmaBufferCurrentTop == 0) { return EFI_NOT_AVAILABLE_YET; } Length = EFI_PAGES_TO_SIZE(Pages); if ((UINTN)HostAddress == DmaBufferInfo->DmaBufferCurrentTop) { DmaBufferInfo->DmaBufferCurrentTop += Length; } return EFI_SUCCESS; }
/** This is the entrypoint of PEIM @param FileHandle Handle of the file being invoked. @param PeiServices Describes the list of possible PEI Services. @retval EFI_SUCCESS if it completed successfully. **/ EFI_STATUS EFIAPI PeiInitPlatform ( IN EFI_PEI_FILE_HANDLE FileHandle, IN CONST EFI_PEI_SERVICES **PeiServices ) { EFI_STATUS Status; EFI_BOOT_MODE BootMode; EFI_PEI_STALL_PPI *StallPpi; EFI_PEI_PPI_DESCRIPTOR *StallPeiPpiDescriptor; EFI_FV_FILE_INFO FileInfo; EFI_PLATFORM_INFO *PlatformInfo; EFI_HOB_GUID_TYPE *GuidHob; EFI_PLATFORM_TYPE PlatformType; GuidHob = GetFirstGuidHob (&gEfiPlatformInfoGuid); PlatformInfo = GET_GUID_HOB_DATA (GuidHob); ASSERT (PlatformInfo != NULL); PlatformType = (EFI_PLATFORM_TYPE) PlatformInfo->Type; // // Initialize Firmware Volume security. // This must be done before any firmware volume accesses (excl. BFV) // Status = PeiInitializeFvSecurity(); ASSERT_EFI_ERROR (Status); // // Allocate an initial buffer from heap for debugger use // DEBUG_CODE ( BpeDsAllocation (); );
/** Worker function to parse CPU BIST information from Guided HOB. @param[out] StructureSize Pointer to the variable describing size of the input buffer. @param[out] StructureBuffer Pointer to the buffer save CPU BIST information. @retval EFI_SUCCESS The data was successfully returned. @retval EFI_BUFFER_TOO_SMALL The buffer was too small. **/ EFI_STATUS GetBistFromHob ( IN OUT UINT64 *StructureSize, IN OUT VOID *StructureBuffer ) { EFI_HOB_GUID_TYPE *GuidHob; VOID *DataInHob; UINTN DataSize; GuidHob = GetFirstGuidHob (&gEfiCallerIdGuid); if (GuidHob == NULL) { *StructureSize = 0; return EFI_SUCCESS; } DataInHob = GET_GUID_HOB_DATA (GuidHob); DataSize = GET_GUID_HOB_DATA_SIZE (GuidHob); // // return the information from BistHob // if ((*StructureSize) < (UINT64) DataSize) { *StructureSize = (UINT64) DataSize; return EFI_BUFFER_TOO_SMALL; } *StructureSize = (UINT64) DataSize; CopyMem (StructureBuffer, DataInHob, DataSize); return EFI_SUCCESS; }
/** Locates the Xen SMBIOS data if it exists @return SMBIOS_TABLE_ENTRY_POINT Address of Xen SMBIOS data **/ SMBIOS_TABLE_ENTRY_POINT * GetXenSmbiosTables ( VOID ) { UINT8 *XenSmbiosPtr; SMBIOS_TABLE_ENTRY_POINT *XenSmbiosEntryPointStructure; EFI_HOB_GUID_TYPE *GuidHob; // // See if a XenInfo HOB is available // GuidHob = GetFirstGuidHob (&gEfiXenInfoGuid); if (GuidHob == NULL) { return NULL; } for (XenSmbiosPtr = (UINT8*)(UINTN) XEN_SMBIOS_PHYSICAL_ADDRESS; XenSmbiosPtr < (UINT8*)(UINTN) XEN_SMBIOS_PHYSICAL_END; XenSmbiosPtr += 0x10) { XenSmbiosEntryPointStructure = (SMBIOS_TABLE_ENTRY_POINT *) XenSmbiosPtr; if (!AsciiStrnCmp ((CHAR8 *) XenSmbiosEntryPointStructure->AnchorString, "_SM_", 4) && !AsciiStrnCmp ((CHAR8 *) XenSmbiosEntryPointStructure->IntermediateAnchorString, "_DMI_", 5) && IsEntryPointStructureValid (XenSmbiosEntryPointStructure)) { return XenSmbiosEntryPointStructure; } } return NULL; }
/** Gets PEI the GUID HOB for PEI performance. This internal function searches for the GUID HOB for PEI performance. If that GUID HOB is not found, it will build a new one. It returns the data area of that GUID HOB to record performance log. @param Handle Pointer to environment specific context used to identify the component being measured. @param Token Pointer to a Null-terminated ASCII string that identifies the component being measured. @param Module Pointer to a Null-terminated ASCII string that identifies the module being measured. @retval The index of log entry in the array. **/ PEI_PERFORMANCE_LOG_HEADER * InternalGetPerformanceHobLog ( VOID ) { EFI_HOB_GUID_TYPE *GuidHob; PEI_PERFORMANCE_LOG_HEADER *PeiPerformanceLog; UINTN PeiPerformanceLogSize; GuidHob = GetFirstGuidHob (&gPerformanceProtocolGuid); if (GuidHob != NULL) { // // PEI Performance HOB was found, then return the existing one. // PeiPerformanceLog = GET_GUID_HOB_DATA (GuidHob); } else { // // PEI Performance HOB was not found, then build one. // PeiPerformanceLogSize = sizeof (PEI_PERFORMANCE_LOG_HEADER) + sizeof (PEI_PERFORMANCE_LOG_ENTRY) * PcdGet8 (PcdMaxPeiPerformanceLogEntries); PeiPerformanceLog = BuildGuidHob (&gPerformanceProtocolGuid, PeiPerformanceLogSize); PeiPerformanceLog = ZeroMem (PeiPerformanceLog, PeiPerformanceLogSize); } return PeiPerformanceLog; }
/** Init SMM communication context. **/ VOID InitCommunicationContext ( VOID ) { EFI_SMRAM_DESCRIPTOR *SmramDescriptor; SMM_S3_RESUME_STATE *SmmS3ResumeState; VOID *GuidHob; EFI_SMM_COMMUNICATION_CONTEXT *SmmCommunicationContext; GuidHob = GetFirstGuidHob (&gEfiAcpiVariableGuid); ASSERT (GuidHob != NULL); SmramDescriptor = (EFI_SMRAM_DESCRIPTOR *) GET_GUID_HOB_DATA (GuidHob); SmmS3ResumeState = (SMM_S3_RESUME_STATE *)(UINTN)SmramDescriptor->CpuStart; DEBUG ((EFI_D_INFO, "InitCommunicationContext - SmmS3ResumeState: %x\n", SmmS3ResumeState)); DEBUG ((EFI_D_INFO, "InitCommunicationContext - Smst: %x\n", SmmS3ResumeState->Smst)); SmmCommunicationContext = (EFI_SMM_COMMUNICATION_CONTEXT *)InternalSmstGetVendorTableByGuid ( SmmS3ResumeState->Signature, (EFI_SMM_SYSTEM_TABLE2 *)(UINTN)SmmS3ResumeState->Smst, &gEfiPeiSmmCommunicationPpiGuid ); ASSERT (SmmCommunicationContext != NULL); SetCommunicationContext (SmmCommunicationContext); return ; }
/** Remove a previously registered callback function from the notification list. ReportStatusCode() messages will no longer be forwarded to the Callback function. @param[in] Callback A pointer to a function of type EFI_PEI_RSC_HANDLER_CALLBACK that is to be unregistered. @retval EFI_SUCCESS The function was successfully unregistered. @retval EFI_INVALID_PARAMETER The callback function was NULL. @retval EFI_NOT_FOUND The callback function was not found to be unregistered. **/ EFI_STATUS EFIAPI Unregister ( IN EFI_PEI_RSC_HANDLER_CALLBACK Callback ) { EFI_PEI_HOB_POINTERS Hob; EFI_PEI_RSC_HANDLER_CALLBACK *CallbackEntry; UINTN *NumberOfEntries; UINTN Index; if (Callback == NULL) { return EFI_INVALID_PARAMETER; } Hob.Raw = GetFirstGuidHob (&gStatusCodeCallbackGuid); while (Hob.Raw != NULL) { NumberOfEntries = GET_GUID_HOB_DATA (Hob); CallbackEntry = (EFI_PEI_RSC_HANDLER_CALLBACK *) (NumberOfEntries + 1); for (Index = 0; Index < *NumberOfEntries; Index++) { if (CallbackEntry[Index] == Callback) { // // Set removed entry as NULL. // CallbackEntry[Index] = NULL; return EFI_SUCCESS; } } Hob.Raw = GET_NEXT_HOB (Hob); Hob.Raw = GetNextGuidHob (&gStatusCodeCallbackGuid, Hob.Raw); } return EFI_NOT_FOUND; }
/** Implementation of the PlatformInformation2 service in EFI_SEC_PLATFORM_INFORMATION2_PPI. @param PeiServices The pointer to the PEI Services Table. @param StructureSize The pointer to the variable describing size of the input buffer. @param PlatformInformationRecord2 The pointer to the EFI_SEC_PLATFORM_INFORMATION_RECORD2. @retval EFI_SUCCESS The data was successfully returned. @retval EFI_BUFFER_TOO_SMALL The buffer was too small. The current buffer size needed to hold the record is returned in StructureSize. **/ EFI_STATUS EFIAPI SecPlatformInformation2 ( IN CONST EFI_PEI_SERVICES **PeiServices, IN OUT UINT64 *StructureSize, OUT EFI_SEC_PLATFORM_INFORMATION_RECORD2 *PlatformInformationRecord2 ) { EFI_HOB_GUID_TYPE *GuidHob; VOID *DataInHob; UINTN DataSize; GuidHob = GetFirstGuidHob (&gEfiSecPlatformInformation2PpiGuid); if (GuidHob == NULL) { *StructureSize = 0; return EFI_SUCCESS; } DataInHob = GET_GUID_HOB_DATA (GuidHob); DataSize = GET_GUID_HOB_DATA_SIZE (GuidHob); // // return the information from BistHob // if ((*StructureSize) < (UINT64) DataSize) { *StructureSize = (UINT64) DataSize; return EFI_BUFFER_TOO_SMALL; } *StructureSize = (UINT64) DataSize; CopyMem (PlatformInformationRecord2, DataInHob, DataSize); return EFI_SUCCESS; }
// // Initialization // EFI_STATUS EFIAPI InitializePnvDxe ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { VOID *Hob; VOID *DeviceTreeBase; EFI_STATUS Status; // // Recover the DeviceTree HOB and install it in the configuration table // Hob = GetFirstGuidHob(&gFdtHobGuid); if (Hob == NULL || GET_GUID_HOB_DATA_SIZE (Hob) != sizeof (UINT64)) { DEBUG ((EFI_D_ERROR, "%a: No FDT HOB found\n", __FUNCTION__)); return EFI_NOT_FOUND; } DeviceTreeBase = (VOID *)(UINTN)*(UINT64 *)GET_GUID_HOB_DATA (Hob); if (fdt_check_header (DeviceTreeBase) != 0) { DEBUG ((EFI_D_ERROR, "%a: DTB Invalid @ 0x%p\n", __FUNCTION__, DeviceTreeBase)); return EFI_NOT_FOUND; } Status = gBS->InstallConfigurationTable (&gFdtTableGuid, DeviceTreeBase); ASSERT_EFI_ERROR (Status); DEBUG ((EFI_D_INFO, "%a: DTB @ 0x%p\n", __FUNCTION__, DeviceTreeBase)); return EFI_SUCCESS; }
/** Worker function to get CPU_FEATURES_DATA pointer. @return Pointer to CPU_FEATURES_DATA. **/ CPU_FEATURES_DATA * GetCpuFeaturesData ( VOID ) { CPU_FEATURES_DATA *CpuInitData; EFI_HOB_GUID_TYPE *GuidHob; VOID *DataInHob; UINT64 Data64; CpuInitData = NULL; GuidHob = GetFirstGuidHob (&mRegisterCpuFeaturesHobGuid); if (GuidHob != NULL) { DataInHob = GET_GUID_HOB_DATA (GuidHob); CpuInitData = (CPU_FEATURES_DATA *) (*(UINTN *) DataInHob); ASSERT (CpuInitData != NULL); } else { CpuInitData = AllocateZeroPool (sizeof (CPU_FEATURES_DATA)); ASSERT (CpuInitData != NULL); // // Build location of CPU MP DATA buffer in HOB // Data64 = (UINT64) (UINTN) CpuInitData; BuildGuidDataHob ( &mRegisterCpuFeaturesHobGuid, (VOID *) &Data64, sizeof (UINT64) ); } return CpuInitData; }
/** Dumps all the PEI performance log to DXE performance gauge array. This internal function dumps all the PEI performance log to the DXE performance gauge array. It retrieves the optional GUID HOB for PEI performance and then saves the performance data to DXE performance data structures. **/ VOID InternalGetPeiPerformance ( VOID ) { EFI_HOB_GUID_TYPE *GuidHob; PEI_PERFORMANCE_LOG_HEADER *LogHob; PEI_PERFORMANCE_LOG_ENTRY *LogEntryArray; UINT32 *LogIdArray; GAUGE_DATA_ENTRY_EX *GaugeEntryExArray; UINT32 Index; UINT32 NumberOfEntries; NumberOfEntries = 0; GaugeEntryExArray = (GAUGE_DATA_ENTRY_EX *) (mGaugeData + 1); // // Dump PEI Log Entries to DXE Guage Data structure. // GuidHob = GetFirstGuidHob (&gPerformanceProtocolGuid); if (GuidHob != NULL) { LogHob = GET_GUID_HOB_DATA (GuidHob); LogEntryArray = (PEI_PERFORMANCE_LOG_ENTRY *) (LogHob + 1); NumberOfEntries = LogHob->NumberOfEntries; for (Index = 0; Index < NumberOfEntries; Index++) { GaugeEntryExArray[Index].Handle = LogEntryArray[Index].Handle; AsciiStrCpyS (GaugeEntryExArray[Index].Token, DXE_PERFORMANCE_STRING_SIZE, LogEntryArray[Index].Token); AsciiStrCpyS (GaugeEntryExArray[Index].Module, DXE_PERFORMANCE_STRING_SIZE, LogEntryArray[Index].Module); GaugeEntryExArray[Index].StartTimeStamp = LogEntryArray[Index].StartTimeStamp; GaugeEntryExArray[Index].EndTimeStamp = LogEntryArray[Index].EndTimeStamp; GaugeEntryExArray[Index].Identifier = 0; } GuidHob = GetFirstGuidHob (&gPerformanceExProtocolGuid); if (GuidHob != NULL) { LogIdArray = GET_GUID_HOB_DATA (GuidHob); for (Index = 0; Index < NumberOfEntries; Index++) { GaugeEntryExArray[Index].Identifier = LogIdArray[Index]; } } } mGaugeData->NumberOfEntries = NumberOfEntries; }
UINT64 GetPciExpressBaseAddressForRootBridge ( IN UINTN HostBridgeNumber, IN UINTN RootBridgeNumber ) /*++ Routine Description: This routine is to get PciExpress Base Address for this RootBridge Arguments: HostBridgeNumber - The number of HostBridge RootBridgeNumber - The number of RootBridge Returns: UINT64 - PciExpressBaseAddress for this HostBridge and RootBridge --*/ { EFI_PCI_EXPRESS_BASE_ADDRESS_INFORMATION *PciExpressBaseAddressInfo; UINTN BufferSize; UINT32 Index; UINT32 Number; EFI_PEI_HOB_POINTERS GuidHob; // // Get PciExpressAddressInfo Hob // PciExpressBaseAddressInfo = NULL; BufferSize = 0; GuidHob.Raw = GetFirstGuidHob (&gEfiPciExpressBaseAddressGuid); if (GuidHob.Raw != NULL) { PciExpressBaseAddressInfo = GET_GUID_HOB_DATA (GuidHob.Guid); BufferSize = GET_GUID_HOB_DATA_SIZE (GuidHob.Guid); } else { return 0; } // // Search the PciExpress Base Address in the Hob for current RootBridge // Number = (UINT32)(BufferSize / sizeof(EFI_PCI_EXPRESS_BASE_ADDRESS_INFORMATION)); for (Index = 0; Index < Number; Index++) { if ((PciExpressBaseAddressInfo[Index].HostBridgeNumber == HostBridgeNumber) && (PciExpressBaseAddressInfo[Index].RootBridgeNumber == RootBridgeNumber)) { return PciExpressBaseAddressInfo[Index].PciExpressBaseAddress; } } // // Do not find the PciExpress Base Address in the Hob // return 0; }
/** Gets the GUID HOB for PEI performance. This internal function searches for the GUID HOB for PEI performance. If that GUID HOB is not found, it will build a new one. It outputs the data area of that GUID HOB to record performance log. @param PeiPerformanceLog Pointer to Pointer to PEI performance log header. @param PeiPerformanceIdArray Pointer to Pointer to PEI performance identifier array. **/ VOID InternalGetPerformanceHobLog ( OUT PEI_PERFORMANCE_LOG_HEADER **PeiPerformanceLog, OUT UINT32 **PeiPerformanceIdArray ) { EFI_HOB_GUID_TYPE *GuidHob; UINTN PeiPerformanceSize; UINT16 PeiPerformanceLogEntries; ASSERT (PeiPerformanceLog != NULL); ASSERT (PeiPerformanceIdArray != NULL); PeiPerformanceLogEntries = (UINT16) (PcdGet16 (PcdMaxPeiPerformanceLogEntries16) != 0 ? PcdGet16 (PcdMaxPeiPerformanceLogEntries16) : PcdGet8 (PcdMaxPeiPerformanceLogEntries)); GuidHob = GetFirstGuidHob (&gPerformanceProtocolGuid); if (GuidHob != NULL) { // // PEI Performance HOB was found, then return the existing one. // *PeiPerformanceLog = GET_GUID_HOB_DATA (GuidHob); GuidHob = GetFirstGuidHob (&gPerformanceExProtocolGuid); ASSERT (GuidHob != NULL); *PeiPerformanceIdArray = GET_GUID_HOB_DATA (GuidHob); } else { // // PEI Performance HOB was not found, then build one. // PeiPerformanceSize = sizeof (PEI_PERFORMANCE_LOG_HEADER) + sizeof (PEI_PERFORMANCE_LOG_ENTRY) * PeiPerformanceLogEntries; *PeiPerformanceLog = BuildGuidHob (&gPerformanceProtocolGuid, PeiPerformanceSize); *PeiPerformanceLog = ZeroMem (*PeiPerformanceLog, PeiPerformanceSize); PeiPerformanceSize = sizeof (UINT32) * PeiPerformanceLogEntries; *PeiPerformanceIdArray = BuildGuidHob (&gPerformanceExProtocolGuid, PeiPerformanceSize); *PeiPerformanceIdArray = ZeroMem (*PeiPerformanceIdArray, PeiPerformanceSize); } }
/** Get PCD database from GUID HOB in PEI phase. @return Pointer to PCD database. **/ PEI_PCD_DATABASE * GetPcdDatabase ( VOID ) { EFI_HOB_GUID_TYPE *GuidHob; GuidHob = GetFirstGuidHob (&gPcdDataBaseHobGuid); ASSERT (GuidHob != NULL); return (PEI_PCD_DATABASE *) GET_GUID_HOB_DATA (GuidHob); }
/** Completes the Map() operation and releases any corresponding resources. @param This The PPI instance pointer. @param Mapping The mapping value returned from Map(). @retval EFI_SUCCESS The range was unmapped. @retval EFI_INVALID_PARAMETER Mapping is not a value that was returned by Map(). @retval EFI_DEVICE_ERROR The data was not committed to the target system memory. @retval EFI_NOT_AVAILABLE_YET DMA protection has been enabled, but DMA buffer are not available to be allocated yet. **/ EFI_STATUS EFIAPI PeiIoMmuUnmap ( IN EDKII_IOMMU_PPI *This, IN VOID *Mapping ) { MAP_INFO *MapInfo; UINTN Length; VOID *Hob; DMA_BUFFER_INFO *DmaBufferInfo; Hob = GetFirstGuidHob (&mDmaBufferInfoGuid); DmaBufferInfo = GET_GUID_HOB_DATA(Hob); DEBUG ((DEBUG_VERBOSE, "PeiIoMmuUnmap - Mapping - %x\n", Mapping)); DEBUG ((DEBUG_VERBOSE, " DmaBufferCurrentTop - %x\n", DmaBufferInfo->DmaBufferCurrentTop)); DEBUG ((DEBUG_VERBOSE, " DmaBufferCurrentBottom - %x\n", DmaBufferInfo->DmaBufferCurrentBottom)); if (DmaBufferInfo->DmaBufferCurrentTop == 0) { return EFI_NOT_AVAILABLE_YET; } if (Mapping == NULL) { return EFI_SUCCESS; } MapInfo = Mapping; ASSERT (MapInfo->Signature == MAP_INFO_SIGNATURE); DEBUG ((DEBUG_VERBOSE, " Op(%x):DeviceAddress - %x, NumberOfBytes - %x\n", MapInfo->Operation, (UINTN)MapInfo->DeviceAddress, MapInfo->NumberOfBytes)); // // If this is a write operation from the Bus Master's point of view, // then copy the contents of the mapped buffer into the real buffer // so the processor can read the contents of the real buffer. // if (MapInfo->Operation == EdkiiIoMmuOperationBusMasterWrite || MapInfo->Operation == EdkiiIoMmuOperationBusMasterWrite64) { CopyMem ( (VOID *) (UINTN) MapInfo->HostAddress, (VOID *) (UINTN) MapInfo->DeviceAddress, MapInfo->NumberOfBytes ); } Length = MapInfo->NumberOfBytes + sizeof(MAP_INFO); if (DmaBufferInfo->DmaBufferCurrentBottom == MapInfo->DeviceAddress + Length) { DmaBufferInfo->DmaBufferCurrentBottom -= Length; } return EFI_SUCCESS; }
/** This function get TPM2.0 interface. @retval TPM2.0 interface. **/ TPM2_DEVICE_INTERFACE * InternalGetTpm2DeviceInterface ( VOID ) { EFI_HOB_GUID_TYPE *Hob; Hob = GetFirstGuidHob (&mInternalTpm2DeviceInterfaceGuid); if (Hob == NULL) { return NULL; } return (TPM2_DEVICE_INTERFACE *)(Hob + 1); }
PRE_PI_EXTRACT_GUIDED_SECTION_DATA * GetSavedData ( VOID ) { EFI_HOB_GUID_TYPE *GuidHob; GUID SavedDataGuid = PRE_PI_EXTRACT_GUIDED_SECTION_DATA_GUID; GuidHob = GetFirstGuidHob(&SavedDataGuid); GuidHob++; return (PRE_PI_EXTRACT_GUIDED_SECTION_DATA *)GuidHob; }
/** Get the location of Mailbox pointer from the GUIDed HOB. @return Pointer to the location saved Mailbox pointer. **/ UINT64 * GetMailboxLocationFromHob ( VOID ) { EFI_HOB_GUID_TYPE *GuidHob; GuidHob = GetFirstGuidHob (&gEfiDebugAgentGuid); if (GuidHob == NULL) { return NULL; } return (UINT64 *) (GET_GUID_HOB_DATA(GuidHob)); }
/** This function get hash interface. @retval hash interface. **/ HASH_INTERFACE_HOB * InternalGetHashInterface ( VOID ) { EFI_HOB_GUID_TYPE *Hob; Hob = GetFirstGuidHob (&mHashLibPeiRouterGuid); if (Hob == NULL) { return NULL; } return (HASH_INTERFACE_HOB *)(Hob + 1); }
/** Invoke the callback function when dynamic PCD entry was set, if this PCD entry has registered callback function. @param ExTokenNumber DynamicEx PCD's token number, if this PCD entry is dyanmicEx type PCD. @param Guid DynamicEx PCD's guid, if this PCD entry is dynamicEx type PCD. @param TokenNumber PCD token number generated by build tools. @param Data Value want to be set for this PCD entry @param Size The size of value **/ VOID InvokeCallbackOnSet ( UINTN ExTokenNumber, CONST EFI_GUID *Guid, OPTIONAL UINTN TokenNumber, VOID *Data, UINTN Size ) { EFI_HOB_GUID_TYPE *GuidHob; PCD_PPI_CALLBACK *CallbackTable; UINTN Idx; PEI_PCD_DATABASE *PeiPcdDb; UINT32 LocalTokenCount; // // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER. // We have to decrement TokenNumber by 1 to make it usable // as the array index. // TokenNumber--; PeiPcdDb = GetPcdDatabase (); LocalTokenCount = PeiPcdDb->LocalTokenCount; if (Guid == NULL) { // EBC compiler is very choosy. It may report warning about comparison // between UINTN and 0 . So we add 1 in each size of the // comparison. ASSERT (TokenNumber + 1 < (LocalTokenCount + 1)); } GuidHob = GetFirstGuidHob (&gEfiCallerIdGuid); ASSERT (GuidHob != NULL); CallbackTable = GET_GUID_HOB_DATA (GuidHob); CallbackTable += (TokenNumber * PcdGet32 (PcdMaxPeiPcdCallBackNumberPerPcdEntry)); for (Idx = 0; Idx < PcdGet32 (PcdMaxPeiPcdCallBackNumberPerPcdEntry); Idx++) { if (CallbackTable[Idx] != NULL) { CallbackTable[Idx] (Guid, (Guid == NULL) ? (TokenNumber + 1) : ExTokenNumber, Data, Size ); } } }
/** Get SMM communication context. @return SMM communication context. **/ EFI_SMM_COMMUNICATION_CONTEXT * GetCommunicationContext ( VOID ) { EFI_HOB_GUID_TYPE *GuidHob; EFI_SMM_COMMUNICATION_CONTEXT *SmmCommunicationContext; GuidHob = GetFirstGuidHob (&gEfiPeiSmmCommunicationPpiGuid); ASSERT (GuidHob != NULL); SmmCommunicationContext = (EFI_SMM_COMMUNICATION_CONTEXT *)GET_GUID_HOB_DATA (GuidHob); return SmmCommunicationContext; }
EFI_STATUS XenHyperpageInit ( IN OUT XENBUS_DEVICE *Dev ) { EFI_HOB_GUID_TYPE *GuidHob; EFI_XEN_INFO *XenInfo; GuidHob = GetFirstGuidHob (&gEfiXenInfoGuid); if (GuidHob == NULL) { return EFI_NOT_FOUND; } XenInfo = (EFI_XEN_INFO *) GET_GUID_HOB_DATA (GuidHob); Dev->Hyperpage = XenInfo->HyperPages; return EFI_SUCCESS; }
/** Report status code into GUID'ed HOB. This function reports status code into GUID'ed HOB. If not all packets are full, then write status code into available entry. Otherwise, create a new packet for it. @param CodeType Indicates the type of status code being reported. @param Value Describes the current status of a hardware or software entity. This includes information about the class and subclass that is used to classify the entity as well as an operation. For progress codes, the operation is the current activity. For error codes, it is the exception.For debug codes,it is not defined at this time. @param Instance The enumeration of a hardware or software entity within the system. A system may contain multiple entities that match a class/subclass pairing. The instance differentiates between them. An instance of 0 indicates that instance information is unavailable, not meaningful, or not relevant. Valid instance numbers start with 1. @retval EFI_SUCCESS The function always return EFI_SUCCESS. **/ EFI_STATUS MemoryStatusCodeReportWorker ( IN EFI_STATUS_CODE_TYPE CodeType, IN EFI_STATUS_CODE_VALUE Value, IN UINT32 Instance ) { EFI_PEI_HOB_POINTERS Hob; MEMORY_STATUSCODE_PACKET_HEADER *PacketHeader; MEMORY_STATUSCODE_RECORD *Record; // // Find GUID'ed HOBs to locate current record buffer. // Hob.Raw = GetFirstGuidHob (&gMemoryStatusCodeRecordGuid); ASSERT (Hob.Raw != NULL); PacketHeader = (MEMORY_STATUSCODE_PACKET_HEADER *) GET_GUID_HOB_DATA (Hob.Guid); Record = (MEMORY_STATUSCODE_RECORD *) (PacketHeader + 1); Record = &Record[PacketHeader->RecordIndex++]; // // Save status code. // Record->CodeType = CodeType; Record->Instance = Instance; Record->Value = Value; // // If record index equals to max record number, then wrap around record index to zero. // // The reader of status code should compare the number of records with max records number, // If it is equal to or larger than the max number, then the wrap-around had happened, // so the first record is pointed by record index. // If it is less then max number, index of the first record is zero. // if (PacketHeader->RecordIndex == PacketHeader->MaxRecordsNumber) { // // Wrap around record index. // PacketHeader->RecordIndex = 0; PacketHeader->PacketIndex ++; } return EFI_SUCCESS; }
/** The constructor function caches the pointer of EMU Thunk protocol. @param ImageHandle The firmware allocated handle for the EFI image. @param SystemTable A pointer to the EFI System Table. @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS. **/ EFI_STATUS EFIAPI DxeEmuLibConstructor ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_HOB_GUID_TYPE *GuidHob; GuidHob = GetFirstGuidHob (&gEmuThunkProtocolGuid); ASSERT (GuidHob != NULL); gEmuThunk = (EMU_THUNK_PROTOCOL *)(*(UINTN *)(GET_GUID_HOB_DATA (GuidHob))); ASSERT (gEmuThunk != NULL); return EFI_SUCCESS; }
/** This function detects if OVMF is running on Xen. **/ BOOLEAN XenDetected ( VOID ) { EFI_HOB_GUID_TYPE *GuidHob; // // See if a XenInfo HOB is available // GuidHob = GetFirstGuidHob (&gEfiXenInfoGuid); if (GuidHob == NULL) { return FALSE; } return TRUE; }
/** CPU Features driver entry point function. If PcdCpuFeaturesInitAfterSmmRelocation is TRUE, it will register one SMM Configuration Protocol notify function to perform CPU features initialization. Otherwise, it will perform CPU features initialization directly. @param ImageHandle Image handle this driver. @param SystemTable Pointer to the System Table. @retval EFI_SUCCESS CPU Features is initialized successfully. **/ EFI_STATUS EFIAPI CpuFeaturesDxeInitialize ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { VOID *Registration; EFI_STATUS Status; EFI_HANDLE Handle; if (GetFirstGuidHob (&gEdkiiCpuFeaturesInitDoneGuid) != NULL) { // // Try to find HOB first. This HOB exist means CPU features have // been initialized by CpuFeaturesPei driver, just install // gEdkiiCpuFeaturesInitDoneGuid. // Handle = NULL; Status = gBS->InstallProtocolInterface ( &Handle, &gEdkiiCpuFeaturesInitDoneGuid, EFI_NATIVE_INTERFACE, NULL ); ASSERT_EFI_ERROR (Status); return Status; } if (PcdGetBool (PcdCpuFeaturesInitAfterSmmRelocation)) { // // Install notification callback on SMM Configuration Protocol // EfiCreateProtocolNotifyEvent ( &gEfiSmmConfigurationProtocolGuid, TPL_CALLBACK, SmmConfigurationEventNotify, NULL, &Registration ); } else { CpuFeaturesInitializeWorker (); } return EFI_SUCCESS; }
/** Get variable header that has consecutive content. @param StoreInfo Pointer to variable store info structure. @param Variable Pointer to the Variable Header. @param VariableHeader Pointer to Pointer to the Variable Header that has consecutive content. @retval TRUE Variable header is valid. @retval FALSE Variable header is not valid. **/ BOOLEAN GetVariableHeader ( IN VARIABLE_STORE_INFO *StoreInfo, IN VARIABLE_HEADER *Variable, OUT VARIABLE_HEADER **VariableHeader ) { EFI_PHYSICAL_ADDRESS TargetAddress; EFI_PHYSICAL_ADDRESS SpareAddress; EFI_HOB_GUID_TYPE *GuidHob; UINTN PartialHeaderSize; // // First assume variable header pointed by Variable is consecutive. // *VariableHeader = Variable; if ((Variable != NULL) && (StoreInfo->FtwLastWriteData != NULL)) { TargetAddress = StoreInfo->FtwLastWriteData->TargetAddress; SpareAddress = StoreInfo->FtwLastWriteData->SpareAddress; if (((UINTN) Variable < (UINTN) TargetAddress) && (((UINTN) Variable + sizeof (VARIABLE_HEADER)) > (UINTN) TargetAddress)) { // // Variable header pointed by Variable is inconsecutive, // create a guid hob to combine the two partial variable header content together. // GuidHob = GetFirstGuidHob (&gEfiCallerIdGuid); if (GuidHob != NULL) { *VariableHeader = (VARIABLE_HEADER *) GET_GUID_HOB_DATA (GuidHob); } else { *VariableHeader = (VARIABLE_HEADER *) BuildGuidHob (&gEfiCallerIdGuid, sizeof (VARIABLE_HEADER)); PartialHeaderSize = (UINTN) TargetAddress - (UINTN) Variable; // // Partial content is in NV storage. // CopyMem ((UINT8 *) *VariableHeader, (UINT8 *) Variable, PartialHeaderSize); // // Another partial content is in spare block. // CopyMem ((UINT8 *) *VariableHeader + PartialHeaderSize, (UINT8 *) (UINTN) SpareAddress, sizeof (VARIABLE_HEADER) - PartialHeaderSize); } } } return IsValidVariableHeader (*VariableHeader); }