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

ncache.c
Go to the documentation of this file.
00001 /*
00002  * PROJECT:         ReactOS Kernel
00003  * LICENSE:         BSD - See COPYING.ARM in the top level directory
00004  * FILE:            ntoskrnl/mm/ARM3/ncache.c
00005  * PURPOSE:         ARM Memory Manager Noncached Memory Allocator
00006  * PROGRAMMERS:     ReactOS Portable Systems Group
00007  */
00008 
00009 /* INCLUDES *******************************************************************/
00010 
00011 #include <ntoskrnl.h>
00012 #define NDEBUG
00013 #include <debug.h>
00014 
00015 #define MODULE_INVOLVED_IN_ARM3
00016 #include "../ARM3/miarm.h"
00017 
00018 /* GLOBALS ********************************************************************/
00019 
00020 /*
00021  * @implemented
00022  */
00023 PVOID
00024 NTAPI
00025 MmAllocateNonCachedMemory(IN SIZE_T NumberOfBytes)
00026 {
00027     PFN_COUNT PageCount, MdlPageCount;
00028     PFN_NUMBER PageFrameIndex;
00029     PHYSICAL_ADDRESS LowAddress, HighAddress, SkipBytes;
00030     MI_PFN_CACHE_ATTRIBUTE CacheAttribute;
00031     PMDL Mdl;
00032     PVOID BaseAddress;
00033     PPFN_NUMBER MdlPages;
00034     PMMPTE PointerPte;
00035     MMPTE TempPte;
00036 
00037     //
00038     // Get the page count
00039     //
00040     ASSERT(NumberOfBytes != 0);
00041     PageCount = (PFN_COUNT)BYTES_TO_PAGES(NumberOfBytes);
00042 
00043     //
00044     // Use the MDL allocator for simplicity, so setup the parameters
00045     //
00046     LowAddress.QuadPart = 0;
00047     HighAddress.QuadPart = -1;
00048     SkipBytes.QuadPart = 0;
00049     CacheAttribute = MiPlatformCacheAttributes[0][MmNonCached];
00050 
00051     //
00052     // Now call the MDL allocator
00053     //
00054     Mdl = MiAllocatePagesForMdl(LowAddress,
00055                                 HighAddress,
00056                                 SkipBytes,
00057                                 NumberOfBytes,
00058                                 CacheAttribute,
00059                                 0);
00060     if (!Mdl) return NULL;
00061 
00062     //
00063     // Get the MDL VA and check how many pages we got (could be partial)
00064     //
00065     BaseAddress = (PVOID)((ULONG_PTR)Mdl->StartVa + Mdl->ByteOffset);
00066     MdlPageCount = ADDRESS_AND_SIZE_TO_SPAN_PAGES(BaseAddress, Mdl->ByteCount);
00067     if (PageCount != MdlPageCount)
00068     {
00069         //
00070         // Unlike MDLs, partial isn't okay for a noncached allocation, so fail
00071         //
00072         ASSERT(PageCount > MdlPageCount);
00073         MmFreePagesFromMdl(Mdl);
00074         ExFreePool(Mdl);
00075         return NULL;
00076     }
00077 
00078     //
00079     // Allocate system PTEs for the base address
00080     // We use an extra page to store the actual MDL pointer for the free later
00081     //
00082     PointerPte = MiReserveSystemPtes(PageCount + 1, SystemPteSpace);
00083     if (!PointerPte)
00084     {
00085         //
00086         // Out of memory...
00087         //
00088         MmFreePagesFromMdl(Mdl);
00089         ExFreePool(Mdl);
00090         return NULL;
00091     }
00092 
00093     //
00094     // Store the MDL pointer
00095     //
00096     *(PMDL*)PointerPte++ = Mdl;
00097 
00098     //
00099     // Okay, now see what range we got
00100     //
00101     BaseAddress = MiPteToAddress(PointerPte);
00102 
00103     //
00104     // This is our array of pages
00105     //
00106     MdlPages = (PPFN_NUMBER)(Mdl + 1);
00107 
00108     //
00109     // Setup the template PTE
00110     //
00111     TempPte = ValidKernelPte;
00112 
00113     //
00114     // Now check what kind of caching we should use
00115     //
00116     switch (CacheAttribute)
00117     {
00118         case MiNonCached:
00119 
00120             //
00121             // Disable caching
00122             //
00123             MI_PAGE_DISABLE_CACHE(&TempPte);
00124             MI_PAGE_WRITE_THROUGH(&TempPte);
00125             break;
00126 
00127         case MiWriteCombined:
00128 
00129             //
00130             // Enable write combining
00131             //
00132             MI_PAGE_DISABLE_CACHE(&TempPte);
00133             MI_PAGE_WRITE_COMBINED(&TempPte);
00134             break;
00135 
00136         default:
00137             //
00138             // Nothing to do
00139             //
00140             break;
00141     }
00142 
00143     //
00144     // Now loop the MDL pages
00145     //
00146     do
00147     {
00148         //
00149         // Get the PFN
00150         //
00151         PageFrameIndex = *MdlPages++;
00152 
00153         //
00154         // Set the PFN in the page and write it
00155         //
00156         TempPte.u.Hard.PageFrameNumber = PageFrameIndex;
00157         MI_WRITE_VALID_PTE(PointerPte++, TempPte);
00158     } while (--PageCount);
00159 
00160     //
00161     // Return the base address
00162     //
00163     return BaseAddress;
00164 
00165 }
00166 
00167 /*
00168  * @implemented
00169  */
00170 VOID
00171 NTAPI
00172 MmFreeNonCachedMemory(IN PVOID BaseAddress,
00173                       IN SIZE_T NumberOfBytes)
00174 {
00175     PMDL Mdl;
00176     PMMPTE PointerPte;
00177     PFN_COUNT PageCount;
00178 
00179     //
00180     // Sanity checks
00181     //
00182     ASSERT(NumberOfBytes != 0);
00183     ASSERT(PAGE_ALIGN(BaseAddress) == BaseAddress);
00184 
00185     //
00186     // Get the page count
00187     //
00188     PageCount = (PFN_COUNT)BYTES_TO_PAGES(NumberOfBytes);
00189 
00190     //
00191     // Get the first PTE
00192     //
00193     PointerPte = MiAddressToPte(BaseAddress);
00194 
00195     //
00196     // Remember this is where we store the shadow MDL pointer
00197     //
00198     Mdl = *(PMDL*)(--PointerPte);
00199 
00200     //
00201     // Kill the MDL (and underlying pages)
00202     //
00203     MmFreePagesFromMdl(Mdl);
00204     ExFreePool(Mdl);
00205 
00206     //
00207     // Now free the system PTEs for the underlying VA
00208     //
00209     MiReleaseSystemPtes(PointerPte, PageCount + 1, SystemPteSpace);
00210 }
00211 
00212 /* EOF */

Generated on Sun May 27 2012 04:37:34 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.