Author: tkreuzer
Date: Fri Sep 23 17:35:45 2011
New Revision: 53816

URL: http://svn.reactos.org/svn/reactos?rev=53816&view=rev
Log:
[FREELDR]
Fix some bugs in the code that deals with memory descriptors:
ArcGetMemoryDescriptor was enumerating the bios generated entries first and 
then the static entries. The latter were conflicting with the former and took 
precedence when initializing the page lookup table. The problem was, that 
MmFindLocationForPageLookupTable would use the highest range of pages 
available. If that range would be conflicting with a following static 
descriptor, the static would have been ignored. It only worked because on x86 
the highest bios descriptor has enough free pages, before it conflicts with a 
static entry (page 0xfff, marked as unusable), so that the page lookup table 
could be created.

MmGetAddressablePageCountIncludingHoles enumerated all memory descriptors to 
find MmLowestPhysicalPage, but it was only counting FreeMemory, thus skipping 
all other memory ranges. This only worked, due to the previous bug, so that the 
bios pages shown first took precedence over the following static descriptors. 
Without the former bug MmLowestPhysicalPage would be 0x100 which would tigger 
in the next bug:
MmAreMemoryPagesAvailable took the passed address range and looked up all pages 
in the lookup table to see whether all are free. Now the function didn't check, 
whether the passed address was below MmLowestPhysicalPage and in case it was, 
happily accessed the memory below the lookup table. This would result in hal 
being loaded at 0x40000 overwriting the loader itself.

This is all fixe by implementing a new way of creating the memory map. First 
there is a static memory map, which has enough free entries to add dynamic 
ranges. Then AddMemoryDescriptor will allow you to add a new range,
while the already existing ranges will take precedence and the new ranges will 
be properly split and inserted, so that the resulting map does not contain any 
overlapping regions and is sorted from low to high pages. The static memory 
descriptor exists in the architecture specific file.
The code that enumerates the bios information now uses this function to add the 
ranges on top of the static descriptor.
More cleanup work to follow.

Modified:
    trunk/reactos/boot/freeldr/freeldr/arch/arm/macharm.c
    trunk/reactos/boot/freeldr/freeldr/arch/i386/pcmem.c
    trunk/reactos/boot/freeldr/freeldr/arch/i386/xboxmem.c
    trunk/reactos/boot/freeldr/freeldr/debug.c
    trunk/reactos/boot/freeldr/freeldr/include/arch/i386/machxbox.h
    trunk/reactos/boot/freeldr/freeldr/include/arch/pc/machpc.h
    trunk/reactos/boot/freeldr/freeldr/include/arch/pc/x86common.h
    trunk/reactos/boot/freeldr/freeldr/include/machine.h
    trunk/reactos/boot/freeldr/freeldr/mm/meminit.c

Modified: trunk/reactos/boot/freeldr/freeldr/arch/arm/macharm.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/arch/arm/macharm.c?rev=53816&r1=53815&r2=53816&view=diff
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/arch/arm/macharm.c [iso-8859-1] 
(original)
+++ trunk/reactos/boot/freeldr/freeldr/arch/arm/macharm.c [iso-8859-1] Fri Sep 
23 17:35:45 2011
@@ -143,12 +143,25 @@
     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

Modified: trunk/reactos/boot/freeldr/freeldr/arch/i386/pcmem.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/arch/i386/pcmem.c?rev=53816&r1=53815&r2=53816&view=diff
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/arch/i386/pcmem.c [iso-8859-1] (original)
+++ trunk/reactos/boot/freeldr/freeldr/arch/i386/pcmem.c [iso-8859-1] Fri Sep 
23 17:35:45 2011
@@ -21,6 +21,7 @@
  */
 
 #include <freeldr.h>
+#include <arch/pc/x86common.h>
 
 #define NDEBUG
 #include <debug.h>
@@ -28,9 +29,43 @@
 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
@@ -153,11 +188,14 @@
   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 @@
    */
   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 @@
       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,14 +244,39 @@
           break;
         }
 
