ReactOS 0.4.15-dev-7918-g2a2556c
memory.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS HAL
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: hal/halx86/generic/memory.c
5 * PURPOSE: HAL memory management
6 * PROGRAMMERS: ReactOS Portable Systems Group
7 */
8
9/* INCLUDES ******************************************************************/
10
11#include <hal.h>
12#define NDEBUG
13#include <debug.h>
14
15/* Share with Mm headers? */
16#define MM_HAL_HEAP_START (PVOID)(MM_HAL_VA_START + (1024 * 1024))
17
18/* GLOBALS *******************************************************************/
19
23
24
25/* PRIVATE FUNCTIONS *********************************************************/
26
30 IN ULONG64 MaxAddress,
31 IN PFN_NUMBER PageCount,
32 IN BOOLEAN Aligned)
33{
34 ULONG UsedDescriptors;
36 PFN_NUMBER MaxPage, BasePage, Alignment;
37 PLIST_ENTRY NextEntry;
38 PMEMORY_ALLOCATION_DESCRIPTOR MdBlock, NewBlock, FreeBlock;
39
40 /* Highest page we'll go */
41 MaxPage = MaxAddress >> PAGE_SHIFT;
42
43 /* We need at least two blocks */
44 if ((HalpUsedAllocDescriptors + 2) > 64) return 0;
45
46 /* Remember how many we have now */
47 UsedDescriptors = HalpUsedAllocDescriptors;
48
49 /* Loop the loader block memory descriptors */
50 NextEntry = LoaderBlock->MemoryDescriptorListHead.Flink;
51 while (NextEntry != &LoaderBlock->MemoryDescriptorListHead)
52 {
53 /* Get the block */
54 MdBlock = CONTAINING_RECORD(NextEntry,
56 ListEntry);
57
58 /* No alignment by default */
59 Alignment = 0;
60
61 /* Unless requested, in which case we use a 64KB block alignment */
62 if (Aligned) Alignment = ((MdBlock->BasePage + 0x0F) & ~0x0F) - MdBlock->BasePage;
63
64 /* Search for free memory */
65 if ((MdBlock->MemoryType == LoaderFree) ||
67 {
68 /* Make sure the page is within bounds, including alignment */
69 BasePage = MdBlock->BasePage;
70 if ((BasePage) &&
71 (MdBlock->PageCount >= PageCount + Alignment) &&
72 (BasePage + PageCount + Alignment < MaxPage))
73 {
74 /* We found an address */
76 break;
77 }
78 }
79
80 /* Keep trying */
81 NextEntry = NextEntry->Flink;
82 }
83
84 /* If we didn't find anything, get out of here */
85 if (NextEntry == &LoaderBlock->MemoryDescriptorListHead) return 0;
86
87 /* Okay, now get a descriptor */
89 NewBlock->PageCount = (ULONG)PageCount;
90 NewBlock->BasePage = MdBlock->BasePage + Alignment;
92
93 /* Update count */
94 UsedDescriptors++;
95 HalpUsedAllocDescriptors = UsedDescriptors;
96
97 /* Check if we had any alignment */
98 if (Alignment)
99 {
100 /* Check if we had leftovers */
101 if (MdBlock->PageCount > (PageCount + Alignment))
102 {
103 /* Get the next descriptor */
104 FreeBlock = &HalpAllocationDescriptorArray[UsedDescriptors];
105 FreeBlock->PageCount = MdBlock->PageCount - Alignment - (ULONG)PageCount;
106 FreeBlock->BasePage = MdBlock->BasePage + Alignment + (ULONG)PageCount;
107
108 /* One more */
110
111 /* Insert it into the list */
112 InsertHeadList(&MdBlock->ListEntry, &FreeBlock->ListEntry);
113 }
114
115 /* Trim the original block to the alignment only */
116 MdBlock->PageCount = Alignment;
117
118 /* Insert the descriptor after the original one */
119 InsertHeadList(&MdBlock->ListEntry, &NewBlock->ListEntry);
120 }
121 else
122 {
123 /* Consume memory from this block */
124 MdBlock->BasePage += (ULONG)PageCount;
125 MdBlock->PageCount -= (ULONG)PageCount;
126
127 /* Insert the descriptor before the original one */
128 InsertTailList(&MdBlock->ListEntry, &NewBlock->ListEntry);
129
130 /* Remove the entry if the whole block was allocated */
131 if (MdBlock->PageCount == 0) RemoveEntryList(&MdBlock->ListEntry);
132 }
133
134 /* Return the address */
135 return PhysicalAddress;
136}
137
138PVOID
139NTAPI
141 IN PFN_COUNT PageCount)
142{
144}
145
146VOID
147NTAPI
149 IN PFN_COUNT PageCount)
150{
152}
153
154PVOID
155NTAPI
157 IN PFN_COUNT PageCount,
158 IN BOOLEAN FlushCurrentTLB)
159{
160 PHARDWARE_PTE PointerPte;
161 PFN_NUMBER UsedPages = 0;
163
164 /* Start at the current HAL heap base */
167
168 /* Loop until we have all the pages required */
169 while (UsedPages < PageCount)
170 {
171 /* If this overflows past the HAL heap, it means there's no space */
172 if (VirtualAddress == NULL) return NULL;
173
174 /* Get the PTE for this address */
175 PointerPte = HalAddressToPte(VirtualAddress);
176
177 /* Go to the next page */
179
180 /* Check if the page is available */
181 if (PointerPte->Valid)
182 {
183 /* PTE has data, skip it and start with a new base address */
185 UsedPages = 0;
186 continue;
187 }
188
189 /* PTE is available, keep going on this run */
190 UsedPages++;
191 }
192
193 /* Take the base address of the page plus the actual offset in the address */
196
197 /* If we are starting at the heap, move the heap */
199 {
200 /* Past this allocation */
201 HalpHeapStart = (PVOID)((ULONG_PTR)BaseAddress + (PageCount * PAGE_SIZE));
202 }
203
204 /* Loop pages that can be mapped */
205 while (UsedPages--)
206 {
207 /* Fill out the PTE */
208 PointerPte = HalAddressToPte(BaseAddress);
210 PointerPte->Valid = 1;
211 PointerPte->Write = 1;
212
213 /* Move to the next address */
216 }
217
218 /* Flush the TLB and return the address */
219 if (FlushCurrentTLB)
220 HalpFlushTLB();
221
222 return VirtualAddress;
223}
224
225VOID
226NTAPI
228 IN PFN_COUNT PageCount,
229 IN BOOLEAN FlushCurrentTLB)
230{
231 PHARDWARE_PTE PointerPte;
232 ULONG i;
233
234 /* Only accept valid addresses */
235 if (VirtualAddress < (PVOID)MM_HAL_VA_START) return;
236
237 /* Align it down to page size */
239
240 /* Loop PTEs */
241 PointerPte = HalAddressToPte(VirtualAddress);
242 for (i = 0; i < PageCount; i++)
243 {
244 *(PULONG)PointerPte = 0;
245 PointerPte++;
246 }
247
248 /* Flush the TLB */
249 if (FlushCurrentTLB)
250 HalpFlushTLB();
251
252 /* Put the heap back */
254}
255
unsigned char BOOLEAN
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define InsertTailList(ListHead, Entry)
#define InsertHeadList(ListHead, Entry)
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
union Alignment_ Alignment
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
MEMORY_ALLOCATION_DESCRIPTOR HalpAllocationDescriptorArray[64]
Definition: memory.c:21
PVOID NTAPI HalpMapPhysicalMemory64Vista(IN PHYSICAL_ADDRESS PhysicalAddress, IN PFN_COUNT PageCount, IN BOOLEAN FlushCurrentTLB)
Definition: memory.c:156
VOID NTAPI HalpUnmapVirtualAddress(IN PVOID VirtualAddress, IN PFN_COUNT PageCount)
Definition: memory.c:148
ULONG HalpUsedAllocDescriptors
Definition: memory.c:20
VOID NTAPI HalpUnmapVirtualAddressVista(IN PVOID VirtualAddress, IN PFN_COUNT PageCount, IN BOOLEAN FlushCurrentTLB)
Definition: memory.c:227
PVOID NTAPI HalpMapPhysicalMemory64(IN PHYSICAL_ADDRESS PhysicalAddress, IN PFN_COUNT PageCount)
Definition: memory.c:140
ULONG64 NTAPI HalpAllocPhysicalMemory(IN PLOADER_PARAMETER_BLOCK LoaderBlock, IN ULONG64 MaxAddress, IN PFN_NUMBER PageCount, IN BOOLEAN Aligned)
Definition: memory.c:29
#define MM_HAL_HEAP_START
Definition: memory.c:16
PVOID HalpHeapStart
Definition: memory.c:22
VOID NTAPI HalpFlushTLB(VOID)
Definition: misc.c:156
#define HalAddressToPte(x)
Definition: halp.h:177
unsigned __int64 ULONG64
Definition: imports.h:198
#define MM_HAL_VA_START
Definition: ketypes.h:322
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
@ LoaderFree
Definition: arc.h:176
@ LoaderFirmwareTemporary
Definition: arc.h:179
@ LoaderHALCachedMemory
Definition: arc.h:200
ULONG PFN_NUMBER
Definition: ke.h:9
ULONG64 PageFrameNumber
Definition: mmtypes.h:78
ULONG64 Write
Definition: mmtypes.h:67
ULONG64 Valid
Definition: mmtypes.h:66
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
TYPE_OF_MEMORY MemoryType
Definition: arc.h:240
uint32_t * PULONG
Definition: typedefs.h:59
#define NTAPI
Definition: typedefs.h:36
void * PVOID
Definition: typedefs.h:50
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
LONGLONG QuadPart
Definition: typedefs.h:114
ULONG LowPart
Definition: typedefs.h:106
_Must_inspect_result_ _In_ WDFDMATRANSACTION _In_ PFN_WDF_PROGRAM_DMA _In_ WDF_DMA_DIRECTION _In_ PMDL _In_ PVOID VirtualAddress
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS PhysicalAddress
Definition: iotypes.h:1098
#define BYTE_OFFSET(Va)
ULONG PFN_COUNT
Definition: mmtypes.h:102