ReactOS  0.4.14-dev-49-gfb4591c
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 
27 ULONG64
28 NTAPI
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) ||
66  (MdBlock->MemoryType == LoaderFirmwareTemporary))
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 */
75  PhysicalAddress = ((ULONG64)BasePage + Alignment) << PAGE_SHIFT;
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 
138 PVOID
139 NTAPI
141  IN PFN_COUNT PageCount)
142 {
144 }
145 
146 VOID
147 NTAPI
149  IN PFN_COUNT PageCount)
150 {
152 }
153 
154 PVOID
155 NTAPI
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 */
198  if (BaseAddress == HalpHeapStart)
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 
225 VOID
226 NTAPI
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 
ULONG64 Valid
Definition: mmtypes.h:66
PVOID NTAPI HalpMapPhysicalMemory64Vista(IN PHYSICAL_ADDRESS PhysicalAddress, IN PFN_COUNT PageCount, IN BOOLEAN FlushCurrentTLB)
Definition: memory.c:156
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
#define IN
Definition: typedefs.h:38
#define MM_HAL_VA_START
Definition: ketypes.h:256
#define TRUE
Definition: types.h:120
ULONG HalpUsedAllocDescriptors
Definition: memory.c:20
ULONG PFN_COUNT
Definition: mmtypes.h:102
VOID NTAPI HalpFlushTLB(VOID)
Definition: misc.c:163
FORCEINLINE VOID InsertHeadList(_Inout_ PLIST_ENTRY ListHead, _Inout_ __drv_aliasesMem PLIST_ENTRY Entry)
Definition: rtlfuncs.h:201
PVOID NTAPI HalpMapPhysicalMemory64(IN PHYSICAL_ADDRESS PhysicalAddress, IN PFN_COUNT PageCount)
Definition: memory.c:140
#define HalAddressToPte(x)
Definition: halp.h:523
#define InsertTailList(ListHead, Entry)
uint32_t ULONG_PTR
Definition: typedefs.h:63
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
TYPE_OF_MEMORY MemoryType
Definition: arc.h:193
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
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
VOID NTAPI HalpUnmapVirtualAddressVista(IN PVOID VirtualAddress, IN PFN_COUNT PageCount, IN BOOLEAN FlushCurrentTLB)
Definition: memory.c:227
union Alignment_ Alignment
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
void * PVOID
Definition: retypes.h:9
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
unsigned __int64 ULONG64
Definition: imports.h:198
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS PhysicalAddress
Definition: iotypes.h:1061
ULONG64 PageFrameNumber
Definition: mmtypes.h:78
ULONG LowPart
Definition: typedefs.h:104
#define PAGE_SIZE
Definition: env_spec_w32.h:49
Definition: typedefs.h:117
_In_ ULONG _In_ BOOLEAN _Must_inspect_result_ PVOID * VirtualAddress
Definition: ndis.h:3791
PVOID HalpHeapStart
Definition: memory.c:22
VOID NTAPI HalpUnmapVirtualAddress(IN PVOID VirtualAddress, IN PFN_COUNT PageCount)
Definition: memory.c:148
unsigned int * PULONG
Definition: retypes.h:1
ULONG64 Write
Definition: mmtypes.h:67
unsigned int ULONG
Definition: retypes.h:1
ULONG64 NTAPI HalpAllocPhysicalMemory(IN PLOADER_PARAMETER_BLOCK LoaderBlock, IN ULONG64 MaxAddress, IN PFN_NUMBER PageCount, IN BOOLEAN Aligned)
Definition: memory.c:29
MEMORY_ALLOCATION_DESCRIPTOR HalpAllocationDescriptorArray[64]
Definition: memory.c:21
#define BYTE_OFFSET(Va)
#define MM_HAL_HEAP_START
Definition: memory.c:16
LONGLONG QuadPart
Definition: typedefs.h:112