diff --git a/reactos/boot/freeldr/freeldr/arch/arm/macharm.c b/reactos/boot/freeldr/freeldr/arch/arm/macharm.c index 53591232bc4..49a38b042c8 100644 --- a/reactos/boot/freeldr/freeldr/arch/arm/macharm.c +++ b/reactos/boot/freeldr/freeldr/arch/arm/macharm.c @@ -143,12 +143,25 @@ ArmHwDetect(VOID) return RootNode; } -PBIOS_MEMORY_MAP -ArmMemGetMemoryMap(OUT PULONG MaxMemoryMapSize) +MEMORY_DESCRIPTOR ArmMemoryMap[32]; + +PMEMORY_DESCRIPTOR +ArmMemGetMemoryMap(OUT ULONG *MemoryMapSize) { + ASSERT(ArmBoardBlock->MemoryMapEntryCount <= 32); + /* Return whatever the board returned to us (CS0 Base + Size and FLASH0) */ - *MaxMemoryMapSize = ArmBoardBlock->MemoryMapEntryCount; - return ArmBoardBlock->MemoryMap; + for (i = 0; i < ArmBoardBlock->MemoryMapEntryCount; i++) + { + ArmMemoryMap[i].BasePage = ArmBoardBlock->MemoryMap[i].BaseAddress / PAGE_SIZE; + ArmMemoryMap[i].PageCount = ArmBoardBlock->MemoryMap[i].Length / PAGE_SIZE; + if (ArmBoardBlock->MemoryMap[i].Type == BiosMemoryUsable) + ArmMemoryMap[i].MemoryType = MemoryFree; + else + ArmMemoryMap[i].MemoryType = MemoryFirmwarePermanent; + } + + return ArmBoardBlock->MemoryMapEntryCount; } VOID diff --git a/reactos/boot/freeldr/freeldr/arch/i386/pcmem.c b/reactos/boot/freeldr/freeldr/arch/i386/pcmem.c index 568c54a11e5..c9fb769aacc 100644 --- a/reactos/boot/freeldr/freeldr/arch/i386/pcmem.c +++ b/reactos/boot/freeldr/freeldr/arch/i386/pcmem.c @@ -21,6 +21,7 @@ */ #include +#include #define NDEBUG #include @@ -28,10 +29,44 @@ DBG_DEFAULT_CHANNEL(MEMORY); #define MAX_BIOS_DESCRIPTORS 32 +#define FREELDR_BASE_PAGE (FREELDR_BASE / PAGE_SIZE) +#define FILEBUF_BASE_PAGE (FILESYSBUFFER / PAGE_SIZE) +#define DISKBUF_BASE_PAGE (DISKREADBUFFER / PAGE_SIZE) +#define STACK_BASE_PAGE (DISKBUF_BASE_PAGE + 1) +#define STACK_END_PAGE (STACK32ADDR / PAGE_SIZE) +#define BIOSBUF_BASE_PAGE (BIOSCALLBUFFER / PAGE_SIZE) + +#define FREELDR_PAGE_COUNT (FILEBUF_BASE_PAGE - FREELDR_BASE_PAGE) +#define FILEBUF_PAGE_COUNT (DISKBUF_BASE_PAGE - FILEBUF_BASE_PAGE) +#define DISKBUF_PAGE_COUNT (1) +#define STACK_PAGE_COUNT (STACK_END_PAGE - STACK_BASE_PAGE) +#define BIOSBUF_PAGE_COUNT (0xA0 - BIOSBUF_BASE_PAGE) BIOS_MEMORY_MAP PcBiosMemoryMap[MAX_BIOS_DESCRIPTORS]; ULONG PcBiosMapCount; +MEMORY_DESCRIPTOR PcMemoryMap[MAX_BIOS_DESCRIPTORS + 1] = +{ + { MemoryFirmwarePermanent, 0x00, 1 }, // realmode int vectors + { MemoryFirmwareTemporary, 0x01, FREELDR_BASE_PAGE - 1 }, // freeldr stack + cmdline + { MemoryLoadedProgram, FREELDR_BASE_PAGE, FREELDR_PAGE_COUNT }, // freeldr image + { MemoryFirmwareTemporary, FILEBUF_BASE_PAGE, FILEBUF_PAGE_COUNT }, // File system read buffer. FILESYSBUFFER + { MemoryFirmwareTemporary, DISKBUF_BASE_PAGE, DISKBUF_PAGE_COUNT }, // Disk read buffer for int 13h. DISKREADBUFFER + { MemorySpecialMemory, STACK_BASE_PAGE, STACK_PAGE_COUNT }, // prot mode stack. + { MemoryFirmwareTemporary, BIOSBUF_BASE_PAGE, BIOSBUF_PAGE_COUNT }, // BIOSCALLBUFFER + { MemoryFirmwarePermanent, 0xA0, 0x60 }, // ROM / Video + { MemorySpecialMemory, 0xFFF, 1 }, // unusable memory + { MemorySpecialMemory, MAXULONG_PTR, 0 }, // end of map +}; + +ULONG +AddMemoryDescriptor( + IN OUT PMEMORY_DESCRIPTOR List, + IN ULONG MaxCount, + IN PFN_NUMBER BasePage, + IN PFN_NUMBER PageCount, + IN MEMORY_TYPE MemoryType); + static BOOLEAN GetExtendedMemoryConfiguration(ULONG* pMemoryAtOneMB /* in KB */, ULONG* pMemoryAtSixteenMB /* in 64KB */) @@ -153,11 +188,14 @@ PcMemGetConventionalMemorySize(VOID) return (ULONG)Regs.w.ax; } -static ULONG -PcMemGetBiosMemoryMap(PBIOS_MEMORY_MAP BiosMemoryMap, ULONG MaxMemoryMapSize) +static +ULONG +PcMemGetBiosMemoryMap(PMEMORY_DESCRIPTOR MemoryMap, ULONG MaxMemoryMapSize) { REGS Regs; - ULONG MapCount; + ULONG MapCount = 0; + ULONGLONG RealBaseAddress, RealSize; + ASSERT(PcBiosMapCount == 0); TRACE("GetBiosMemoryMap()\n"); @@ -181,7 +219,7 @@ PcMemGetBiosMemoryMap(PBIOS_MEMORY_MAP BiosMemoryMap, ULONG MaxMemoryMapSize) */ Regs.x.ebx = 0x00000000; - for (MapCount = 0; MapCount < MaxMemoryMapSize; MapCount++) + while (PcBiosMapCount < MAX_BIOS_DESCRIPTORS) { /* Setup the registers for the BIOS call */ Regs.x.eax = 0x0000E820; @@ -192,7 +230,7 @@ PcMemGetBiosMemoryMap(PBIOS_MEMORY_MAP BiosMemoryMap, ULONG MaxMemoryMapSize) Regs.w.di = BIOSCALLBUFOFFSET; Int386(0x15, &Regs, &Regs); - TRACE("Memory Map Entry %d\n", MapCount); + TRACE("Memory Map Entry %d\n", PcBiosMapCount); TRACE("Int15h AX=E820h\n"); TRACE("EAX = 0x%x\n", Regs.x.eax); TRACE("EBX = 0x%x\n", Regs.x.ebx); @@ -206,15 +244,40 @@ PcMemGetBiosMemoryMap(PBIOS_MEMORY_MAP BiosMemoryMap, ULONG MaxMemoryMapSize) break; } - /* Copy data to caller's buffer */ - RtlCopyMemory(&BiosMemoryMap[MapCount], (PVOID)BIOSCALLBUFFER, Regs.x.ecx); + /* Copy data to global buffer */ + RtlCopyMemory(&PcBiosMemoryMap[PcBiosMapCount], (PVOID)BIOSCALLBUFFER, Regs.x.ecx); - TRACE("BaseAddress: 0x%p\n", (PVOID)(ULONG_PTR)BiosMemoryMap[MapCount].BaseAddress); - TRACE("Length: 0x%p\n", (PVOID)(ULONG_PTR)BiosMemoryMap[MapCount].Length); - TRACE("Type: 0x%x\n", BiosMemoryMap[MapCount].Type); - TRACE("Reserved: 0x%x\n", BiosMemoryMap[MapCount].Reserved); + TRACE("BaseAddress: 0x%p\n", (PVOID)(ULONG_PTR)PcBiosMemoryMap[PcBiosMapCount].BaseAddress); + TRACE("Length: 0x%p\n", (PVOID)(ULONG_PTR)PcBiosMemoryMap[PcBiosMapCount].Length); + TRACE("Type: 0x%x\n", PcBiosMemoryMap[PcBiosMapCount].Type); + TRACE("Reserved: 0x%x\n", PcBiosMemoryMap[PcBiosMapCount].Reserved); TRACE("\n"); + /* Align up base of memory area */ + RealBaseAddress = ROUND_UP(PcBiosMemoryMap[PcBiosMapCount].BaseAddress, MM_PAGE_SIZE); + RealSize = PcBiosMemoryMap[PcBiosMapCount].Length - + (RealBaseAddress - PcBiosMemoryMap[PcBiosMapCount].BaseAddress); + + /* Check if we can add this descriptor */ + if ((RealSize >= MM_PAGE_SIZE) && (MapCount < MaxMemoryMapSize)) + { + MEMORY_TYPE MemoryType; + + if (PcBiosMemoryMap[PcBiosMapCount].Type == BiosMemoryUsable) + MemoryType = MemoryFree; + else + MemoryType = MemoryFirmwarePermanent; + + /* Add the descriptor */ + MapCount = AddMemoryDescriptor(PcMemoryMap, + MAX_BIOS_DESCRIPTORS, + RealBaseAddress / MM_PAGE_SIZE, + RealSize / MM_PAGE_SIZE, + MemoryType); + } + + PcBiosMapCount++; + /* If the continuation value is zero or the * carry flag is set then this was * the last entry so we're done */ @@ -229,46 +292,59 @@ PcMemGetBiosMemoryMap(PBIOS_MEMORY_MAP BiosMemoryMap, ULONG MaxMemoryMapSize) return MapCount; } -PBIOS_MEMORY_MAP + +PMEMORY_DESCRIPTOR PcMemGetMemoryMap(ULONG *MemoryMapSize) { - ULONG EntryCount; + ULONG i, EntryCount; ULONG ExtendedMemorySizeAtOneMB; ULONG ExtendedMemorySizeAtSixteenMB; - EntryCount = PcMemGetBiosMemoryMap(PcBiosMemoryMap, MAX_BIOS_DESCRIPTORS); - PcBiosMapCount = EntryCount; + EntryCount = PcMemGetBiosMemoryMap(PcMemoryMap, MAX_BIOS_DESCRIPTORS); /* If the BIOS didn't provide a memory map, synthesize one */ if (0 == EntryCount) { GetExtendedMemoryConfiguration(&ExtendedMemorySizeAtOneMB, &ExtendedMemorySizeAtSixteenMB); - /* Conventional memory */ - PcBiosMemoryMap[EntryCount].BaseAddress = 0; - PcBiosMemoryMap[EntryCount].Length = PcMemGetConventionalMemorySize() * 1024; - PcBiosMemoryMap[EntryCount].Type = BiosMemoryUsable; - EntryCount++; + /* Conventional memory */ + AddMemoryDescriptor(PcMemoryMap, + MAX_BIOS_DESCRIPTORS, + 0, + PcMemGetConventionalMemorySize() * 1024 / PAGE_SIZE, + MemoryFree); - /* Extended memory at 1MB */ - PcBiosMemoryMap[EntryCount].BaseAddress = 1024 * 1024; - PcBiosMemoryMap[EntryCount].Length = ExtendedMemorySizeAtOneMB * 1024; - PcBiosMemoryMap[EntryCount].Type = BiosMemoryUsable; + /* Extended memory */ + EntryCount = AddMemoryDescriptor(PcMemoryMap, + MAX_BIOS_DESCRIPTORS, + 1024 * 1024 / PAGE_SIZE, + ExtendedMemorySizeAtOneMB * 1024 / PAGE_SIZE, + MemoryFree); EntryCount++; if (ExtendedMemorySizeAtSixteenMB != 0) { /* Extended memory at 16MB */ - PcBiosMemoryMap[EntryCount].BaseAddress = 0x1000000; - PcBiosMemoryMap[EntryCount].Length = ExtendedMemorySizeAtSixteenMB * 64 * 1024; - PcBiosMemoryMap[EntryCount].Type = BiosMemoryUsable; - EntryCount++; + EntryCount = AddMemoryDescriptor(PcMemoryMap, + MAX_BIOS_DESCRIPTORS, + 0x1000000 / PAGE_SIZE, + ExtendedMemorySizeAtSixteenMB * 64 * 1024 / PAGE_SIZE, + MemoryFree); } } + TRACE("Dumping resulting memory map:\n"); + for (i = 0; i < EntryCount; i++) + { + TRACE("BasePage=0x%lx, PageCount=0x%lx, Type=%s\n", + PcMemoryMap[i].BasePage, + PcMemoryMap[i].PageCount, + MmGetSystemMemoryMapTypeString(PcMemoryMap[i].MemoryType)); + } + *MemoryMapSize = EntryCount; - return PcBiosMemoryMap; + return PcMemoryMap; } /* EOF */ diff --git a/reactos/boot/freeldr/freeldr/arch/i386/xboxmem.c b/reactos/boot/freeldr/freeldr/arch/i386/xboxmem.c index f2e5e4a71e9..33e99230839 100644 --- a/reactos/boot/freeldr/freeldr/arch/i386/xboxmem.c +++ b/reactos/boot/freeldr/freeldr/arch/i386/xboxmem.c @@ -75,21 +75,21 @@ XboxMemInit(VOID) AvailableMemoryMb = InstalledMemoryMb; } -BIOS_MEMORY_MAP BiosMemoryMap[2]; +MEMORY_DESCRIPTOR BiosMemoryMap[2]; -PBIOS_MEMORY_MAP +PMEMORY_DESCRIPTOR XboxMemGetMemoryMap(ULONG *MemoryMapSize) { /* Synthesize memory map */ /* Available RAM block */ - BiosMemoryMap[0].BaseAddress = 0; - BiosMemoryMap[0].Length = AvailableMemoryMb * 1024 * 1024; - BiosMemoryMap[0].Type = BiosMemoryUsable; + BiosMemoryMap[0].BasePage = 0; + BiosMemoryMap[0].PageCount = AvailableMemoryMb * 1024 * 1024 / MM_PAGE_SIZE; + BiosMemoryMap[0].MemoryType = MemoryFree; /* Video memory */ - BiosMemoryMap[1].BaseAddress = AvailableMemoryMb * 1024 * 1024; - BiosMemoryMap[1].Length = (InstalledMemoryMb - AvailableMemoryMb) * 1024 * 1024; - BiosMemoryMap[1].Type = BiosMemoryReserved; + BiosMemoryMap[1].BasePage = AvailableMemoryMb * 1024 * 1024 / MM_PAGE_SIZE; + BiosMemoryMap[1].PageCount = (InstalledMemoryMb - AvailableMemoryMb) * 1024 * 1024 / MM_PAGE_SIZE; + BiosMemoryMap[1].MemoryType = MemoryFirmwarePermanent; *MemoryMapSize = 2; return BiosMemoryMap; diff --git a/reactos/boot/freeldr/freeldr/debug.c b/reactos/boot/freeldr/freeldr/debug.c index 67c73bdc72a..93b5edd59b7 100644 --- a/reactos/boot/freeldr/freeldr/debug.c +++ b/reactos/boot/freeldr/freeldr/debug.c @@ -26,7 +26,7 @@ //#define DEBUG_ALL //#define DEBUG_INIFILE //#define DEBUG_REACTOS -//#define DEBUG_CUSTOM +#define DEBUG_CUSTOM #define DEBUG_NONE #if defined (DEBUG_ALL) @@ -38,7 +38,7 @@ ULONG DebugPrintMask = DPRINT_INIFILE; #elif defined (DEBUG_REACTOS) ULONG DebugPrintMask = DPRINT_REACTOS | DPRINT_REGISTRY; #elif defined (DEBUG_CUSTOM) -ULONG DebugPrintMask = DPRINT_WARNING | DPRINT_WINDOWS; +ULONG DebugPrintMask = DPRINT_WARNING | DPRINT_MEMORY; #else //#elif defined (DEBUG_NONE) ULONG DebugPrintMask = 0; #endif diff --git a/reactos/boot/freeldr/freeldr/include/arch/i386/machxbox.h b/reactos/boot/freeldr/freeldr/include/arch/i386/machxbox.h index b7ec5079573..2daa37d6743 100644 --- a/reactos/boot/freeldr/freeldr/include/arch/i386/machxbox.h +++ b/reactos/boot/freeldr/freeldr/include/arch/i386/machxbox.h @@ -49,7 +49,7 @@ VOID XboxPrepareForReactOS(IN BOOLEAN Setup); VOID XboxMemInit(VOID); PVOID XboxMemReserveMemory(ULONG MbToReserve); -PBIOS_MEMORY_MAP XboxMemGetMemoryMap(ULONG *MemoryMapSize); +PMEMORY_DESCRIPTOR XboxMemGetMemoryMap(ULONG *MemoryMapSize); BOOLEAN XboxDiskReadLogicalSectors(UCHAR DriveNumber, ULONGLONG SectorNumber, ULONG SectorCount, PVOID Buffer); BOOLEAN XboxDiskGetPartitionEntry(UCHAR DriveNumber, ULONG PartitionNumber, PPARTITION_TABLE_ENTRY PartitionTableEntry); diff --git a/reactos/boot/freeldr/freeldr/include/arch/pc/machpc.h b/reactos/boot/freeldr/freeldr/include/arch/pc/machpc.h index 0a8b4ddeba7..9fb6914d915 100644 --- a/reactos/boot/freeldr/freeldr/include/arch/pc/machpc.h +++ b/reactos/boot/freeldr/freeldr/include/arch/pc/machpc.h @@ -46,7 +46,7 @@ VOID PcVideoSync(VOID); VOID PcVideoPrepareForReactOS(IN BOOLEAN Setup); VOID PcPrepareForReactOS(IN BOOLEAN Setup); -PBIOS_MEMORY_MAP PcMemGetMemoryMap(ULONG *MemoryMapSize); +PMEMORY_DESCRIPTOR PcMemGetMemoryMap(ULONG *MemoryMapSize); BOOLEAN PcDiskGetBootPath(char *BootPath, unsigned Size); BOOLEAN PcDiskReadLogicalSectors(UCHAR DriveNumber, ULONGLONG SectorNumber, ULONG SectorCount, PVOID Buffer); diff --git a/reactos/boot/freeldr/freeldr/include/arch/pc/x86common.h b/reactos/boot/freeldr/freeldr/include/arch/pc/x86common.h index c8b94f7ed27..4cdc80e57df 100644 --- a/reactos/boot/freeldr/freeldr/include/arch/pc/x86common.h +++ b/reactos/boot/freeldr/freeldr/include/arch/pc/x86common.h @@ -13,11 +13,11 @@ #define BSS_START HEX(6F00) #define FREELDR_BASE HEX(F800) #define FREELDR_PE_BASE HEX(10000) +#define FILESYSBUFFER HEX(80000) /* Buffer to store file system data (e.g. cluster buffer for FAT) */ +#define DISKREADBUFFER HEX(90000) /* Buffer to store data read in from the disk via the BIOS */ #define STACK32ADDR HEX(98000) /* The 32-bit stack top will be at 9000:8000, or 0xA8000 */ #define STACK64ADDR HEX(98000) /* The 64-bit stack top will be at 98000 */ #define BIOSCALLBUFFER HEX(98000) /* Buffer to store temporary data for any Int386() call */ -#define FILESYSBUFFER HEX(80000) /* Buffer to store file system data (e.g. cluster buffer for FAT) */ -#define DISKREADBUFFER HEX(90000) /* Buffer to store data read in from the disk via the BIOS */ #define DISKREADBUFFER_SIZE 512 #define BIOSCALLBUFSEGMENT (BIOSCALLBUFFER/16) /* Buffer to store temporary data for any Int386() call */ diff --git a/reactos/boot/freeldr/freeldr/include/machine.h b/reactos/boot/freeldr/freeldr/include/machine.h index 7235eb1d06f..ce083f7cb52 100644 --- a/reactos/boot/freeldr/freeldr/include/machine.h +++ b/reactos/boot/freeldr/freeldr/include/machine.h @@ -1,5 +1,4 @@ -/* $Id$ - * +/* * FreeLoader * * This program is free software; you can redistribute it and/or modify @@ -59,7 +58,7 @@ typedef struct tagMACHVTBL VOID (*PrepareForReactOS)(IN BOOLEAN Setup); MEMORY_DESCRIPTOR* (*GetMemoryDescriptor)(MEMORY_DESCRIPTOR* Current); - PBIOS_MEMORY_MAP (*GetMemoryMap)(PULONG MemoryMapSize); + PMEMORY_DESCRIPTOR (*GetMemoryMap)(PULONG MaxMemoryMapSize); BOOLEAN (*DiskGetBootPath)(char *BootPath, unsigned Size); BOOLEAN (*DiskReadLogicalSectors)(UCHAR DriveNumber, ULONGLONG SectorNumber, ULONG SectorCount, PVOID Buffer); diff --git a/reactos/boot/freeldr/freeldr/mm/meminit.c b/reactos/boot/freeldr/freeldr/mm/meminit.c index bb7efaed488..24283ae029c 100644 --- a/reactos/boot/freeldr/freeldr/mm/meminit.c +++ b/reactos/boot/freeldr/freeldr/mm/meminit.c @@ -53,211 +53,106 @@ ULONG LastFreePageHint = 0; ULONG MmLowestPhysicalPage = 0xFFFFFFFF; ULONG MmHighestPhysicalPage = 0; +PMEMORY_DESCRIPTOR BiosMemoryMap; +ULONG BiosMemoryMapEntryCount; + extern ULONG_PTR MmHeapPointer; extern ULONG_PTR MmHeapStart; -typedef struct +ULONG +AddMemoryDescriptor( + IN OUT PMEMORY_DESCRIPTOR List, + IN ULONG MaxCount, + IN PFN_NUMBER BasePage, + IN PFN_NUMBER PageCount, + IN MEMORY_TYPE MemoryType) { - MEMORY_DESCRIPTOR m; - ULONG Index; - BOOLEAN GeneratedDescriptor; -} MEMORY_DESCRIPTOR_INT; -static const MEMORY_DESCRIPTOR_INT MemoryDescriptors[] = -{ -#if defined (__i386__) || defined (_M_AMD64) - { { MemoryFirmwarePermanent, 0x00, 1 }, 0, }, // realmode int vectors - { { MemoryFirmwareTemporary, 0x01, 7 }, 1, }, // freeldr stack + cmdline - { { MemoryLoadedProgram, 0x08, 0x70 }, 2, }, // freeldr image (roughly max. 0x64 pages) - { { MemorySpecialMemory, 0x78, 8 }, 3, }, // prot mode stack. BIOSCALLBUFFER - { { MemoryFirmwareTemporary, 0x80, 0x10 }, 4, }, // File system read buffer. FILESYSBUFFER - { { MemoryFirmwareTemporary, 0x90, 0x10 }, 5, }, // Disk read buffer for int 13h. DISKREADBUFFER - { { MemoryFirmwarePermanent, 0xA0, 0x60 }, 6, }, // ROM / Video - { { MemorySpecialMemory, 0xFFF, 1 }, 7, }, // unusable memory -#elif __arm__ // This needs to be done per-platform specific way + ULONG i, c; + PFN_NUMBER NextBase; + TRACE("AddMemoryDescriptor(0x%lx-0x%lx [0x%lx pages])\n", + BasePage, BasePage + PageCount, PageCount); -#endif -}; + /* Scan through all existing descriptors */ + for (i = 0, c = 0; (c < MaxCount) && (List[c].PageCount != 0); c++) + { + /* Count entries completely below the new range */ + if (List[i].BasePage + List[i].PageCount <= BasePage) i++; + } -static -VOID MmFixupSystemMemoryMap(PBIOS_MEMORY_MAP BiosMemoryMap, ULONG* MapCount) -{ - int Index; - int Index2; - ULONGLONG BaseAddressOffset; + /* Check if the list is full */ + if (c >= MaxCount) return c; - // Loop through each entry in the array - for (Index=0; Index<*MapCount; Index++) - { - // Correct all the addresses to be aligned on page boundaries - BaseAddressOffset = ROUND_UP(BiosMemoryMap[Index].BaseAddress, MM_PAGE_SIZE) - BiosMemoryMap[Index].BaseAddress; - BiosMemoryMap[Index].BaseAddress += BaseAddressOffset; - if (BiosMemoryMap[Index].Length < BaseAddressOffset) - { - BiosMemoryMap[Index].Length = 0; - } - else - { - BiosMemoryMap[Index].Length -= BaseAddressOffset; - } - BiosMemoryMap[Index].Length = ROUND_DOWN(BiosMemoryMap[Index].Length, MM_PAGE_SIZE); + /* Is there an existing descriptor starting before the new range */ + while ((i < c) && (List[i].BasePage <= BasePage)) + { + /* The end of the existing one is the minimum for the new range */ + NextBase = List[i].BasePage + List[i].PageCount; - // If the entry type isn't usable then remove - // it from the memory map (this will help reduce - // the size of our lookup table) - // If the length is less than a full page then - // get rid of it also. - if (BiosMemoryMap[Index].Type != BiosMemoryUsable || - BiosMemoryMap[Index].Length < MM_PAGE_SIZE) - { - // Slide every entry after this down one - for (Index2=Index; Index2<(*MapCount - 1); Index2++) - { - BiosMemoryMap[Index2] = BiosMemoryMap[Index2 + 1]; - } - (*MapCount)--; - Index--; - } - } + /* Bail out, if everything is trimmed away */ + if ((BasePage + PageCount) <= NextBase) return c; + + /* Trim the naew range at the lower end */ + PageCount -= (NextBase - BasePage); + BasePage = NextBase; + + /* Go to the next entry and repeat */ + i++; + } + + ASSERT(PageCount > 0); + + /* Are there still entries above? */ + if (i < c) + { + /* Shift the following entries one up */ + RtlMoveMemory(&List[i+1], &List[i], (c - i) * sizeof(List[0])); + + /* Insert the new range */ + List[i].BasePage = BasePage; + List[i].PageCount = min(PageCount, List[i+1].BasePage - BasePage); + List[i].MemoryType = MemoryType; + c++; + + TRACE("Inserting at i=%ld: (0x%lx:0x%lx)\n", + i, List[i].BasePage, List[i].PageCount); + + /* Check if the range was trimmed */ + if (PageCount > List[i].PageCount) + { + /* Recursively process the trimmed part */ + c = AddMemoryDescriptor(List, + MaxCount, + BasePage + List[i].PageCount, + PageCount - List[i].PageCount, + MemoryType); + } + } + else + { + /* We can simply add the range here */ + TRACE("Adding i=%ld: (0x%lx:0x%lx)\n", i, BasePage, PageCount); + List[i].BasePage = BasePage; + List[i].PageCount = PageCount; + List[i].MemoryType = MemoryType; + c++; + } + + /* Return the new count */ + return c; } const MEMORY_DESCRIPTOR* ArcGetMemoryDescriptor(const MEMORY_DESCRIPTOR* Current) { - MEMORY_DESCRIPTOR_INT* CurrentDescriptor; - PBIOS_MEMORY_MAP BiosMemoryMap; - static ULONG BiosMemoryMapEntryCount; - static MEMORY_DESCRIPTOR_INT BiosMemoryDescriptors[32]; - static BOOLEAN MemoryMapInitialized = FALSE; - ULONG i, j; - - // - // Check if it is the first time we're called - // - if (!MemoryMapInitialized) - { - // - // Get the machine generated memory map - // - BiosMemoryMap = MachVtbl.GetMemoryMap(&BiosMemoryMapEntryCount); - - // - // Fix entries that are not page aligned - // - MmFixupSystemMemoryMap(BiosMemoryMap, &BiosMemoryMapEntryCount); - - // - // Copy the entries to our structure - // - for (i = 0, j = 0; i < BiosMemoryMapEntryCount; i++) - { - // - // Is it suitable memory? - // - if (BiosMemoryMap[i].Type != BiosMemoryUsable) - { - // - // No. Process next descriptor - // - continue; - } - - // - // Copy this memory descriptor - // - BiosMemoryDescriptors[j].m.MemoryType = MemoryFree; - BiosMemoryDescriptors[j].m.BasePage = (ULONG)(BiosMemoryMap[i].BaseAddress / MM_PAGE_SIZE); - BiosMemoryDescriptors[j].m.PageCount = (ULONG)(BiosMemoryMap[i].Length / MM_PAGE_SIZE); - BiosMemoryDescriptors[j].Index = j; - BiosMemoryDescriptors[j].GeneratedDescriptor = TRUE; - j++; - } - - // - // Remember how much descriptors we found - // - BiosMemoryMapEntryCount = j; - - // - // Mark memory map as already retrieved and initialized - // - MemoryMapInitialized = TRUE; - } - - CurrentDescriptor = CONTAINING_RECORD(Current, MEMORY_DESCRIPTOR_INT, m); - if (Current == NULL) { - // - // First descriptor requested - // - if (BiosMemoryMapEntryCount > 0) - { - // - // Return first generated memory descriptor - // - return &BiosMemoryDescriptors[0].m; - } - else if (sizeof(MemoryDescriptors) > 0) - { - // - // Return first fixed memory descriptor - // - return &MemoryDescriptors[0].m; - } - else - { - // - // Strange case, we have no memory descriptor - // - return NULL; - } - } - else if (CurrentDescriptor->GeneratedDescriptor) - { - // - // Current entry is a generated descriptor - // - if (CurrentDescriptor->Index + 1 < BiosMemoryMapEntryCount) - { - // - // Return next generated descriptor - // - return &BiosMemoryDescriptors[CurrentDescriptor->Index + 1].m; - } - else if (sizeof(MemoryDescriptors) > 0) - { - // - // Return first fixed memory descriptor - // - return &MemoryDescriptors[0].m; - } - else - { - // - // No fixed memory descriptor; end of memory map - // - return NULL; - } + return BiosMemoryMap; } else { - // - // Current entry is a fixed descriptor - // - if (CurrentDescriptor->Index + 1 < sizeof(MemoryDescriptors) / sizeof(MemoryDescriptors[0])) - { - // - // Return next fixed descriptor - // - return &MemoryDescriptors[CurrentDescriptor->Index + 1].m; - } - else - { - // - // No more fixed memory descriptor; end of memory map - // - return NULL; - } + Current++; + if (Current->PageCount == 0) return NULL; + return Current; } } @@ -270,6 +165,8 @@ BOOLEAN MmInitializeMemoryManager(VOID) TRACE("Initializing Memory Manager.\n"); + BiosMemoryMap = MachVtbl.GetMemoryMap(&BiosMemoryMapEntryCount); + #if DBG // Dump the system memory map TRACE("System Memory Map (Base Address, Length, Type):\n"); @@ -298,6 +195,26 @@ BOOLEAN MmInitializeMemoryManager(VOID) // Initialize the page lookup table MmInitPageLookupTable(PageLookupTableAddress, TotalPagesInLookupTable); + +{ + ULONG Type, Index, PrevIndex = 0; + PPAGE_LOOKUP_TABLE_ITEM RealPageLookupTable = (PPAGE_LOOKUP_TABLE_ITEM)PageLookupTableAddress; + + Type = RealPageLookupTable[0].PageAllocated; + for (Index = 1; Index < TotalPagesInLookupTable; Index++) + { + if ((RealPageLookupTable[Index].PageAllocated != Type) || + (Index == TotalPagesInLookupTable - 1)) + { + TRACE("Range: 0x%lx - 0x%lx Type=%d\n", + PrevIndex, Index - 1, Type); + Type = RealPageLookupTable[Index].PageAllocated; + PrevIndex = Index; + } + } +} + + MmUpdateLastFreePageHint(PageLookupTableAddress, TotalPagesInLookupTable); FreePagesInLookupTable = MmCountFreePagesInLookupTable(PageLookupTableAddress, TotalPagesInLookupTable); @@ -305,6 +222,8 @@ BOOLEAN MmInitializeMemoryManager(VOID) MmInitializeHeap(PageLookupTableAddress); TRACE("Memory Manager initialized. %d pages available.\n", FreePagesInLookupTable); + + return TRUE; } @@ -359,7 +278,7 @@ ULONG MmGetAddressablePageCountIncludingHoles(VOID) // // Yes, remember it if this is real memory // - if (MemoryDescriptor->MemoryType == MemoryFree) MmLowestPhysicalPage = MemoryDescriptor->BasePage; + MmLowestPhysicalPage = MemoryDescriptor->BasePage; } } @@ -467,6 +386,10 @@ VOID MmInitPageLookupTable(PVOID PageLookupTable, ULONG TotalPageCount) // while ((MemoryDescriptor = ArcGetMemoryDescriptor(MemoryDescriptor)) != NULL) { + TRACE("Got range: 0x%lx-0x%lx, type=%s\n", + MemoryDescriptor->BasePage, + MemoryDescriptor->BasePage + MemoryDescriptor->PageCount, + MmGetSystemMemoryMapTypeString(MemoryDescriptor->MemoryType)); // // Convert ARC memory type to loader memory type // @@ -704,6 +627,9 @@ BOOLEAN MmAreMemoryPagesAvailable(PVOID PageLookupTable, ULONG TotalPageCount, P ULONG Index; StartPage = MmGetPageNumberFromAddress(PageAddress); + + if (StartPage < MmLowestPhysicalPage) return FALSE; + StartPage -= MmLowestPhysicalPage; // Make sure they aren't trying to go past the