-      /* Copy data to caller's buffer */
-      RtlCopyMemory(&BiosMemoryMap[MapCount], (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);
+      /* Copy data to global buffer */
+      RtlCopyMemory(&PcBiosMemoryMap[PcBiosMapCount], (PVOID)BIOSCALLBUFFER, 
Regs.x.ecx);
+
+      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
@@ -229,46 +292,59 @@
   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 */

Modified: trunk/reactos/boot/freeldr/freeldr/arch/i386/xboxmem.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/arch/i386/xboxmem.c?rev=53816&r1=53815&r2=53816&view=diff
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/arch/i386/xboxmem.c [iso-8859-1] 
(original)
+++ trunk/reactos/boot/freeldr/freeldr/arch/i386/xboxmem.c [iso-8859-1] Fri Sep 
23 17:35:45 2011
@@ -75,21 +75,21 @@
   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;

Modified: trunk/reactos/boot/freeldr/freeldr/debug.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/debug.c?rev=53816&r1=53815&r2=53816&view=diff
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/debug.c [iso-8859-1] (original)
+++ trunk/reactos/boot/freeldr/freeldr/debug.c [iso-8859-1] Fri Sep 23 17:35:45 
2011
@@ -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 @@
 #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

Modified: trunk/reactos/boot/freeldr/freeldr/include/arch/i386/machxbox.h
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/include/arch/i386/machxbox.h?rev=53816&r1=53815&r2=53816&view=diff
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/include/arch/i386/machxbox.h 
[iso-8859-1] (original)
+++ trunk/reactos/boot/freeldr/freeldr/include/arch/i386/machxbox.h 
[iso-8859-1] Fri Sep 23 17:35:45 2011
@@ -49,7 +49,7 @@
 
 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);

Modified: trunk/reactos/boot/freeldr/freeldr/include/arch/pc/machpc.h
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/include/arch/pc/machpc.h?rev=53816&r1=53815&r2=53816&view=diff
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/include/arch/pc/machpc.h [iso-8859-1] 
(original)
+++ trunk/reactos/boot/freeldr/freeldr/include/arch/pc/machpc.h [iso-8859-1] 
Fri Sep 23 17:35:45 2011
@@ -46,7 +46,7 @@
 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);

Modified: trunk/reactos/boot/freeldr/freeldr/include/arch/pc/x86common.h
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/include/arch/pc/x86common.h?rev=53816&r1=53815&r2=53816&view=diff
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/include/arch/pc/x86common.h [iso-8859-1] 
(original)
+++ trunk/reactos/boot/freeldr/freeldr/include/arch/pc/x86common.h [iso-8859-1] 
Fri Sep 23 17:35:45 2011
@@ -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 */

Modified: trunk/reactos/boot/freeldr/freeldr/include/machine.h
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/include/machine.h?rev=53816&r1=53815&r2=53816&view=diff
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/include/machine.h [iso-8859-1] (original)
+++ trunk/reactos/boot/freeldr/freeldr/include/machine.h [iso-8859-1] Fri Sep 
23 17:35:45 2011
@@ -1,5 +1,4 @@
-/* $Id$
- *
+/* 
  *  FreeLoader
  *
  *  This program is free software; you can redistribute it and/or modify
@@ -59,7 +58,7 @@
   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);

Modified: trunk/reactos/boot/freeldr/freeldr/mm/meminit.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/mm/meminit.c?rev=53816&r1=53815&r2=53816&view=diff
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/mm/meminit.c [iso-8859-1] (original)
+++ trunk/reactos/boot/freeldr/freeldr/mm/meminit.c [iso-8859-1] Fri Sep 23 
17:35:45 2011
@@ -53,211 +53,106 @@
 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--;
-               }
-       }
+ULONG
+AddMemoryDescriptor(
+    IN OUT PMEMORY_DESCRIPTOR List,
+    IN ULONG MaxCount,
+    IN PFN_NUMBER BasePage,
+    IN PFN_NUMBER PageCount,
+    IN MEMORY_TYPE MemoryType)
+{
+    ULONG i, c;
+    PFN_NUMBER NextBase;
+    TRACE("AddMemoryDescriptor(0x%lx-0x%lx [0x%lx pages])\n",
+          BasePage, BasePage + PageCount, PageCount);
+
+    /* 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++;
+    }
+
+    /* Check if the list is full */
+    if (c >= MaxCount) return c;
+
+    /* 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;
+
+        /* 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;
     }
 }
 
@@ -269,6 +164,8 @@
 #endif
 
        TRACE("Initializing Memory Manager.\n");
+
+    BiosMemoryMap = MachVtbl.GetMemoryMap(&BiosMemoryMapEntryCount);
 
 #if DBG
        // Dump the system memory map
@@ -298,6 +195,26 @@
 
        // 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 @@
        MmInitializeHeap(PageLookupTableAddress);
 
        TRACE("Memory Manager initialized. %d pages available.\n", 
FreePagesInLookupTable);
+
+
        return TRUE;
 }
 
@@ -359,7 +278,7 @@
             //
             // Yes, remember it if this is real memory
             //
-            if (MemoryDescriptor->MemoryType == MemoryFree) 
MmLowestPhysicalPage = MemoryDescriptor->BasePage;
+            MmLowestPhysicalPage = MemoryDescriptor->BasePage;
         }
     }
 
@@ -467,6 +386,10 @@
     //
     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 @@
        ULONG                                                   Index;
 
        StartPage = MmGetPageNumberFromAddress(PageAddress);
+
+       if (StartPage < MmLowestPhysicalPage) return FALSE;
+
     StartPage -= MmLowestPhysicalPage;
 
        // Make sure they aren't trying to go past the


Reply via email to