ReactOS  0.4.14-dev-41-g31d7680
ncache.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Kernel
3  * LICENSE: BSD - See COPYING.ARM in the top level directory
4  * FILE: ntoskrnl/mm/ARM3/ncache.c
5  * PURPOSE: ARM Memory Manager Noncached Memory Allocator
6  * PROGRAMMERS: ReactOS Portable Systems Group
7  */
8 
9 /* INCLUDES *******************************************************************/
10 
11 #include <ntoskrnl.h>
12 #define NDEBUG
13 #include <debug.h>
14 
15 #define MODULE_INVOLVED_IN_ARM3
16 #include <mm/ARM3/miarm.h>
17 
18 /* GLOBALS ********************************************************************/
19 
20 /*
21  * @implemented
22  */
23 PVOID
24 NTAPI
26 {
27  PFN_COUNT PageCount, MdlPageCount;
28  PFN_NUMBER PageFrameIndex;
30  MI_PFN_CACHE_ATTRIBUTE CacheAttribute;
31  PMDL Mdl;
33  PPFN_NUMBER MdlPages;
34  PMMPTE PointerPte;
35  MMPTE TempPte;
36 
37  //
38  // Get the page count
39  //
40  ASSERT(NumberOfBytes != 0);
42 
43  //
44  // Use the MDL allocator for simplicity, so setup the parameters
45  //
46  LowAddress.QuadPart = 0;
47  HighAddress.QuadPart = -1;
48  SkipBytes.QuadPart = 0;
49  CacheAttribute = MiPlatformCacheAttributes[0][MmNonCached];
50 
51  //
52  // Now call the MDL allocator
53  //
54  Mdl = MiAllocatePagesForMdl(LowAddress,
56  SkipBytes,
58  CacheAttribute,
59  0);
60  if (!Mdl) return NULL;
61 
62  //
63  // Get the MDL VA and check how many pages we got (could be partial)
64  //
65  BaseAddress = (PVOID)((ULONG_PTR)Mdl->StartVa + Mdl->ByteOffset);
66  MdlPageCount = ADDRESS_AND_SIZE_TO_SPAN_PAGES(BaseAddress, Mdl->ByteCount);
67  if (PageCount != MdlPageCount)
68  {
69  //
70  // Unlike MDLs, partial isn't okay for a noncached allocation, so fail
71  //
72  ASSERT(PageCount > MdlPageCount);
73  MmFreePagesFromMdl(Mdl);
75  return NULL;
76  }
77 
78  //
79  // Allocate system PTEs for the base address
80  // We use an extra page to store the actual MDL pointer for the free later
81  //
82  PointerPte = MiReserveSystemPtes(PageCount + 1, SystemPteSpace);
83  if (!PointerPte)
84  {
85  //
86  // Out of memory...
87  //
88  MmFreePagesFromMdl(Mdl);
90  return NULL;
91  }
92 
93  //
94  // Store the MDL pointer
95  //
96  *(PMDL*)PointerPte++ = Mdl;
97 
98  //
99  // Okay, now see what range we got
100  //
101  BaseAddress = MiPteToAddress(PointerPte);
102 
103  //
104  // This is our array of pages
105  //
106  MdlPages = (PPFN_NUMBER)(Mdl + 1);
107 
108  //
109  // Setup the template PTE
110  //
112 
113  //
114  // Now check what kind of caching we should use
115  //
116  switch (CacheAttribute)
117  {
118  case MiNonCached:
119 
120  //
121  // Disable caching
122  //
125  break;
126 
127  case MiWriteCombined:
128 
129  //
130  // Enable write combining
131  //
134  break;
135 
136  default:
137  //
138  // Nothing to do
139  //
140  break;
141  }
142 
143  //
144  // Now loop the MDL pages
145  //
146  do
147  {
148  //
149  // Get the PFN
150  //
151  PageFrameIndex = *MdlPages++;
152 
153  //
154  // Set the PFN in the page and write it
155  //
156  TempPte.u.Hard.PageFrameNumber = PageFrameIndex;
157  MI_WRITE_VALID_PTE(PointerPte++, TempPte);
158  } while (--PageCount);
159 
160  //
161  // Return the base address
162  //
163  return BaseAddress;
164 
165 }
166 
167 /*
168  * @implemented
169  */
170 VOID
171 NTAPI
174 {
175  PMDL Mdl;
176  PMMPTE PointerPte;
177  PFN_COUNT PageCount;
178 
179  //
180  // Sanity checks
181  //
182  ASSERT(NumberOfBytes != 0);
184 
185  //
186  // Get the page count
187  //
188  PageCount = (PFN_COUNT)BYTES_TO_PAGES(NumberOfBytes);
189 
190  //
191  // Get the first PTE
192  //
193  PointerPte = MiAddressToPte(BaseAddress);
194 
195  //
196  // Remember this is where we store the shadow MDL pointer
197  //
198  Mdl = *(PMDL*)(--PointerPte);
199 
200  //
201  // Kill the MDL (and underlying pages)
202  //
203  MmFreePagesFromMdl(Mdl);
205 
206  //
207  // Now free the system PTEs for the underlying VA
208  //
209  MiReleaseSystemPtes(PointerPte, PageCount + 1, SystemPteSpace);
210 }
211 
212 /* EOF */
#define IN
Definition: typedefs.h:38
#define MI_PAGE_WRITE_COMBINED(x)
Definition: mm.h:100
ULONG PFN_COUNT
Definition: mmtypes.h:102
PMMPTE NTAPI MiReserveSystemPtes(IN ULONG NumberOfPtes, IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType)
Definition: syspte.c:246
enum _MI_PFN_CACHE_ATTRIBUTE MI_PFN_CACHE_ATTRIBUTE
uint32_t ULONG_PTR
Definition: typedefs.h:63
ULONG * PPFN_NUMBER
Definition: ke.h:8
#define MiAddressToPte(x)
Definition: mmx86.c:19
ULONG PFN_NUMBER
Definition: ke.h:8
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
FORCEINLINE VOID MI_WRITE_VALID_PTE(IN PMMPTE PointerPte, IN MMPTE TempPte)
Definition: miarm.h:951
MI_PFN_CACHE_ATTRIBUTE MiPlatformCacheAttributes[2][MmMaximumCacheType]
Definition: iosup.c:27
VOID NTAPI MmFreePagesFromMdl(IN PMDL Mdl)
Definition: mdlsup.c:568
smooth NULL
Definition: ftsmooth.c:416
PVOID FORCEINLINE MiPteToAddress(PMMPTE PointerPte)
Definition: mm.h:198
void * PVOID
Definition: retypes.h:9
VOID NTAPI MiReleaseSystemPtes(IN PMMPTE StartingPte, IN ULONG NumberOfPtes, IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType)
Definition: syspte.c:275
_Must_inspect_result_ _In_ PHYSICAL_ADDRESS _In_ PHYSICAL_ADDRESS SkipBytes
Definition: mmfuncs.h:226
#define ADDRESS_AND_SIZE_TO_SPAN_PAGES(_Va, _Size)
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
#define TAG_MDL
Definition: tag.h:86
#define PAGE_ALIGN(Va)
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:76
MMPTE ValidKernelPte
Definition: init.c:31
#define MI_PAGE_WRITE_THROUGH(x)
Definition: mm.h:99
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define BYTES_TO_PAGES(Size)
ULONG_PTR SIZE_T
Definition: typedefs.h:78
_Must_inspect_result_ _In_ PHYSICAL_ADDRESS HighAddress
Definition: mmfuncs.h:226
#define MI_PAGE_DISABLE_CACHE(x)
Definition: mm.h:98
VOID NTAPI MmFreeNonCachedMemory(IN PVOID BaseAddress, IN SIZE_T NumberOfBytes)
Definition: ncache.c:172
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS _Inout_ PLARGE_INTEGER NumberOfBytes
Definition: iotypes.h:998
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
PVOID NTAPI MmAllocateNonCachedMemory(IN SIZE_T NumberOfBytes)
Definition: ncache.c:25
PMDL NTAPI MiAllocatePagesForMdl(IN PHYSICAL_ADDRESS LowAddress, IN PHYSICAL_ADDRESS HighAddress, IN PHYSICAL_ADDRESS SkipBytes, IN SIZE_T TotalBytes, IN MI_PFN_CACHE_ATTRIBUTE CacheAttribute, IN ULONG Flags)
Definition: freelist.c:150
LONGLONG QuadPart
Definition: typedefs.h:112
ULONG PageFrameNumber
Definition: mmtypes.h:109