diff --git a/boot/freeldr/freeldr/include/mm.h b/boot/freeldr/freeldr/include/mm.h index d29fe6087fc..adc13d0ebf5 100644 --- a/boot/freeldr/freeldr/include/mm.h +++ b/boot/freeldr/freeldr/include/mm.h @@ -58,8 +58,7 @@ typedef struct _FREELDR_MEMORY_DESCRIPTOR #define MM_PAGE_SIZE 4096 #define MM_PAGE_MASK 0xFFF #define MM_PAGE_SHIFT 12 -// FIXME: freeldr implementation uses ULONG for page numbers -#define MM_MAX_PAGE 0xFFFFFFFFFFFFF +#define MM_MAX_PAGE 0x3FFFF /* freeldr only maps 1 GB */ #define MM_SIZE_TO_PAGES(a) \ ( ((a) >> MM_PAGE_SHIFT) + ((a) & MM_PAGE_MASK ? 1 : 0) ) diff --git a/boot/freeldr/freeldr/lib/mm/meminit.c b/boot/freeldr/freeldr/lib/mm/meminit.c index bbf7a571fe4..164236c81c1 100644 --- a/boot/freeldr/freeldr/lib/mm/meminit.c +++ b/boot/freeldr/freeldr/lib/mm/meminit.c @@ -415,13 +415,15 @@ PVOID MmFindLocationForPageLookupTable(PFN_NUMBER TotalPageCount) { const FREELDR_MEMORY_DESCRIPTOR* MemoryDescriptor = NULL; SIZE_T PageLookupTableSize; - PFN_NUMBER PageLookupTablePages; - PFN_NUMBER PageLookupTableStartPage = 0; + PFN_NUMBER RequiredPages; + PFN_NUMBER CandidateBasePage = 0; + PFN_NUMBER CandidatePageCount; + PFN_NUMBER PageLookupTableEndPage; PVOID PageLookupTableMemAddress = NULL; // Calculate how much pages we need to keep the page lookup table PageLookupTableSize = TotalPageCount * sizeof(PAGE_LOOKUP_TABLE_ITEM); - PageLookupTablePages = PageLookupTableSize / MM_PAGE_SIZE; + RequiredPages = PageLookupTableSize / MM_PAGE_SIZE; // Search the highest memory block big enough to contain lookup table while ((MemoryDescriptor = ArcGetMemoryDescriptor(MemoryDescriptor)) != NULL) @@ -429,22 +431,28 @@ PVOID MmFindLocationForPageLookupTable(PFN_NUMBER TotalPageCount) // Continue, if memory is not free if (MemoryDescriptor->MemoryType != LoaderFree) continue; - // Continue, if the block is not big enough? - if (MemoryDescriptor->PageCount < PageLookupTablePages) continue; + // Continue, if the block is not big enough + if (MemoryDescriptor->PageCount < RequiredPages) continue; // Continue, if it is not at a higher address than previous address - if (MemoryDescriptor->BasePage < PageLookupTableStartPage) continue; + if (MemoryDescriptor->BasePage < CandidateBasePage) continue; // Continue, if the address is too high - if (MemoryDescriptor->BasePage >= MM_MAX_PAGE) continue; + if (MemoryDescriptor->BasePage + RequiredPages >= MM_MAX_PAGE) continue; // Memory block is more suitable than the previous one - PageLookupTableStartPage = MemoryDescriptor->BasePage; - PageLookupTableMemAddress = (PVOID)((ULONG_PTR) - (MemoryDescriptor->BasePage + MemoryDescriptor->PageCount) * MM_PAGE_SIZE - - PageLookupTableSize); + CandidateBasePage = MemoryDescriptor->BasePage; + CandidatePageCount = MemoryDescriptor->PageCount; } + // Calculate the end address for the lookup table + PageLookupTableEndPage = min(CandidateBasePage + CandidatePageCount, + MM_MAX_PAGE); + + // Calculate the virtual address + PageLookupTableMemAddress = (PVOID)((PageLookupTableEndPage * PAGE_SIZE) + - PageLookupTableSize); + TRACE("MmFindLocationForPageLookupTable() returning 0x%x\n", PageLookupTableMemAddress); return PageLookupTableMemAddress;