Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenncache.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
1.7.6.1
|