- Removed the initialisation of the kernel map area.
[reactos.git] / reactos / ntoskrnl / mm / mminit.c
index bb2d14b..c06a57e 100644 (file)
@@ -1,25 +1,16 @@
-/* $Id: mminit.c,v 1.64 2004/08/01 07:24:58 hbirr Exp $
+/* $Id$
  *
- * COPYRIGHT:   See COPYING in the top directory
- * PROJECT:     ReactOS kernel 
- * FILE:        ntoskrnl/mm/mminit.c
- * PURPOSE:     kernel memory managment initialization functions
- * PROGRAMMER:  David Welch (welch@cwcom.net)
- * UPDATE HISTORY:
- *              Created 9/4/98
+ * COPYRIGHT:       See COPYING in the top directory
+ * PROJECT:         ReactOS kernel
+ * FILE:            ntoskrnl/mm/mminit.c
+ * PURPOSE:         Kernel memory managment initialization functions
+ *
+ * PROGRAMMERS:     David Welch (welch@cwcom.net)
  */
 
 /* INCLUDES *****************************************************************/
 
-#include <ddk/ntddk.h>
-#include <roscfg.h>
-#include <internal/i386/segment.h>
-#include <internal/mm.h>
-#include <internal/ntoskrnl.h>
-#include <internal/io.h>
-#include <internal/ps.h>
-#include <internal/pool.h>
-
+#include <ntoskrnl.h>
 #define NDEBUG
 #include <internal/debug.h>
 
@@ -40,24 +31,13 @@ extern unsigned int _bss_end__;
 static BOOLEAN IsThisAnNtAsSystem = FALSE;
 static MM_SYSTEM_SIZE MmSystemSize = MmSmallSystem;
 
-static MEMORY_AREA* kernel_text_desc = NULL;
-static MEMORY_AREA* kernel_init_desc = NULL;
-static MEMORY_AREA* kernel_map_desc = NULL;
-static MEMORY_AREA* kernel_kpcr_desc = NULL;
-static MEMORY_AREA* kernel_data_desc = NULL;
-static MEMORY_AREA* kernel_param_desc = NULL;
-static MEMORY_AREA* kernel_pool_desc = NULL;
-static MEMORY_AREA* kernel_shared_data_desc = NULL;
-static MEMORY_AREA* kernel_mapped_vga_framebuffer_desc = NULL;
-static MEMORY_AREA* MiKernelMapDescriptor = NULL;
-static MEMORY_AREA* MiPagedPoolDescriptor = NULL;
-
 PHYSICAL_ADDRESS MmSharedDataPagePhysicalAddress;
 
 PVOID MiNonPagedPoolStart;
 ULONG MiNonPagedPoolLength;
-PVOID MiKernelMapStart;
-ULONG MiKernelMapLength;
+
+extern ULONG init_stack;
+extern ULONG init_stack_top;
 
 /* FUNCTIONS ****************************************************************/
 
@@ -77,11 +57,15 @@ MM_SYSTEM_SIZE STDCALL MmQuerySystemSize(VOID)
    return(MmSystemSize);
 }
 
-VOID MiShutdownMemoryManager(VOID)
+VOID
+NTAPI
+MiShutdownMemoryManager(VOID)
 {}
 
