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
*/
#include <freeldr.h>
+#include <arch/pc/x86common.h>
#define NDEBUG
#include <debug.h>
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 */)
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");
*/
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;
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);
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 */
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++;
-
- /* Extended memory at 1MB */
- PcBiosMemoryMap[EntryCount].BaseAddress = 1024 * 1024;
- PcBiosMemoryMap[EntryCount].Length = ExtendedMemorySizeAtOneMB * 1024;
- PcBiosMemoryMap[EntryCount].Type = BiosMemoryUsable;
+ /* Conventional memory */
+ AddMemoryDescriptor(PcMemoryMap,
+ MAX_BIOS_DESCRIPTORS,
+ 0,
+ PcMemGetConventionalMemorySize() * 1024 / PAGE_SIZE,
+ MemoryFree);
+
+ /* 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 */
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;
//#define DEBUG_ALL
//#define DEBUG_INIFILE
//#define DEBUG_REACTOS
-//#define DEBUG_CUSTOM
+#define DEBUG_CUSTOM
#define DEBUG_NONE
#if defined (DEBUG_ALL)
#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
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);
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);
#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 */
-/* $Id$
- *
+/*
* FreeLoader
*
* This program is free software; you can redistribute it and/or modify
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);
ULONG MmLowestPhysicalPage = 0xFFFFFFFF;
ULONG MmHighestPhysicalPage = 0;
+PMEMORY_DESCRIPTOR BiosMemoryMap;
+ULONG BiosMemoryMapEntryCount;
+
extern ULONG_PTR MmHeapPointer;
extern ULONG_PTR MmHeapStart;
-typedef struct
-{
- 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
-
-#endif
-};
-
-static
-VOID MmFixupSystemMemoryMap(PBIOS_MEMORY_MAP BiosMemoryMap, ULONG* MapCount)
-{
- int Index;
- int Index2;
- ULONGLONG BaseAddressOffset;
-
- // 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);
-
- // 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--;
- }
- }
-}
-
-const MEMORY_DESCRIPTOR*
-ArcGetMemoryDescriptor(const MEMORY_DESCRIPTOR* Current)
+ULONG
+AddMemoryDescriptor(
+ IN OUT PMEMORY_DESCRIPTOR List,
+ IN ULONG MaxCount,
+ IN PFN_NUMBER BasePage,
+ IN PFN_NUMBER PageCount,
+ IN MEMORY_TYPE MemoryType)
{
- MEMORY_DESCRIPTOR_INT* CurrentDescriptor;
- PBIOS_MEMORY_MAP BiosMemoryMap;
- static ULONG BiosMemoryMapEntryCount;
- static MEMORY_DESCRIPTOR_INT BiosMemoryDescriptors[32];
- static BOOLEAN MemoryMapInitialized = FALSE;
- ULONG i, j;
+ ULONG i, c;
+ PFN_NUMBER NextBase;
+ TRACE("AddMemoryDescriptor(0x%lx-0x%lx [0x%lx pages])\n",
+ BasePage, BasePage + PageCount, PageCount);
- //
- // Check if it is the first time we're called
- //
- if (!MemoryMapInitialized)
+ /* Scan through all existing descriptors */
+ for (i = 0, c = 0; (c < MaxCount) && (List[c].PageCount != 0); c++)
{
- //
- // Get the machine generated memory map
- //
- BiosMemoryMap = MachVtbl.GetMemoryMap(&BiosMemoryMapEntryCount);
+ /* Count entries completely below the new range */
+ if (List[i].BasePage + List[i].PageCount <= BasePage) i++;
+ }
- //
- // Fix entries that are not page aligned
- //
- MmFixupSystemMemoryMap(BiosMemoryMap, &BiosMemoryMapEntryCount);
+ /* Check if the list is full */
+ if (c >= MaxCount) return c;
- //
- // 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;
- }
+ /* 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;
- //
- // 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++;
- }
+ /* Bail out, if everything is trimmed away */
+ if ((BasePage + PageCount) <= NextBase) return c;
- //
- // Remember how much descriptors we found
- //
- BiosMemoryMapEntryCount = j;
+ /* Trim the naew range at the lower end */
+ PageCount -= (NextBase - BasePage);
+ BasePage = NextBase;
- //
- // Mark memory map as already retrieved and initialized
- //
- MemoryMapInitialized = TRUE;
+ /* Go to the next entry and repeat */
+ i++;
}
- CurrentDescriptor = CONTAINING_RECORD(Current, MEMORY_DESCRIPTOR_INT, m);
+ ASSERT(PageCount > 0);
- if (Current == NULL)
+ /* Are there still entries above? */
+ if (i < c)
{
- //
- // 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
+ /* 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)
{
- //
- // Strange case, we have no memory descriptor
- //
- return NULL;
+ /* Recursively process the trimmed part */
+ c = AddMemoryDescriptor(List,
+ MaxCount,
+ BasePage + List[i].PageCount,
+ PageCount - List[i].PageCount,
+ MemoryType);
}
}
- else if (CurrentDescriptor->GeneratedDescriptor)
+ else
{
- //
- // 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;
- }
+ /* 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)
+{
+ if (Current == 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;
}
}
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");
// 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);
MmInitializeHeap(PageLookupTableAddress);
TRACE("Memory Manager initialized. %d pages available.\n", FreePagesInLookupTable);
+
+
return TRUE;
}
//
// Yes, remember it if this is real memory
//
- if (MemoryDescriptor->MemoryType == MemoryFree) MmLowestPhysicalPage = MemoryDescriptor->BasePage;
+ MmLowestPhysicalPage = MemoryDescriptor->BasePage;
}
}
//
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
//
ULONG Index;
StartPage = MmGetPageNumberFromAddress(PageAddress);
+
+ if (StartPage < MmLowestPhysicalPage) return FALSE;
+
StartPage -= MmLowestPhysicalPage;
// Make sure they aren't trying to go past the