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); }
/** 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; }
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 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; }
// // 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; }
/** 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); } }
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; }
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; }
/** 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 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; }
/** 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 ; }
/* * 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; }
/** 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; }
/** 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; }
STATIC EFI_STATUS GetNextCapsuleVolumeHob ( IN OUT VOID **HobStart, OUT EFI_PHYSICAL_ADDRESS *BaseAddress, OUT UINT64 *Length ) /*++ Routine Description: Find the next Capsule volume HOB Arguments: HobStart - start of HOBs BaseAddress - returned base address of capsule volume Length - length of capsule volume pointed to by BaseAddress Returns: EFI_SUCCESS - one found EFI_NOT_FOUND - did not find one --*/ { EFI_PEI_HOB_POINTERS Hob; Hob.Raw = *HobStart; if (END_OF_HOB_LIST (Hob)) { return EFI_NOT_FOUND; } Hob.Raw = GetHob (EFI_HOB_TYPE_CV, *HobStart); if (Hob.Header->HobType != EFI_HOB_TYPE_CV) { return EFI_NOT_FOUND; } *BaseAddress = Hob.CapsuleVolume->BaseAddress; *Length = Hob.CapsuleVolume->Length; *HobStart = GET_NEXT_HOB (Hob); return EFI_SUCCESS; }
int dram_init_f(void) { phys_size_t ram_size = 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 || hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_MEMORY_RESERVED) { ram_size += hob.ResourceDescriptor->ResourceLength; } } hob.Raw = GET_NEXT_HOB(hob); } gd->ram_size = ram_size; return 0; }
EFIAPI GetNextHob ( IN UINT16 Type, IN CONST VOID *HobStart ) { EFI_PEI_HOB_POINTERS Hob; ASSERT (HobStart != NULL); Hob.Raw = (UINT8 *) HobStart; // // Parse the HOB list until end of list or matching type is found. // while (!END_OF_HOB_LIST (Hob)) { if (Hob.Header->HobType == Type) { return Hob.Raw; } Hob.Raw = GET_NEXT_HOB (Hob); } return NULL; }
EFIAPI get_next_hob( UINT16 type, CONST VOID *hob_start ) { EFI_PEI_HOB_POINTERS hob; ASSERT(hob_start != 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; }
/** 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 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_PEI_HOB_POINTERS Hob; *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) { // // 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); } }
/** Get available system memory below 1MB by specified size. @param[in] WakeupBufferSize Wakeup buffer size required @retval other Return wakeup buffer address below 1MB. @retval -1 Cannot find free memory below 1MB. **/ UINTN GetWakeupBuffer ( IN UINTN WakeupBufferSize ) { EFI_PEI_HOB_POINTERS Hob; UINT64 WakeupBufferStart; UINT64 WakeupBufferEnd; WakeupBufferSize = (WakeupBufferSize + SIZE_4KB - 1) & ~(SIZE_4KB - 1); // // 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->PhysicalStart < BASE_1MB) && (Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) && ((Hob.ResourceDescriptor->ResourceAttribute & (EFI_RESOURCE_ATTRIBUTE_READ_PROTECTED | EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTED | EFI_RESOURCE_ATTRIBUTE_EXECUTION_PROTECTED )) == 0) ) { // // Need memory under 1MB to be collected here // WakeupBufferEnd = Hob.ResourceDescriptor->PhysicalStart + Hob.ResourceDescriptor->ResourceLength; if (WakeupBufferEnd > BASE_1MB) { // // Wakeup buffer should be under 1MB // WakeupBufferEnd = BASE_1MB; } while (WakeupBufferEnd > WakeupBufferSize) { // // Wakeup buffer should be aligned on 4KB // WakeupBufferStart = (WakeupBufferEnd - WakeupBufferSize) & ~(SIZE_4KB - 1); if (WakeupBufferStart < Hob.ResourceDescriptor->PhysicalStart) { break; } if (CheckOverlapWithAllocatedBuffer (WakeupBufferStart, WakeupBufferEnd)) { // // If this range is overlapped with existing allocated buffer, skip it // and find the next range // WakeupBufferEnd -= WakeupBufferSize; continue; } DEBUG ((DEBUG_INFO, "WakeupBufferStart = %x, WakeupBufferSize = %x\n", WakeupBufferStart, WakeupBufferSize)); return (UINTN)WakeupBufferStart; } } } // // Find the next HOB // Hob.Raw = GET_NEXT_HOB (Hob); } return (UINTN) -1; }
/** Install SEC HOB data to the HOB List. @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. @param SecHobList Pointer to SEC HOB List. @return EFI_SUCCESS Success to install SEC HOB data. @retval EFI_OUT_OF_RESOURCES If there is no more memory to grow the Hoblist. **/ EFI_STATUS PeiInstallSecHobData ( IN CONST EFI_PEI_SERVICES **PeiServices, IN EFI_HOB_GENERIC_HEADER *SecHobList ) { EFI_STATUS Status; EFI_HOB_HANDOFF_INFO_TABLE *HandOffHob; EFI_PEI_HOB_POINTERS HobStart; EFI_PEI_HOB_POINTERS Hob; UINTN SecHobListLength; EFI_PHYSICAL_ADDRESS FreeMemory; EFI_HOB_GENERIC_HEADER *HobEnd; HandOffHob = NULL; Status = PeiGetHobList (PeiServices, (VOID **) &HandOffHob); if (EFI_ERROR(Status)) { return Status; } ASSERT (HandOffHob != NULL); HobStart.Raw = (UINT8 *) SecHobList; // // The HobList must not contain a EFI_HOB_HANDOFF_INFO_TABLE HOB (PHIT) HOB. // ASSERT (HobStart.Header->HobType != EFI_HOB_TYPE_HANDOFF); // // Calculate the SEC HOB List length, // not including the terminated HOB(EFI_HOB_TYPE_END_OF_HOB_LIST). // for (Hob.Raw = HobStart.Raw; !END_OF_HOB_LIST (Hob); Hob.Raw = GET_NEXT_HOB (Hob)); SecHobListLength = (UINTN) Hob.Raw - (UINTN) HobStart.Raw; // // The length must be 8-bytes aligned. // ASSERT ((SecHobListLength & 0x7) == 0); FreeMemory = HandOffHob->EfiFreeMemoryTop - HandOffHob->EfiFreeMemoryBottom; if (FreeMemory < SecHobListLength) { DEBUG ((DEBUG_ERROR, "PeiInstallSecHobData fail: SecHobListLength - 0x%08x\n", SecHobListLength)); DEBUG ((DEBUG_ERROR, " FreeMemoryTop - 0x%08x\n", (UINTN)HandOffHob->EfiFreeMemoryTop)); DEBUG ((DEBUG_ERROR, " FreeMemoryBottom - 0x%08x\n", (UINTN)HandOffHob->EfiFreeMemoryBottom)); return EFI_OUT_OF_RESOURCES; } Hob.Raw = (UINT8 *) (UINTN) HandOffHob->EfiEndOfHobList; CopyMem (Hob.Raw, HobStart.Raw, SecHobListLength); HobEnd = (EFI_HOB_GENERIC_HEADER *) ((UINTN) Hob.Raw + SecHobListLength); HandOffHob->EfiEndOfHobList = (EFI_PHYSICAL_ADDRESS) (UINTN) HobEnd; HobEnd->HobType = EFI_HOB_TYPE_END_OF_HOB_LIST; HobEnd->HobLength = (UINT16) sizeof (EFI_HOB_GENERIC_HEADER); HobEnd->Reserved = 0; HobEnd++; HandOffHob->EfiFreeMemoryBottom = (EFI_PHYSICAL_ADDRESS) (UINTN) HobEnd; return EFI_SUCCESS; }
EFI_STATUS EFIAPI InitAcpiSmmPlatform ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) /*++ Routine Description: Initializes the SMM S3 Handler Driver. Arguments: ImageHandle - The image handle of Sleep State Wake driver. SystemTable - The starndard EFI system table. Returns: EFI_OUT_OF_RESOURCES - Insufficient resources to complete function. EFI_SUCCESS - Function has completed successfully. Other - Error occured during execution. --*/ { EFI_STATUS Status; EFI_GLOBAL_NVS_AREA_PROTOCOL *AcpiNvsProtocol = NULL; UINTN MemoryLength; EFI_PEI_HOB_POINTERS Hob; Status = gBS->LocateProtocol ( &gEfiGlobalNvsAreaProtocolGuid, NULL, (VOID **) &AcpiNvsProtocol ); ASSERT_EFI_ERROR (Status); mAcpiSmm.BootScriptSaved = 0; mPlatformType = (EFI_PLATFORM_TYPE)PcdGet16 (PcdPlatformType); // // 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 += (UINTN)Hob.ResourceDescriptor->ResourceLength; } } Hob.Raw = GET_NEXT_HOB (Hob); Hob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, Hob.Raw); } ReservedS3Memory(MemoryLength); // // Locate and Register to Parent driver // Status = RegisterToDispatchDriver (); ASSERT_EFI_ERROR (Status); return EFI_SUCCESS; }
EFI_STATUS RebuildHeap ( IN OUT HEAP_MANAGER **HeapManagerPtr ) { EFI_STATUS Status; AGESA_STATUS AgesaStatus; UINTN AlignTo16ByteInDxeMem; UINTN TotalAlignTo16ByteInHob; EFI_PEI_HOB_POINTERS Hob; VOID *HobList; VOID *HeapBufferInHob; HEAP_MANAGER *HeapManagerInHob; BUFFER_NODE *HeapHeaderNodeInHob; BUFFER_NODE *HeapCurrentNodeInHob; BUFFER_NODE *HeapPreNodeInHob; HEAP_MANAGER *HeapManagerInDxeMem; BUFFER_NODE *HeapHeaderNodeInDxeMem; BUFFER_NODE *HeapCurrentNodeInDxeMem; BUFFER_NODE *HeapPreNodeInDxeMem; UINT32 OffsetOfHeapCurrentNodeInDxeMem; EFI_HOB_GUID_TYPE *GuidHob; AGESA_BUFFER_PARAMS AllocParams; Status = EfiGetSystemConfigurationTable (&gEfiHobListGuid, &HobList); ASSERT_EFI_ERROR (Status); Hob.Raw = HobList; HeapBufferInHob = NULL; while (!END_OF_HOB_LIST (Hob)) { GuidHob = GetNextGuidHob (&gAmdHeapHobGuid, HobList); HeapBufferInHob = GET_GUID_HOB_DATA (GuidHob); if (HeapBufferInHob != NULL) { HeapManagerInHob = (HEAP_MANAGER *) HeapBufferInHob; HeapHeaderNodeInHob = (BUFFER_NODE *) ((UINT8 *) HeapManagerInHob + HeapManagerInHob->FirstActiveBufferOffset); HeapCurrentNodeInHob = HeapHeaderNodeInHob; // // 1. Analyse heap buffer from HOB data to calculate the final size for recreating the heap buffers // Reserve maximum pad size for each heap node. // 2. Allocate memory for heap buffers // 3. Copying heap manager data from HOB include extracing 1-byte alignment to 16-byte alignment // // // 1. Analyse heap buffer from HOB data to calculate the final size for recreating the heap buffers. // Reserve maximum pad size for each heap node. // TotalAlignTo16ByteInHob = 0; do { HeapPreNodeInHob = HeapCurrentNodeInHob; TotalAlignTo16ByteInHob += 0xF; HeapCurrentNodeInHob = (BUFFER_NODE *) ((UINT8 *) HeapBufferInHob + HeapCurrentNodeInHob->OffsetOfNextNode); } while (HeapPreNodeInHob->OffsetOfNextNode != AMD_HEAP_INVALID_HEAP_OFFSET); // // 2. Allocate memory for heap buffers // AllocParams.BufferLength = (UINT32) (HeapManagerInHob->UsedSize + TotalAlignTo16ByteInHob + 0x0F); AllocParams.BufferHandle = AMD_HEAP_IN_MAIN_MEMORY_HANDLE; if ((AgesaStatus = AgesaAllocateBuffer (0, &AllocParams)) != AGESA_SUCCESS) { if (AGESA_ERROR > AgesaStatus) { return EFI_OUT_OF_RESOURCES; } } ZeroMem (AllocParams.BufferPointer, AllocParams.BufferLength); *HeapManagerPtr = AllocParams.BufferPointer; // // 3. Copying heap manager data from HOB include extracing 1-byte alignment to 16-byte alignment // HeapManagerInDxeMem = *HeapManagerPtr; HeapManagerInDxeMem->FirstActiveBufferOffset = sizeof (HEAP_MANAGER); HeapManagerInDxeMem->UsedSize = sizeof (HEAP_MANAGER); HeapHeaderNodeInDxeMem = (BUFFER_NODE *) ((UINT8 *) HeapManagerInDxeMem + HeapManagerInDxeMem->FirstActiveBufferOffset); OffsetOfHeapCurrentNodeInDxeMem = HeapManagerInDxeMem->FirstActiveBufferOffset; HeapCurrentNodeInDxeMem = HeapHeaderNodeInDxeMem; HeapCurrentNodeInHob = HeapHeaderNodeInHob; HeapPreNodeInHob = NULL; do { // Create BUFFER_NODE with 16-byte alignment padding considered. // The beginning of data buffer is on 16-byte boundary address. // The structure of a heap buffer would be looked like below. // // +---------------------------------------------------------------------------------+ // | BUFFER_NODE | Pad | IDS SENTINEL ("Head") | Data buffer | IDS SENTINEL ("Tail") | // +---------------------------------------------------------------------------------+ // AlignTo16ByteInDxeMem = ((0x10 - (((UINTN) (VOID *) HeapCurrentNodeInDxeMem + sizeof (BUFFER_NODE) + SIZE_OF_SENTINEL) & 0xF)) & 0xF); HeapCurrentNodeInDxeMem->BufferHandle = HeapCurrentNodeInHob->BufferHandle; HeapCurrentNodeInDxeMem->BufferSize = (UINT32) (HeapCurrentNodeInHob->BufferSize + AlignTo16ByteInDxeMem); HeapCurrentNodeInDxeMem->Persist = HeapCurrentNodeInHob->Persist; HeapCurrentNodeInDxeMem->PadSize = (UINT8) AlignTo16ByteInDxeMem; HeapCurrentNodeInDxeMem->OffsetOfNextNode = OffsetOfHeapCurrentNodeInDxeMem + sizeof (BUFFER_NODE) + HeapCurrentNodeInDxeMem->BufferSize; // Copy buffer data gBS->CopyMem ( (UINT8 *) ((UINT8 *) HeapCurrentNodeInDxeMem + sizeof (BUFFER_NODE) + AlignTo16ByteInDxeMem), (UINT8 *) ((UINT8 *) HeapCurrentNodeInHob + sizeof (BUFFER_NODE)), HeapCurrentNodeInHob->BufferSize ); // Point to the next heap node HeapPreNodeInHob = HeapCurrentNodeInHob; HeapPreNodeInDxeMem = HeapCurrentNodeInDxeMem; HeapCurrentNodeInHob = (BUFFER_NODE *) ((UINT8 *) HeapBufferInHob + HeapCurrentNodeInHob->OffsetOfNextNode); HeapCurrentNodeInDxeMem = (BUFFER_NODE *) ((UINT8 *) HeapManagerInDxeMem + HeapCurrentNodeInDxeMem->OffsetOfNextNode); OffsetOfHeapCurrentNodeInDxeMem = (UINT32) ((UINTN) HeapCurrentNodeInDxeMem - (UINTN) HeapManagerInDxeMem); } while (HeapPreNodeInHob->OffsetOfNextNode != AMD_HEAP_INVALID_HEAP_OFFSET); // // Finalize the last heap node // HeapManagerInDxeMem->UsedSize = (UINT32) HeapPreNodeInDxeMem->OffsetOfNextNode; HeapPreNodeInDxeMem->OffsetOfNextNode = AMD_HEAP_INVALID_HEAP_OFFSET; // // Finalize Heap Manager pointer // No free buffer node is provide after heap recreation. // *HeapManagerPtr = HeapManagerInDxeMem; HeapManagerInDxeMem->FirstActiveBufferOffset = (UINT32) ((UINT8 *) HeapHeaderNodeInDxeMem - (UINT8 *) HeapManagerInDxeMem); HeapManagerInDxeMem->FirstFreeSpaceOffset = AMD_HEAP_INVALID_HEAP_OFFSET; HeapManagerInDxeMem->Signature = HeapManagerInHob->Signature; return EFI_SUCCESS; } } return EFI_NOT_FOUND; }
/** Main entry point to DXE Core. @param HobStart Pointer to the beginning of the HOB List from PEI. @return This function should never return. **/ VOID EFIAPI DxeMain ( IN VOID *HobStart ) { EFI_STATUS Status; EFI_PHYSICAL_ADDRESS MemoryBaseAddress; UINT64 MemoryLength; PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; UINTN Index; EFI_HOB_GUID_TYPE *GuidHob; EFI_VECTOR_HANDOFF_INFO *VectorInfoList; EFI_VECTOR_HANDOFF_INFO *VectorInfo; VOID *EntryPoint; // // Setup the default exception handlers // VectorInfoList = NULL; GuidHob = GetNextGuidHob (&gEfiVectorHandoffInfoPpiGuid, HobStart); if (GuidHob != NULL) { VectorInfoList = (EFI_VECTOR_HANDOFF_INFO *) (GET_GUID_HOB_DATA(GuidHob)); } Status = InitializeCpuExceptionHandlers (VectorInfoList); ASSERT_EFI_ERROR (Status); // // Initialize Debug Agent to support source level debug in DXE phase // InitializeDebugAgent (DEBUG_AGENT_INIT_DXE_CORE, HobStart, NULL); // // Initialize Memory Services // CoreInitializeMemoryServices (&HobStart, &MemoryBaseAddress, &MemoryLength); MemoryProfileInit (HobStart); // // Allocate the EFI System Table and EFI Runtime Service Table from EfiRuntimeServicesData // Use the templates to initialize the contents of the EFI System Table and EFI Runtime Services Table // gDxeCoreST = AllocateRuntimeCopyPool (sizeof (EFI_SYSTEM_TABLE), &mEfiSystemTableTemplate); ASSERT (gDxeCoreST != NULL); gDxeCoreRT = AllocateRuntimeCopyPool (sizeof (EFI_RUNTIME_SERVICES), &mEfiRuntimeServicesTableTemplate); ASSERT (gDxeCoreRT != NULL); gDxeCoreST->RuntimeServices = gDxeCoreRT; // // Start the Image Services. // Status = CoreInitializeImageServices (HobStart); ASSERT_EFI_ERROR (Status); // // Initialize the Global Coherency Domain Services // Status = CoreInitializeGcdServices (&HobStart, MemoryBaseAddress, MemoryLength); ASSERT_EFI_ERROR (Status); // // Call constructor for all libraries // ProcessLibraryConstructorList (gDxeCoreImageHandle, gDxeCoreST); PERF_END (NULL,"PEI", NULL, 0) ; PERF_START (NULL,"DXE", NULL, 0) ; // // Report DXE Core image information to the PE/COFF Extra Action Library // ZeroMem (&ImageContext, sizeof (ImageContext)); ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)gDxeCoreLoadedImage->ImageBase; ImageContext.PdbPointer = PeCoffLoaderGetPdbPointer ((VOID*)(UINTN)ImageContext.ImageAddress); ImageContext.SizeOfHeaders = PeCoffGetSizeOfHeaders ((VOID*)(UINTN)ImageContext.ImageAddress); Status = PeCoffLoaderGetEntryPoint ((VOID*)(UINTN)ImageContext.ImageAddress, &EntryPoint); if (Status == EFI_SUCCESS) { ImageContext.EntryPoint = (EFI_PHYSICAL_ADDRESS)(UINTN)EntryPoint; } ImageContext.Handle = (VOID *)(UINTN)gDxeCoreLoadedImage->ImageBase; ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory; PeCoffLoaderRelocateImageExtraAction (&ImageContext); // // Install the DXE Services Table into the EFI System Tables's Configuration Table // Status = CoreInstallConfigurationTable (&gEfiDxeServicesTableGuid, gDxeCoreDS); ASSERT_EFI_ERROR (Status); // // Install the HOB List into the EFI System Tables's Configuration Table // Status = CoreInstallConfigurationTable (&gEfiHobListGuid, HobStart); ASSERT_EFI_ERROR (Status); // // Install Memory Type Information Table into the EFI System Tables's Configuration Table // Status = CoreInstallConfigurationTable (&gEfiMemoryTypeInformationGuid, &gMemoryTypeInformation); ASSERT_EFI_ERROR (Status); // // If Loading modules At fixed address feature is enabled, install Load moduels at fixed address // Configuration Table so that user could easily to retrieve the top address to load Dxe and PEI // Code and Tseg base to load SMM driver. // if (PcdGet64(PcdLoadModuleAtFixAddressEnable) != 0) { Status = CoreInstallConfigurationTable (&gLoadFixedAddressConfigurationTableGuid, &gLoadModuleAtFixAddressConfigurationTable); ASSERT_EFI_ERROR (Status); } // // Report Status Code here for DXE_ENTRY_POINT once it is available // REPORT_STATUS_CODE ( EFI_PROGRESS_CODE, (EFI_SOFTWARE_DXE_CORE | EFI_SW_DXE_CORE_PC_ENTRY_POINT) ); // // Create the aligned system table pointer structure that is used by external // debuggers to locate the system table... Also, install debug image info // configuration table. // CoreInitializeDebugImageInfoTable (); CoreNewDebugImageInfoEntry ( EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL, gDxeCoreLoadedImage, gDxeCoreImageHandle ); DEBUG ((DEBUG_INFO | DEBUG_LOAD, "HOBLIST address in DXE = 0x%p\n", HobStart)); DEBUG_CODE_BEGIN (); EFI_PEI_HOB_POINTERS Hob; for (Hob.Raw = HobStart; !END_OF_HOB_LIST(Hob); Hob.Raw = GET_NEXT_HOB(Hob)) { if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_MEMORY_ALLOCATION) { DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Memory Allocation 0x%08x 0x%0lx - 0x%0lx\n", \ Hob.MemoryAllocation->AllocDescriptor.MemoryType, \ Hob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress, \ Hob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress + Hob.MemoryAllocation->AllocDescriptor.MemoryLength - 1)); } } for (Hob.Raw = HobStart; !END_OF_HOB_LIST(Hob); Hob.Raw = GET_NEXT_HOB(Hob)) { if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_FV2) { DEBUG ((DEBUG_INFO | DEBUG_LOAD, "FV2 Hob 0x%0lx - 0x%0lx\n", Hob.FirmwareVolume2->BaseAddress, Hob.FirmwareVolume2->BaseAddress + Hob.FirmwareVolume2->Length - 1)); } else if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_FV) { DEBUG ((DEBUG_INFO | DEBUG_LOAD, "FV Hob 0x%0lx - 0x%0lx\n", Hob.FirmwareVolume->BaseAddress, Hob.FirmwareVolume->BaseAddress + Hob.FirmwareVolume->Length - 1)); } } DEBUG_CODE_END (); // // Initialize the Event Services // Status = CoreInitializeEventServices (); ASSERT_EFI_ERROR (Status); MemoryProfileInstallProtocol (); CoreInitializePropertiesTable (); CoreInitializeMemoryAttributesTable (); // // Get persisted vector hand-off info from GUIDeed HOB again due to HobStart may be updated, // and install configuration table // GuidHob = GetNextGuidHob (&gEfiVectorHandoffInfoPpiGuid, HobStart); if (GuidHob != NULL) { VectorInfoList = (EFI_VECTOR_HANDOFF_INFO *) (GET_GUID_HOB_DATA(GuidHob)); VectorInfo = VectorInfoList; Index = 1; while (VectorInfo->Attribute != EFI_VECTOR_HANDOFF_LAST_ENTRY) { VectorInfo ++; Index ++; } VectorInfo = AllocateCopyPool (sizeof (EFI_VECTOR_HANDOFF_INFO) * Index, (VOID *) VectorInfoList); ASSERT (VectorInfo != NULL); Status = CoreInstallConfigurationTable (&gEfiVectorHandoffTableGuid, (VOID *) VectorInfo); ASSERT_EFI_ERROR (Status); } // // Get the Protocols that were passed in from PEI to DXE through GUIDed HOBs // // These Protocols are not architectural. This implementation is sharing code between // PEI and DXE in order to save FLASH space. These Protocols could also be implemented // as part of the DXE Core. However, that would also require the DXE Core to be ported // each time a different CPU is used, a different Decompression algorithm is used, or a // different Image type is used. By placing these Protocols in PEI, the DXE Core remains // generic, and only PEI and the Arch Protocols need to be ported from Platform to Platform, // and from CPU to CPU. // // // Publish the EFI, Tiano, and Custom Decompress protocols for use by other DXE components // Status = CoreInstallMultipleProtocolInterfaces ( &mDecompressHandle, &gEfiDecompressProtocolGuid, &gEfiDecompress, NULL ); ASSERT_EFI_ERROR (Status); // // Register for the GUIDs of the Architectural Protocols, so the rest of the // EFI Boot Services and EFI Runtime Services tables can be filled in. // Also register for the GUIDs of optional protocols. // CoreNotifyOnProtocolInstallation (); // // Produce Firmware Volume Protocols, one for each FV in the HOB list. // Status = FwVolBlockDriverInit (gDxeCoreImageHandle, gDxeCoreST); ASSERT_EFI_ERROR (Status); Status = FwVolDriverInit (gDxeCoreImageHandle, gDxeCoreST); ASSERT_EFI_ERROR (Status); // // Produce the Section Extraction Protocol // Status = InitializeSectionExtraction (gDxeCoreImageHandle, gDxeCoreST); ASSERT_EFI_ERROR (Status); // // Initialize the DXE Dispatcher // PERF_START (NULL,"CoreInitializeDispatcher", "DxeMain", 0) ; CoreInitializeDispatcher (); PERF_END (NULL,"CoreInitializeDispatcher", "DxeMain", 0) ; // // Invoke the DXE Dispatcher // PERF_START (NULL, "CoreDispatcher", "DxeMain", 0); CoreDispatcher (); PERF_END (NULL, "CoreDispatcher", "DxeMain", 0); // // Display Architectural protocols that were not loaded if this is DEBUG build // DEBUG_CODE_BEGIN (); CoreDisplayMissingArchProtocols (); DEBUG_CODE_END (); // // Display any drivers that were not dispatched because dependency expression // evaluated to false if this is a debug build // DEBUG_CODE_BEGIN (); CoreDisplayDiscoveredNotDispatched (); DEBUG_CODE_END (); // // Assert if the Architectural Protocols are not present. // Status = CoreAllEfiServicesAvailable (); if (EFI_ERROR(Status)) { // // Report Status code that some Architectural Protocols are not present. // REPORT_STATUS_CODE ( EFI_ERROR_CODE | EFI_ERROR_MAJOR, (EFI_SOFTWARE_DXE_CORE | EFI_SW_DXE_CORE_EC_NO_ARCH) ); } ASSERT_EFI_ERROR (Status); // // Report Status code before transfer control to BDS // REPORT_STATUS_CODE ( EFI_PROGRESS_CODE, (EFI_SOFTWARE_DXE_CORE | EFI_SW_DXE_CORE_PC_HANDOFF_TO_NEXT) ); // // Transfer control to the BDS Architectural Protocol // gBds->Entry (gBds); // // BDS should never return // ASSERT (FALSE); CpuDeadLoop (); UNREACHABLE (); }