MemoryAllocationLib.c revision e386b444c88b01c5a14ca846b6ba10dcf5536e05
1/** @file
2  Support routines for memory allocation routines for use with drivers.
3
4  Copyright (c) 2006, Intel Corporation<BR>
5  All rights reserved. This program and the accompanying materials
6  are licensed and made available under the terms and conditions of the BSD License
7  which accompanies this distribution.  The full text of the license may be found at
8  http://opensource.org/licenses/bsd-license.php
9
10  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13  Module Name:  MemoryAllocationLib.c
14
15**/
16
17//
18// Include common header file for this module.
19//
20#include "CommonHeader.h"
21
22#include "MemoryAllocationLibInternals.h"
23
24/**
25  Allocates one or more 4KB pages of a certain memory type.
26
27  Allocates the number of 4KB pages of a certain memory type and returns a pointer to the allocated
28  buffer.  The buffer returned is aligned on a 4KB boundary.  If Pages is 0, then NULL is returned.
29  If there is not enough memory remaining to satisfy the request, then NULL is returned.
30
31  @param  MemoryType            The type of memory to allocate.
32  @param  Pages                 The number of 4 KB pages to allocate.
33
34  @return A pointer to the allocated buffer or NULL if allocation fails.
35
36**/
37VOID *
38InternalAllocatePages (
39  IN EFI_MEMORY_TYPE  MemoryType,
40  IN UINTN            Pages
41  )
42{
43  EFI_STATUS            Status;
44  EFI_PHYSICAL_ADDRESS  Memory;
45  EFI_PEI_SERVICES      **PeiServices;
46
47  if (Pages == 0) {
48    return NULL;
49  }
50
51  PeiServices = GetPeiServicesTablePointer ();
52  Status = (*PeiServices)->AllocatePages (PeiServices, MemoryType, Pages, &Memory);
53  if (EFI_ERROR (Status)) {
54    Memory = 0;
55  }
56  return (VOID *) (UINTN) Memory;
57}
58
59/**
60  Allocates one or more 4KB pages of type EfiBootServicesData.
61
62  Allocates the number of 4KB pages of type EfiBootServicesData and returns a pointer to the
63  allocated buffer.  The buffer returned is aligned on a 4KB boundary.  If Pages is 0, then NULL
64  is returned.  If there is not enough memory remaining to satisfy the request, then NULL is
65  returned.
66
67  @param  Pages                 The number of 4 KB pages to allocate.
68
69  @return A pointer to the allocated buffer or NULL if allocation fails.
70
71**/
72VOID *
73EFIAPI
74AllocatePages (
75  IN UINTN  Pages
76  )
77{
78  return InternalAllocatePages (EfiBootServicesData, Pages);
79}
80
81/**
82  Allocates one or more 4KB pages of type EfiRuntimeServicesData.
83
84  Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer to the
85  allocated buffer.  The buffer returned is aligned on a 4KB boundary.  If Pages is 0, then NULL
86  is returned.  If there is not enough memory remaining to satisfy the request, then NULL is
87  returned.
88
89  @param  Pages                 The number of 4 KB pages to allocate.
90
91  @return A pointer to the allocated buffer or NULL if allocation fails.
92
93**/
94VOID *
95EFIAPI
96AllocateRuntimePages (
97  IN UINTN  Pages
98  )
99{
100  return InternalAllocatePages (EfiRuntimeServicesData, Pages);
101}
102
103/**
104  Allocates one or more 4KB pages of type EfiReservedMemoryType.
105
106  Allocates the number of 4KB pages of type EfiReservedMemoryType and returns a pointer to the
107  allocated buffer.  The buffer returned is aligned on a 4KB boundary.  If Pages is 0, then NULL
108  is returned.  If there is not enough memory remaining to satisfy the request, then NULL is
109  returned.
110
111  @param  Pages                 The number of 4 KB pages to allocate.
112
113  @return A pointer to the allocated buffer or NULL if allocation fails.
114
115**/
116VOID *
117EFIAPI
118AllocateReservedPages (
119  IN UINTN  Pages
120  )
121{
122  return InternalAllocatePages (EfiReservedMemoryType, Pages);
123}
124
125/**
126  Frees one or more 4KB pages that were previously allocated with one of the page allocation
127  functions in the Memory Allocation Library.
128
129  Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer.  Buffer
130  must have been allocated on a previous call to the page allocation services of the Memory
131  Allocation Library.
132  If Buffer was not allocated with a page allocation function in the Memory Allocation Library,
133  then ASSERT().
134  If Pages is zero, then ASSERT().
135
136  @param  Buffer                Pointer to the buffer of pages to free.
137  @param  Pages                 The number of 4 KB pages to free.
138
139**/
140VOID
141EFIAPI
142FreePages (
143  IN VOID   *Buffer,
144  IN UINTN  Pages
145  )
146{
147  //
148  // PEI phase does not support to free pages, so leave it as NOP.
149  //
150}
151
152/**
153  Allocates one or more 4KB pages of a certain memory type at a specified alignment.
154
155  Allocates the number of 4KB pages specified by Pages of a certain memory type with an alignment
156  specified by Alignment.  The allocated buffer is returned.  If Pages is 0, then NULL is returned.
157  If there is not enough memory at the specified alignment remaining to satisfy the request, then
158  NULL is returned.
159  If Alignment is not a power of two and Alignment is not zero, then ASSERT().
160
161  @param  MemoryType            The type of memory to allocate.
162  @param  Pages                 The number of 4 KB pages to allocate.
163  @param  Alignment             The requested alignment of the allocation.  Must be a power of two.
164                                If Alignment is zero, then byte alignment is used.
165
166  @return A pointer to the allocated buffer or NULL if allocation fails.
167
168**/
169VOID *
170InternalAllocateAlignedPages (
171  IN EFI_MEMORY_TYPE  MemoryType,
172  IN UINTN            Pages,
173  IN UINTN            Alignment
174  )
175{
176  VOID    *Memory;
177  UINTN   AlignmentMask;
178
179  //
180  // Alignment must be a power of two or zero.
181  //
182  ASSERT ((Alignment & (Alignment - 1)) == 0);
183
184  if (Pages == 0) {
185    return NULL;
186  }
187  //
188  // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow.
189  //
190  ASSERT (Pages <= (MAX_ADDRESS - EFI_SIZE_TO_PAGES (Alignment)));
191  //
192  // We would rather waste some memory to save PEI code size.
193  //
194  Memory = InternalAllocatePages (MemoryType, Pages + EFI_SIZE_TO_PAGES (Alignment));
195  if (Alignment == 0) {
196    AlignmentMask = Alignment;
197  } else {
198    AlignmentMask = Alignment - 1;
199  }
200  return (VOID *) (UINTN) (((UINTN) Memory + AlignmentMask) & ~AlignmentMask);
201}
202
203/**
204  Allocates one or more 4KB pages of type EfiBootServicesData at a specified alignment.
205
206  Allocates the number of 4KB pages specified by Pages of type EfiBootServicesData with an
207  alignment specified by Alignment.  The allocated buffer is returned.  If Pages is 0, then NULL is
208  returned.  If there is not enough memory at the specified alignment remaining to satisfy the
209  request, then NULL is returned.
210  If Alignment is not a power of two and Alignment is not zero, then ASSERT().
211
212  @param  Pages                 The number of 4 KB pages to allocate.
213  @param  Alignment             The requested alignment of the allocation.  Must be a power of two.
214                                If Alignment is zero, then byte alignment is used.
215
216  @return A pointer to the allocated buffer or NULL if allocation fails.
217
218**/
219VOID *
220EFIAPI
221AllocateAlignedPages (
222  IN UINTN  Pages,
223  IN UINTN  Alignment
224  )
225{
226  return InternalAllocateAlignedPages (EfiBootServicesData, Pages, Alignment);
227}
228
229/**
230  Allocates one or more 4KB pages of type EfiRuntimeServicesData at a specified alignment.
231
232  Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData with an
233  alignment specified by Alignment.  The allocated buffer is returned.  If Pages is 0, then NULL is
234  returned.  If there is not enough memory at the specified alignment remaining to satisfy the
235  request, then NULL is returned.
236  If Alignment is not a power of two and Alignment is not zero, then ASSERT().
237
238  @param  Pages                 The number of 4 KB pages to allocate.
239  @param  Alignment             The requested alignment of the allocation.  Must be a power of two.
240                                If Alignment is zero, then byte alignment is used.
241
242  @return A pointer to the allocated buffer or NULL if allocation fails.
243
244**/
245VOID *
246EFIAPI
247AllocateAlignedRuntimePages (
248  IN UINTN  Pages,
249  IN UINTN  Alignment
250  )
251{
252  return InternalAllocateAlignedPages (EfiRuntimeServicesData, Pages, Alignment);
253}
254
255/**
256  Allocates one or more 4KB pages of type EfiReservedMemoryType at a specified alignment.
257
258  Allocates the number of 4KB pages specified by Pages of type EfiReservedMemoryType with an
259  alignment specified by Alignment.  The allocated buffer is returned.  If Pages is 0, then NULL is
260  returned.  If there is not enough memory at the specified alignment remaining to satisfy the
261  request, then NULL is returned.
262  If Alignment is not a power of two and Alignment is not zero, then ASSERT().
263
264  @param  Pages                 The number of 4 KB pages to allocate.
265  @param  Alignment             The requested alignment of the allocation.  Must be a power of two.
266                                If Alignment is zero, then byte alignment is used.
267
268  @return A pointer to the allocated buffer or NULL if allocation fails.
269
270**/
271VOID *
272EFIAPI
273AllocateAlignedReservedPages (
274  IN UINTN  Pages,
275  IN UINTN  Alignment
276  )
277{
278  return InternalAllocateAlignedPages (EfiReservedMemoryType, Pages, Alignment);
279}
280
281/**
282  Frees one or more 4KB pages that were previously allocated with one of the aligned page
283  allocation functions in the Memory Allocation Library.
284
285  Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer.  Buffer
286  must have been allocated on a previous call to the aligned page allocation services of the Memory
287  Allocation Library.
288  If Buffer was not allocated with an aligned page allocation function in the Memory Allocation
289  Library, then ASSERT().
290  If Pages is zero, then ASSERT().
291
292  @param  Buffer                Pointer to the buffer of pages to free.
293  @param  Pages                 The number of 4 KB pages to free.
294
295**/
296VOID
297EFIAPI
298FreeAlignedPages (
299  IN VOID   *Buffer,
300  IN UINTN  Pages
301  )
302{
303  //
304  // PEI phase does not support to free pages, so leave it as NOP.
305  //
306}
307
308/**
309  Allocates a buffer of a certain pool type.
310
311  Allocates the number bytes specified by AllocationSize of a certain pool type and returns a
312  pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is
313  returned.  If there is not enough memory remaining to satisfy the request, then NULL is returned.
314
315  @param  MemoryType            The type of memory to allocate.
316  @param  AllocationSize        The number of bytes to allocate.
317
318  @return A pointer to the allocated buffer or NULL if allocation fails.
319
320**/
321VOID *
322InternalAllocatePool (
323  IN EFI_MEMORY_TYPE  MemoryType,
324  IN UINTN            AllocationSize
325  )
326{
327  //
328  // If we need lots of small runtime/reserved memory type from PEI in the future,
329  // we can consider providing a more complex algorithm that allocates runtime pages and
330  // provide pool allocations from those pages.
331  //
332  return InternalAllocatePages (MemoryType, EFI_SIZE_TO_PAGES (AllocationSize));
333}
334
335/**
336  Allocates a buffer of type EfiBootServicesData.
337
338  Allocates the number bytes specified by AllocationSize of type EfiBootServicesData and returns a
339  pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is
340  returned.  If there is not enough memory remaining to satisfy the request, then NULL is returned.
341
342  @param  AllocationSize        The number of bytes to allocate.
343
344  @return A pointer to the allocated buffer or NULL if allocation fails.
345
346**/
347VOID *
348EFIAPI
349AllocatePool (
350  IN UINTN  AllocationSize
351  )
352{
353  EFI_STATUS        Status;
354  EFI_PEI_SERVICES  **PeiServices;
355  VOID              *Buffer;
356
357  PeiServices = GetPeiServicesTablePointer ();
358
359  Status = (*PeiServices)->AllocatePool (PeiServices, AllocationSize, &Buffer);
360  if (EFI_ERROR (Status)) {
361    Buffer = NULL;
362  }
363  return Buffer;
364}
365
366/**
367  Allocates a buffer of type EfiRuntimeServicesData.
368
369  Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData and returns
370  a pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is
371  returned.  If there is not enough memory remaining to satisfy the request, then NULL is returned.
372
373  @param  AllocationSize        The number of bytes to allocate.
374
375  @return A pointer to the allocated buffer or NULL if allocation fails.
376
377**/
378VOID *
379EFIAPI
380AllocateRuntimePool (
381  IN UINTN  AllocationSize
382  )
383{
384  return InternalAllocatePool (EfiRuntimeServicesData, AllocationSize);
385}
386
387/**
388  Allocates a buffer of type EfieservedMemoryType.
389
390  Allocates the number bytes specified by AllocationSize of type EfieservedMemoryType and returns
391  a pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is
392  returned.  If there is not enough memory remaining to satisfy the request, then NULL is returned.
393
394  @param  AllocationSize        The number of bytes to allocate.
395
396  @return A pointer to the allocated buffer or NULL if allocation fails.
397
398**/
399VOID *
400EFIAPI
401AllocateReservedPool (
402  IN UINTN  AllocationSize
403  )
404{
405  return InternalAllocatePool (EfiReservedMemoryType, AllocationSize);
406}
407
408/**
409  Allocates and zeros a buffer of a certian pool type.
410
411  Allocates the number bytes specified by AllocationSize of a certian pool type, clears the buffer
412  with zeros, and returns a pointer to the allocated buffer.  If AllocationSize is 0, then a valid
413  buffer of 0 size is returned.  If there is not enough memory remaining to satisfy the request,
414  then NULL is returned.
415
416  @param  PoolType              The type of memory to allocate.
417  @param  AllocationSize        The number of bytes to allocate and zero.
418
419  @return A pointer to the allocated buffer or NULL if allocation fails.
420
421**/
422VOID *
423InternalAllocateZeroPool (
424  IN EFI_MEMORY_TYPE  PoolType,
425  IN UINTN            AllocationSize
426  )
427{
428  VOID  *Memory;
429
430  Memory = InternalAllocatePool (PoolType, AllocationSize);
431  if (Memory != NULL) {
432    Memory = ZeroMem (Memory, AllocationSize);
433  }
434  return Memory;
435}
436
437/**
438  Allocates and zeros a buffer of type EfiBootServicesData.
439
440  Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, clears the
441  buffer with zeros, and returns a pointer to the allocated buffer.  If AllocationSize is 0, then a
442  valid buffer of 0 size is returned.  If there is not enough memory remaining to satisfy the
443  request, then NULL is returned.
444
445  @param  AllocationSize        The number of bytes to allocate and zero.
446
447  @return A pointer to the allocated buffer or NULL if allocation fails.
448
449**/
450VOID *
451EFIAPI
452AllocateZeroPool (
453  IN UINTN  AllocationSize
454  )
455{
456  VOID  *Memory;
457
458  Memory = AllocatePool (AllocationSize);
459  if (Memory != NULL) {
460    Memory = ZeroMem (Memory, AllocationSize);
461  }
462  return Memory;
463}
464
465/**
466  Allocates and zeros a buffer of type EfiRuntimeServicesData.
467
468  Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, clears the
469  buffer with zeros, and returns a pointer to the allocated buffer.  If AllocationSize is 0, then a
470  valid buffer of 0 size is returned.  If there is not enough memory remaining to satisfy the
471  request, then NULL is returned.
472
473  @param  AllocationSize        The number of bytes to allocate and zero.
474
475  @return A pointer to the allocated buffer or NULL if allocation fails.
476
477**/
478VOID *
479EFIAPI
480AllocateRuntimeZeroPool (
481  IN UINTN  AllocationSize
482  )
483{
484  return InternalAllocateZeroPool (EfiRuntimeServicesData, AllocationSize);
485}
486
487/**
488  Allocates and zeros a buffer of type EfiReservedMemoryType.
489
490  Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, clears the
491  buffer with zeros, and returns a pointer to the allocated buffer.  If AllocationSize is 0, then a
492  valid buffer of 0 size is returned.  If there is not enough memory remaining to satisfy the
493  request, then NULL is returned.
494
495  @param  AllocationSize        The number of bytes to allocate and zero.
496
497  @return A pointer to the allocated buffer or NULL if allocation fails.
498
499**/
500VOID *
501EFIAPI
502AllocateReservedZeroPool (
503  IN UINTN  AllocationSize
504  )
505{
506  return InternalAllocateZeroPool (EfiReservedMemoryType, AllocationSize);
507}
508
509/**
510  Copies a buffer to an allocated buffer of a certian pool type.
511
512  Allocates the number bytes specified by AllocationSize of a certian pool type, copies
513  AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
514  allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.  If there
515  is not enough memory remaining to satisfy the request, then NULL is returned.
516  If Buffer is NULL, then ASSERT().
517  If AllocationSize is greater than (MAX_ADDRESS ? Buffer + 1), then ASSERT().
518
519  @param  PoolType              The type of pool to allocate.
520  @param  AllocationSize        The number of bytes to allocate and zero.
521  @param  Buffer                The buffer to copy to the allocated buffer.
522
523  @return A pointer to the allocated buffer or NULL if allocation fails.
524
525**/
526VOID *
527InternalAllocateCopyPool (
528  IN EFI_MEMORY_TYPE  PoolType,
529  IN UINTN            AllocationSize,
530  IN CONST VOID       *Buffer
531  )
532{
533  VOID  *Memory;
534
535  ASSERT (Buffer != NULL);
536  ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN) Buffer + 1));
537
538  Memory = InternalAllocatePool (PoolType, AllocationSize);
539  if (Memory != NULL) {
540     Memory = CopyMem (Memory, Buffer, AllocationSize);
541  }
542  return Memory;
543}
544
545/**
546  Copies a buffer to an allocated buffer of type EfiBootServicesData.
547
548  Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, copies
549  AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
550  allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.  If there
551  is not enough memory remaining to satisfy the request, then NULL is returned.
552  If Buffer is NULL, then ASSERT().
553  If AllocationSize is greater than (MAX_ADDRESS ? Buffer + 1), then ASSERT().
554
555  @param  AllocationSize        The number of bytes to allocate and zero.
556  @param  Buffer                The buffer to copy to the allocated buffer.
557
558  @return A pointer to the allocated buffer or NULL if allocation fails.
559
560**/
561VOID *
562EFIAPI
563AllocateCopyPool (
564  IN UINTN       AllocationSize,
565  IN CONST VOID  *Buffer
566  )
567{
568  VOID  *Memory;
569
570  ASSERT (Buffer != NULL);
571  ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN) Buffer + 1));
572
573  Memory = AllocatePool (AllocationSize);
574  if (Memory != NULL) {
575     Memory = CopyMem (Memory, Buffer, AllocationSize);
576  }
577  return Memory;
578}
579
580/**
581  Copies a buffer to an allocated buffer of type EfiRuntimeServicesData.
582
583  Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, copies
584  AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
585  allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.  If there
586  is not enough memory remaining to satisfy the request, then NULL is returned.
587  If Buffer is NULL, then ASSERT().
588  If AllocationSize is greater than (MAX_ADDRESS ? Buffer + 1), then ASSERT().
589
590  @param  AllocationSize        The number of bytes to allocate and zero.
591  @param  Buffer                The buffer to copy to the allocated buffer.
592
593  @return A pointer to the allocated buffer or NULL if allocation fails.
594
595**/
596VOID *
597EFIAPI
598AllocateRuntimeCopyPool (
599  IN UINTN       AllocationSize,
600  IN CONST VOID  *Buffer
601  )
602{
603  return InternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer);
604}
605
606/**
607  Copies a buffer to an allocated buffer of type EfiReservedMemoryType.
608
609  Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, copies
610  AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
611  allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.  If there
612  is not enough memory remaining to satisfy the request, then NULL is returned.
613  If Buffer is NULL, then ASSERT().
614  If AllocationSize is greater than (MAX_ADDRESS ? Buffer + 1), then ASSERT().
615
616  @param  AllocationSize        The number of bytes to allocate and zero.
617  @param  Buffer                The buffer to copy to the allocated buffer.
618
619  @return A pointer to the allocated buffer or NULL if allocation fails.
620
621**/
622VOID *
623EFIAPI
624AllocateReservedCopyPool (
625  IN UINTN       AllocationSize,
626  IN CONST VOID  *Buffer
627  )
628{
629  return InternalAllocateCopyPool (EfiReservedMemoryType, AllocationSize, Buffer);
630}
631
632/**
633  Frees a buffer that was previously allocated with one of the pool allocation functions in the
634  Memory Allocation Library.
635
636  Frees the buffer specified by Buffer.  Buffer must have been allocated on a previous call to the
637  pool allocation services of the Memory Allocation Library.
638  If Buffer was not allocated with a pool allocation function in the Memory Allocation Library,
639  then ASSERT().
640
641  @param  Buffer                Pointer to the buffer to free.
642
643**/
644VOID
645EFIAPI
646FreePool (
647  IN VOID   *Buffer
648  )
649{
650  //
651  // PEI phase does not support to free pool, so leave it as NOP.
652  //
653}
654
655/**
656  Allocates a buffer of a certain pool type at a specified alignment.
657
658  Allocates the number bytes specified by AllocationSize of a certain pool type with an alignment
659  specified by Alignment.  The allocated buffer is returned.  If AllocationSize is 0, then a valid
660  buffer of 0 size is returned.  If there is not enough memory at the specified alignment remaining
661  to satisfy the request, then NULL is returned.
662  If Alignment is not a power of two and Alignment is not zero, then ASSERT().
663
664  @param  PoolType              The type of pool to allocate.
665  @param  AllocationSize        The number of bytes to allocate.
666  @param  Alignment             The requested alignment of the allocation.  Must be a power of two.                            If Alignment is zero, then byte alignment is used.
667                                If Alignment is zero, then byte alignment is used.
668
669  @return A pointer to the allocated buffer or NULL if allocation fails.
670
671**/
672VOID *
673InternalAllocateAlignedPool (
674  IN EFI_MEMORY_TYPE  PoolType,
675  IN UINTN            AllocationSize,
676  IN UINTN            Alignment
677  )
678{
679  VOID    *RawAddress;
680  UINTN   AlignedAddress;
681  UINTN   AlignmentMask;
682
683  //
684  // Alignment must be a power of two or zero.
685  //
686  ASSERT ((Alignment & (Alignment - 1)) == 0);
687
688  if (Alignment == 0) {
689    AlignmentMask = Alignment;
690  } else {
691    AlignmentMask = Alignment - 1;
692  }
693  //
694  // Make sure that AllocationSize plus AlignmentMask does not overflow.
695  //
696  ASSERT (AllocationSize <= (MAX_ADDRESS - AlignmentMask));
697
698  RawAddress      = InternalAllocatePool (PoolType, AllocationSize + AlignmentMask);
699
700  AlignedAddress  = ((UINTN) RawAddress + AlignmentMask) & ~AlignmentMask;
701
702  return (VOID *) AlignedAddress;
703}
704
705/**
706  Allocates a buffer of type EfiBootServicesData at a specified alignment.
707
708  Allocates the number bytes specified by AllocationSize of type EfiBootServicesData with an
709  alignment specified by Alignment.  The allocated buffer is returned.  If AllocationSize is 0,
710  then a valid buffer of 0 size is returned.  If there is not enough memory at the specified
711  alignment remaining to satisfy the request, then NULL is returned.
712  If Alignment is not a power of two and Alignment is not zero, then ASSERT().
713
714  @param  AllocationSize        The number of bytes to allocate.
715  @param  Alignment             The requested alignment of the allocation.  Must be a power of two.
716                                If Alignment is zero, then byte alignment is used.
717
718  @return A pointer to the allocated buffer or NULL if allocation fails.
719
720**/
721VOID *
722EFIAPI
723AllocateAlignedPool (
724  IN UINTN  AllocationSize,
725  IN UINTN  Alignment
726  )
727{
728  VOID    *RawAddress;
729  UINTN   AlignedAddress;
730  UINTN   AlignmentMask;
731
732  //
733  // Alignment must be a power of two or zero.
734  //
735  ASSERT ((Alignment & (Alignment - 1)) == 0);
736
737  if (Alignment == 0) {
738    AlignmentMask = Alignment;
739  } else {
740    AlignmentMask = Alignment - 1;
741  }
742
743  //
744  // Make sure that AllocationSize plus AlignmentMask does not overflow.
745  //
746  ASSERT (AllocationSize <= (MAX_ADDRESS - AlignmentMask));
747
748  RawAddress      = AllocatePool (AllocationSize + AlignmentMask);
749
750  AlignedAddress  = ((UINTN) RawAddress + AlignmentMask) & ~AlignmentMask;
751
752  return (VOID *) AlignedAddress;
753}
754
755/**
756  Allocates a buffer of type EfiRuntimeServicesData at a specified alignment.
757
758  Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData with an
759  alignment specified by Alignment.  The allocated buffer is returned.  If AllocationSize is 0,
760  then a valid buffer of 0 size is returned.  If there is not enough memory at the specified
761  alignment remaining to satisfy the request, then NULL is returned.
762  If Alignment is not a power of two and Alignment is not zero, then ASSERT().
763
764  @param  AllocationSize        The number of bytes to allocate.
765  @param  Alignment             The requested alignment of the allocation.  Must be a power of two.
766                                If Alignment is zero, then byte alignment is used.
767
768  @return A pointer to the allocated buffer or NULL if allocation fails.
769
770**/
771VOID *
772EFIAPI
773AllocateAlignedRuntimePool (
774  IN UINTN  AllocationSize,
775  IN UINTN  Alignment
776  )
777{
778  return InternalAllocateAlignedPool (EfiRuntimeServicesData, AllocationSize, Alignment);
779}
780
781/**
782  Allocates a buffer of type EfieservedMemoryType at a specified alignment.
783
784  Allocates the number bytes specified by AllocationSize of type EfieservedMemoryType with an
785  alignment specified by Alignment.  The allocated buffer is returned.  If AllocationSize is 0,
786  then a valid buffer of 0 size is returned.  If there is not enough memory at the specified
787  alignment remaining to satisfy the request, then NULL is returned.
788  If Alignment is not a power of two and Alignment is not zero, then ASSERT().
789
790  @param  AllocationSize        The number of bytes to allocate.
791  @param  Alignment             The requested alignment of the allocation.  Must be a power of two.
792                                If Alignment is zero, then byte alignment is used.
793
794  @return A pointer to the allocated buffer or NULL if allocation fails.
795
796**/
797VOID *
798EFIAPI
799AllocateAlignedReservedPool (
800  IN UINTN  AllocationSize,
801  IN UINTN  Alignment
802  )
803{
804  return InternalAllocateAlignedPool (EfiReservedMemoryType, AllocationSize, Alignment);
805}
806
807/**
808  Allocates and zeros a buffer of a certain pool type at a specified alignment.
809
810  Allocates the number bytes specified by AllocationSize of a certain pool type with an alignment
811  specified by Alignment, clears the buffer with zeros, and returns a pointer to the allocated
812  buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.  If there is not
813  enough memory at the specified alignment remaining to satisfy the request, then NULL is returned.
814  If Alignment is not a power of two and Alignment is not zero, then ASSERT().
815
816  @param  PoolType              The type of pool to allocate.
817  @param  AllocationSize        The number of bytes to allocate.
818  @param  Alignment             The requested alignment of the allocation.  Must be a power of two.
819                                If Alignment is zero, then byte alignment is used.
820
821  @return A pointer to the allocated buffer or NULL if allocation fails.
822
823**/
824VOID *
825InternalAllocateAlignedZeroPool (
826  IN EFI_MEMORY_TYPE  PoolType,
827  IN UINTN            AllocationSize,
828  IN UINTN            Alignment
829  )
830{
831  VOID    *Memory;
832
833  Memory = InternalAllocateAlignedPool (PoolType, AllocationSize, Alignment);
834  if (Memory != NULL) {
835    Memory = ZeroMem (Memory, AllocationSize);
836  }
837  return Memory;
838}
839
840/**
841  Allocates and zeros a buffer of type EfiBootServicesData at a specified alignment.
842
843  Allocates the number bytes specified by AllocationSize of type EfiBootServicesData with an
844  alignment specified by Alignment, clears the buffer with zeros, and returns a pointer to the
845  allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.  If there
846  is not enough memory at the specified alignment remaining to satisfy the request, then NULL is
847  returned.
848  If Alignment is not a power of two and Alignment is not zero, then ASSERT().
849
850  @param  AllocationSize        The number of bytes to allocate.
851  @param  Alignment             The requested alignment of the allocation.  Must be a power of two.
852                                If Alignment is zero, then byte alignment is used.
853
854  @return A pointer to the allocated buffer or NULL if allocation fails.
855
856**/
857VOID *
858EFIAPI
859AllocateAlignedZeroPool (
860  IN UINTN  AllocationSize,
861  IN UINTN  Alignment
862  )
863{
864  VOID    *Memory;
865
866  Memory = AllocateAlignedPool (AllocationSize, Alignment);
867  if (Memory != NULL) {
868    Memory = ZeroMem (Memory, AllocationSize);
869  }
870  return Memory;
871}
872
873/**
874  Allocates and zeros a buffer of type EfiRuntimeServicesData at a specified alignment.
875
876  Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData with an
877  alignment specified by Alignment, clears the buffer with zeros, and returns a pointer to the
878  allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.  If there
879  is not enough memory at the specified alignment remaining to satisfy the request, then NULL is
880  returned.
881  If Alignment is not a power of two and Alignment is not zero, then ASSERT().
882
883  @param  AllocationSize        The number of bytes to allocate.
884  @param  Alignment             The requested alignment of the allocation.  Must be a power of two.
885                                If Alignment is zero, then byte alignment is used.
886
887  @return A pointer to the allocated buffer or NULL if allocation fails.
888
889**/
890VOID *
891EFIAPI
892AllocateAlignedRuntimeZeroPool (
893  IN UINTN  AllocationSize,
894  IN UINTN  Alignment
895  )
896{
897  return InternalAllocateAlignedZeroPool (EfiRuntimeServicesData, AllocationSize, Alignment);
898}
899
900/**
901  Allocates and zeros a buffer of type EfieservedMemoryType at a specified alignment.
902
903  Allocates the number bytes specified by AllocationSize of type EfieservedMemoryType with an
904  alignment specified by Alignment, clears the buffer with zeros, and returns a pointer to the
905  allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.  If there
906  is not enough memory at the specified alignment remaining to satisfy the request, then NULL is
907  returned.
908  If Alignment is not a power of two and Alignment is not zero, then ASSERT().
909
910  @param  AllocationSize        The number of bytes to allocate.
911  @param  Alignment             The requested alignment of the allocation.  Must be a power of two.
912                                If Alignment is zero, then byte alignment is used.
913
914  @return A pointer to the allocated buffer or NULL if allocation fails.
915
916**/
917VOID *
918EFIAPI
919AllocateAlignedReservedZeroPool (
920  IN UINTN  AllocationSize,
921  IN UINTN  Alignment
922  )
923{
924  return InternalAllocateAlignedZeroPool (EfiReservedMemoryType, AllocationSize, Alignment);
925}
926
927/**
928  Copies a buffer to an allocated buffer of a certain pool type at a specified alignment.
929
930  Allocates the number bytes specified by AllocationSize of a certain pool type with an alignment
931  specified by Alignment.  The allocated buffer is returned.  If AllocationSize is 0, then a valid
932  buffer of 0 size is returned.  If there is not enough memory at the specified alignment remaining
933  to satisfy the request, then NULL is returned.
934  If Alignment is not a power of two and Alignment is not zero, then ASSERT().
935
936  @param  PoolType              The type of pool to allocate.
937  @param  AllocationSize        The number of bytes to allocate.
938  @param  Buffer                The buffer to copy to the allocated buffer.
939  @param  Alignment             The requested alignment of the allocation.  Must be a power of two.
940                                If Alignment is zero, then byte alignment is used.
941
942  @return A pointer to the allocated buffer or NULL if allocation fails.
943
944**/
945VOID *
946InternalAllocateAlignedCopyPool (
947  IN EFI_MEMORY_TYPE  PoolType,
948  IN UINTN            AllocationSize,
949  IN CONST VOID       *Buffer,
950  IN UINTN            Alignment
951  )
952{
953  VOID  *Memory;
954
955  ASSERT (Buffer != NULL);
956  ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN) Buffer + 1));
957
958  Memory = InternalAllocateAlignedPool (PoolType, AllocationSize, Alignment);
959  if (Memory != NULL) {
960    Memory = CopyMem (Memory, Buffer, AllocationSize);
961  }
962  return Memory;
963}
964
965/**
966  Copies a buffer to an allocated buffer of type EfiBootServicesData at a specified alignment.
967
968  Allocates the number bytes specified by AllocationSize of type EfiBootServicesData type with an
969  alignment specified by Alignment.  The allocated buffer is returned.  If AllocationSize is 0,
970  then a valid buffer of 0 size is returned.  If there is not enough memory at the specified
971  alignment remaining to satisfy the request, then NULL is returned.
972  If Alignment is not a power of two and Alignment is not zero, then ASSERT().
973
974  @param  AllocationSize        The number of bytes to allocate.
975  @param  Buffer                The buffer to copy to the allocated buffer.
976  @param  Alignment             The requested alignment of the allocation.  Must be a power of two.
977                                If Alignment is zero, then byte alignment is used.
978
979  @return A pointer to the allocated buffer or NULL if allocation fails.
980
981**/
982VOID *
983EFIAPI
984AllocateAlignedCopyPool (
985  IN UINTN       AllocationSize,
986  IN CONST VOID  *Buffer,
987  IN UINTN       Alignment
988  )
989{
990  VOID  *Memory;
991
992  ASSERT (Buffer != NULL);
993  ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN) Buffer + 1));
994
995  Memory = AllocateAlignedPool (AllocationSize, Alignment);
996  if (Memory != NULL) {
997    Memory = CopyMem (Memory, Buffer, AllocationSize);
998  }
999  return Memory;
1000}
1001
1002/**
1003  Copies a buffer to an allocated buffer of type EfiRuntimeServicesData at a specified alignment.
1004
1005  Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData type with an
1006  alignment specified by Alignment.  The allocated buffer is returned.  If AllocationSize is 0,
1007  then a valid buffer of 0 size is returned.  If there is not enough memory at the specified
1008  alignment remaining to satisfy the request, then NULL is returned.
1009  If Alignment is not a power of two and Alignment is not zero, then ASSERT().
1010
1011  @param  AllocationSize        The number of bytes to allocate.
1012  @param  Buffer                The buffer to copy to the allocated buffer.
1013  @param  Alignment             The requested alignment of the allocation.  Must be a power of two.
1014                                If Alignment is zero, then byte alignment is used.
1015
1016  @return A pointer to the allocated buffer or NULL if allocation fails.
1017
1018**/
1019VOID *
1020EFIAPI
1021AllocateAlignedRuntimeCopyPool (
1022  IN UINTN       AllocationSize,
1023  IN CONST VOID  *Buffer,
1024  IN UINTN       Alignment
1025  )
1026{
1027  return InternalAllocateAlignedCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer, Alignment);
1028}
1029
1030/**
1031  Copies a buffer to an allocated buffer of type EfiReservedMemoryType at a specified alignment.
1032
1033  Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType type with an
1034  alignment specified by Alignment.  The allocated buffer is returned.  If AllocationSize is 0,
1035  then a valid buffer of 0 size is returned.  If there is not enough memory at the specified
1036  alignment remaining to satisfy the request, then NULL is returned.
1037  If Alignment is not a power of two and Alignment is not zero, then ASSERT().
1038
1039  @param  AllocationSize        The number of bytes to allocate.
1040  @param  Buffer                The buffer to copy to the allocated buffer.
1041  @param  Alignment             The requested alignment of the allocation.  Must be a power of two.
1042                                If Alignment is zero, then byte alignment is used.
1043
1044  @return A pointer to the allocated buffer or NULL if allocation fails.
1045
1046**/
1047VOID *
1048EFIAPI
1049AllocateAlignedReservedCopyPool (
1050  IN UINTN       AllocationSize,
1051  IN CONST VOID  *Buffer,
1052  IN UINTN       Alignment
1053  )
1054{
1055  return InternalAllocateAlignedCopyPool (EfiReservedMemoryType, AllocationSize, Buffer, Alignment);
1056}
1057
1058/**
1059  Frees a buffer that was previously allocated with one of the aligned pool allocation functions
1060  in the Memory Allocation Library.
1061
1062  Frees the buffer specified by Buffer.  Buffer must have been allocated on a previous call to the
1063  aligned pool allocation services of the Memory Allocation Library.
1064  If Buffer was not allocated with an aligned pool allocation function in the Memory Allocation
1065  Library, then ASSERT().
1066
1067  @param  Buffer                Pointer to the buffer to free.
1068
1069**/
1070VOID
1071EFIAPI
1072FreeAlignedPool (
1073  IN VOID   *Buffer
1074  )
1075{
1076  //
1077  // PEI phase does not support to free pool, so leave it as NOP.
1078  //
1079}
1080