-VOID INIT_FUNCTION
-MmInitVirtualMemory(ULONG LastKernelAddress,
+VOID
+INIT_FUNCTION
+NTAPI
+MmInitVirtualMemory(ULONG_PTR LastKernelAddress,
                     ULONG KernelLength)
 /*
  * FUNCTION: Intialize the memory areas list
@@ -96,6 +80,7 @@ MmInitVirtualMemory(ULONG LastKernelAddress,
    NTSTATUS Status;
    PHYSICAL_ADDRESS BoundaryAddressMultiple;
    PFN_TYPE Pfn;
+   PMEMORY_AREA MArea;
 
    DPRINT("MmInitVirtualMemory(%x, %x)\n",LastKernelAddress, KernelLength);
 
@@ -104,44 +89,58 @@ MmInitVirtualMemory(ULONG LastKernelAddress,
 
    MmInitMemoryAreas();
 
-   /* Don't change the start of kernel map. Pte's must always exist for this region. */
-   MiKernelMapStart = (char*)LastKernelAddress + PAGE_SIZE;
-   MiKernelMapLength = MM_KERNEL_MAP_SIZE;
-
-   MiNonPagedPoolStart = (char*)MiKernelMapStart + MiKernelMapLength + PAGE_SIZE;
+   /* Start the paged and nonpaged pool at a 4MB boundary. */ 
+   MiNonPagedPoolStart = (PVOID)ROUND_UP((ULONG_PTR)LastKernelAddress + PAGE_SIZE, 0x400000);
    MiNonPagedPoolLength = MM_NONPAGED_POOL_SIZE;
 
-   MmPagedPoolBase = (char*)MiNonPagedPoolStart + MiNonPagedPoolLength + PAGE_SIZE;
+   MmPagedPoolBase = (PVOID)ROUND_UP((ULONG_PTR)MiNonPagedPoolStart + MiNonPagedPoolLength + PAGE_SIZE, 0x400000);
    MmPagedPoolSize = MM_PAGED_POOL_SIZE;
 
+   DPRINT("NonPagedPool %x - %x, PagedPool %x - %x\n", MiNonPagedPoolStart, (ULONG_PTR)MiNonPagedPoolStart + MiNonPagedPoolLength - 1, 
+           MmPagedPoolBase, (ULONG_PTR)MmPagedPoolBase + MmPagedPoolSize - 1);
 
-   MiInitKernelMap();
    MiInitializeNonPagedPool();
 
    /*
     * Setup the system area descriptor list
     */
-   BaseAddress = (PVOID)0xf0000000;
+   MiInitPageDirectoryMap();
+
+   BaseAddress = (PVOID)KPCR_BASE;
    MmCreateMemoryArea(NULL,
                       MmGetKernelAddressSpace(),
                       MEMORY_AREA_SYSTEM,
                       &BaseAddress,
-                      0x400000,
+                      PAGE_SIZE * MAXIMUM_PROCESSORS,
                       0,
-                      &kernel_map_desc,
-                      FALSE,
+                      &MArea,
+                      TRUE,
                       FALSE,
                       BoundaryAddressMultiple);
 
-   BaseAddress = (PVOID)KPCR_BASE;
+   /* Local APIC base */
+   BaseAddress = (PVOID)0xFEE00000;
    MmCreateMemoryArea(NULL,
                       MmGetKernelAddressSpace(),
                       MEMORY_AREA_SYSTEM,
                       &BaseAddress,
-                      PAGE_SIZE * MAXIMUM_PROCESSORS,
+                      PAGE_SIZE,
                       0,
-                      &kernel_kpcr_desc,
+                      &MArea,
+                      TRUE,
                       FALSE,
+                      BoundaryAddressMultiple);
+
+   /* i/o APIC base */
+   BaseAddress = (PVOID)0xFEC00000;
+   MmCreateMemoryArea(NULL,
+                      MmGetKernelAddressSpace(),
+                      MEMORY_AREA_SYSTEM,
+                      &BaseAddress,
+                      PAGE_SIZE,
+                      0,
+                      &MArea,
+                      TRUE,
                       FALSE,
                       BoundaryAddressMultiple);
 
@@ -152,13 +151,13 @@ MmInitVirtualMemory(ULONG LastKernelAddress,
                       &BaseAddress,
                       0x20000,
                       0,
-                      &kernel_mapped_vga_framebuffer_desc,
-                      FALSE,
+                      &MArea,
+                      TRUE,
                       FALSE,
                       BoundaryAddressMultiple);
 
    BaseAddress = (PVOID)KERNEL_BASE;
-   Length = PAGE_ROUND_UP(((ULONG)&_text_end__)) - KERNEL_BASE;
+   Length = PAGE_ROUND_UP(((ULONG_PTR)&_text_end__)) - KERNEL_BASE;
    ParamLength = ParamLength - Length;
 
    /*
@@ -171,15 +170,15 @@ MmInitVirtualMemory(ULONG LastKernelAddress,
                       &BaseAddress,
                       Length,
                       0,
-                      &kernel_text_desc,
-                      FALSE,
+                      &MArea,
+                      TRUE,
                       FALSE,
                       BoundaryAddressMultiple);
 
-   BaseAddress = (PVOID)PAGE_ROUND_UP(((ULONG)&_text_end__));
-   assert (BaseAddress == (PVOID)&_init_start__);
-   Length = PAGE_ROUND_UP(((ULONG)&_init_end__)) -
-            PAGE_ROUND_UP(((ULONG)&_text_end__));
+   BaseAddress = (PVOID)PAGE_ROUND_UP(((ULONG_PTR)&_text_end__));
+   ASSERT(BaseAddress == (PVOID)&_init_start__);
+   Length = PAGE_ROUND_UP(((ULONG_PTR)&_init_end__)) -
+            PAGE_ROUND_UP(((ULONG_PTR)&_text_end__));
    ParamLength = ParamLength - Length;
 
    MmCreateMemoryArea(NULL,
@@ -188,16 +187,16 @@ MmInitVirtualMemory(ULONG LastKernelAddress,
                       &BaseAddress,
                       Length,
                       0,
-                      &kernel_init_desc,
-                      FALSE,
+                      &MArea,
+                      TRUE,
                       FALSE,
                       BoundaryAddressMultiple);
 
-   Length = PAGE_ROUND_UP(((ULONG)&_bss_end__)) -
-            PAGE_ROUND_UP(((ULONG)&_init_end__));
+   Length = PAGE_ROUND_UP(((ULONG_PTR)&_bss_end__)) -
+            PAGE_ROUND_UP(((ULONG_PTR)&_init_end__));
    ParamLength = ParamLength - Length;
    DPRINT("Length %x\n",Length);
-   BaseAddress = (PVOID)PAGE_ROUND_UP(((ULONG)&_init_end__));
+   BaseAddress = (PVOID)PAGE_ROUND_UP(((ULONG_PTR)&_init_end__));
    DPRINT("BaseAddress %x\n",BaseAddress);
 
    /*
@@ -210,21 +209,21 @@ MmInitVirtualMemory(ULONG LastKernelAddress,
                       &BaseAddress,
                       Length,
                       0,
-                      &kernel_data_desc,
-                      FALSE,
+                      &MArea,
+                      TRUE,
                       FALSE,
                       BoundaryAddressMultiple);
 
-   BaseAddress = (PVOID)PAGE_ROUND_UP(((ULONG)&_bss_end__));
-   Length = LastKernelAddress - (ULONG)BaseAddress;
+   BaseAddress = (PVOID)PAGE_ROUND_UP(((ULONG_PTR)&_bss_end__));
+   Length = LastKernelAddress - (ULONG_PTR)BaseAddress;
    MmCreateMemoryArea(NULL,
                       MmGetKernelAddressSpace(),
                       MEMORY_AREA_SYSTEM,
                       &BaseAddress,
                       Length,
                       0,
-                      &kernel_param_desc,
-                      FALSE,
+                      &MArea,
+                      TRUE,
                       FALSE,
                       BoundaryAddressMultiple);
 
@@ -235,23 +234,11 @@ MmInitVirtualMemory(ULONG LastKernelAddress,
                       &BaseAddress,
                       MiNonPagedPoolLength,
                       0,
-                      &kernel_pool_desc,
-                      FALSE,
+                      &MArea,
+                      TRUE,
                       FALSE,
                       BoundaryAddressMultiple);
 
-   BaseAddress = MiKernelMapStart;
-   Status = MmCreateMemoryArea(NULL,
-                               MmGetKernelAddressSpace(),
-                               MEMORY_AREA_SYSTEM,
-                               &BaseAddress,
-                               MiKernelMapLength,
-                               0,
-                               &MiKernelMapDescriptor,
-                               FALSE,
-                               FALSE,
-                               BoundaryAddressMultiple);
-
    BaseAddress = MmPagedPoolBase;
    Status = MmCreateMemoryArea(NULL,
                                MmGetKernelAddressSpace(),
@@ -259,8 +246,8 @@ MmInitVirtualMemory(ULONG LastKernelAddress,
                                &BaseAddress,
                                MmPagedPoolSize,
                                0,
-                               &MiPagedPoolDescriptor,
-                               FALSE,
+                               &MArea,
+                               TRUE,
                                FALSE,
                                BoundaryAddressMultiple);
 
@@ -277,8 +264,8 @@ MmInitVirtualMemory(ULONG LastKernelAddress,
                       &BaseAddress,
                       Length,
                       0,
-                      &kernel_shared_data_desc,
-                      FALSE,
+                      &MArea,
+                      TRUE,
                       FALSE,
                       BoundaryAddressMultiple);
    Status = MmRequestPageMemoryConsumer(MC_NPPOOL, TRUE, &Pfn);
@@ -301,10 +288,12 @@ MmInitVirtualMemory(ULONG LastKernelAddress,
    MmInitializeMemoryConsumer(MC_USER, MmTrimUserMemory);
 }
 
-VOID INIT_FUNCTION
-MmInit1(ULONG FirstKrnlPhysAddr,
-        ULONG LastKrnlPhysAddr,
-        ULONG LastKernelAddress,
+VOID
+INIT_FUNCTION
+NTAPI
+MmInit1(ULONG_PTR FirstKrnlPhysAddr,
+        ULONG_PTR LastKrnlPhysAddr,
+        ULONG_PTR LastKernelAddress,
         PADDRESS_RANGE BIOSMemoryMap,
         ULONG AddressRangeCount,
         ULONG MaxMem)
@@ -314,17 +303,13 @@ MmInit1(ULONG FirstKrnlPhysAddr,
 {
    ULONG i;
    ULONG kernel_len;
-#ifndef MP
+   ULONG_PTR MappingAddress;
 
-   extern unsigned int unmap_me, unmap_me2, unmap_me3;
-#endif
-
-   DPRINT("MmInit1(FirstKrnlPhysAddr, %x, LastKrnlPhysAddr %x, LastKernelAddress %x)\n",
+   DPRINT("MmInit1(FirstKrnlPhysAddr, %p, LastKrnlPhysAddr %p, LastKernelAddress %p)\n",
           FirstKrnlPhysAddr,
           LastKrnlPhysAddr,
           LastKernelAddress);
 
-
    if ((BIOSMemoryMap != NULL) && (AddressRangeCount > 0))
    {
       // If we have a bios memory map, recalulate the memory size
@@ -348,14 +333,9 @@ MmInit1(ULONG FirstKrnlPhysAddr,
       KeLoaderBlock.MemHigher = (MaxMem - 1) * 1024;
    }
 
-   /*
-    * FIXME: Set this based on the system command line
-    */
-   MmSystemRangeStart = (PVOID)KERNEL_BASE; // 0xC0000000
-   MmUserProbeAddress = (PVOID)0x7fff0000;
-   MmHighestUserAddress = (PVOID)0x7ffeffff;
-
-   MmInitGlobalKernelPageDirectory();
+   /* Set memory limits */
+   MmUserProbeAddress = (ULONG_PTR)MmSystemRangeStart - 0x10000;
+   MmHighestUserAddress = (PVOID)(MmUserProbeAddress - 1);
 
    /*
     * Initialize memory managment statistics
@@ -371,20 +351,6 @@ MmInit1(ULONG FirstKrnlPhysAddr,
    MmStats.PagingRequestsInLastFiveMinutes = 0;
    MmStats.PagingRequestsInLastFifteenMinutes = 0;
 
-   /*
-    * Initialize the kernel address space
-    */
-   MmInitializeKernelAddressSpace();
-
-   /*
-    * Unmap low memory
-    */
-#ifndef MP
-   /* In SMP mode we unmap the low memory in MmInit3.
-      The APIC needs the mapping of the first pages
-      while the processors are starting up. */
-   MmDeletePageTable(NULL, 0);
-#endif
    /*
     * Free all pages not used for kernel memory
     * (we assume the kernel occupies a continuous range of physical
@@ -411,10 +377,19 @@ MmInit1(ULONG FirstKrnlPhysAddr,
    MmStats.NrTotalPages += 16;
 #endif
 
+   /*
+    * Initialize the kernel address space
+    */
+   MmInitializeKernelAddressSpace();
+
+   MmInitGlobalKernelPageDirectory();
+
    DbgPrint("Used memory %dKb\n", (MmStats.NrTotalPages * PAGE_SIZE) / 1024);
+   DPRINT1("Kernel Stack Limits. InitTop = 0x%x, Init = 0x%x\n", init_stack_top, init_stack);
 
-   LastKernelAddress = (ULONG)MmInitializePageList((PVOID)FirstKrnlPhysAddr,
-                       (PVOID)LastKrnlPhysAddr,
+   LastKernelAddress = (ULONG_PTR)MmInitializePageList(
+                       FirstKrnlPhysAddr,
+                       LastKrnlPhysAddr,
                        MmStats.NrTotalPages,
                        PAGE_ROUND_UP(LastKernelAddress),
                        BIOSMemoryMap,
@@ -422,40 +397,37 @@ MmInit1(ULONG FirstKrnlPhysAddr,
    kernel_len = LastKrnlPhysAddr - FirstKrnlPhysAddr;
 
    /*
-    * Create a trap for null pointer references and protect text
-    * segment
+    * Unmap low memory
     */
-   CHECKPOINT;
-   DPRINT("_text_start__ %x _init_end__ %x\n",(int)&_text_start__,(int)&_init_end__);
-   for (i=PAGE_ROUND_DOWN(((int)&_text_start__));
-         i<PAGE_ROUND_UP(((int)&_init_end__));i=i+PAGE_SIZE)
-   {
-      MmSetPageProtect(NULL,
-                       (PVOID)i,
-                       PAGE_EXECUTE_READ);
-   }
-
-   DPRINT("Invalidating between %x and %x\n",
-          LastKernelAddress, 0xc0600000);
-   for (i=(LastKernelAddress); i<0xc0600000; i+=PAGE_SIZE)
+#ifdef CONFIG_SMP
+   /* In SMP mode we unmap the low memory pagetable in MmInit3.
+      The APIC needs the mapping of the first pages
+      while the processors are starting up.
+      We unmap all pages except page 2 and 3. */
+   for (MappingAddress = 0;
+        MappingAddress < 1024 * PAGE_SIZE;
+        MappingAddress += PAGE_SIZE)
    {
-      MmRawDeleteVirtualMapping((PVOID)(i));
+      if (MappingAddress != 2 * PAGE_SIZE &&
+          MappingAddress != 3 * PAGE_SIZE)
+      {
+         MmRawDeleteVirtualMapping((PVOID)MappingAddress);
+      }
    }
+#else
+   MmDeletePageTable(NULL, 0);
+#endif
 
    DPRINT("Invalidating between %x and %x\n",
-          0xd0100000, 0xd0400000);
-   for (i=0xd0100000; i<0xd0400000; i+=PAGE_SIZE)
+          LastKernelAddress, KERNEL_BASE + 0x00600000);
+   for (MappingAddress = LastKernelAddress;
+        MappingAddress < KERNEL_BASE + 0x00600000;
+        MappingAddress += PAGE_SIZE)
    {
-      MmRawDeleteVirtualMapping((PVOID)(i));
+      MmRawDeleteVirtualMapping((PVOID)MappingAddress);
    }
 
    DPRINT("Almost done MmInit()\n");
-#ifndef MP
-   /* FIXME: This is broken in SMP mode */
-   MmDeleteVirtualMapping(NULL, (PVOID)&unmap_me, TRUE, NULL, NULL);
-   MmDeleteVirtualMapping(NULL, (PVOID)&unmap_me2, TRUE, NULL, NULL);
-   MmDeleteVirtualMapping(NULL, (PVOID)&unmap_me3, TRUE, NULL, NULL);
-#endif
    /*
     * Intialize memory areas
     */
@@ -464,7 +436,9 @@ MmInit1(ULONG FirstKrnlPhysAddr,
    MmInitializeMdlImplementation();
 }
 
-VOID INIT_FUNCTION
+VOID
+NTAPI
+INIT_FUNCTION
 MmInit2(VOID)
 {
    MmInitializeRmapList();
@@ -473,13 +447,15 @@ MmInit2(VOID)
    MmInitPagingFile();
 }
 
-VOID INIT_FUNCTION
+VOID
+INIT_FUNCTION
+NTAPI
 MmInit3(VOID)
 {
    /*
     * Unmap low memory
     */
-#ifdef MP
+#ifdef CONFIG_SMP
    /* In SMP mode we can unmap the low memory
       if all processors are started. */
    MmDeletePageTable(NULL, 0);
@@ -502,7 +478,7 @@ MiFreeInitMemoryPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address,
                      PFN_TYPE Page, SWAPENTRY SwapEntry,
                      BOOLEAN Dirty)
 {
-   assert(SwapEntry == 0);
+   ASSERT(SwapEntry == 0);
    if (Page != 0)
    {
       MmReleasePageMemoryConsumer(MC_NPPOOL, Page);
@@ -510,13 +486,13 @@ MiFreeInitMemoryPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address,
 }
 
 VOID
+NTAPI
 MiFreeInitMemory(VOID)
 {
    MmLockAddressSpace(MmGetKernelAddressSpace());
-   MmFreeMemoryArea(MmGetKernelAddressSpace(),
-                    (PVOID)&_init_start__,
-                    PAGE_ROUND_UP((ULONG)&_init_end__) - (ULONG)_init_start__,
-                    MiFreeInitMemoryPage,
-                    NULL);
+   MmFreeMemoryAreaByPtr(MmGetKernelAddressSpace(),
+                         (PVOID)&_init_start__,
+                         MiFreeInitMemoryPage,
+                         NULL);
    MmUnlockAddressSpace(MmGetKernelAddressSpace());
 }