OpenCore  1.0.4
OpenCore Bootloader
Loading...
Searching...
No Matches
UserBaseMemoryLib.c
Go to the documentation of this file.
1
6#include <Uefi.h>
7#include <Library/BaseMemoryLib.h>
8#include <Library/PhaseMemoryAllocationLib.h>
9#include <Library/MemoryAllocationLib.h>
10#include <Library/DebugLib.h>
11#include <Library/UefiLib.h>
12#include <Library/UefiApplicationEntryPoint.h>
13
14#include <string.h>
15#include <stdlib.h>
16
17#include <UserMemory.h>
18
19#ifdef WIN32
20 #include <malloc.h>
21#endif // WIN32
22
23GLOBAL_REMOVE_IF_UNREFERENCED CONST EFI_MEMORY_TYPE gPhaseDefaultDataType = EfiBootServicesData;
24GLOBAL_REMOVE_IF_UNREFERENCED CONST EFI_MEMORY_TYPE gPhaseDefaultCodeType = EfiBootServicesCode;
25
26//
27// Limits single pool allocation size to 512MB by default.
28// Use SetPoolAllocationSizeLimit to change this limit.
29//
30STATIC UINTN mPoolAllocationSizeLimit = BASE_512MB;
31
32GLOBAL_REMOVE_IF_UNREFERENCED UINTN mPoolAllocations;
33GLOBAL_REMOVE_IF_UNREFERENCED UINTN mPageAllocations;
34
35STATIC UINT64 mPoolAllocationMask = MAX_UINT64;
37STATIC UINT64 mPageAllocationMask = MAX_UINT64;
39
40VOID
42 IN CONST UINT8 *Data,
43 IN UINTN Size,
44 IN OUT UINT32 *ConfigSize
45 )
46{
49
50 if (Size - *ConfigSize >= sizeof (UINT64)) {
51 *ConfigSize += sizeof (UINT64);
52 CopyMem (&mPoolAllocationMask, &Data[Size - *ConfigSize], sizeof (UINT64));
53 } else {
54 mPoolAllocationMask = MAX_UINT64;
55 }
56
57 if (Size - *ConfigSize >= sizeof (UINT64)) {
58 *ConfigSize += sizeof (UINT64);
59 CopyMem (&mPageAllocationMask, &Data[Size - *ConfigSize], sizeof (UINT64));
60 } else {
61 mPageAllocationMask = MAX_UINT64;
62 }
63}
64
65VOID
67 UINTN AllocationSize
68 )
69{
70 mPoolAllocationSizeLimit = AllocationSize;
71}
72
73VOID *
74EFIAPI
76 OUT VOID *DestinationBuffer,
77 IN CONST VOID *SourceBuffer,
78 IN UINTN Length
79 )
80{
81 ASSERT (DestinationBuffer != NULL);
82 ASSERT (SourceBuffer != NULL);
83
84 return memmove (DestinationBuffer, SourceBuffer, Length);
85}
86
87VOID *
88EFIAPI
90 OUT VOID *Buffer,
91 IN UINTN Length,
92 IN UINT8 Value
93 )
94{
95 ASSERT (Buffer != NULL);
96
97 return memset (Buffer, Value, Length);
98}
99
100VOID *
101EFIAPI
103 OUT VOID *Buffer,
104 IN UINTN Length
105 )
106{
107 ASSERT (Buffer != NULL);
108
109 return memset (Buffer, 0, Length);
110}
111
112BOOLEAN
113EFIAPI
115 IN CONST VOID *Buffer,
116 IN UINTN Length
117 )
118{
119 UINTN Index;
120 UINT8 *Walker;
121
122 Walker = (UINT8 *)Buffer;
123
124 for (Index = 0; Index < Length; ++Index) {
125 if (Walker[Index] != 0) {
126 return FALSE;
127 }
128 }
129
130 return TRUE;
131}
132
133BOOLEAN
134EFIAPI
136 IN CONST GUID *Guid
137 )
138{
139 UINT64 LowPartOfGuid;
140 UINT64 HighPartOfGuid;
141
142 LowPartOfGuid = ReadUnaligned64 ((CONST UINT64 *)Guid);
143 HighPartOfGuid = ReadUnaligned64 ((CONST UINT64 *)Guid + 1);
144
145 return (BOOLEAN)(LowPartOfGuid == 0 && HighPartOfGuid == 0);
146}
147
148INTN
149EFIAPI
151 IN CONST VOID *DestinationBuffer,
152 IN CONST VOID *SourceBuffer,
153 IN UINTN Length
154 )
155{
156 ASSERT (DestinationBuffer != NULL);
157 ASSERT (SourceBuffer != NULL);
158
159 return memcmp (DestinationBuffer, SourceBuffer, Length);
160}
161
162VOID *
163EFIAPI
165 IN CONST VOID *Buffer,
166 IN UINTN Length,
167 IN UINT16 Value
168 )
169{
170 UINT16 *Walker;
171 UINTN Index;
172
173 Walker = (UINT16 *)Buffer;
174
175 for (Index = 0; Index < Length; ++Index) {
176 if (Walker[Index] == Value) {
177 return Walker;
178 }
179 }
180
181 return NULL;
182}
183
184VOID *
185EFIAPI
187 IN EFI_MEMORY_TYPE MemoryType,
188 IN UINTN AllocationSize
189 )
190{
191 VOID *Buffer;
192 UINTN RequestedAllocationSize;
193
194 Buffer = NULL;
195 RequestedAllocationSize = 0;
196
197 if (((mPoolAllocationMask & (1ULL << mPoolAllocationIndex)) != 0) && (AllocationSize + 7ULL > AllocationSize)) {
198 //
199 // UEFI guarantees 8-byte alignment.
200 //
201 RequestedAllocationSize = (AllocationSize + 7ULL) & ~7ULL;
202 //
203 // Check that we have not gone beyond the single allocation size limit
204 //
205 if (RequestedAllocationSize <= mPoolAllocationSizeLimit) {
206 Buffer = malloc (RequestedAllocationSize);
207 } else {
208 DEBUG ((
209 DEBUG_POOL,
210 "UMEM: Requested allocation size %u exceeds the pool allocation limit %u \n",
211 (UINT32)RequestedAllocationSize,
213 ));
214 }
215 }
216
218 mPoolAllocationIndex &= 63ULL;
219
220 DEBUG ((
221 DEBUG_POOL,
222 "UMEM: Allocating pool %u at 0x%p\n",
223 (UINT32)AllocationSize,
224 Buffer
225 ));
226
227 ASSERT (((UINTN)Buffer & 7ULL) == 0);
228
229 if (Buffer != NULL) {
231 }
232
233 return Buffer;
234}
235
236STATIC
237EFI_STATUS
239 IN EFI_ALLOCATE_TYPE Type,
240 IN EFI_MEMORY_TYPE MemoryType,
241 IN UINTN Pages,
242 IN OUT EFI_PHYSICAL_ADDRESS *Memory,
243 IN UINT32 Alignment
244 )
245{
246 VOID *Buffer;
247 UINTN RequestedAllocationSize;
248
249 ASSERT (Type == AllocateAnyPages);
250
251 Buffer = NULL;
252 RequestedAllocationSize = Pages * EFI_PAGE_SIZE;
253
254 if (((mPageAllocationMask & (1ULL << mPageAllocationIndex)) != 0) &&
255 ((Pages != 0) && (RequestedAllocationSize / Pages == EFI_PAGE_SIZE)))
256 {
257 //
258 // Check that we have not gone beyond the single allocation size limit
259 //
260 if (RequestedAllocationSize <= mPoolAllocationSizeLimit) {
261 if (Alignment < EFI_PAGE_SIZE) {
262 Alignment = EFI_PAGE_SIZE;
263 }
264
265 #ifdef _WIN32
266 Buffer = _aligned_malloc (RequestedAllocationSize, Alignment);
267 #else // !_WIN32
268 Buffer = NULL;
269 INTN RetVal;
270
271 RetVal = posix_memalign (&Buffer, Alignment, RequestedAllocationSize);
272 if (RetVal != 0) {
273 DEBUG ((DEBUG_ERROR, "posix_memalign returns error %d\n", RetVal));
274 Buffer = NULL;
275 }
276
277 #endif // _WIN32
278 }
279 }
280
283
284 DEBUG ((
285 DEBUG_PAGE,
286 "UMEM: Allocating %u pages at 0x%p\n",
287 (UINT32)Pages,
288 Buffer
289 ));
290
291 if (Buffer == NULL) {
292 return EFI_NOT_FOUND;
293 }
294
295 mPageAllocations += Pages;
296
297 *Memory = (UINTN)Buffer;
298
299 return EFI_SUCCESS;
300}
301
302EFI_STATUS
303EFIAPI
305 IN EFI_ALLOCATE_TYPE Type,
306 IN EFI_MEMORY_TYPE MemoryType,
307 IN UINTN Pages,
308 IN OUT EFI_PHYSICAL_ADDRESS *Memory
309 )
310{
312 Type,
313 MemoryType,
314 Pages,
315 Memory,
316 EFI_PAGE_SIZE
317 );
318}
319
320VOID
321EFIAPI
323 IN VOID *Buffer
324 )
325{
326 ASSERT (Buffer != NULL);
327
328 DEBUG ((
329 DEBUG_POOL,
330 "UMEM: Deallocating pool 0x%p\n",
331 Buffer
332 ));
333
334 //
335 // Check that we are freeing buffer produced by our AllocatePool implementation
336 //
337 if (mPoolAllocations == 0) {
338 DEBUG ((
339 DEBUG_ERROR,
340 "UMEM: Requested buffer to free allocated not by AllocatePool implementations \n"
341 ));
342 abort ();
343 }
344
346
347 free (Buffer);
348}
349
350EFI_STATUS
351EFIAPI
353 IN EFI_PHYSICAL_ADDRESS Memory,
354 IN UINTN Pages
355 )
356{
357 VOID *Buffer;
358 UINTN BytesToFree;
359
360 Buffer = (VOID *)(UINTN)Memory;
361
362 ASSERT (Buffer != NULL);
363
364 DEBUG ((
365 DEBUG_PAGE,
366 "UMEM: Deallocating %u pages at 0x%p\n",
367 (UINT32)Pages,
368 Buffer
369 ));
370
371 //
372 // Check that requested pages count to free not exceeds total
373 // allocated pages count
374 //
375 if (Pages > mPageAllocations) {
376 DEBUG ((
377 DEBUG_ERROR,
378 "UMEM: Requested pages count %u to free exceeds total allocated pages %u\n",
379 (UINT32)Pages,
380 (UINT32)mPageAllocations
381 ));
382 abort ();
383 }
384
385 BytesToFree = Pages * EFI_PAGE_SIZE;
386 if ((Pages != 0) && (BytesToFree / Pages == EFI_PAGE_SIZE)) {
387 mPageAllocations -= Pages;
388 } else {
389 DEBUG ((
390 DEBUG_ERROR,
391 "UMEM: Passed pages count %u proceeds unsigned integer overflow during BytesToFree multiplication\n",
392 (UINT32)Pages
393 ));
394 abort ();
395 }
396
397 #ifdef _WIN32
398 _aligned_free (Buffer);
399 #else
400 free (Buffer);
401 #endif
402
403 return EFI_SUCCESS;
404}
405
406VOID *
408 IN EFI_MEMORY_TYPE MemoryType,
409 IN UINTN Pages,
410 IN UINTN Alignment
411 )
412{
413 EFI_STATUS Status;
414 EFI_PHYSICAL_ADDRESS Memory;
415
417 AllocateAnyPages,
418 MemoryType,
419 Pages,
420 &Memory,
421 (UINT32)Alignment
422 );
423 if (EFI_ERROR (Status)) {
424 return NULL;
425 }
426
427 return (VOID *)(UINTN)Memory;
428}
429
430VOID
432 IN VOID *Buffer,
433 IN UINTN Pages
434 )
435{
436 PhaseFreePages ((UINTN)Buffer, Pages);
437}
438
439GUID *
440EFIAPI
442 OUT GUID *DestinationGuid,
443 IN CONST GUID *SourceGuid
444 )
445{
446 ASSERT (DestinationGuid != NULL);
447 ASSERT (SourceGuid != NULL);
448
449 CopyMem (DestinationGuid, SourceGuid, sizeof (GUID));
450
451 return DestinationGuid;
452}
453
454BOOLEAN
455EFIAPI
457 IN CONST GUID *Guid1,
458 IN CONST GUID *Guid2
459 )
460{
461 ASSERT (Guid1 != NULL);
462 ASSERT (Guid2 != NULL);
463
464 return CompareMem (Guid1, Guid2, sizeof (GUID)) == 0;
465}
466
467UINT16
468EFIAPI
470 IN CONST UINT16 *Buffer
471 )
472{
473 UINT16 Value;
474
475 CopyMem (&Value, Buffer, sizeof (UINT16));
476
477 return Value;
478}
479
480UINT16
481EFIAPI
483 OUT UINT16 *Buffer,
484 IN UINT16 Value
485 )
486{
487 ASSERT (Buffer != NULL);
488
489 CopyMem (Buffer, &Value, sizeof (UINT16));
490
491 return Value;
492}
493
494UINT32
495EFIAPI
497 IN CONST UINT32 *Buffer
498 )
499{
500 UINT32 Value;
501
502 Value = ReadUnaligned32 (Buffer) & 0xFFFFFFU;
503
504 return Value;
505}
506
507UINT32
508EFIAPI
510 IN CONST UINT32 *Buffer
511 )
512{
513 UINT32 Value;
514
515 ASSERT (Buffer != NULL);
516
517 CopyMem (&Value, Buffer, sizeof (UINT32));
518
519 return Value;
520}
521
522UINT64
523EFIAPI
525 IN CONST UINT64 *Buffer
526 )
527{
528 UINT64 Value;
529
530 ASSERT (Buffer != NULL);
531
532 CopyMem (&Value, Buffer, sizeof (UINT64));
533
534 return Value;
535}
536
537UINT32
538EFIAPI
540 OUT UINT32 *Buffer,
541 IN UINT32 Value
542 )
543{
544 ASSERT (Buffer != NULL);
545
546 CopyMem (Buffer, &Value, sizeof (UINT32));
547
548 return Value;
549}
550
551UINT64
552EFIAPI
554 OUT UINT64 *Buffer,
555 IN UINT64 Value
556 )
557{
558 ASSERT (Buffer != NULL);
559
560 CopyMem (Buffer, &Value, sizeof (UINT64));
561
562 return Value;
563}
UINT64 Length
DMG_SIZE_DEVICE_PATH Size
OC_TYPING_BUFFER_ENTRY Buffer[OC_TYPING_BUFFER_SIZE]
Definition OcTypingLib.h:42
STATIC UINT64 mPageAllocationMask
VOID *EFIAPI ScanMem16(IN CONST VOID *Buffer, IN UINTN Length, IN UINT16 Value)
GLOBAL_REMOVE_IF_UNREFERENCED CONST EFI_MEMORY_TYPE gPhaseDefaultCodeType
INTN EFIAPI CompareMem(IN CONST VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
EFI_STATUS EFIAPI PhaseAllocatePages(IN EFI_ALLOCATE_TYPE Type, IN EFI_MEMORY_TYPE MemoryType, IN UINTN Pages, IN OUT EFI_PHYSICAL_ADDRESS *Memory)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
UINT64 EFIAPI ReadUnaligned64(IN CONST UINT64 *Buffer)
STATIC UINTN mPoolAllocationSizeLimit
VOID *EFIAPI SetMem(OUT VOID *Buffer, IN UINTN Length, IN UINT8 Value)
VOID SetPoolAllocationSizeLimit(UINTN AllocationSize)
VOID EFIAPI PhaseFreePool(IN VOID *Buffer)
UINT16 EFIAPI ReadUnaligned16(IN CONST UINT16 *Buffer)
BOOLEAN EFIAPI CompareGuid(IN CONST GUID *Guid1, IN CONST GUID *Guid2)
STATIC UINTN mPageAllocationIndex
GUID *EFIAPI CopyGuid(OUT GUID *DestinationGuid, IN CONST GUID *SourceGuid)
EFI_STATUS EFIAPI PhaseFreePages(IN EFI_PHYSICAL_ADDRESS Memory, IN UINTN Pages)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
UINT32 EFIAPI WriteUnaligned32(OUT UINT32 *Buffer, IN UINT32 Value)
STATIC UINT64 mPoolAllocationMask
BOOLEAN EFIAPI IsZeroGuid(IN CONST GUID *Guid)
UINT16 EFIAPI WriteUnaligned16(OUT UINT16 *Buffer, IN UINT16 Value)
STATIC EFI_STATUS InternalAllocatePagesAlign(IN EFI_ALLOCATE_TYPE Type, IN EFI_MEMORY_TYPE MemoryType, IN UINTN Pages, IN OUT EFI_PHYSICAL_ADDRESS *Memory, IN UINT32 Alignment)
UINT32 EFIAPI ReadUnaligned24(IN CONST UINT32 *Buffer)
VOID *EFIAPI PhaseAllocatePool(IN EFI_MEMORY_TYPE MemoryType, IN UINTN AllocationSize)
VOID ConfigureMemoryAllocations(IN CONST UINT8 *Data, IN UINTN Size, IN OUT UINT32 *ConfigSize)
BOOLEAN EFIAPI IsZeroBuffer(IN CONST VOID *Buffer, IN UINTN Length)
GLOBAL_REMOVE_IF_UNREFERENCED CONST EFI_MEMORY_TYPE gPhaseDefaultDataType
VOID * InternalAllocateAlignedPages(IN EFI_MEMORY_TYPE MemoryType, IN UINTN Pages, IN UINTN Alignment)
VOID InternalFreeAlignedPages(IN VOID *Buffer, IN UINTN Pages)
GLOBAL_REMOVE_IF_UNREFERENCED UINTN mPageAllocations
UINT64 EFIAPI WriteUnaligned64(OUT UINT64 *Buffer, IN UINT64 Value)
STATIC UINTN mPoolAllocationIndex
UINT32 EFIAPI ReadUnaligned32(IN CONST UINT32 *Buffer)
GLOBAL_REMOVE_IF_UNREFERENCED UINTN mPoolAllocations
#define ASSERT(x)
Definition coder.h:55
#define memset(ptr, c, len)
#define memcmp(b1, b2, len)
#define memmove(dst, src, len)
#define malloc(Size)
Definition lzss.h:49
#define free(Ptr)
Definition lzss.h:50