2 * COPYRIGHT: See COPYING.ARM in the top level directory
3 * PROJECT: ReactOS UEFI Boot Library
4 * FILE: boot/environ/lib/mm/mm.c
5 * PURPOSE: Boot Library Memory Manager Core
6 * PROGRAMMER: Alex Ionescu (alex.ionescu@reactos.org)
9 /* INCLUDES ******************************************************************/
14 /* DATA VARIABLES ************************************************************/
16 BL_TRANSLATION_TYPE MmTranslationType
, MmOriginalTranslationType
;
17 ULONG MmDescriptorCallTreeCount
;
19 /* FUNCTIONS *****************************************************************/
26 /* Nothing to track if we're using physical memory */
27 if (MmTranslationType
== BlNone
)
29 return STATUS_SUCCESS
;
33 EfiPrintf(L
"Required for protected mode\r\n");
34 return STATUS_NOT_IMPLEMENTED
;
45 ULONGLONG BadPageCount
;
47 /* First check if bad memory access is allowed */
49 Status
= BlGetBootOptionBoolean(BlpApplicationEntry
.BcdData
,
50 BcdLibraryBoolean_AllowBadMemoryAccess
,
52 if ((NT_SUCCESS(Status
)) && (AllowBad
))
54 /* No point checking the list if it is */
55 return STATUS_SUCCESS
;
58 /* Otherwise, check if there's a persisted bad page list */
59 Status
= BlpGetBootOptionIntegerList(BlpApplicationEntry
.BcdData
,
60 BcdLibraryIntegerList_BadMemoryList
,
64 if (NT_SUCCESS(Status
))
66 EfiPrintf(L
"Persistent bad page list not supported\r\n");
67 return STATUS_NOT_IMPLEMENTED
;
71 return STATUS_SUCCESS
;
75 MmSelectMappingAddress (
76 _Out_ PVOID
* MappingAddress
,
78 _In_ ULONG AllocationAttributes
,
80 _In_ PHYSICAL_ADDRESS PhysicalAddress
83 /* Are we in physical mode? */
84 if (MmTranslationType
== BlNone
)
86 /* Just return the physical address as the mapping address */
87 *MappingAddress
= (PVOID
)PhysicalAddress
.LowPart
;
88 return STATUS_SUCCESS
;
91 /* Have to allocate physical pages */
92 EfiPrintf(L
"VM Todo\r\n");
93 return STATUS_NOT_IMPLEMENTED
;
97 MmMapPhysicalAddress (
98 _Inout_ PPHYSICAL_ADDRESS PhysicalAddress
,
99 _Out_ PVOID VirtualAddress
,
100 _Inout_ PULONGLONG Size
,
101 _In_ ULONG CacheAttributes
104 ULONGLONG MappingSize
;
106 /* Fail if any parameters are missing */
107 if (!(PhysicalAddress
) || !(VirtualAddress
) || !(Size
))
109 return STATUS_INVALID_PARAMETER
;
112 /* Fail if the size is over 32-bits */
114 if (MappingSize
> 0xFFFFFFFF)
116 return STATUS_INVALID_PARAMETER
;
119 /* Nothing to do if we're in physical mode */
120 if (MmTranslationType
== BlNone
)
122 return STATUS_SUCCESS
;
125 /* Can't use virtual memory in real mode */
126 if (CurrentExecutionContext
->Mode
== BlRealMode
)
128 return STATUS_UNSUCCESSFUL
;
131 EfiPrintf(L
"VM todo\r\n");
132 return STATUS_NOT_IMPLEMENTED
;
136 BlMmMapPhysicalAddressEx (
137 _In_ PVOID
* VirtualAddress
,
140 _In_ PHYSICAL_ADDRESS PhysicalAddress
144 PVOID MappingAddress
;
145 PHYSICAL_ADDRESS MappedAddress
;
148 UCHAR CacheAttributes
;
150 /* Increase call depth */
151 ++MmDescriptorCallTreeCount
;
153 /* Check if any parameters are missing */
154 if (!(VirtualAddress
) || !(Size
))
156 Status
= STATUS_INVALID_PARAMETER
;
160 /* Check for fixed allocation without an actual address */
161 if ((Flags
& BlMemoryFixed
) &&
162 (PhysicalAddress
.QuadPart
== -1) &&
165 Status
= STATUS_INVALID_PARAMETER
;
169 /* Check for invalid requirement flag, if one is present */
170 if (((Flags
& BlMemoryValidAllocationAttributes
) != BlMemoryFixed
) &&
171 ((Flags
& BlMemoryValidAllocationAttributes
) != BlMemoryNonFixed
) &&
172 (Flags
& BlMemoryValidAllocationAttributes
))
174 Status
= STATUS_INVALID_PARAMETER
;
178 /* Check for invalid cache attribute flags */
179 if (((Flags
& BlMemoryValidCacheAttributeMask
) - 1) &
180 (Flags
& BlMemoryValidCacheAttributeMask
))
182 Status
= STATUS_INVALID_PARAMETER
;
186 /* Select an address to map this at */
187 Status
= MmSelectMappingAddress(&MappingAddress
,
189 Flags
& BlMemoryValidAllocationAttributes
,
192 if (!NT_SUCCESS(Status
))
197 /* Map the selected address, using the appropriate caching attributes */
198 MappedAddress
= PhysicalAddress
;
200 CacheAttributes
= ((Flags
& BlMemoryValidCacheAttributeMask
) != 0x20) ?
201 (Flags
& BlMemoryValidCacheAttributeMask
) : 0;
202 Status
= MmMapPhysicalAddress(&MappedAddress
,
206 if (!NT_SUCCESS(Status
))
211 /* Compute the final address where the mapping was made */
212 MappedBase
= (PVOID
)((ULONG_PTR
)MappingAddress
+
213 PhysicalAddress
.LowPart
-
214 MappedAddress
.LowPart
);
216 /* Check if we're in physical or virtual mode */
217 if (MmTranslationType
!= BlNone
)
219 /* For virtual memory, there's more to do */
220 EfiPrintf(L
"VM not supported for mapping\r\n");
221 Status
= STATUS_NOT_IMPLEMENTED
;
225 /* Return the mapped virtual address */
226 Status
= STATUS_SUCCESS
;
227 *VirtualAddress
= MappedBase
;
230 /* Cleanup descriptors and reduce depth */
231 MmMdFreeGlobalDescriptors();
232 --MmDescriptorCallTreeCount
;
237 MmUnmapVirtualAddress (
238 _Inout_ PVOID
* VirtualAddress
,
239 _Inout_ PULONGLONG Size
244 /* Make sure parameters were passed in and are valid */
245 if ((VirtualAddress
) && (Size
) && (*Size
<= 0xFFFFFFFF))
247 /* Nothing to do if translation isn't active */
248 if (MmTranslationType
== BlNone
)
250 Status
= STATUS_SUCCESS
;
254 Status
= STATUS_NOT_IMPLEMENTED
;
259 Status
= STATUS_INVALID_PARAMETER
;
267 BlMmUnmapVirtualAddressEx (
268 _In_ PVOID VirtualAddress
,
274 /* Increment call depth */
275 ++MmDescriptorCallTreeCount
;
277 /* Make sure all parameters are there */
278 if ((VirtualAddress
) && (Size
))
280 /* Unmap the virtual address */
281 Status
= MmUnmapVirtualAddress(&VirtualAddress
, &Size
);
283 /* Check if we actually had a virtual mapping active */
284 if ((NT_SUCCESS(Status
)) && (MmTranslationType
!= BlNone
))
287 Status
= STATUS_NOT_IMPLEMENTED
;
293 Status
= STATUS_INVALID_PARAMETER
;
296 /* Cleanup descriptors and reduce depth */
297 MmMdFreeGlobalDescriptors();
298 --MmDescriptorCallTreeCount
;
304 _In_ PBL_MEMORY_DATA MemoryData
,
305 _In_ BL_TRANSLATION_TYPE TranslationType
,
306 _In_ PBL_LIBRARY_PARAMETERS LibraryParameters
311 /* Take a reference */
312 MmDescriptorCallTreeCount
= 1;
314 /* Only support valid translation types */
315 if ((TranslationType
> BlPae
) || (LibraryParameters
->TranslationType
> BlPae
))
318 EfiPrintf(L
"Invalid translation types present\r\n");
319 Status
= STATUS_INVALID_PARAMETER
;
323 /* Initialize memory descriptors */
324 MmMdInitialize(0, LibraryParameters
);
326 /* Remember the page type we came in with */
327 MmOriginalTranslationType
= TranslationType
;
329 /* Initialize the physical page allocator */
330 Status
= MmPaInitialize(MemoryData
,
331 LibraryParameters
->MinimumAllocationCount
);
332 if (!NT_SUCCESS(Status
))
337 /* Initialize the memory tracker */
338 Status
= MmTrInitialize();
339 if (!NT_SUCCESS(Status
))
346 /* Initialize paging, large pages, self-mapping, PAE, if needed */
347 Status
= MmArchInitialize(1,
350 LibraryParameters
->TranslationType
);
351 if (NT_SUCCESS(Status
))
353 /* Save the newly active transation type */
354 MmTranslationType
= LibraryParameters
->TranslationType
;
356 /* Initialize the heap allocator now */
357 Status
= MmHaInitialize(LibraryParameters
->MinimumHeapSize
,
358 LibraryParameters
->HeapAllocationAttributes
);
361 /* If Phase 1 init failed, bail out */
362 if (!NT_SUCCESS(Status
))
364 /* Kill everything set setup so far */
372 /* Do we have too many descriptors? */
373 if (LibraryParameters
->DescriptorCount
> 512)
375 /* Switch to using a dynamic buffer instead */
376 EfiPrintf(L
"Warning: too many descriptors\r\n");
377 Status
= STATUS_NOT_IMPLEMENTED
;
379 //MmMdpSwitchToDynamicDescriptors(LibraryParameters->DescriptorCount);
382 /* Remove memory that the BCD says is bad */
383 BlMmRemoveBadMemory();
385 /* Now map all the memory regions as needed */
386 Status
= MmArchInitialize(2,
389 LibraryParameters
->TranslationType
);
390 if (NT_SUCCESS(Status
))
392 /* Initialize the block allocator */
393 Status
= MmBaInitialize();
396 /* Check if anything in phase 2 failed */
397 if (!NT_SUCCESS(Status
))
399 /* Go back to static descriptors and kill the heap */
400 //MmMdpSwitchToStaticDescriptors();
401 //HapInitializationStatus = 0;
402 //++MmDescriptorCallTreeCount;
404 /* Destroy the Phase 1 initialization */
412 /* Free the memory descriptors and return the initialization state */
413 MmMdFreeGlobalDescriptors();
414 --MmDescriptorCallTreeCount
;