/** This function initializes the mCapsulePtr, mCapsuleStatusArray and mCapsuleTotalNumber. **/ VOID InitCapsulePtr ( VOID ) { EFI_PEI_HOB_POINTERS HobPointer; UINTN Index; // // Find all capsule images from hob // HobPointer.Raw = GetHobList (); while ((HobPointer.Raw = GetNextHob (EFI_HOB_TYPE_UEFI_CAPSULE, HobPointer.Raw)) != NULL) { if (!IsValidCapsuleHeader((VOID *)(UINTN)HobPointer.Capsule->BaseAddress, HobPointer.Capsule->Length)) { HobPointer.Header->HobType = EFI_HOB_TYPE_UNUSED; // Mark this hob as invalid } else { mCapsuleTotalNumber++; } HobPointer.Raw = GET_NEXT_HOB (HobPointer); } DEBUG ((DEBUG_INFO, "mCapsuleTotalNumber - 0x%x\n", mCapsuleTotalNumber)); if (mCapsuleTotalNumber == 0) { return ; } // // Init temp Capsule Data table. // mCapsulePtr = (VOID **) AllocateZeroPool (sizeof (VOID *) * mCapsuleTotalNumber); if (mCapsulePtr == NULL) { DEBUG ((DEBUG_ERROR, "Allocate mCapsulePtr fail!\n")); mCapsuleTotalNumber = 0; return ; } mCapsuleStatusArray = (EFI_STATUS *) AllocateZeroPool (sizeof (EFI_STATUS) * mCapsuleTotalNumber); if (mCapsuleStatusArray == NULL) { DEBUG ((DEBUG_ERROR, "Allocate mCapsuleStatusArray fail!\n")); FreePool (mCapsulePtr); mCapsulePtr = NULL; mCapsuleTotalNumber = 0; return ; } SetMemN (mCapsuleStatusArray, sizeof (EFI_STATUS) * mCapsuleTotalNumber, EFI_NOT_READY); // // Find all capsule images from hob // HobPointer.Raw = GetHobList (); Index = 0; while ((HobPointer.Raw = GetNextHob (EFI_HOB_TYPE_UEFI_CAPSULE, HobPointer.Raw)) != NULL) { mCapsulePtr [Index++] = (VOID *) (UINTN) HobPointer.Capsule->BaseAddress; HobPointer.Raw = GET_NEXT_HOB (HobPointer); } }
/** Check if AP wakeup buffer is overlapped with existing allocated buffer. @param[in] WakeupBufferStart AP wakeup buffer start address. @param[in] WakeupBufferEnd AP wakeup buffer end address. @retval TRUE There is overlap. @retval FALSE There is no overlap. **/ BOOLEAN CheckOverlapWithAllocatedBuffer ( IN UINT64 WakeupBufferStart, IN UINT64 WakeupBufferEnd ) { EFI_PEI_HOB_POINTERS Hob; EFI_HOB_MEMORY_ALLOCATION *MemoryHob; BOOLEAN Overlapped; UINT64 MemoryStart; UINT64 MemoryEnd; Overlapped = FALSE; // // Get the HOB list for processing // Hob.Raw = GetHobList (); // // Collect memory ranges // while (!END_OF_HOB_LIST (Hob)) { if (Hob.Header->HobType == EFI_HOB_TYPE_MEMORY_ALLOCATION) { MemoryHob = Hob.MemoryAllocation; MemoryStart = MemoryHob->AllocDescriptor.MemoryBaseAddress; MemoryEnd = MemoryHob->AllocDescriptor.MemoryBaseAddress + MemoryHob->AllocDescriptor.MemoryLength; if (!((WakeupBufferStart >= MemoryEnd) || (WakeupBufferEnd <= MemoryStart))) { Overlapped = TRUE; break; } } Hob.Raw = GET_NEXT_HOB (Hob); } return Overlapped; }
// // Return list of cores in the system // EFI_STATUS PrePeiCoreGetMpCoreInfo ( OUT UINTN *ArmCoreCount, OUT ARM_CORE_INFO **ArmCoreInfoTable ) { EFI_PEI_HOB_POINTERS Hob; if (ArmIsMpCore()) { // Iterate through the HOBs and find if there is ARM PROCESSOR ENTRY HOB for (Hob.Raw = GetHobList (); !END_OF_HOB_LIST(Hob); Hob.Raw = GET_NEXT_HOB(Hob)) { // Check for Correct HOB type if ((GET_HOB_TYPE (Hob)) == EFI_HOB_TYPE_GUID_EXTENSION) { // Check for correct GUID type if (CompareGuid(&(Hob.Guid->Name), &gAmdStyxMpCoreInfoGuid)) { *ArmCoreInfoTable = (ARM_CORE_INFO *) GET_GUID_HOB_DATA(Hob); *ArmCoreCount = GET_GUID_HOB_DATA_SIZE(Hob)/sizeof(ARM_CORE_INFO); return EFI_SUCCESS; } } } } return EFI_UNSUPPORTED; }
unsigned install_e820_map(unsigned max_entries, struct e820entry *entries) { unsigned num_entries = 0; EFI_PEI_HOB_POINTERS hob; hob.Raw = gd->arch.hob_list; while (!END_OF_HOB_LIST(hob)) { if (hob.Header->HobType == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) { if (hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) { entries[num_entries].addr = hob.ResourceDescriptor->PhysicalStart; entries[num_entries].size = hob.ResourceDescriptor->ResourceLength; entries[num_entries].type = E820_RAM; } else if (hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_MEMORY_RESERVED) { entries[num_entries].addr = hob.ResourceDescriptor->PhysicalStart; entries[num_entries].size = hob.ResourceDescriptor->ResourceLength; entries[num_entries].type = E820_RESERVED; } } hob.Raw = GET_NEXT_HOB(hob); num_entries++; } return num_entries; }
void GetHighMemorySize ( uint64_t *HighMemoryLength ) { EFI_PEI_HOB_POINTERS Hob; *HighMemoryLength = 0x0; // // Get the HOB list for processing // Hob.Raw = GetHobList(); // // Collect memory ranges // while (!END_OF_HOB_LIST (Hob)) { if (Hob.Header->HobType == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) { if (Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) { // // Need memory above 4GB to be collected here // if (Hob.ResourceDescriptor->PhysicalStart >= (EFI_PHYSICAL_ADDRESS) 0x100000000) { *HighMemoryLength += (uint64_t) (Hob.ResourceDescriptor->ResourceLength); } } } Hob.Raw = GET_NEXT_HOB (Hob); } return; }
/** Process FSP HOB list @param[in] FspHobList Pointer to the HOB data structure produced by FSP. **/ VOID ProcessFspHobList ( IN VOID *FspHobList ) { EFI_PEI_HOB_POINTERS FspHob; FspHob.Raw = FspHobList; // // Add all the HOBs from FSP binary to FSP wrapper // while (!END_OF_HOB_LIST (FspHob)) { if (FspHob.Header->HobType == EFI_HOB_TYPE_GUID_EXTENSION) { // // Skip FSP binary creates PcdDataBaseHobGuid // if (!CompareGuid(&FspHob.Guid->Name, &gPcdDataBaseHobGuid)) { BuildGuidDataHob ( &FspHob.Guid->Name, GET_GUID_HOB_DATA(FspHob), GET_GUID_HOB_DATA_SIZE(FspHob) ); } } FspHob.Raw = GET_NEXT_HOB (FspHob); } }
/** Update the Stack Hob if the stack has been moved @param BaseAddress The 64 bit physical address of the Stack. @param Length The length of the stack in bytes. **/ VOID UpdateStackHob ( IN EFI_PHYSICAL_ADDRESS BaseAddress, IN UINT64 Length ) { EFI_PEI_HOB_POINTERS Hob; Hob.Raw = GetHobList (); while ((Hob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, Hob.Raw)) != NULL) { if (CompareGuid (&gEfiHobMemoryAllocStackGuid, &(Hob.MemoryAllocationStack->AllocDescriptor.Name))) { // // Build a new memory allocation HOB with old stack info with EfiConventionalMemory type // to be reclaimed by DXE core. // BuildMemoryAllocationHob ( Hob.MemoryAllocationStack->AllocDescriptor.MemoryBaseAddress, Hob.MemoryAllocationStack->AllocDescriptor.MemoryLength, EfiConventionalMemory ); // // Update the BSP Stack Hob to reflect the new stack info. // Hob.MemoryAllocationStack->AllocDescriptor.MemoryBaseAddress = BaseAddress; Hob.MemoryAllocationStack->AllocDescriptor.MemoryLength = Length; break; } Hob.Raw = GET_NEXT_HOB (Hob); } }
/** Updates the Stack HOB passed to DXE phase. This function traverses the whole HOB list and update the stack HOB to reflect the real stack that is used by DXE core. @param BaseAddress The lower address of stack used by DxeCore. @param Length The length of stack used by DxeCore. **/ VOID UpdateStackHob ( IN EFI_PHYSICAL_ADDRESS BaseAddress, IN UINT64 Length ) { EFI_PEI_HOB_POINTERS Hob; Hob.Raw = GetHobList (); while ((Hob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, Hob.Raw)) != NULL) { if (CompareGuid (&gEfiHobMemoryAllocStackGuid, &(Hob.MemoryAllocationStack->AllocDescriptor.Name))) { // // Build a new memory allocation HOB with old stack info with EfiBootServicesData type. Need to // avoid this region be reclaimed by DXE core as the IDT built in SEC might be on stack, and some // PEIMs may also keep key information on stack // BuildMemoryAllocationHob ( Hob.MemoryAllocationStack->AllocDescriptor.MemoryBaseAddress, Hob.MemoryAllocationStack->AllocDescriptor.MemoryLength, EfiBootServicesData ); // // Update the BSP Stack Hob to reflect the new stack info. // Hob.MemoryAllocationStack->AllocDescriptor.MemoryBaseAddress = BaseAddress; Hob.MemoryAllocationStack->AllocDescriptor.MemoryLength = Length; break; } Hob.Raw = GET_NEXT_HOB (Hob); } }
EFIAPI FspGetResourceDescriptorByOwner ( IN EFI_GUID *OwnerGuid ) { EFI_PEI_HOB_POINTERS Hob; // // Get the HOB list for processing // Hob.Raw = GetHobList (); // // Collect memory ranges // while (!END_OF_HOB_LIST (Hob)) { if (Hob.Header->HobType == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) { if ((Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_MEMORY_RESERVED) && \ (CompareGuid (&Hob.ResourceDescriptor->Owner, OwnerGuid))) { return Hob.ResourceDescriptor; } } Hob.Raw = GET_NEXT_HOB (Hob); } return NULL; }
/** * * HeapGetBaseAddressInTempMem * * This function gets heap base address in HEAP_TEMP_MEM phase * * @param[in] StdHeader - Pointer to AMD_CONFIG_PARAMS struct. * * @retval UINT64 - Heap base address in HEAP_TEMP_MEM phase * */ UINT64 HeapGetBaseAddressInTempMem ( IN AMD_CONFIG_PARAMS *StdHeader ) { EFI_PEI_SERVICES **PeiServices; EFI_PEI_HOB_POINTERS Hob; AGESA_STATUS IgnoredStatus; UINT64 BaseAddress; BaseAddress = UserOptions.CfgHeapDramAddress; if (IsBsp (StdHeader, &IgnoredStatus) && (StdHeader->HeapStatus != HEAP_LOCAL_CACHE)) { PeiServices = (EFI_PEI_SERVICES **) StdHeader->ImageBasePtr; // // Retrieve the new Heap Manager base in HOB and update StdHeader // (*PeiServices)->GetHobList (PeiServices, &Hob.Raw); while (!END_OF_HOB_LIST (Hob)) { if (Hob.Header->HobType == EFI_HOB_TYPE_GUID_EXTENSION && CompareGuid ( &Hob.Guid->Name, &gAmdHeapHobGuid)) { BaseAddress = (UINT64) (VOID *) (Hob.Raw + sizeof (EFI_HOB_GENERIC_HEADER) + sizeof (EFI_GUID)); break; } Hob.Raw = GET_NEXT_HOB (Hob); } } return BaseAddress; }
/** 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; }
void GetFspReservedMemoryFromGuid ( uint32_t *FspMemoryBase, uint32_t *FspMemoryLength, EFI_GUID FspReservedMemoryGuid ) { EFI_PEI_HOB_POINTERS Hob; // // Get the HOB list for processing // Hob.Raw = GetHobList(); *FspMemoryBase = 0; *FspMemoryLength = 0; // // Collect memory ranges // while (!END_OF_HOB_LIST (Hob)) { if (Hob.Header->HobType == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) { if (Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_MEMORY_RESERVED) { if (CompareGuid(&Hob.ResourceDescriptor->Owner, &FspReservedMemoryGuid)) { *FspMemoryBase = (uint32_t) (Hob.ResourceDescriptor->PhysicalStart); *FspMemoryLength = (uint32_t) (Hob.ResourceDescriptor->ResourceLength); break; } } } Hob.Raw = GET_NEXT_HOB (Hob); } return; }
/** Get system memory from HOB. @param[in,out] LowMemoryLength less than 4G memory length @param[in,out] HighMemoryLength greater than 4G memory length **/ VOID EFIAPI FspGetSystemMemorySize ( IN OUT UINT64 *LowMemoryLength, IN OUT UINT64 *HighMemoryLength ) { EFI_STATUS Status; EFI_BOOT_MODE BootMode; EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttribute; EFI_PEI_HOB_POINTERS Hob; ResourceAttribute = ( EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE | EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE | EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE | EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE ); Status = PeiServicesGetBootMode (&BootMode); ASSERT_EFI_ERROR (Status); if (BootMode != BOOT_ON_S3_RESUME) { ResourceAttribute |= EFI_RESOURCE_ATTRIBUTE_TESTED; } *HighMemoryLength = 0; *LowMemoryLength = SIZE_1MB; // // Get the HOB list for processing // Hob.Raw = GetHobList (); // // Collect memory ranges // while (!END_OF_HOB_LIST (Hob)) { if (Hob.Header->HobType == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) { if ((Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) || ((Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_MEMORY_RESERVED) && (Hob.ResourceDescriptor->ResourceAttribute == ResourceAttribute))) { // // Need memory above 1MB to be collected here // if (Hob.ResourceDescriptor->PhysicalStart >= BASE_1MB && Hob.ResourceDescriptor->PhysicalStart < (EFI_PHYSICAL_ADDRESS) BASE_4GB) { *LowMemoryLength += (UINT64) (Hob.ResourceDescriptor->ResourceLength); } else if (Hob.ResourceDescriptor->PhysicalStart >= (EFI_PHYSICAL_ADDRESS) BASE_4GB) { *HighMemoryLength += (UINT64) (Hob.ResourceDescriptor->ResourceLength); } } } Hob.Raw = GET_NEXT_HOB (Hob); } }
EFI_STATUS GetDxeCoreHobInfo ( IN VOID *HobStart, OUT EFI_PHYSICAL_ADDRESS *BaseAddress, OUT UINT64 *Length, OUT VOID **EntryPoint, OUT EFI_GUID **FileName ) /*++ Routine Description: Get memory allocation hob created for DXE core and extract its information Arguments: HobStart - Start pointer of the hob list BaseAddress - Start address of memory allocated for DXE core Length - Length of memory allocated for DXE core EntryPoint - DXE core file name FileName - File Name Returns: EFI_NOT_FOUND - DxeCoreHob not found EFI_SUCCESS - DxeCoreHob found and information got --*/ { EFI_PEI_HOB_POINTERS DxeCoreHob; DxeCoreHob.Raw = HobStart; DxeCoreHob.Raw = GetHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, DxeCoreHob.Raw); while (DxeCoreHob.Header->HobType == EFI_HOB_TYPE_MEMORY_ALLOCATION && !EfiCompareGuid (&DxeCoreHob.MemoryAllocationModule->MemoryAllocationHeader.Name, &gEfiHobMemeryAllocModuleGuid)) { DxeCoreHob.Raw = GET_NEXT_HOB (DxeCoreHob); DxeCoreHob.Raw = GetHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, DxeCoreHob.Raw); } if (DxeCoreHob.Header->HobType != EFI_HOB_TYPE_MEMORY_ALLOCATION) { return EFI_NOT_FOUND; } *BaseAddress = DxeCoreHob.MemoryAllocationModule->MemoryAllocationHeader.MemoryBaseAddress; *Length = DxeCoreHob.MemoryAllocationModule->MemoryAllocationHeader.MemoryLength; *EntryPoint = (VOID *) (UINTN) DxeCoreHob.MemoryAllocationModule->EntryPoint; *FileName = &DxeCoreHob.MemoryAllocationModule->ModuleName; return EFI_SUCCESS; }
EFI_STATUS GetPeiProtocol ( IN EFI_GUID *ProtocolGuid, IN VOID **Interface ) /*++ Routine Description: Searches for a Protocol Interface passed from PEI through a HOB Arguments: ProtocolGuid - The Protocol GUID to search for in the HOB List Interface - A pointer to the interface for the Protocol GUID Returns: EFI_SUCCESS - The Protocol GUID was found and its interface is returned in Interface EFI_NOT_FOUND - The Protocol GUID was not found in the HOB List --*/ { EFI_STATUS Status; EFI_PEI_HOB_POINTERS GuidHob; // // Get Hob list // Status = EfiLibGetSystemConfigurationTable (&gEfiHobListGuid, (VOID **) &GuidHob.Raw); if (EFI_ERROR (Status)) { return Status; } for (Status = EFI_NOT_FOUND; EFI_ERROR (Status);) { if (END_OF_HOB_LIST (GuidHob)) { Status = EFI_NOT_FOUND; break; } if (GET_HOB_TYPE (GuidHob) == EFI_HOB_TYPE_GUID_EXTENSION) { if (EfiCompareGuid (ProtocolGuid, &GuidHob.Guid->Name)) { Status = EFI_SUCCESS; *Interface = (VOID *) *(UINTN *) ((UINT8 *) (&GuidHob.Guid->Name) + sizeof (EFI_GUID)); } } GuidHob.Raw = GET_NEXT_HOB (GuidHob); } return Status; }
VOID * GetHob ( IN UINT16 Type, IN VOID *HobStart ) /*++ Routine Description: This function returns the first instance of a HOB type in a HOB list. Arguments: Type The HOB type to return. HobStart The first HOB in the HOB list. Returns: HobStart There were no HOBs found with the requested type. else Returns the first HOB with the matching type. --*/ { EFI_PEI_HOB_POINTERS Hob; Hob.Raw = HobStart; // // Return input if not found // if (HobStart == NULL) { return HobStart; } // // Parse the HOB list, stop if end of list or matching type found. // while (!END_OF_HOB_LIST (Hob)) { if (Hob.Header->HobType == Type) { break; } Hob.Raw = GET_NEXT_HOB (Hob); } // // Return input if not found // if (END_OF_HOB_LIST (Hob)) { return HobStart; } return (VOID *) (Hob.Raw); }
/** Hook point for AcpiVariableThunkPlatform for S3Ready. @param AcpiS3Context ACPI s3 context **/ VOID S3ReadyThunkPlatform ( IN ACPI_S3_CONTEXT *AcpiS3Context ) { EFI_PHYSICAL_ADDRESS AcpiMemoryBase; UINT32 AcpiMemorySize; EFI_PEI_HOB_POINTERS Hob; UINT64 MemoryLength; DEBUG ((EFI_D_INFO, "S3ReadyThunkPlatform\n")); if (mAcpiVariableSetCompatibility == NULL) { return; } // // Allocate ACPI reserved memory under 4G // AcpiMemoryBase = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocateMemoryBelow4G (EfiReservedMemoryType, PcdGet32 (PcdS3AcpiReservedMemorySize)); ASSERT (AcpiMemoryBase != 0); AcpiMemorySize = PcdGet32 (PcdS3AcpiReservedMemorySize); // // Calculate the system memory length by memory hobs // MemoryLength = 0x100000; Hob.Raw = GetFirstHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR); ASSERT (Hob.Raw != NULL); while ((Hob.Raw != NULL) && (!END_OF_HOB_LIST (Hob))) { if (Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) { // // Skip the memory region below 1MB // if (Hob.ResourceDescriptor->PhysicalStart >= 0x100000) { MemoryLength += Hob.ResourceDescriptor->ResourceLength; } } Hob.Raw = GET_NEXT_HOB (Hob); Hob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, Hob.Raw); } mAcpiVariableSetCompatibility->AcpiReservedMemoryBase = AcpiMemoryBase; mAcpiVariableSetCompatibility->AcpiReservedMemorySize = AcpiMemorySize; mAcpiVariableSetCompatibility->SystemMemoryLength = MemoryLength; DEBUG((EFI_D_INFO, "AcpiVariableThunkPlatform: AcpiMemoryBase is 0x%8x\n", mAcpiVariableSetCompatibility->AcpiReservedMemoryBase)); DEBUG((EFI_D_INFO, "AcpiVariableThunkPlatform: AcpiMemorySize is 0x%8x\n", mAcpiVariableSetCompatibility->AcpiReservedMemorySize)); DEBUG((EFI_D_INFO, "AcpiVariableThunkPlatform: SystemMemoryLength is 0x%8x\n", mAcpiVariableSetCompatibility->SystemMemoryLength)); return ; }
/* * Returns the next instance of the matching resource HOB from the starting HOB. */ void *get_next_resource_hob(const EFI_GUID *guid, const void *hob_start) { EFI_PEI_HOB_POINTERS hob; hob.Raw = (UINT8 *)hob_start; while ((hob.Raw = get_next_hob(EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, hob.Raw)) != NULL) { if (compare_guid(guid, &hob.ResourceDescriptor->Owner)) break; hob.Raw = GET_NEXT_HOB(hob.Raw); } return hob.Raw; }
/* Returns the next instance of the matched GUID HOB from the starting HOB. */ void *get_next_guid_hob(const EFI_GUID * guid, const void *hob_start) { EFI_PEI_HOB_POINTERS hob; hob.Raw = (uint8_t *)hob_start; while ((hob.Raw = get_next_hob(EFI_HOB_TYPE_GUID_EXTENSION, hob.Raw)) != NULL) { if (compare_guid(guid, &hob.Guid->Name)) break; hob.Raw = GET_NEXT_HOB(hob.Raw); } return hob.Raw; }
/* * Print out a structure of all the HOBs * that match a certain type: * Print all types (0x0000) * EFI_HOB_TYPE_HANDOFF (0x0001) * EFI_HOB_TYPE_MEMORY_ALLOCATION (0x0002) * EFI_HOB_TYPE_RESOURCE_DESCRIPTOR (0x0003) * EFI_HOB_TYPE_GUID_EXTENSION (0x0004) * EFI_HOB_TYPE_MEMORY_POOL (0x0007) * EFI_HOB_TYPE_UNUSED (0xFFFE) * EFI_HOB_TYPE_END_OF_HOB_LIST (0xFFFF) */ void print_hob_type_structure(u16 hob_type, void *hob_list_ptr) { u32 *current_hob; u32 *next_hob = 0; u8 last_hob = 0; u32 current_type; const char *current_type_str; current_hob = hob_list_ptr; /* * Print out HOBs of our desired type until * the end of the HOB list */ printk(BIOS_DEBUG, "\n=== FSP HOB Data Structure ===\n"); printk(BIOS_DEBUG, "0x%p: hob_list_ptr\n", hob_list_ptr); do { EFI_HOB_GENERIC_HEADER *current_header_ptr = (EFI_HOB_GENERIC_HEADER *)current_hob; /* Get the type of this HOB */ current_type = current_header_ptr->HobType; current_type_str = get_hob_type_string(current_hob); if (current_type == hob_type || hob_type == 0x0000) { printk(BIOS_DEBUG, "HOB %p is an %s (type 0x%0x)\n", current_hob, current_type_str, current_type); switch (current_type) { case EFI_HOB_TYPE_MEMORY_ALLOCATION: print_hob_mem_attributes(current_hob); break; case EFI_HOB_TYPE_RESOURCE_DESCRIPTOR: print_hob_resource_attributes(current_hob); break; } } /* Check for end of HOB list */ last_hob = END_OF_HOB_LIST(current_hob); if (!last_hob) { /* Get next HOB pointer */ next_hob = GET_NEXT_HOB(current_hob); /* Start on next HOB */ current_hob = next_hob; } } while (!last_hob); printk(BIOS_DEBUG, "=== End of FSP HOB Data Structure ===\n\n"); }
EFI_STATUS GetNextFirmwareVolume2Hob ( IN OUT VOID **HobStart, OUT EFI_PHYSICAL_ADDRESS *BaseAddress, OUT UINT64 *Length, OUT EFI_GUID *FileName ) /*++ Routine Description: Get next firmware volume2 hob from HobStart Arguments: HobStart - Start pointer of hob list BaseAddress - Start address of next firmware volume Length - Length of next firmware volume Returns: EFI_NOT_FOUND - Next firmware volume not found EFI_SUCCESS - Next firmware volume found with address information --*/ { EFI_PEI_HOB_POINTERS FirmwareVolumeHob; FirmwareVolumeHob.Raw = *HobStart; if (END_OF_HOB_LIST (FirmwareVolumeHob)) { return EFI_NOT_FOUND; } FirmwareVolumeHob.Raw = GetHob (EFI_HOB_TYPE_FV2, *HobStart); if (FirmwareVolumeHob.Header->HobType != EFI_HOB_TYPE_FV2) { return EFI_NOT_FOUND; } *BaseAddress = FirmwareVolumeHob.FirmwareVolume2->BaseAddress; *Length = FirmwareVolumeHob.FirmwareVolume2->Length; EfiCommonLibCopyMem(FileName,&FirmwareVolumeHob.FirmwareVolume2->FileName,sizeof(EFI_GUID)); *HobStart = GET_NEXT_HOB (FirmwareVolumeHob); return EFI_SUCCESS; }
EFI_STATUS testHotKey() { EFI_STATUS Status = 0; EFI_HOB_GENERIC_HEADER *Hob; UINT16 HobType; UINT16 HobLength; for(Hob = GetHobList();!END_OF_HOB_LIST(Hob);Hob = GET_NEXT_HOB(Hob)) { HobType = GET_HOB_TYPE (Hob); HobLength = GET_HOB_LENGTH (Hob); Print((CONST CHAR16*)L"Hob %x %x\n", HobType, HobLength); } return Status; }
EFIAPI GetNextGuidHob ( IN CONST EFI_GUID *Guid, IN CONST VOID *HobStart ){ EFI_PEI_HOB_POINTERS GuidHob; GuidHob.Raw = (UINT8 *) HobStart; while ((GuidHob.Raw = GetNextHob (EFI_HOB_TYPE_GUID_EXTENSION, GuidHob.Raw)) != NULL) { if (CompareGuid (Guid, &GuidHob.Guid->Name)) { break; } GuidHob.Raw = GET_NEXT_HOB (GuidHob); } return GuidHob.Raw; }
/** Allocates one or more 4KB pages of a certain memory type. Allocates the number of 4KB pages of a certain memory type and returns a pointer to the allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL is returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. @param MemoryType The type of memory to allocate. @param Pages The number of 4 KB pages to allocate. @return A pointer to the allocated buffer or NULL if allocation fails. **/ VOID * InternalAllocatePages ( IN EFI_MEMORY_TYPE MemoryType, IN UINTN Pages ) { EFI_STATUS Status; EFI_PHYSICAL_ADDRESS Memory; EFI_MEMORY_TYPE RequestType; EFI_PEI_HOB_POINTERS Hob; if (Pages == 0) { return NULL; } RequestType = MemoryType; if (MemoryType == EfiReservedMemoryType) { // // PEI AllocatePages() doesn't support EfiReservedMemoryType. // Change RequestType to EfiBootServicesData for memory allocation. // RequestType = EfiBootServicesData; } Status = PeiServicesAllocatePages (RequestType, Pages, &Memory); if (EFI_ERROR (Status)) { return NULL; } if (MemoryType == EfiReservedMemoryType) { // // Memory type needs to be updated to EfiReservedMemoryType. Per PI spec Volume 1, // PEI AllocatePages() will automate the creation of the Memory Allocation HOB types. // Search Memory Allocation HOB and find the matched memory region, // then change its memory type to EfiReservedMemoryType. // Hob.Raw = GetFirstHob (EFI_HOB_TYPE_MEMORY_ALLOCATION); while (Hob.Raw != NULL && Hob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress != Memory) { Hob.Raw = GET_NEXT_HOB (Hob); Hob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, Hob.Raw); } ASSERT (Hob.Raw != NULL); Hob.MemoryAllocation->AllocDescriptor.MemoryType = EfiReservedMemoryType; } return (VOID *) (UINTN) Memory; }
/** Notify function on End Of PEI PPI. On S3 boot, this function will restore wakeup buffer data. On normal boot, this function will flag wakeup buffer to be un-used type. @param[in] PeiServices The pointer to the PEI Services Table. @param[in] NotifyDescriptor Address of the notification descriptor data structure. @param[in] Ppi Address of the PPI that was installed. @retval EFI_SUCCESS When everything is OK. **/ EFI_STATUS EFIAPI CpuMpEndOfPeiCallback ( IN EFI_PEI_SERVICES **PeiServices, IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, IN VOID *Ppi ) { EFI_STATUS Status; EFI_BOOT_MODE BootMode; CPU_MP_DATA *CpuMpData; EFI_PEI_HOB_POINTERS Hob; EFI_HOB_MEMORY_ALLOCATION *MemoryHob; DEBUG ((DEBUG_INFO, "PeiMpInitLib: CpuMpEndOfPeiCallback () invoked\n")); Status = PeiServicesGetBootMode (&BootMode); ASSERT_EFI_ERROR (Status); CpuMpData = GetCpuMpData (); if (BootMode != BOOT_ON_S3_RESUME) { // // Get the HOB list for processing // Hob.Raw = GetHobList (); // // Collect memory ranges // while (!END_OF_HOB_LIST (Hob)) { if (Hob.Header->HobType == EFI_HOB_TYPE_MEMORY_ALLOCATION) { MemoryHob = Hob.MemoryAllocation; if (MemoryHob->AllocDescriptor.MemoryBaseAddress == CpuMpData->WakeupBuffer) { // // Flag this HOB type to un-used // GET_HOB_TYPE (Hob) = EFI_HOB_TYPE_UNUSED; break; } } Hob.Raw = GET_NEXT_HOB (Hob); } } else { CpuMpData->SaveRestoreFlag = TRUE; RestoreWakeupBuffer (CpuMpData); } return EFI_SUCCESS; }
EFIAPI get_next_guid_hob( CONST EFI_GUID * guid, CONST VOID *hob_start ) { EFI_PEI_HOB_POINTERS hob; hob.Raw = (UINT8 *)hob_start; while ((hob.Raw = get_next_hob(EFI_HOB_TYPE_GUID_EXTENSION, hob.Raw)) != NULL) { if (compare_guid(guid, &hob.Guid->Name)) break; hob.Raw = GET_NEXT_HOB(hob.Raw); } return hob.Raw; }
/** Adds SMBIOS records to tables @param[in] ImageHandle Image handle of this driver. @param[in] SystemTable Global system service table. @retval EFI_UNSUPPORTED - Could not locate SMBIOS protocol @retval EFI_OUT_OF_RESOURCES - Failed to allocate memory for SMBIOS HOB type. @retval EFI_SUCCESS - Successfully added SMBIOS records based on HOB. **/ EFI_STATUS EFIAPI DxeSmbiosDataHobLibConstructor ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_PEI_HOB_POINTERS Hob; EFI_SMBIOS_HANDLE SmbiosHandle; EFI_SMBIOS_PROTOCOL *Smbios; EFI_STATUS Status; UINT8 *RecordPtr; UINT16 RecordCount; RecordCount = 0; DEBUG ((DEBUG_INFO, "Adding SMBIOS records from HOB..\n")); Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, (VOID **)&Smbios); if (Smbios == NULL) { DEBUG ((DEBUG_WARN, "Can't locate SMBIOS protocol\n")); return EFI_UNSUPPORTED; } /// /// Get SMBIOS HOB data (each hob contains one SMBIOS record) /// for (Hob.Raw = GetHobList (); !END_OF_HOB_LIST(Hob); Hob.Raw = GET_NEXT_HOB (Hob)) { if ((GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_GUID_EXTENSION) && (CompareGuid (&Hob.Guid->Name, &gIntelSmbiosDataHobGuid))) { RecordPtr = GET_GUID_HOB_DATA (Hob.Raw); /// /// Add generic SMBIOS HOB to SMBIOS table /// DEBUG ((DEBUG_VERBOSE, "Add SMBIOS record type: %x\n", ((EFI_SMBIOS_TABLE_HEADER *) RecordPtr)->Type)); SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED; Status = Smbios->Add (Smbios, NULL, &SmbiosHandle, (EFI_SMBIOS_TABLE_HEADER *) RecordPtr); if (!EFI_ERROR (Status)) { RecordCount++; } } } DEBUG ((DEBUG_INFO, "Found %d Records and added to SMBIOS table.\n", RecordCount)); return EFI_SUCCESS; }
STATIC EFI_STATUS GetMemorySize ( IN CONST EFI_PEI_SERVICES **PeiServices, OUT UINT64 *LowMemoryLength, OUT UINT64 *HighMemoryLength ) { EFI_STATUS Status; EFI_PEI_HOB_POINTERS Hob; *HighMemoryLength = 0; *LowMemoryLength = 0x100000; // // Get the HOB list for processing // Status = (*PeiServices)->GetHobList (PeiServices, (void **)&Hob.Raw); if (EFI_ERROR(Status)) { return Status; } // // Collect memory ranges // while (!END_OF_HOB_LIST (Hob)) { if (Hob.Header->HobType == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) { if (Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) { // // Need memory above 1MB to be collected here // if (Hob.ResourceDescriptor->PhysicalStart >= 0x100000 && Hob.ResourceDescriptor->PhysicalStart < (EFI_PHYSICAL_ADDRESS) 0x100000000) { *LowMemoryLength += (UINT64) (Hob.ResourceDescriptor->ResourceLength); } else if (Hob.ResourceDescriptor->PhysicalStart >= (EFI_PHYSICAL_ADDRESS) 0x100000000) { *HighMemoryLength += (UINT64) (Hob.ResourceDescriptor->ResourceLength); } } } Hob.Raw = GET_NEXT_HOB (Hob); } return EFI_SUCCESS; }
/* Returns the next instance of a HOB type from the starting HOB. */ void *get_next_hob(uint16_t type, const void *hob_start) { EFI_PEI_HOB_POINTERS hob; if (!hob_start) return NULL; hob.Raw = (UINT8 *)hob_start; /* Parse the HOB list until end of list or matching type is found. */ while (!END_OF_HOB_LIST(hob.Raw)) { if (hob.Header->HobType == type) return hob.Raw; if (GET_HOB_LENGTH(hob.Raw) < sizeof(*hob.Header)) break; hob.Raw = GET_NEXT_HOB(hob.Raw); } return NULL; }
/** Register DXE Core to memory profile. @param HobStart The start address of the HOB. @param ContextData Memory profile context. @retval TRUE Register success. @retval FALSE Register fail. **/ BOOLEAN RegisterDxeCore ( IN VOID *HobStart, IN MEMORY_PROFILE_CONTEXT_DATA *ContextData ) { EFI_PEI_HOB_POINTERS DxeCoreHob; MEMORY_PROFILE_DRIVER_INFO_DATA *DriverInfoData; PHYSICAL_ADDRESS ImageBase; ASSERT (ContextData != NULL); // // Searching for image hob // DxeCoreHob.Raw = HobStart; while ((DxeCoreHob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, DxeCoreHob.Raw)) != NULL) { if (CompareGuid (&DxeCoreHob.MemoryAllocationModule->MemoryAllocationHeader.Name, &gEfiHobMemoryAllocModuleGuid)) { // // Find Dxe Core HOB // break; } DxeCoreHob.Raw = GET_NEXT_HOB (DxeCoreHob); } ASSERT (DxeCoreHob.Raw != NULL); ImageBase = DxeCoreHob.MemoryAllocationModule->MemoryAllocationHeader.MemoryBaseAddress; DriverInfoData = BuildDriverInfo ( ContextData, &DxeCoreHob.MemoryAllocationModule->ModuleName, ImageBase, DxeCoreHob.MemoryAllocationModule->MemoryAllocationHeader.MemoryLength, DxeCoreHob.MemoryAllocationModule->EntryPoint, InternalPeCoffGetSubsystem ((VOID *) (UINTN) ImageBase), EFI_FV_FILETYPE_DXE_CORE ); if (DriverInfoData == NULL) { return FALSE; } return TRUE; }