/** Called to initialize the memory map and add descriptors to the current descriptor list. The first descriptor that is added must be general usable memory as the addition allocates heap. @param Type The type of memory to add @param Start The starting address in the memory range Must be page aligned @param NumberOfPages The number of pages in the range @param Attribute Attributes of the memory to add @return None. The range is added to the memory map **/ VOID CoreAddMemoryDescriptor ( IN EFI_MEMORY_TYPE Type, IN EFI_PHYSICAL_ADDRESS Start, IN UINT64 NumberOfPages, IN UINT64 Attribute ) { EFI_PHYSICAL_ADDRESS End; EFI_STATUS Status; UINTN Index; UINTN FreeIndex; if ((Start & EFI_PAGE_MASK) != 0) { return; } if (Type >= EfiMaxMemoryType && Type <= 0x7fffffff) { return; } CoreAcquireMemoryLock (); End = Start + LShiftU64 (NumberOfPages, EFI_PAGE_SHIFT) - 1; CoreAddRange (Type, Start, End, Attribute); CoreFreeMemoryMapStack (); CoreReleaseMemoryLock (); // // If Loading Module At Fixed Address feature is enabled. try to allocate memory with Runtime code & Boot time code type // if (PcdGet64(PcdLoadModuleAtFixAddressEnable) != 0) { CoreLoadingFixedAddressHook(); } // // Check to see if the statistics for the different memory types have already been established // if (mMemoryTypeInformationInitialized) { return; } // // Loop through each memory type in the order specified by the gMemoryTypeInformation[] array // for (Index = 0; gMemoryTypeInformation[Index].Type != EfiMaxMemoryType; Index++) { // // Make sure the memory type in the gMemoryTypeInformation[] array is valid // Type = (EFI_MEMORY_TYPE) (gMemoryTypeInformation[Index].Type); if (Type < 0 || Type > EfiMaxMemoryType) { continue; } if (gMemoryTypeInformation[Index].NumberOfPages != 0) { // // Allocate pages for the current memory type from the top of available memory // Status = CoreAllocatePages ( AllocateAnyPages, Type, gMemoryTypeInformation[Index].NumberOfPages, &mMemoryTypeStatistics[Type].BaseAddress ); if (EFI_ERROR (Status)) { // // If an error occurs allocating the pages for the current memory type, then // free all the pages allocates for the previous memory types and return. This // operation with be retied when/if more memory is added to the system // for (FreeIndex = 0; FreeIndex < Index; FreeIndex++) { // // Make sure the memory type in the gMemoryTypeInformation[] array is valid // Type = (EFI_MEMORY_TYPE) (gMemoryTypeInformation[FreeIndex].Type); if (Type < 0 || Type > EfiMaxMemoryType) { continue; } if (gMemoryTypeInformation[FreeIndex].NumberOfPages != 0) { CoreFreePages ( mMemoryTypeStatistics[Type].BaseAddress, gMemoryTypeInformation[FreeIndex].NumberOfPages ); mMemoryTypeStatistics[Type].BaseAddress = 0; mMemoryTypeStatistics[Type].MaximumAddress = MAX_ADDRESS; } } return; } // // Compute the address at the top of the current statistics // mMemoryTypeStatistics[Type].MaximumAddress = mMemoryTypeStatistics[Type].BaseAddress + LShiftU64 (gMemoryTypeInformation[Index].NumberOfPages, EFI_PAGE_SHIFT) - 1; // // If the current base address is the lowest address so far, then update the default // maximum address // if (mMemoryTypeStatistics[Type].BaseAddress < mDefaultMaximumAddress) { mDefaultMaximumAddress = mMemoryTypeStatistics[Type].BaseAddress - 1; } } } // // There was enough system memory for all the the memory types were allocated. So, // those memory areas can be freed for future allocations, and all future memory // allocations can occur within their respective bins // for (Index = 0; gMemoryTypeInformation[Index].Type != EfiMaxMemoryType; Index++) { // // Make sure the memory type in the gMemoryTypeInformation[] array is valid // Type = (EFI_MEMORY_TYPE) (gMemoryTypeInformation[Index].Type); if (Type < 0 || Type > EfiMaxMemoryType) { continue; } if (gMemoryTypeInformation[Index].NumberOfPages != 0) { CoreFreePages ( mMemoryTypeStatistics[Type].BaseAddress, gMemoryTypeInformation[Index].NumberOfPages ); mMemoryTypeStatistics[Type].NumberOfPages = gMemoryTypeInformation[Index].NumberOfPages; gMemoryTypeInformation[Index].NumberOfPages = 0; } } // // If the number of pages reserved for a memory type is 0, then all allocations for that type // should be in the default range. // for (Type = (EFI_MEMORY_TYPE) 0; Type < EfiMaxMemoryType; Type++) { for (Index = 0; gMemoryTypeInformation[Index].Type != EfiMaxMemoryType; Index++) { if (Type == (EFI_MEMORY_TYPE)gMemoryTypeInformation[Index].Type) { mMemoryTypeStatistics[Type].InformationIndex = Index; } } mMemoryTypeStatistics[Type].CurrentNumberOfPages = 0; if (mMemoryTypeStatistics[Type].MaximumAddress == MAX_ADDRESS) { mMemoryTypeStatistics[Type].MaximumAddress = mDefaultMaximumAddress; } } mMemoryTypeInformationInitialized = TRUE; }
/** Creates and initializes the DebugImageInfo Table. Also creates the configuration table and registers it into the system table. **/ VOID CoreInitializeDebugImageInfoTable ( VOID ) { EFI_STATUS Status; UINTN Pages; EFI_PHYSICAL_ADDRESS Memory; UINTN AlignedMemory; UINTN AlignmentMask; UINTN UnalignedPages; UINTN RealPages; // // Allocate 4M aligned page for the structure and fill in the data. // Ideally we would update the CRC now as well, but the service may not yet be available. // See comments in the CoreUpdateDebugTableCrc32() function below for details. // Pages = EFI_SIZE_TO_PAGES (sizeof (EFI_SYSTEM_TABLE_POINTER)); AlignmentMask = SIZE_4MB - 1; RealPages = Pages + EFI_SIZE_TO_PAGES (SIZE_4MB); // // Attempt to allocate memory below PcdMaxEfiSystemTablePointerAddress // If PcdMaxEfiSystemTablePointerAddress is 0, then allocate memory below // MAX_ADDRESS // Memory = PcdGet64 (PcdMaxEfiSystemTablePointerAddress); if (Memory == 0) { Memory = MAX_ADDRESS; } Status = CoreAllocatePages ( AllocateMaxAddress, EfiBootServicesData, RealPages, &Memory ); if (EFI_ERROR (Status)) { /* if (PcdGet64 (PcdMaxEfiSystemTablePointerAddress) != 0) { DEBUG ((EFI_D_INFO, "Allocate memory for EFI_SYSTEM_TABLE_POINTER below PcdMaxEfiSystemTablePointerAddress failed. \ Retry to allocate memroy as close to the top of memory as feasible.\n")); } */ // // If the initial memory allocation fails, then reattempt allocation // as close to the top of memory as feasible. // Status = CoreAllocatePages ( AllocateAnyPages, EfiBootServicesData, RealPages, &Memory ); ASSERT_EFI_ERROR (Status); if (EFI_ERROR (Status)) { return; } } // // Free overallocated pages // AlignedMemory = ((UINTN) Memory + AlignmentMask) & ~AlignmentMask; UnalignedPages = EFI_SIZE_TO_PAGES (AlignedMemory - (UINTN)Memory); if (UnalignedPages > 0) { // // Free first unaligned page(s). // Status = CoreFreePages (Memory, UnalignedPages); ASSERT_EFI_ERROR (Status); } Memory = (EFI_PHYSICAL_ADDRESS)(AlignedMemory + EFI_PAGES_TO_SIZE (Pages)); UnalignedPages = RealPages - Pages - UnalignedPages; if (UnalignedPages > 0) { // // Free last unaligned page(s). // Status = CoreFreePages (Memory, UnalignedPages); ASSERT_EFI_ERROR (Status); } // // Set mDebugTable to the 4MB aligned allocated pages // mDebugTable = (EFI_SYSTEM_TABLE_POINTER *)(AlignedMemory); ASSERT (mDebugTable != NULL); // // Initialize EFI_SYSTEM_TABLE_POINTER structure // mDebugTable->Signature = EFI_SYSTEM_TABLE_SIGNATURE; mDebugTable->EfiSystemTableBase = (EFI_PHYSICAL_ADDRESS) (UINTN) gDxeCoreST; mDebugTable->Crc32 = 0; // // Install the EFI_SYSTEM_TABLE_POINTER structure in the EFI System // Configuration Table // Status = CoreInstallConfigurationTable (&gEfiDebugImageInfoTableGuid, &mDebugInfoTableHeader); ASSERT_EFI_ERROR (Status); }