2 * PROJECT: ReactOS Kernel
3 * LICENSE: BSD - See COPYING.ARM in the top level directory
4 * FILE: ntoskrnl/mm/ARM3/pool.c
5 * PURPOSE: ARM Memory Manager Pool Allocator
6 * PROGRAMMERS: ReactOS Portable Systems Group
9 /* INCLUDES *******************************************************************/
15 #line 15 "ARMĀ³::POOL"
16 #define MODULE_INVOLVED_IN_ARM3
17 #include "../ARM3/miarm.h"
19 /* GLOBALS ********************************************************************/
21 LIST_ENTRY MmNonPagedPoolFreeListHead
[MI_MAX_FREE_PAGE_LISTS
];
22 PFN_NUMBER MmNumberOfFreeNonPagedPool
, MiExpansionPoolPagesInitialCharge
;
23 PVOID MmNonPagedPoolEnd0
;
24 PFN_NUMBER MiStartOfInitialPoolFrame
, MiEndOfInitialPoolFrame
;
26 /* PRIVATE FUNCTIONS **********************************************************/
30 MiInitializeArmPool(VOID
)
34 PMMFREE_POOL_ENTRY FreeEntry
, FirstEntry
;
39 // We keep 4 lists of free pages (4 lists help avoid contention)
41 for (i
= 0; i
< MI_MAX_FREE_PAGE_LISTS
; i
++)
44 // Initialize each of them
46 InitializeListHead(&MmNonPagedPoolFreeListHead
[i
]);
50 // Calculate how many pages the initial nonpaged pool has
52 PoolPages
= BYTES_TO_PAGES(MmSizeOfNonPagedPoolInBytes
);
53 MmNumberOfFreeNonPagedPool
= PoolPages
;
56 // Initialize the first free entry
58 FreeEntry
= MmNonPagedPoolStart
;
59 FirstEntry
= FreeEntry
;
60 FreeEntry
->Size
= PoolPages
;
61 FreeEntry
->Owner
= FirstEntry
;
64 // Insert it into the last list
66 InsertHeadList(&MmNonPagedPoolFreeListHead
[MI_MAX_FREE_PAGE_LISTS
- 1],
70 // Now create free entries for every single other page
72 while (PoolPages
-- > 1)
75 // Link them all back to the original entry
77 FreeEntry
= (PMMFREE_POOL_ENTRY
)((ULONG_PTR
)FreeEntry
+ PAGE_SIZE
);
78 FreeEntry
->Owner
= FirstEntry
;
82 // Validate and remember first allocated pool page
84 PointerPte
= MiAddressToPte(MmNonPagedPoolStart
);
85 ASSERT(PointerPte
->u
.Hard
.Valid
== 1);
86 MiStartOfInitialPoolFrame
= PFN_FROM_PTE(PointerPte
);
89 // Keep track of where initial nonpaged pool ends
91 MmNonPagedPoolEnd0
= (PVOID
)((ULONG_PTR
)MmNonPagedPoolStart
+
92 MmSizeOfNonPagedPoolInBytes
);
95 // Validate and remember last allocated pool page
97 PointerPte
= MiAddressToPte((PVOID
)((ULONG_PTR
)MmNonPagedPoolEnd0
- 1));
98 ASSERT(PointerPte
->u
.Hard
.Valid
== 1);
99 MiEndOfInitialPoolFrame
= PFN_FROM_PTE(PointerPte
);
102 // Validate the first nonpaged pool expansion page (which is a guard page)
104 PointerPte
= MiAddressToPte(MmNonPagedPoolExpansionStart
);
105 ASSERT(PointerPte
->u
.Hard
.Valid
== 0);
108 // Calculate the size of the expansion region alone
110 MiExpansionPoolPagesInitialCharge
=
111 BYTES_TO_PAGES(MmMaximumNonPagedPoolInBytes
- MmSizeOfNonPagedPoolInBytes
);
114 // Remove 2 pages, since there's a guard page on top and on the bottom
116 MiExpansionPoolPagesInitialCharge
-= 2;
119 // Now initialize the nonpaged pool expansion PTE space. Remember there's a
120 // guard page on top so make sure to skip it. The bottom guard page will be
121 // guaranteed by the fact our size is off by one.
123 MiInitializeSystemPtes(PointerPte
+ 1,
124 MiExpansionPoolPagesInitialCharge
,
125 NonPagedPoolExpansion
);