]> git.proxmox.com Git - mirror_edk2.git/blame - EmulatorPkg/Library/GuardUefiMemoryAllocationLib/MemoryAllocationLib.c
EmulatorPkg: Remove all trailing whitespace
[mirror_edk2.git] / EmulatorPkg / Library / GuardUefiMemoryAllocationLib / MemoryAllocationLib.c
CommitLineData
1d7ac5a6 1/** @file\r
d18d8a1d 2 Support routines for memory allocation routines based\r
1d7ac5a6 3 on boot services for Dxe phase drivers using OS malloc.\r
d18d8a1d 4\r
5 OS malloc is used so OS based malloc debugging tools can be used.\r
6 If a single driver links against this lib protocols from other\r
7 drivers, or EFI boot services can return a buffer that needs to\r
8 freed using the EFI scheme. This is why the gEmuThunk->Free ()\r
1d7ac5a6 9 can detect if the memory rang is for EFI so the right free can be\r
10 called.\r
11\r
12 Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>\r
d18d8a1d 13 Portions copyright (c) 2011, Apple Inc. All rights reserved.\r
14 This program and the accompanying materials\r
15 are licensed and made available under the terms and conditions of the BSD License\r
16 which accompanies this distribution. The full text of the license may be found at\r
17 http://opensource.org/licenses/bsd-license.php.\r
1d7ac5a6 18\r
d18d8a1d 19 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
20 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
1d7ac5a6 21\r
22**/\r
23\r
24\r
25#include <Uefi.h>\r
26\r
27\r
28#include <Library/MemoryAllocationLib.h>\r
29#include <Library/UefiBootServicesTableLib.h>\r
30#include <Library/BaseMemoryLib.h>\r
31#include <Library/DebugLib.h>\r
32#include <Library/EmuThunkLib.h>\r
33\r
34/**\r
35 Allocates one or more 4KB pages of a certain memory type.\r
36\r
37 Allocates the number of 4KB pages of a certain memory type and returns a pointer to the allocated\r
38 buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL is returned.\r
39 If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
40\r
41 @param MemoryType The type of memory to allocate.\r
42 @param Pages The number of 4 KB pages to allocate.\r
43\r
44 @return A pointer to the allocated buffer or NULL if allocation fails.\r
45\r
46**/\r
47VOID *\r
48InternalAllocatePages (\r
d18d8a1d 49 IN EFI_MEMORY_TYPE MemoryType,\r
1d7ac5a6 50 IN UINTN Pages\r
51 )\r
52{\r
53 EFI_STATUS Status;\r
d18d8a1d 54 EFI_PHYSICAL_ADDRESS Memory;\r
1d7ac5a6 55\r
56 if (Pages == 0) {\r
57 return NULL;\r
58 }\r
59\r
60 return gEmuThunk->Valloc (Pages * EFI_PAGE_SIZE);\r
61}\r
62\r
63/**\r
64 Allocates one or more 4KB pages of type EfiBootServicesData.\r
65\r
66 Allocates the number of 4KB pages of type EfiBootServicesData and returns a pointer to the\r
67 allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL\r
68 is returned. If there is not enough memory remaining to satisfy the request, then NULL is\r
69 returned.\r
70\r
71 @param Pages The number of 4 KB pages to allocate.\r
72\r
73 @return A pointer to the allocated buffer or NULL if allocation fails.\r
74\r
75**/\r
76VOID *\r
77EFIAPI\r
78AllocatePages (\r
79 IN UINTN Pages\r
80 )\r
81{\r
82 return InternalAllocatePages (EfiBootServicesData, Pages);\r
83}\r
84\r
85/**\r
86 Allocates one or more 4KB pages of type EfiRuntimeServicesData.\r
87\r
88 Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer to the\r
89 allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL\r
90 is returned. If there is not enough memory remaining to satisfy the request, then NULL is\r
91 returned.\r
92\r
93 @param Pages The number of 4 KB pages to allocate.\r
94\r
95 @return A pointer to the allocated buffer or NULL if allocation fails.\r
96\r
97**/\r
98VOID *\r
99EFIAPI\r
100AllocateRuntimePages (\r
101 IN UINTN Pages\r
102 )\r
103{\r
104 return InternalAllocatePages (EfiRuntimeServicesData, Pages);\r
105}\r
106\r
107/**\r
108 Allocates one or more 4KB pages of type EfiReservedMemoryType.\r
109\r
110 Allocates the number of 4KB pages of type EfiReservedMemoryType and returns a pointer to the\r
111 allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL\r
112 is returned. If there is not enough memory remaining to satisfy the request, then NULL is\r
113 returned.\r
114\r
115 @param Pages The number of 4 KB pages to allocate.\r
116\r
117 @return A pointer to the allocated buffer or NULL if allocation fails.\r
118\r
119**/\r
120VOID *\r
121EFIAPI\r
122AllocateReservedPages (\r
123 IN UINTN Pages\r
124 )\r
125{\r
126 return InternalAllocatePages (EfiReservedMemoryType, Pages);\r
127}\r
128\r
129/**\r
130 Frees one or more 4KB pages that were previously allocated with one of the page allocation\r
131 functions in the Memory Allocation Library.\r
132\r
133 Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer\r
134 must have been allocated on a previous call to the page allocation services of the Memory\r
135 Allocation Library. If it is not possible to free allocated pages, then this function will\r
136 perform no actions.\r
d18d8a1d 137\r
1d7ac5a6 138 If Buffer was not allocated with a page allocation function in the Memory Allocation Library,\r
139 then ASSERT().\r
140 If Pages is zero, then ASSERT().\r
d18d8a1d 141\r
1d7ac5a6 142 @param Buffer The pointer to the buffer of pages to free.\r
143 @param Pages The number of 4 KB pages to free.\r
144\r
145**/\r
146VOID\r
147EFIAPI\r
148FreePages (\r
149 IN VOID *Buffer,\r
150 IN UINTN Pages\r
151 )\r
152{\r
8e4b3d32 153 EFI_STATUS Status;\r
154\r
1d7ac5a6 155 ASSERT (Pages != 0);\r
8e4b3d32 156 if (!gEmuThunk->Free (Buffer)) {\r
157 // The Free thunk will not free memory allocated in emulated EFI memory.\r
d18d8a1d 158 // The assmuption is this was allocated directly by EFI. We need this as some\r
8e4b3d32 159 // times protocols or EFI BootServices can return dynamically allocated buffers.\r
160 Status = gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) Buffer, Pages);\r
161 ASSERT_EFI_ERROR (Status);\r
162 }\r
1d7ac5a6 163}\r
164\r
165/**\r
166 Allocates one or more 4KB pages of a certain memory type at a specified alignment.\r
167\r
168 Allocates the number of 4KB pages specified by Pages of a certain memory type with an alignment\r
169 specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is returned.\r
170 If there is not enough memory at the specified alignment remaining to satisfy the request, then\r
171 NULL is returned.\r
172 If Alignment is not a power of two and Alignment is not zero, then ASSERT().\r
173\r
174 @param MemoryType The type of memory to allocate.\r
175 @param Pages The number of 4 KB pages to allocate.\r
176 @param Alignment The requested alignment of the allocation. Must be a power of two.\r
177 If Alignment is zero, then byte alignment is used.\r
178\r
179 @return A pointer to the allocated buffer or NULL if allocation fails.\r
180\r
181**/\r
182VOID *\r
183InternalAllocateAlignedPages (\r
d18d8a1d 184 IN EFI_MEMORY_TYPE MemoryType,\r
1d7ac5a6 185 IN UINTN Pages,\r
186 IN UINTN Alignment\r
187 )\r
188{\r
8e4b3d32 189 EFI_STATUS Status;\r
1d7ac5a6 190 VOID *Memory;\r
191 UINTN AlignedMemory;\r
192 UINTN AlignmentMask;\r
193 UINTN UnalignedPages;\r
194 UINTN RealPages;\r
195\r
196 //\r
197 // Alignment must be a power of two or zero.\r
198 //\r
199 ASSERT ((Alignment & (Alignment - 1)) == 0);\r
d18d8a1d 200\r
1d7ac5a6 201 if (Pages == 0) {\r
202 return NULL;\r
203 }\r
204 if (Alignment > EFI_PAGE_SIZE) {\r
205 //\r
206 // Caculate the total number of pages since alignment is larger than page size.\r
207 //\r
208 AlignmentMask = Alignment - 1;\r
209 RealPages = Pages + EFI_SIZE_TO_PAGES (Alignment);\r
210 //\r
211 // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow.\r
212 //\r
213 ASSERT (RealPages > Pages);\r
d18d8a1d 214\r
1d7ac5a6 215 Memory = gEmuThunk->Valloc (Pages * EFI_PAGE_SIZE);\r
216 if (Memory != NULL) {\r
217 return NULL;\r
218 }\r
219 AlignedMemory = ((UINTN) Memory + AlignmentMask) & ~AlignmentMask;\r
220 UnalignedPages = EFI_SIZE_TO_PAGES (AlignedMemory - (UINTN) Memory);\r
221 if (UnalignedPages > 0) {\r
222 //\r
223 // Free first unaligned page(s).\r
224 //\r
8e4b3d32 225 FreePages (Memory, UnalignedPages);\r
1d7ac5a6 226 }\r
227 Memory = (VOID *) (AlignedMemory + EFI_PAGES_TO_SIZE (Pages));\r
228 UnalignedPages = RealPages - Pages - UnalignedPages;\r
229 if (UnalignedPages > 0) {\r
230 //\r
231 // Free last unaligned page(s).\r
232 //\r
8e4b3d32 233 FreePages (Memory, UnalignedPages);\r
1d7ac5a6 234 }\r
235 } else {\r
236 //\r
237 // Do not over-allocate pages in this case.\r
238 //\r
239 Memory = gEmuThunk->Valloc (Pages * EFI_PAGE_SIZE);\r
240 if (Memory != NULL) {\r
241 return NULL;\r
242 }\r
243 AlignedMemory = (UINTN) Memory;\r
244 }\r
245 return (VOID *) AlignedMemory;\r
246}\r
247\r
248/**\r
249 Allocates one or more 4KB pages of type EfiBootServicesData at a specified alignment.\r
250\r
251 Allocates the number of 4KB pages specified by Pages of type EfiBootServicesData with an\r
252 alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is\r
253 returned. If there is not enough memory at the specified alignment remaining to satisfy the\r
254 request, then NULL is returned.\r
d18d8a1d 255\r
1d7ac5a6 256 If Alignment is not a power of two and Alignment is not zero, then ASSERT().\r
257\r
258 @param Pages The number of 4 KB pages to allocate.\r
259 @param Alignment The requested alignment of the allocation. Must be a power of two.\r
260 If Alignment is zero, then byte alignment is used.\r
261\r
262 @return A pointer to the allocated buffer or NULL if allocation fails.\r
263\r
264**/\r
265VOID *\r
266EFIAPI\r
267AllocateAlignedPages (\r
268 IN UINTN Pages,\r
269 IN UINTN Alignment\r
270 )\r
271{\r
272 return InternalAllocateAlignedPages (EfiBootServicesData, Pages, Alignment);\r
273}\r
274\r
275/**\r
276 Allocates one or more 4KB pages of type EfiRuntimeServicesData at a specified alignment.\r
277\r
278 Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData with an\r
279 alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is\r
280 returned. If there is not enough memory at the specified alignment remaining to satisfy the\r
281 request, then NULL is returned.\r
d18d8a1d 282\r
1d7ac5a6 283 If Alignment is not a power of two and Alignment is not zero, then ASSERT().\r
284\r
285 @param Pages The number of 4 KB pages to allocate.\r
286 @param Alignment The requested alignment of the allocation. Must be a power of two.\r
287 If Alignment is zero, then byte alignment is used.\r
288\r
289 @return A pointer to the allocated buffer or NULL if allocation fails.\r
290\r
291**/\r
292VOID *\r
293EFIAPI\r
294AllocateAlignedRuntimePages (\r
295 IN UINTN Pages,\r
296 IN UINTN Alignment\r
297 )\r
298{\r
299 return InternalAllocateAlignedPages (EfiRuntimeServicesData, Pages, Alignment);\r
300}\r
301\r
302/**\r
303 Allocates one or more 4KB pages of type EfiReservedMemoryType at a specified alignment.\r
304\r
305 Allocates the number of 4KB pages specified by Pages of type EfiReservedMemoryType with an\r
306 alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is\r
307 returned. If there is not enough memory at the specified alignment remaining to satisfy the\r
308 request, then NULL is returned.\r
d18d8a1d 309\r
1d7ac5a6 310 If Alignment is not a power of two and Alignment is not zero, then ASSERT().\r
311\r
312 @param Pages The number of 4 KB pages to allocate.\r
313 @param Alignment The requested alignment of the allocation. Must be a power of two.\r
314 If Alignment is zero, then byte alignment is used.\r
315\r
316 @return A pointer to the allocated buffer or NULL if allocation fails.\r
317\r
318**/\r
319VOID *\r
320EFIAPI\r
321AllocateAlignedReservedPages (\r
322 IN UINTN Pages,\r
323 IN UINTN Alignment\r
324 )\r
325{\r
326 return InternalAllocateAlignedPages (EfiReservedMemoryType, Pages, Alignment);\r
327}\r
328\r
329/**\r
330 Frees one or more 4KB pages that were previously allocated with one of the aligned page\r
331 allocation functions in the Memory Allocation Library.\r
332\r
333 Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer\r
334 must have been allocated on a previous call to the aligned page allocation services of the Memory\r
d18d8a1d 335 Allocation Library. If it is not possible to free allocated pages, then this function will\r
1d7ac5a6 336 perform no actions.\r
d18d8a1d 337\r
1d7ac5a6 338 If Buffer was not allocated with an aligned page allocation function in the Memory Allocation\r
339 Library, then ASSERT().\r
340 If Pages is zero, then ASSERT().\r
d18d8a1d 341\r
1d7ac5a6 342 @param Buffer The pointer to the buffer of pages to free.\r
343 @param Pages The number of 4 KB pages to free.\r
344\r
345**/\r
346VOID\r
347EFIAPI\r
348FreeAlignedPages (\r
349 IN VOID *Buffer,\r
350 IN UINTN Pages\r
351 )\r
352{\r
8e4b3d32 353 FreePages (Buffer, Pages);\r
1d7ac5a6 354}\r
355\r
356/**\r
357 Allocates a buffer of a certain pool type.\r
358\r
359 Allocates the number bytes specified by AllocationSize of a certain pool type and returns a\r
360 pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is\r
361 returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
362\r
363 @param MemoryType The type of memory to allocate.\r
364 @param AllocationSize The number of bytes to allocate.\r
365\r
366 @return A pointer to the allocated buffer or NULL if allocation fails.\r
367\r
368**/\r
369VOID *\r
370InternalAllocatePool (\r
d18d8a1d 371 IN EFI_MEMORY_TYPE MemoryType,\r
1d7ac5a6 372 IN UINTN AllocationSize\r
373 )\r
374{\r
375 return gEmuThunk->Malloc (AllocationSize);\r
376}\r
377\r
378/**\r
379 Allocates a buffer of type EfiBootServicesData.\r
380\r
381 Allocates the number bytes specified by AllocationSize of type EfiBootServicesData and returns a\r
382 pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is\r
383 returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
384\r
385 @param AllocationSize The number of bytes to allocate.\r
386\r
387 @return A pointer to the allocated buffer or NULL if allocation fails.\r
388\r
389**/\r
390VOID *\r
391EFIAPI\r
392AllocatePool (\r
393 IN UINTN AllocationSize\r
394 )\r
395{\r
396 return InternalAllocatePool (EfiBootServicesData, AllocationSize);\r
397}\r
398\r
399/**\r
400 Allocates a buffer of type EfiRuntimeServicesData.\r
401\r
402 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData and returns\r
403 a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is\r
404 returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
405\r
406 @param AllocationSize The number of bytes to allocate.\r
407\r
408 @return A pointer to the allocated buffer or NULL if allocation fails.\r
409\r
410**/\r
411VOID *\r
412EFIAPI\r
413AllocateRuntimePool (\r
414 IN UINTN AllocationSize\r
415 )\r
416{\r
417 return InternalAllocatePool (EfiRuntimeServicesData, AllocationSize);\r
418}\r
419\r
420/**\r
421 Allocates a buffer of type EfiReservedMemoryType.\r
422\r
423 Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType and returns\r
424 a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is\r
425 returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
426\r
427 @param AllocationSize The number of bytes to allocate.\r
428\r
429 @return A pointer to the allocated buffer or NULL if allocation fails.\r
430\r
431**/\r
432VOID *\r
433EFIAPI\r
434AllocateReservedPool (\r
435 IN UINTN AllocationSize\r
436 )\r
437{\r
438 return InternalAllocatePool (EfiReservedMemoryType, AllocationSize);\r
439}\r
440\r
441/**\r
442 Allocates and zeros a buffer of a certain pool type.\r
443\r
444 Allocates the number bytes specified by AllocationSize of a certain pool type, clears the buffer\r
445 with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a valid\r
446 buffer of 0 size is returned. If there is not enough memory remaining to satisfy the request,\r
447 then NULL is returned.\r
448\r
449 @param PoolType The type of memory to allocate.\r
450 @param AllocationSize The number of bytes to allocate and zero.\r
451\r
452 @return A pointer to the allocated buffer or NULL if allocation fails.\r
453\r
454**/\r
455VOID *\r
456InternalAllocateZeroPool (\r
d18d8a1d 457 IN EFI_MEMORY_TYPE PoolType,\r
1d7ac5a6 458 IN UINTN AllocationSize\r
d18d8a1d 459 )\r
1d7ac5a6 460{\r
461 VOID *Memory;\r
462\r
463 Memory = InternalAllocatePool (PoolType, AllocationSize);\r
464 if (Memory != NULL) {\r
465 Memory = ZeroMem (Memory, AllocationSize);\r
466 }\r
467 return Memory;\r
468}\r
469\r
470/**\r
471 Allocates and zeros a buffer of type EfiBootServicesData.\r
472\r
473 Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, clears the\r
474 buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a\r
475 valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the\r
476 request, then NULL is returned.\r
477\r
478 @param AllocationSize The number of bytes to allocate and zero.\r
479\r
480 @return A pointer to the allocated buffer or NULL if allocation fails.\r
481\r
482**/\r
483VOID *\r
484EFIAPI\r
485AllocateZeroPool (\r
486 IN UINTN AllocationSize\r
487 )\r
488{\r
489 return InternalAllocateZeroPool (EfiBootServicesData, AllocationSize);\r
490}\r
491\r
492/**\r
493 Allocates and zeros a buffer of type EfiRuntimeServicesData.\r
494\r
495 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, clears the\r
496 buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a\r
497 valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the\r
498 request, then NULL is returned.\r
499\r
500 @param AllocationSize The number of bytes to allocate and zero.\r
501\r
502 @return A pointer to the allocated buffer or NULL if allocation fails.\r
503\r
504**/\r
505VOID *\r
506EFIAPI\r
507AllocateRuntimeZeroPool (\r
508 IN UINTN AllocationSize\r
509 )\r
510{\r
511 return InternalAllocateZeroPool (EfiRuntimeServicesData, AllocationSize);\r
512}\r
513\r
514/**\r
515 Allocates and zeros a buffer of type EfiReservedMemoryType.\r
516\r
517 Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, clears the\r
518 buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a\r
519 valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the\r
520 request, then NULL is returned.\r
521\r
522 @param AllocationSize The number of bytes to allocate and zero.\r
523\r
524 @return A pointer to the allocated buffer or NULL if allocation fails.\r
525\r
526**/\r
527VOID *\r
528EFIAPI\r
529AllocateReservedZeroPool (\r
530 IN UINTN AllocationSize\r
531 )\r
532{\r
533 return InternalAllocateZeroPool (EfiReservedMemoryType, AllocationSize);\r
534}\r
535\r
536/**\r
537 Copies a buffer to an allocated buffer of a certain pool type.\r
538\r
539 Allocates the number bytes specified by AllocationSize of a certain pool type, copies\r
540 AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the\r
541 allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there\r
542 is not enough memory remaining to satisfy the request, then NULL is returned.\r
543 If Buffer is NULL, then ASSERT().\r
d18d8a1d 544 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().\r
1d7ac5a6 545\r
546 @param PoolType The type of pool to allocate.\r
547 @param AllocationSize The number of bytes to allocate and zero.\r
548 @param Buffer The buffer to copy to the allocated buffer.\r
549\r
550 @return A pointer to the allocated buffer or NULL if allocation fails.\r
551\r
552**/\r
553VOID *\r
554InternalAllocateCopyPool (\r
d18d8a1d 555 IN EFI_MEMORY_TYPE PoolType,\r
1d7ac5a6 556 IN UINTN AllocationSize,\r
557 IN CONST VOID *Buffer\r
d18d8a1d 558 )\r
1d7ac5a6 559{\r
560 VOID *Memory;\r
561\r
562 ASSERT (Buffer != NULL);\r
563 ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN) Buffer + 1));\r
564\r
565 Memory = InternalAllocatePool (PoolType, AllocationSize);\r
566 if (Memory != NULL) {\r
567 Memory = CopyMem (Memory, Buffer, AllocationSize);\r
568 }\r
569 return Memory;\r
d18d8a1d 570}\r
1d7ac5a6 571\r
572/**\r
573 Copies a buffer to an allocated buffer of type EfiBootServicesData.\r
574\r
575 Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, copies\r
576 AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the\r
577 allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there\r
578 is not enough memory remaining to satisfy the request, then NULL is returned.\r
d18d8a1d 579\r
1d7ac5a6 580 If Buffer is NULL, then ASSERT().\r
d18d8a1d 581 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().\r
1d7ac5a6 582\r
583 @param AllocationSize The number of bytes to allocate and zero.\r
584 @param Buffer The buffer to copy to the allocated buffer.\r
585\r
586 @return A pointer to the allocated buffer or NULL if allocation fails.\r
587\r
588**/\r
589VOID *\r
590EFIAPI\r
591AllocateCopyPool (\r
592 IN UINTN AllocationSize,\r
593 IN CONST VOID *Buffer\r
594 )\r
595{\r
596 return InternalAllocateCopyPool (EfiBootServicesData, AllocationSize, Buffer);\r
597}\r
598\r
599/**\r
600 Copies a buffer to an allocated buffer of type EfiRuntimeServicesData.\r
601\r
602 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, copies\r
603 AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the\r
604 allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there\r
605 is not enough memory remaining to satisfy the request, then NULL is returned.\r
d18d8a1d 606\r
1d7ac5a6 607 If Buffer is NULL, then ASSERT().\r
d18d8a1d 608 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().\r
1d7ac5a6 609\r
610 @param AllocationSize The number of bytes to allocate and zero.\r
611 @param Buffer The buffer to copy to the allocated buffer.\r
612\r
613 @return A pointer to the allocated buffer or NULL if allocation fails.\r
614\r
615**/\r
616VOID *\r
617EFIAPI\r
618AllocateRuntimeCopyPool (\r
619 IN UINTN AllocationSize,\r
620 IN CONST VOID *Buffer\r
621 )\r
622{\r
623 return InternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer);\r
624}\r
625\r
626/**\r
627 Copies a buffer to an allocated buffer of type EfiReservedMemoryType.\r
628\r
629 Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, copies\r
630 AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the\r
631 allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there\r
632 is not enough memory remaining to satisfy the request, then NULL is returned.\r
d18d8a1d 633\r
1d7ac5a6 634 If Buffer is NULL, then ASSERT().\r
d18d8a1d 635 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().\r
1d7ac5a6 636\r
637 @param AllocationSize The number of bytes to allocate and zero.\r
638 @param Buffer The buffer to copy to the allocated buffer.\r
639\r
640 @return A pointer to the allocated buffer or NULL if allocation fails.\r
641\r
642**/\r
643VOID *\r
644EFIAPI\r
645AllocateReservedCopyPool (\r
646 IN UINTN AllocationSize,\r
647 IN CONST VOID *Buffer\r
648 )\r
649{\r
650 return InternalAllocateCopyPool (EfiReservedMemoryType, AllocationSize, Buffer);\r
651}\r
652\r
653/**\r
654 Reallocates a buffer of a specified memory type.\r
655\r
656 Allocates and zeros the number bytes specified by NewSize from memory of the type\r
d18d8a1d 657 specified by PoolType. If OldBuffer is not NULL, then the smaller of OldSize and\r
658 NewSize bytes are copied from OldBuffer to the newly allocated buffer, and\r
659 OldBuffer is freed. A pointer to the newly allocated buffer is returned.\r
660 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not\r
1d7ac5a6 661 enough memory remaining to satisfy the request, then NULL is returned.\r
d18d8a1d 662\r
1d7ac5a6 663 If the allocation of the new buffer is successful and the smaller of NewSize and OldSize\r
664 is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().\r
665\r
666 @param PoolType The type of pool to allocate.\r
667 @param OldSize The size, in bytes, of OldBuffer.\r
668 @param NewSize The size, in bytes, of the buffer to reallocate.\r
d18d8a1d 669 @param OldBuffer The buffer to copy to the allocated buffer. This is an optional\r
1d7ac5a6 670 parameter that may be NULL.\r
671\r
672 @return A pointer to the allocated buffer or NULL if allocation fails.\r
673\r
674**/\r
675VOID *\r
676InternalReallocatePool (\r
d18d8a1d 677 IN EFI_MEMORY_TYPE PoolType,\r
1d7ac5a6 678 IN UINTN OldSize,\r
679 IN UINTN NewSize,\r
680 IN VOID *OldBuffer OPTIONAL\r
681 )\r
682{\r
683 VOID *NewBuffer;\r
684\r
685 NewBuffer = InternalAllocateZeroPool (PoolType, NewSize);\r
686 if (NewBuffer != NULL && OldBuffer != NULL) {\r
687 CopyMem (NewBuffer, OldBuffer, MIN (OldSize, NewSize));\r
688 FreePool (OldBuffer);\r
689 }\r
690 return NewBuffer;\r
691}\r
692\r
693/**\r
694 Reallocates a buffer of type EfiBootServicesData.\r
695\r
696 Allocates and zeros the number bytes specified by NewSize from memory of type\r
d18d8a1d 697 EfiBootServicesData. If OldBuffer is not NULL, then the smaller of OldSize and\r
698 NewSize bytes are copied from OldBuffer to the newly allocated buffer, and\r
699 OldBuffer is freed. A pointer to the newly allocated buffer is returned.\r
700 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not\r
1d7ac5a6 701 enough memory remaining to satisfy the request, then NULL is returned.\r
d18d8a1d 702\r
1d7ac5a6 703 If the allocation of the new buffer is successful and the smaller of NewSize and OldSize\r
704 is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().\r
705\r
706 @param OldSize The size, in bytes, of OldBuffer.\r
707 @param NewSize The size, in bytes, of the buffer to reallocate.\r
d18d8a1d 708 @param OldBuffer The buffer to copy to the allocated buffer. This is an optional\r
1d7ac5a6 709 parameter that may be NULL.\r
710\r
711 @return A pointer to the allocated buffer or NULL if allocation fails.\r
712\r
713**/\r
714VOID *\r
715EFIAPI\r
716ReallocatePool (\r
717 IN UINTN OldSize,\r
718 IN UINTN NewSize,\r
719 IN VOID *OldBuffer OPTIONAL\r
720 )\r
721{\r
722 return InternalReallocatePool (EfiBootServicesData, OldSize, NewSize, OldBuffer);\r
723}\r
724\r
725/**\r
726 Reallocates a buffer of type EfiRuntimeServicesData.\r
727\r
728 Allocates and zeros the number bytes specified by NewSize from memory of type\r
d18d8a1d 729 EfiRuntimeServicesData. If OldBuffer is not NULL, then the smaller of OldSize and\r
730 NewSize bytes are copied from OldBuffer to the newly allocated buffer, and\r
731 OldBuffer is freed. A pointer to the newly allocated buffer is returned.\r
732 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not\r
1d7ac5a6 733 enough memory remaining to satisfy the request, then NULL is returned.\r
734\r
735 If the allocation of the new buffer is successful and the smaller of NewSize and OldSize\r
736 is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().\r
737\r
738 @param OldSize The size, in bytes, of OldBuffer.\r
739 @param NewSize The size, in bytes, of the buffer to reallocate.\r
d18d8a1d 740 @param OldBuffer The buffer to copy to the allocated buffer. This is an optional\r
1d7ac5a6 741 parameter that may be NULL.\r
742\r
743 @return A pointer to the allocated buffer or NULL if allocation fails.\r
744\r
745**/\r
746VOID *\r
747EFIAPI\r
748ReallocateRuntimePool (\r
749 IN UINTN OldSize,\r
750 IN UINTN NewSize,\r
751 IN VOID *OldBuffer OPTIONAL\r
752 )\r
753{\r
754 return InternalReallocatePool (EfiRuntimeServicesData, OldSize, NewSize, OldBuffer);\r
755}\r
756\r
757/**\r
758 Reallocates a buffer of type EfiReservedMemoryType.\r
759\r
760 Allocates and zeros the number bytes specified by NewSize from memory of type\r
d18d8a1d 761 EfiReservedMemoryType. If OldBuffer is not NULL, then the smaller of OldSize and\r
762 NewSize bytes are copied from OldBuffer to the newly allocated buffer, and\r
763 OldBuffer is freed. A pointer to the newly allocated buffer is returned.\r
764 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not\r
1d7ac5a6 765 enough memory remaining to satisfy the request, then NULL is returned.\r
766\r
767 If the allocation of the new buffer is successful and the smaller of NewSize and OldSize\r
768 is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().\r
769\r
770 @param OldSize The size, in bytes, of OldBuffer.\r
771 @param NewSize The size, in bytes, of the buffer to reallocate.\r
d18d8a1d 772 @param OldBuffer The buffer to copy to the allocated buffer. This is an optional\r
1d7ac5a6 773 parameter that may be NULL.\r
774\r
775 @return A pointer to the allocated buffer or NULL if allocation fails.\r
776\r
777**/\r
778VOID *\r
779EFIAPI\r
780ReallocateReservedPool (\r
781 IN UINTN OldSize,\r
782 IN UINTN NewSize,\r
783 IN VOID *OldBuffer OPTIONAL\r
784 )\r
785{\r
786 return InternalReallocatePool (EfiReservedMemoryType, OldSize, NewSize, OldBuffer);\r
787}\r
788\r
789/**\r
790 Frees a buffer that was previously allocated with one of the pool allocation functions in the\r
791 Memory Allocation Library.\r
792\r
793 Frees the buffer specified by Buffer. Buffer must have been allocated on a previous call to the\r
794 pool allocation services of the Memory Allocation Library. If it is not possible to free pool\r
795 resources, then this function will perform no actions.\r
d18d8a1d 796\r
1d7ac5a6 797 If Buffer was not allocated with a pool allocation function in the Memory Allocation Library,\r
798 then ASSERT().\r
799\r
800 @param Buffer The pointer to the buffer to free.\r
801\r
802**/\r
803VOID\r
804EFIAPI\r
805FreePool (\r
806 IN VOID *Buffer\r
807 )\r
808{\r
8e4b3d32 809 EFI_STATUS Status;\r
810\r
1d7ac5a6 811 if (!gEmuThunk->Free (Buffer)) {\r
812 // The Free thunk will not free memory allocated in emulated EFI memory.\r
d18d8a1d 813 // The assmuption is this was allocated directly by EFI. We need this as some\r
1d7ac5a6 814 // times protocols or EFI BootServices can return dynamically allocated buffers.\r
8e4b3d32 815 Status = gBS->FreePool (Buffer);\r
816 ASSERT_EFI_ERROR (Status);\r
1d7ac5a6 817 }\r
818}\r
819\r