ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

mm.c
Go to the documentation of this file.
00001 /*
00002  *  FreeLoader
00003  *  Copyright (C) 2006-2008     Aleksey Bragin  <aleksey@reactos.org>
00004  *
00005  *  This program is free software; you can redistribute it and/or modify
00006  *  it under the terms of the GNU General Public License as published by
00007  *  the Free Software Foundation; either version 2 of the License, or
00008  *  (at your option) any later version.
00009  *
00010  *  This program is distributed in the hope that it will be useful,
00011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  *  GNU General Public License for more details.
00014  *
00015  *  You should have received a copy of the GNU General Public License along
00016  *  with this program; if not, write to the Free Software Foundation, Inc.,
00017  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
00018  */
00019 
00020 #include <freeldr.h>
00021 #include <debug.h>
00022 
00023 #if DBG
00024 VOID        DumpMemoryAllocMap(VOID);
00025 VOID        MemAllocTest(VOID);
00026 #endif // DBG
00027 
00028 DBG_DEFAULT_CHANNEL(MEMORY);
00029 
00030 PFN_NUMBER LoaderPagesSpanned = 0;
00031 
00032 PVOID MmAllocateMemoryWithType(SIZE_T MemorySize, TYPE_OF_MEMORY MemoryType)
00033 {
00034     PFN_NUMBER  PagesNeeded;
00035     PFN_NUMBER  FirstFreePageFromEnd;
00036     PVOID   MemPointer;
00037 
00038     if (MemorySize == 0)
00039     {
00040         WARN("MmAllocateMemory() called for 0 bytes. Returning NULL.\n");
00041         UiMessageBoxCritical("Memory allocation failed: MmAllocateMemory() called for 0 bytes.");
00042         return NULL;
00043     }
00044 
00045     MemorySize = ROUND_UP(MemorySize, 4);
00046 
00047     // Find out how many blocks it will take to
00048     // satisfy this allocation
00049     PagesNeeded = ROUND_UP(MemorySize, MM_PAGE_SIZE) / MM_PAGE_SIZE;
00050 
00051     // If we don't have enough available mem
00052     // then return NULL
00053     if (FreePagesInLookupTable < PagesNeeded)
00054     {
00055         ERR("Memory allocation failed in MmAllocateMemory(). Not enough free memory to allocate %d bytes.\n", MemorySize);
00056         UiMessageBoxCritical("Memory allocation failed: out of memory.");
00057         return NULL;
00058     }
00059 
00060     FirstFreePageFromEnd = MmFindAvailablePages(PageLookupTableAddress, TotalPagesInLookupTable, PagesNeeded, FALSE);
00061 
00062     if (FirstFreePageFromEnd == 0)
00063     {
00064         ERR("Memory allocation failed in MmAllocateMemory(). Not enough free memory to allocate %d bytes.\n", MemorySize);
00065         UiMessageBoxCritical("Memory allocation failed: out of memory.");
00066         return NULL;
00067     }
00068 
00069     MmAllocatePagesInLookupTable(PageLookupTableAddress, FirstFreePageFromEnd, PagesNeeded, MemoryType);
00070 
00071     FreePagesInLookupTable -= PagesNeeded;
00072     MemPointer = (PVOID)((ULONG_PTR)FirstFreePageFromEnd * MM_PAGE_SIZE);
00073 
00074     TRACE("Allocated %d bytes (%d pages) of memory (type %ld) starting at page 0x%lx.\n",
00075           MemorySize, PagesNeeded, MemoryType, FirstFreePageFromEnd);
00076     TRACE("Memory allocation pointer: 0x%x\n", MemPointer);
00077 
00078     // Update LoaderPagesSpanned count
00079     if ((((ULONG_PTR)MemPointer + MemorySize + PAGE_SIZE - 1) >> PAGE_SHIFT) > LoaderPagesSpanned)
00080         LoaderPagesSpanned = (((ULONG_PTR)MemPointer + MemorySize + PAGE_SIZE - 1) >> PAGE_SHIFT);
00081 
00082     // Now return the pointer
00083     return MemPointer;
00084 }
00085 
00086 PVOID MmAllocateMemoryAtAddress(SIZE_T MemorySize, PVOID DesiredAddress, TYPE_OF_MEMORY MemoryType)
00087 {
00088     PFN_NUMBER      PagesNeeded;
00089     PFN_NUMBER      StartPageNumber;
00090     PVOID   MemPointer;
00091 
00092     if (MemorySize == 0)
00093     {
00094         WARN("MmAllocateMemoryAtAddress() called for 0 bytes. Returning NULL.\n");
00095         UiMessageBoxCritical("Memory allocation failed: MmAllocateMemoryAtAddress() called for 0 bytes.");
00096         return NULL;
00097     }
00098 
00099     // Find out how many blocks it will take to
00100     // satisfy this allocation
00101     PagesNeeded = ROUND_UP(MemorySize, MM_PAGE_SIZE) / MM_PAGE_SIZE;
00102 
00103     // Get the starting page number
00104     StartPageNumber = MmGetPageNumberFromAddress(DesiredAddress);
00105 
00106     // If we don't have enough available mem
00107     // then return NULL
00108     if (FreePagesInLookupTable < PagesNeeded)
00109     {
00110         ERR("Memory allocation failed in MmAllocateMemoryAtAddress(). "
00111             "Not enough free memory to allocate %d bytes (requesting %d pages but have only %d). "
00112             "\n", MemorySize, PagesNeeded, FreePagesInLookupTable);
00113         UiMessageBoxCritical("Memory allocation failed: out of memory.");
00114         return NULL;
00115     }
00116 
00117     if (MmAreMemoryPagesAvailable(PageLookupTableAddress, TotalPagesInLookupTable, DesiredAddress, PagesNeeded) == FALSE)
00118     {
00119         WARN("Memory allocation failed in MmAllocateMemoryAtAddress(). "
00120              "Not enough free memory to allocate %d bytes at address %p.\n",
00121              MemorySize, DesiredAddress);
00122 
00123         // Don't tell this to user since caller should try to alloc this memory
00124         // at a different address
00125         //UiMessageBoxCritical("Memory allocation failed: out of memory.");
00126         return NULL;
00127     }
00128 
00129     MmAllocatePagesInLookupTable(PageLookupTableAddress, StartPageNumber, PagesNeeded, MemoryType);
00130 
00131     FreePagesInLookupTable -= PagesNeeded;
00132     MemPointer = (PVOID)((ULONG_PTR)StartPageNumber * MM_PAGE_SIZE);
00133 
00134     TRACE("Allocated %d bytes (%d pages) of memory starting at page %d.\n", MemorySize, PagesNeeded, StartPageNumber);
00135     TRACE("Memory allocation pointer: 0x%x\n", MemPointer);
00136 
00137     // Update LoaderPagesSpanned count
00138     if ((((ULONG_PTR)MemPointer + MemorySize + PAGE_SIZE - 1) >> PAGE_SHIFT) > LoaderPagesSpanned)
00139         LoaderPagesSpanned = (((ULONG_PTR)MemPointer + MemorySize + PAGE_SIZE - 1) >> PAGE_SHIFT);
00140 
00141     // Now return the pointer
00142     return MemPointer;
00143 }
00144 
00145 VOID MmSetMemoryType(PVOID MemoryAddress, SIZE_T MemorySize, TYPE_OF_MEMORY NewType)
00146 {
00147     PFN_NUMBER      PagesNeeded;
00148     PFN_NUMBER      StartPageNumber;
00149 
00150     // Find out how many blocks it will take to
00151     // satisfy this allocation
00152     PagesNeeded = ROUND_UP(MemorySize, MM_PAGE_SIZE) / MM_PAGE_SIZE;
00153 
00154     // Get the starting page number
00155     StartPageNumber = MmGetPageNumberFromAddress(MemoryAddress);
00156 
00157     // Set new type for these pages
00158     MmAllocatePagesInLookupTable(PageLookupTableAddress, StartPageNumber, PagesNeeded, NewType);
00159 }
00160 
00161 PVOID MmAllocateHighestMemoryBelowAddress(SIZE_T MemorySize, PVOID DesiredAddress, TYPE_OF_MEMORY MemoryType)
00162 {
00163     PFN_NUMBER      PagesNeeded;
00164     PFN_NUMBER      FirstFreePageFromEnd;
00165     PFN_NUMBER      DesiredAddressPageNumber;
00166     PVOID   MemPointer;
00167 
00168     if (MemorySize == 0)
00169     {
00170         WARN("MmAllocateHighestMemoryBelowAddress() called for 0 bytes. Returning NULL.\n");
00171         UiMessageBoxCritical("Memory allocation failed: MmAllocateHighestMemoryBelowAddress() called for 0 bytes.");
00172         return NULL;
00173     }
00174 
00175     // Find out how many blocks it will take to
00176     // satisfy this allocation
00177     PagesNeeded = ROUND_UP(MemorySize, MM_PAGE_SIZE) / MM_PAGE_SIZE;
00178 
00179     // Get the page number for their desired address
00180     DesiredAddressPageNumber = (ULONG_PTR)DesiredAddress / MM_PAGE_SIZE;
00181 
00182     // If we don't have enough available mem
00183     // then return NULL
00184     if (FreePagesInLookupTable < PagesNeeded)
00185     {
00186         ERR("Memory allocation failed in MmAllocateHighestMemoryBelowAddress(). Not enough free memory to allocate %d bytes.\n", MemorySize);
00187         UiMessageBoxCritical("Memory allocation failed: out of memory.");
00188         return NULL;
00189     }
00190 
00191     FirstFreePageFromEnd = MmFindAvailablePagesBeforePage(PageLookupTableAddress, TotalPagesInLookupTable, PagesNeeded, DesiredAddressPageNumber);
00192 
00193     if (FirstFreePageFromEnd == 0)
00194     {
00195         ERR("Memory allocation failed in MmAllocateHighestMemoryBelowAddress(). Not enough free memory to allocate %d bytes.\n", MemorySize);
00196         UiMessageBoxCritical("Memory allocation failed: out of memory.");
00197         return NULL;
00198     }
00199 
00200     MmAllocatePagesInLookupTable(PageLookupTableAddress, FirstFreePageFromEnd, PagesNeeded, MemoryType);
00201 
00202     FreePagesInLookupTable -= PagesNeeded;
00203     MemPointer = (PVOID)((ULONG_PTR)FirstFreePageFromEnd * MM_PAGE_SIZE);
00204 
00205     TRACE("Allocated %d bytes (%d pages) of memory starting at page %d.\n", MemorySize, PagesNeeded, FirstFreePageFromEnd);
00206     TRACE("Memory allocation pointer: 0x%x\n", MemPointer);
00207 
00208     // Update LoaderPagesSpanned count
00209     if ((((ULONG_PTR)MemPointer + MemorySize) >> PAGE_SHIFT) > LoaderPagesSpanned)
00210         LoaderPagesSpanned = (((ULONG_PTR)MemPointer + MemorySize) >> PAGE_SHIFT);
00211 
00212     // Now return the pointer
00213     return MemPointer;
00214 }
00215 
00216 VOID MmFreeMemory(PVOID MemoryPointer)
00217 {
00218 }
00219 
00220 #if DBG
00221 
00222 VOID DumpMemoryAllocMap(VOID)
00223 {
00224     PFN_NUMBER  Idx;
00225     PPAGE_LOOKUP_TABLE_ITEM     RealPageLookupTable = (PPAGE_LOOKUP_TABLE_ITEM)PageLookupTableAddress;
00226 
00227     DbgPrint("----------- Memory Allocation Bitmap -----------\n");
00228 
00229     for (Idx=0; Idx<TotalPagesInLookupTable; Idx++)
00230     {
00231         if ((Idx % 32) == 0)
00232         {
00233             DbgPrint("\n");
00234             DbgPrint("%08x:\t", (Idx * MM_PAGE_SIZE));
00235         }
00236         else if ((Idx % 4) == 0)
00237         {
00238             DbgPrint(" ");
00239         }
00240 
00241         switch (RealPageLookupTable[Idx].PageAllocated)
00242         {
00243         case LoaderFree:
00244             DbgPrint("*");
00245             break;
00246         case LoaderBad:
00247             DbgPrint( "-");
00248             break;
00249         case LoaderLoadedProgram:
00250             DbgPrint("O");
00251             break;
00252         case LoaderFirmwareTemporary:
00253             DbgPrint("T");
00254             break;
00255         case LoaderFirmwarePermanent:
00256             DbgPrint( "P");
00257             break;
00258         case LoaderOsloaderHeap:
00259             DbgPrint("H");
00260             break;
00261         case LoaderOsloaderStack:
00262             DbgPrint("S");
00263             break;
00264         case LoaderSystemCode:
00265             DbgPrint("K");
00266             break;
00267         case LoaderHalCode:
00268             DbgPrint("L");
00269             break;
00270         case LoaderBootDriver:
00271             DbgPrint("B");
00272             break;
00273         case LoaderStartupPcrPage:
00274             DbgPrint("G");
00275             break;
00276         case LoaderRegistryData:
00277             DbgPrint("R");
00278             break;
00279         case LoaderMemoryData:
00280             DbgPrint("M");
00281             break;
00282         case LoaderNlsData:
00283             DbgPrint("N");
00284             break;
00285         case LoaderSpecialMemory:
00286             DbgPrint("C");
00287             break;
00288         default:
00289             DbgPrint("?");
00290             break;
00291         }
00292     }
00293 
00294     DbgPrint("\n");
00295 }
00296 #endif // DBG
00297 
00298 PPAGE_LOOKUP_TABLE_ITEM MmGetMemoryMap(PFN_NUMBER *NoEntries)
00299 {
00300     PPAGE_LOOKUP_TABLE_ITEM     RealPageLookupTable = (PPAGE_LOOKUP_TABLE_ITEM)PageLookupTableAddress;
00301 
00302     *NoEntries = TotalPagesInLookupTable;
00303 
00304     return RealPageLookupTable;
00305 }
00306 

Generated on Sat May 26 2012 04:18:03 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.