ReactOS  r73918
contmem.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/contmem.c
5  * PURPOSE: ARM Memory Manager Contiguous 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 /* PRIVATE FUNCTIONS **********************************************************/
19 
21 NTAPI
23  IN PFN_NUMBER HighestPfn,
24  IN PFN_NUMBER BoundaryPfn,
25  IN PFN_NUMBER SizeInPages,
27 {
28  PFN_NUMBER Page, PageCount, LastPage, Length, BoundaryMask;
29  ULONG i = 0;
30  PMMPFN Pfn1, EndPfn;
31  KIRQL OldIrql;
32  PAGED_CODE();
33  ASSERT(SizeInPages != 0);
34 
35  //
36  // Convert the boundary PFN into an alignment mask
37  //
38  BoundaryMask = ~(BoundaryPfn - 1);
39 
40  /* Disable APCs */
42 
43  //
44  // Loop all the physical memory blocks
45  //
46  do
47  {
48  //
49  // Capture the base page and length of this memory block
50  //
52  PageCount = MmPhysicalMemoryBlock->Run[i].PageCount;
53 
54  //
55  // Check how far this memory block will go
56  //
57  LastPage = Page + PageCount;
58 
59  //
60  // Trim it down to only the PFNs we're actually interested in
61  //
62  if ((LastPage - 1) > HighestPfn) LastPage = HighestPfn + 1;
63  if (Page < LowestPfn) Page = LowestPfn;
64 
65  //
66  // Skip this run if it's empty or fails to contain all the pages we need
67  //
68  if (!(PageCount) || ((Page + SizeInPages) > LastPage)) continue;
69 
70  //
71  // Now scan all the relevant PFNs in this run
72  //
73  Length = 0;
74  for (Pfn1 = MI_PFN_ELEMENT(Page); Page < LastPage; Page++, Pfn1++)
75  {
76  //
77  // If this PFN is in use, ignore it
78  //
79  if (MiIsPfnInUse(Pfn1))
80  {
81  Length = 0;
82  continue;
83  }
84 
85  //
86  // If we haven't chosen a start PFN yet and the caller specified an
87  // alignment, make sure the page matches the alignment restriction
88  //
89  if ((!(Length) && (BoundaryPfn)) &&
90  (((Page ^ (Page + SizeInPages - 1)) & BoundaryMask)))
91  {
92  //
93  // It does not, so bail out
94  //
95  continue;
96  }
97 
98  //
99  // Increase the number of valid pages, and check if we have enough
100  //
101  if (++Length == SizeInPages)
102  {
103  //
104  // It appears we've amassed enough legitimate pages, rollback
105  //
106  Pfn1 -= (Length - 1);
107  Page -= (Length - 1);
108 
109  //
110  // Acquire the PFN lock
111  //
113  do
114  {
115  //
116  // Things might've changed for us. Is the page still free?
117  //
118  if (MiIsPfnInUse(Pfn1)) break;
119 
120  //
121  // So far so good. Is this the last confirmed valid page?
122  //
123  if (!--Length)
124  {
125  //
126  // Sanity check that we didn't go out of bounds
127  //
129 
130  //
131  // Loop until all PFN entries have been processed
132  //
133  EndPfn = Pfn1 - SizeInPages + 1;
134  do
135  {
136  //
137  // This PFN is now a used page, set it up
138  //
140  MI_SET_PROCESS2("Kernel Driver");
142  Pfn1->u3.e2.ReferenceCount = 1;
143  Pfn1->u2.ShareCount = 1;
145  Pfn1->u3.e1.StartOfAllocation = 0;
146  Pfn1->u3.e1.EndOfAllocation = 0;
147  Pfn1->u3.e1.PrototypePte = 0;
148  Pfn1->u4.VerifierAllocation = 0;
149  Pfn1->PteAddress = (PVOID)0xBAADF00D;
150 
151  //
152  // Check if this is the last PFN, otherwise go on
153  //
154  if (Pfn1 == EndPfn) break;
155  Pfn1--;
156  } while (TRUE);
157 
158  //
159  // Mark the first and last PFN so we can find them later
160  //
161  Pfn1->u3.e1.StartOfAllocation = 1;
162  (Pfn1 + SizeInPages - 1)->u3.e1.EndOfAllocation = 1;
163 
164  //
165  // Now it's safe to let go of the PFN lock
166  //
168 
169  //
170  // Quick sanity check that the last PFN is consistent
171  //
172  EndPfn = Pfn1 + SizeInPages;
173  ASSERT(EndPfn == MI_PFN_ELEMENT(Page + 1));
174 
175  //
176  // Compute the first page, and make sure it's consistent
177  //
178  Page = Page - SizeInPages + 1;
179  ASSERT(Pfn1 == MI_PFN_ELEMENT(Page));
180  ASSERT(Page != 0);
181 
182  /* Enable APCs and return the page */
184  return Page;
185  }
186 
187  //
188  // Keep going. The purpose of this loop is to reconfirm that
189  // after acquiring the PFN lock these pages are still usable
190  //
191  Pfn1++;
192  Page++;
193  } while (TRUE);
194 
195  //
196  // If we got here, something changed while we hadn't acquired
197  // the PFN lock yet, so we'll have to restart
198  //
200  Length = 0;
201  }
202  }
203  } while (++i != MmPhysicalMemoryBlock->NumberOfRuns);
204 
205  //
206  // And if we get here, it means no suitable physical memory runs were found
207  //
209  return 0;
210 }
211 
212 PVOID
213 NTAPI
215  IN PFN_NUMBER BaseAddressPages,
216  IN PFN_NUMBER SizeInPages,
217  IN PFN_NUMBER LowestPfn,
218  IN PFN_NUMBER HighestPfn,
219  IN PFN_NUMBER BoundaryPfn,
220  IN MI_PFN_CACHE_ATTRIBUTE CacheAttribute)
221 {
222  PMMPTE StartPte, EndPte;
223  PFN_NUMBER PreviousPage = 0, Page, HighPage, BoundaryMask, Pages = 0;
224 
225  //
226  // Okay, first of all check if the PFNs match our restrictions
227  //
228  if (LowestPfn > HighestPfn) return NULL;
229  if (LowestPfn + SizeInPages <= LowestPfn) return NULL;
230  if (LowestPfn + SizeInPages - 1 > HighestPfn) return NULL;
231  if (BaseAddressPages < SizeInPages) return NULL;
232 
233  //
234  // This is the last page we need to get to and the boundary requested
235  //
236  HighPage = HighestPfn + 1 - SizeInPages;
237  BoundaryMask = ~(BoundaryPfn - 1);
238 
239  //
240  // And here's the PTEs for this allocation. Let's go scan them.
241  //
242  StartPte = MiAddressToPte(BaseAddress);
243  EndPte = StartPte + BaseAddressPages;
244  while (StartPte < EndPte)
245  {
246  //
247  // Get this PTE's page number
248  //
249  ASSERT (StartPte->u.Hard.Valid == 1);
250  Page = PFN_FROM_PTE(StartPte);
251 
252  //
253  // Is this the beginning of our adventure?
254  //
255  if (!Pages)
256  {
257  //
258  // Check if this PFN is within our range
259  //
260  if ((Page >= LowestPfn) && (Page <= HighPage))
261  {
262  //
263  // It is! Do you care about boundary (alignment)?
264  //
265  if (!(BoundaryPfn) ||
266  (!((Page ^ (Page + SizeInPages - 1)) & BoundaryMask)))
267  {
268  //
269  // You don't care, or you do care but we deliver
270  //
271  Pages++;
272  }
273  }
274 
275  //
276  // Have we found all the pages we need by now?
277  // Incidently, this means you only wanted one page
278  //
279  if (Pages == SizeInPages)
280  {
281  //
282  // Mission complete
283  //
284  return MiPteToAddress(StartPte);
285  }
286  }
287  else
288  {
289  //
290  // Have we found a page that doesn't seem to be contiguous?
291  //
292  if (Page != (PreviousPage + 1))
293  {
294  //
295  // Ah crap, we have to start over
296  //
297  Pages = 0;
298  continue;
299  }
300 
301  //
302  // Otherwise, we're still in the game. Do we have all our pages?
303  //
304  if (++Pages == SizeInPages)
305  {
306  //
307  // We do! This entire range was contiguous, so we'll return it!
308  //
309  return MiPteToAddress(StartPte - Pages + 1);
310  }
311  }
312 
313  //
314  // Try with the next PTE, remember this PFN
315  //
316  PreviousPage = Page;
317  StartPte++;
318  continue;
319  }
320 
321  //
322  // All good returns are within the loop...
323  //
324  return NULL;
325 }
326 
327 PVOID
328 NTAPI
330  IN PFN_NUMBER HighestPfn,
331  IN PFN_NUMBER BoundaryPfn,
332  IN PFN_NUMBER SizeInPages,
334 {
335  PFN_NUMBER Page;
337  PMMPFN Pfn1, EndPfn;
338  PMMPTE PointerPte;
340  PAGED_CODE();
341  ASSERT(SizeInPages != 0);
342 
343  //
344  // Our last hope is to scan the free page list for contiguous pages
345  //
346  Page = MiFindContiguousPages(LowestPfn,
347  HighestPfn,
348  BoundaryPfn,
349  SizeInPages,
350  CacheType);
351  if (!Page) return NULL;
352 
353  //
354  // We'll just piggyback on the I/O memory mapper
355  //
356  PhysicalAddress.QuadPart = Page << PAGE_SHIFT;
357  BaseAddress = MmMapIoSpace(PhysicalAddress, SizeInPages << PAGE_SHIFT, CacheType);
358  ASSERT(BaseAddress);
359 
360  /* Loop the PFN entries */
361  Pfn1 = MiGetPfnEntry(Page);
362  EndPfn = Pfn1 + SizeInPages;
363  PointerPte = MiAddressToPte(BaseAddress);
364  do
365  {
366  /* Write the PTE address */
367  Pfn1->PteAddress = PointerPte;
368  Pfn1->u4.PteFrame = PFN_FROM_PTE(MiAddressToPte(PointerPte++));
369  } while (++Pfn1 < EndPfn);
370 
371  /* Return the address */
372  return BaseAddress;
373 }
374 
375 PVOID
376 NTAPI
378  IN PFN_NUMBER LowestAcceptablePfn,
379  IN PFN_NUMBER HighestAcceptablePfn,
380  IN PFN_NUMBER BoundaryPfn,
382 {
384  PFN_NUMBER SizeInPages;
385  MI_PFN_CACHE_ATTRIBUTE CacheAttribute;
386 
387  //
388  // Verify count and cache type
389  //
390  ASSERT(NumberOfBytes != 0);
391  ASSERT(CacheType <= MmWriteCombined);
392 
393  //
394  // Compute size requested
395  //
396  SizeInPages = BYTES_TO_PAGES(NumberOfBytes);
397 
398  //
399  // Convert the cache attribute and check for cached requests
400  //
401  CacheAttribute = MiPlatformCacheAttributes[FALSE][CacheType];
402  if (CacheAttribute == MiCached)
403  {
404  //
405  // Because initial nonpaged pool is supposed to be contiguous, go ahead
406  // and try making a nonpaged pool allocation first.
407  //
409  NumberOfBytes,
410  'mCmM');
411  if (BaseAddress)
412  {
413  //
414  // Now make sure it's actually contiguous (if it came from expansion
415  // it might not be).
416  //
417  if (MiCheckForContiguousMemory(BaseAddress,
418  SizeInPages,
419  SizeInPages,
420  LowestAcceptablePfn,
421  HighestAcceptablePfn,
422  BoundaryPfn,
423  CacheAttribute))
424  {
425  //
426  // Sweet, we're in business!
427  //
428  return BaseAddress;
429  }
430 
431  //
432  // No such luck
433  //
434  ExFreePoolWithTag(BaseAddress, 'mCmM');
435  }
436  }
437 
438  //
439  // According to MSDN, the system won't try anything else if you're higher
440  // than APC level.
441  //
442  if (KeGetCurrentIrql() > APC_LEVEL) return NULL;
443 
444  //
445  // Otherwise, we'll go try to find some
446  //
447  return MiFindContiguousMemory(LowestAcceptablePfn,
448  HighestAcceptablePfn,
449  BoundaryPfn,
450  SizeInPages,
451  CacheType);
452 }
453 
454 VOID
455 NTAPI
457 {
458  KIRQL OldIrql;
459  PFN_NUMBER PageFrameIndex, LastPage, PageCount;
460  PMMPFN Pfn1, StartPfn;
461  PMMPTE PointerPte;
462  PAGED_CODE();
463 
464  //
465  // First, check if the memory came from initial nonpaged pool, or expansion
466  //
467  if (((BaseAddress >= MmNonPagedPoolStart) &&
468  (BaseAddress < (PVOID)((ULONG_PTR)MmNonPagedPoolStart +
470  ((BaseAddress >= MmNonPagedPoolExpansionStart) &&
471  (BaseAddress < MmNonPagedPoolEnd)))
472  {
473  //
474  // It did, so just use the pool to free this
475  //
476  ExFreePoolWithTag(BaseAddress, 'mCmM');
477  return;
478  }
479 
480  /* Get the PTE and frame number for the allocation*/
481  PointerPte = MiAddressToPte(BaseAddress);
482  PageFrameIndex = PFN_FROM_PTE(PointerPte);
483 
484  //
485  // Now get the PFN entry for this, and make sure it's the correct one
486  //
487  Pfn1 = MiGetPfnEntry(PageFrameIndex);
488  if ((!Pfn1) || (Pfn1->u3.e1.StartOfAllocation == 0))
489  {
490  //
491  // This probably means you did a free on an address that was in between
492  //
493  KeBugCheckEx(BAD_POOL_CALLER,
494  0x60,
495  (ULONG_PTR)BaseAddress,
496  0,
497  0);
498  }
499 
500  //
501  // Now this PFN isn't the start of any allocation anymore, it's going out
502  //
503  StartPfn = Pfn1;
504  Pfn1->u3.e1.StartOfAllocation = 0;
505 
506  /* Loop the PFNs until we find the one that marks the end of the allocation */
507  do
508  {
509  /* Make sure these are the pages we setup in the allocation routine */
510  ASSERT(Pfn1->u3.e2.ReferenceCount == 1);
511  ASSERT(Pfn1->u2.ShareCount == 1);
512  ASSERT(Pfn1->PteAddress == PointerPte);
514  ASSERT(Pfn1->u4.VerifierAllocation == 0);
515  ASSERT(Pfn1->u3.e1.PrototypePte == 0);
516 
517  /* Set the special pending delete marker */
518  MI_SET_PFN_DELETED(Pfn1);
519 
520  /* Keep going for assertions */
521  PointerPte++;
522  } while (Pfn1++->u3.e1.EndOfAllocation == 0);
523 
524  //
525  // Found it, unmark it
526  //
527  Pfn1--;
528  Pfn1->u3.e1.EndOfAllocation = 0;
529 
530  //
531  // Now compute how many pages this represents
532  //
533  PageCount = (ULONG)(Pfn1 - StartPfn + 1);
534 
535  //
536  // So we can know how much to unmap (recall we piggyback on I/O mappings)
537  //
538  MmUnmapIoSpace(BaseAddress, PageCount << PAGE_SHIFT);
539 
540  //
541  // Lock the PFN database
542  //
544 
545  //
546  // Loop all the pages
547  //
548  LastPage = PageFrameIndex + PageCount;
549  Pfn1 = MiGetPfnEntry(PageFrameIndex);
550  do
551  {
552  /* Decrement the share count and move on */
553  MiDecrementShareCount(Pfn1++, PageFrameIndex++);
554  } while (PageFrameIndex < LastPage);
555 
556  //
557  // Release the PFN lock
558  //
560 }
561 
562 /* PUBLIC FUNCTIONS ***********************************************************/
563 
564 /*
565  * @implemented
566  */
567 PVOID
568 NTAPI
574 {
575  PFN_NUMBER LowestPfn, HighestPfn, BoundaryPfn;
576 
577  //
578  // Verify count and cache type
579  //
580  ASSERT(NumberOfBytes != 0);
582 
583  //
584  // Convert the lowest address into a PFN
585  //
587  if (BYTE_OFFSET(LowestAcceptableAddress.LowPart)) LowestPfn++;
588 
589  //
590  // Convert and validate the boundary address into a PFN
591  //
594 
595  //
596  // Convert the highest address into a PFN
597  //
598  HighestPfn = (PFN_NUMBER)(HighestAcceptableAddress.QuadPart >> PAGE_SHIFT);
599  if (HighestPfn > MmHighestPhysicalPage) HighestPfn = MmHighestPhysicalPage;
600 
601  //
602  // Validate the PFN bounds
603  //
604  if (LowestPfn > HighestPfn) return NULL;
605 
606  //
607  // Let the contiguous memory allocator handle it
608  //
609  return MiAllocateContiguousMemory(NumberOfBytes,
610  LowestPfn,
611  HighestPfn,
612  BoundaryPfn,
613  CacheType);
614 }
615 
616 /*
617  * @implemented
618  */
619 PVOID
620 NTAPI
623 {
624  PFN_NUMBER HighestPfn;
625 
626  //
627  // Verify byte count
628  //
629  ASSERT(NumberOfBytes != 0);
630 
631  //
632  // Convert and normalize the highest address into a PFN
633  //
634  HighestPfn = (PFN_NUMBER)(HighestAcceptableAddress.QuadPart >> PAGE_SHIFT);
635  if (HighestPfn > MmHighestPhysicalPage) HighestPfn = MmHighestPhysicalPage;
636 
637  //
638  // Let the contiguous memory allocator handle it
639  //
640  return MiAllocateContiguousMemory(NumberOfBytes, 0, HighestPfn, 0, MmCached);
641 }
642 
643 /*
644  * @implemented
645  */
646 VOID
647 NTAPI
649 {
650  //
651  // Let the contiguous memory allocator handle it
652  //
653  MiFreeContiguousMemory(BaseAddress);
654 }
655 
656 /*
657  * @implemented
658  */
659 VOID
660 NTAPI
664 {
665  //
666  // Just call the non-cached version (there's no cache issues for freeing)
667  //
668  MiFreeContiguousMemory(BaseAddress);
669 }
670 
671 /* EOF */
DWORD *typedef PVOID
Definition: winlogon.h:52
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
_Must_inspect_result_ _In_ PHYSICAL_ADDRESS _In_ PHYSICAL_ADDRESS _In_opt_ PHYSICAL_ADDRESS BoundaryAddressMultiple
Definition: mmfuncs.h:214
struct _MMPFN::@1488::@1494 e2
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
#define IN
Definition: typedefs.h:39
union _MMPFN::@1491 u4
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
PVOID NTAPI MiCheckForContiguousMemory(IN PVOID BaseAddress, IN PFN_NUMBER BaseAddressPages, IN PFN_NUMBER SizeInPages, IN PFN_NUMBER LowestPfn, IN PFN_NUMBER HighestPfn, IN PFN_NUMBER BoundaryPfn, IN MI_PFN_CACHE_ATTRIBUTE CacheAttribute)
Definition: contmem.c:214
PFN_NUMBER PageCount
Definition: miarm.h:396
PVOID MmNonPagedPoolExpansionStart
Definition: init.c:25
#define TRUE
Definition: numbers.c:17
PVOID NTAPI MiFindContiguousMemory(IN PFN_NUMBER LowestPfn, IN PFN_NUMBER HighestPfn, IN PFN_NUMBER BoundaryPfn, IN PFN_NUMBER SizeInPages, IN MEMORY_CACHING_TYPE CacheType)
Definition: contmem.c:329
PHYSICAL_MEMORY_RUN Run[1]
Definition: miarm.h:403
PVOID NTAPI MmMapIoSpace(IN PHYSICAL_ADDRESS PhysicalAddress, IN SIZE_T NumberOfBytes, IN MEMORY_CACHING_TYPE CacheType)
Definition: iosup.c:47
union _MMPFN::@1487 u2
VOID NTAPI MiFreeContiguousMemory(IN PVOID BaseAddress)
Definition: contmem.c:456
USHORT PageLocation
Definition: mm.h:297
VOID NTAPI MmFreeContiguousMemory(IN PVOID BaseAddress)
Definition: contmem.c:648
enum _MI_PFN_CACHE_ATTRIBUTE MI_PFN_CACHE_ATTRIBUTE
PVOID MmNonPagedPoolEnd
Definition: mminit.c:99
uint32_t ULONG_PTR
Definition: typedefs.h:64
USHORT PrototypePte
Definition: mm.h:295
UCHAR KIRQL
Definition: env_spec_w32.h:591
MMPFNENTRY e1
Definition: mm.h:329
GLenum GLclampf GLint i
Definition: glfuncs.h:14
#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
ULONG_PTR ShareCount
Definition: mm.h:322
PFN_NUMBER BasePage
Definition: miarm.h:395
#define NULL
Definition: mystdio.h:57
#define MI_SET_PROCESS2(x)
Definition: mm.h:254
MI_PFN_CACHE_ATTRIBUTE MiPlatformCacheAttributes[2][MmMaximumCacheType]
Definition: iosup.c:27
_Must_inspect_result_ _In_ PHYSICAL_ADDRESS _In_ PHYSICAL_ADDRESS _In_opt_ PHYSICAL_ADDRESS _In_ MEMORY_CACHING_TYPE CacheType
Definition: mmfuncs.h:214
PVOID FORCEINLINE MiPteToAddress(PMMPTE PointerPte)
Definition: mm.h:185
#define KeLeaveGuardedRegion()
Definition: ke_x.h:63
ULONG_PTR VerifierAllocation
Definition: mm.h:352
VOID NTAPI MiDecrementShareCount(IN PMMPFN Pfn1, IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:1133
#define MI_SET_USAGE(x)
Definition: mm.h:253
PFN_NUMBER NTAPI MiFindContiguousPages(IN PFN_NUMBER LowestPfn, IN PFN_NUMBER HighestPfn, IN PFN_NUMBER BoundaryPfn, IN PFN_NUMBER SizeInPages, IN MEMORY_CACHING_TYPE CacheType)
Definition: contmem.c:22
union _MMPFN::@1488 u3
PPHYSICAL_MEMORY_DESCRIPTOR MmPhysicalMemoryBlock
Definition: init.c:45
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
ULONG64 Valid
Definition: mmtypes.h:150
PVOID NTAPI MiAllocateContiguousMemory(IN SIZE_T NumberOfBytes, IN PFN_NUMBER LowestAcceptablePfn, IN PFN_NUMBER HighestAcceptablePfn, IN PFN_NUMBER BoundaryPfn, IN MEMORY_CACHING_TYPE CacheType)
Definition: contmem.c:377
VOID FASTCALL KeReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber, IN KIRQL OldIrql)
Definition: spinlock.c:154
#define PAGED_CODE()
Definition: video.h:57
#define KeEnterGuardedRegion()
Definition: ke_x.h:34
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define BYTES_TO_PAGES(Size)
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS PhysicalAddress
Definition: iotypes.h:1060
FORCEINLINE PMMPFN MI_PFN_ELEMENT(IN PFN_NUMBER Pfn)
Definition: miarm.h:1391
VOID UINTN Length
Definition: acefiex.h:718
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
IN SIZE_T NumberOfBytes
Definition: ndis.h:3914
_Out_ PNDIS_HANDLE _Out_ PUINT _In_ PNDIS_STRING _In_ NDIS_PHYSICAL_ADDRESS HighestAcceptableAddress
Definition: ndis.h:3208
Definition: mm.h:305
ULONG LowPart
Definition: typedefs.h:105
KIRQL FASTCALL KeAcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber)
Definition: spinlock.c:108
FORCEINLINE PMMPFN MiGetPfnEntry(IN PFN_NUMBER Pfn)
Definition: mm.h:877
_Must_inspect_result_ _In_ PHYSICAL_ADDRESS LowestAcceptableAddress
Definition: mmfuncs.h:214
PVOID MmNonPagedPoolStart
Definition: init.c:24
ULONG_PTR SIZE_T
Definition: typedefs.h:79
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
union _MMPTE::@1885 u
#define MI_SET_PFN_DELETED(x)
Definition: miarm.h:161
ULONG_PTR PteFrame
Definition: mm.h:350
VOID NTAPI MmUnmapIoSpace(IN PVOID BaseAddress, IN SIZE_T NumberOfBytes)
Definition: iosup.c:193
PMMPTE PteAddress
Definition: mm.h:318
PVOID NTAPI MmAllocateContiguousMemory(IN SIZE_T NumberOfBytes, IN PHYSICAL_ADDRESS HighestAcceptableAddress)
Definition: contmem.c:621
VOID NTAPI MmFreeContiguousMemorySpecifyCache(IN PVOID BaseAddress, IN SIZE_T NumberOfBytes, IN MEMORY_CACHING_TYPE CacheType)
Definition: contmem.c:661
#define FALSE
Definition: numbers.c:16
unsigned int ULONG
Definition: retypes.h:1
BOOLEAN NTAPI MiIsPfnInUse(IN PMMPFN Pfn1)
Definition: freelist.c:142
PFN_NUMBER MmHighestPhysicalPage
Definition: meminit.c:31
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1097
ULONG MmSizeOfNonPagedPoolInBytes
Definition: init.c:21
static BYTE u3[]
Definition: msg.c:580
enum _MEMORY_CACHING_TYPE MEMORY_CACHING_TYPE
VOID NTAPI MiUnlinkFreeOrZeroedPage(IN PMMPFN Entry)
Definition: pfnlist.c:137
#define APC_LEVEL
Definition: env_spec_w32.h:695
#define PFN_FROM_PTE(v)
Definition: mm.h:82
#define BYTE_OFFSET(Va)
IN HDEVINFO IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL
Definition: devinst.c:44
VOID NTAPI KeBugCheckEx(_In_ ULONG BugCheckCode, _In_ ULONG_PTR BugCheckParameter1, _In_ ULONG_PTR BugCheckParameter2, _In_ ULONG_PTR BugCheckParameter3, _In_ ULONG_PTR BugCheckParameter4)
Definition: rtlcompat.c:90
LONGLONG QuadPart
Definition: typedefs.h:113
PVOID NTAPI MmAllocateContiguousMemorySpecifyCache(IN SIZE_T NumberOfBytes, IN PHYSICAL_ADDRESS LowestAcceptableAddress OPTIONAL, IN PHYSICAL_ADDRESS HighestAcceptableAddress, IN PHYSICAL_ADDRESS BoundaryAddressMultiple OPTIONAL, IN MEMORY_CACHING_TYPE CacheType OPTIONAL)
Definition: contmem.c:569