1 /** @file
2   UncachedMemoryAllocation lib that uses DXE Service to change cachability for
3   a buffer.
4 
5   Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
6   Copyright (c) 2014, AMR Ltd. All rights reserved.<BR>
7 
8   This program and the accompanying materials
9   are licensed and made available under the terms and conditions of the BSD License
10   which accompanies this distribution.  The full text of the license may be found at
11   http://opensource.org/licenses/bsd-license.php
12 
13   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
14   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 
16 **/
17 
18 #include <Base.h>
19 #include <Library/BaseLib.h>
20 #include <Library/BaseMemoryLib.h>
21 #include <Library/MemoryAllocationLib.h>
22 #include <Library/DebugLib.h>
23 #include <Library/UefiBootServicesTableLib.h>
24 #include <Library/UncachedMemoryAllocationLib.h>
25 #include <Library/PcdLib.h>
26 #include <Library/ArmLib.h>
27 #include <Library/DxeServicesTableLib.h>
28 #include <Library/CacheMaintenanceLib.h>
29 
30 VOID *
31 UncachedInternalAllocatePages (
32   IN EFI_MEMORY_TYPE  MemoryType,
33   IN UINTN            Pages
34   );
35 
36 VOID *
37 UncachedInternalAllocateAlignedPages (
38   IN EFI_MEMORY_TYPE  MemoryType,
39   IN UINTN            Pages,
40   IN UINTN            Alignment
41   );
42 
43 
44 
45 //
46 // Assume all of memory has the same cache attributes, unless we do our magic
47 //
48 UINT64  gAttributes;
49 
50 typedef struct {
51   EFI_PHYSICAL_ADDRESS  Base;
52   VOID                  *Allocation;
53   UINTN                 Pages;
54   EFI_MEMORY_TYPE       MemoryType;
55   BOOLEAN               Allocated;
56   LIST_ENTRY            Link;
57 } FREE_PAGE_NODE;
58 
59 STATIC LIST_ENTRY  mPageList = INITIALIZE_LIST_HEAD_VARIABLE (mPageList);
60 // Track the size of the non-allocated buffer in the linked-list
61 STATIC UINTN   mFreedBufferSize = 0;
62 
63 /**
64  * This function firstly checks if the requested allocation can fit into one
65  * of the previously allocated buffer.
66  * If the requested allocation does not fit in the existing pool then
67  * the function makes a new allocation.
68  *
69  * @param MemoryType    Type of memory requested for the new allocation
70  * @param Pages         Number of requested page
71  * @param Alignment     Required alignment
72  * @param Allocation    Address of the newly allocated buffer
73  *
74  * @return EFI_SUCCESS  If the function manage to allocate a buffer
75  * @return !EFI_SUCCESS If the function did not manage to allocate a buffer
76  */
77 STATIC
78 EFI_STATUS
AllocatePagesFromList(IN EFI_MEMORY_TYPE MemoryType,IN UINTN Pages,IN UINTN Alignment,OUT VOID ** Allocation)79 AllocatePagesFromList (
80   IN EFI_MEMORY_TYPE  MemoryType,
81   IN UINTN            Pages,
82   IN UINTN            Alignment,
83   OUT VOID            **Allocation
84   )
85 {
86   EFI_STATUS       Status;
87   LIST_ENTRY      *Link;
88   FREE_PAGE_NODE  *Node;
89   FREE_PAGE_NODE  *NewNode;
90   UINTN            AlignmentMask;
91   EFI_PHYSICAL_ADDRESS Memory;
92   EFI_GCD_MEMORY_SPACE_DESCRIPTOR Descriptor;
93 
94   // Alignment must be a power of two or zero.
95   ASSERT ((Alignment & (Alignment - 1)) == 0);
96 
97   //
98   // Look in our list for the smallest page that could satisfy the new allocation
99   //
100   Node = NULL;
101   NewNode = NULL;
102   for (Link = mPageList.ForwardLink; Link != &mPageList; Link = Link->ForwardLink) {
103     Node = BASE_CR (Link, FREE_PAGE_NODE, Link);
104     if ((Node->Allocated == FALSE) && (Node->MemoryType == MemoryType)) {
105       // We have a node that fits our requirements
106       if (((UINTN)Node->Base & (Alignment - 1)) == 0) {
107         // We found a page that matches the page size
108         if (Node->Pages == Pages) {
109           Node->Allocated  = TRUE;
110           Node->Allocation = (VOID*)(UINTN)Node->Base;
111           *Allocation      = Node->Allocation;
112 
113           // Update the size of the freed buffer
114           mFreedBufferSize  -= Pages * EFI_PAGE_SIZE;
115           return EFI_SUCCESS;
116         } else if (Node->Pages > Pages) {
117           if (NewNode == NULL) {
118             // It is the first node that could contain our new allocation
119             NewNode = Node;
120           } else if (NewNode->Pages > Node->Pages) {
121             // This node offers a smaller number of page.
122             NewNode = Node;
123           }
124         }
125       }
126     }
127   }
128   // Check if we have found a node that could contain our new allocation
129   if (NewNode != NULL) {
130     NewNode->Allocated  = TRUE;
131     NewNode->Allocation = (VOID*)(UINTN)NewNode->Base;
132     *Allocation         = NewNode->Allocation;
133     mFreedBufferSize    -= NewNode->Pages * EFI_PAGE_SIZE;
134     return EFI_SUCCESS;
135   }
136 
137   //
138   // Otherwise, we need to allocate a new buffer
139   //
140 
141   // We do not want to over-allocate in case the alignment requirement does not
142   // require extra pages
143   if (Alignment > EFI_PAGE_SIZE) {
144     AlignmentMask  = Alignment - 1;
145     Pages          += EFI_SIZE_TO_PAGES (Alignment);
146   } else {
147     AlignmentMask  = 0;
148   }
149 
150   Status = gBS->AllocatePages (AllocateAnyPages, MemoryType, Pages, &Memory);
151   if (EFI_ERROR (Status)) {
152     return Status;
153   }
154 
155   Status = gDS->GetMemorySpaceDescriptor (Memory, &Descriptor);
156   if (!EFI_ERROR (Status)) {
157     // We are making an assumption that all of memory has the same default attributes
158     gAttributes = Descriptor.Attributes;
159   } else {
160     gBS->FreePages (Memory, Pages);
161     return Status;
162   }
163 
164   Status = gDS->SetMemorySpaceAttributes (Memory, EFI_PAGES_TO_SIZE (Pages), EFI_MEMORY_WC);
165   if (EFI_ERROR (Status)) {
166     gBS->FreePages (Memory, Pages);
167     return Status;
168   }
169 
170   InvalidateDataCacheRange ((VOID *)(UINTN)Memory, EFI_PAGES_TO_SIZE (Pages));
171 
172   NewNode = AllocatePool (sizeof (FREE_PAGE_NODE));
173   if (NewNode == NULL) {
174     ASSERT (FALSE);
175     gBS->FreePages (Memory, Pages);
176     return EFI_OUT_OF_RESOURCES;
177   }
178 
179   NewNode->Base       = Memory;
180   NewNode->Allocation = (VOID*)(((UINTN)Memory + AlignmentMask) & ~AlignmentMask);
181   NewNode->Pages      = Pages;
182   NewNode->Allocated  = TRUE;
183   NewNode->MemoryType = MemoryType;
184 
185   InsertTailList (&mPageList, &NewNode->Link);
186 
187   *Allocation = NewNode->Allocation;
188   return EFI_SUCCESS;
189 }
190 
191 /**
192  * Free the memory allocation
193  *
194  * This function will actually try to find the allocation in the linked list.
195  * And it will then mark the entry as freed.
196  *
197  * @param  Allocation  Base address of the buffer to free
198  *
199  * @return EFI_SUCCESS            The allocation has been freed
200  * @return EFI_NOT_FOUND          The allocation was not found in the pool.
201  * @return EFI_INVALID_PARAMETER  If Allocation is NULL
202  *
203  */
204 STATIC
205 EFI_STATUS
FreePagesFromList(IN VOID * Allocation)206 FreePagesFromList (
207   IN  VOID  *Allocation
208   )
209 {
210   LIST_ENTRY      *Link;
211   FREE_PAGE_NODE  *Node;
212 
213   if (Allocation == NULL) {
214     return EFI_INVALID_PARAMETER;
215   }
216 
217   for (Link = mPageList.ForwardLink; Link != &mPageList; Link = Link->ForwardLink) {
218     Node = BASE_CR (Link, FREE_PAGE_NODE, Link);
219     if ((UINTN)Node->Allocation == (UINTN)Allocation) {
220       Node->Allocated = FALSE;
221 
222       // Update the size of the freed buffer
223       mFreedBufferSize  += Node->Pages * EFI_PAGE_SIZE;
224 
225       // If the size of the non-allocated reaches the threshold we raise a warning.
226       // It might be an expected behaviour in some cases.
227       // We might device to free some of these buffers later on.
228       if (mFreedBufferSize > PcdGet64 (PcdArmFreeUncachedMemorySizeThreshold)) {
229         DEBUG ((EFI_D_WARN, "Warning: The list of non-allocated buffer has reach the threshold.\n"));
230       }
231       return EFI_SUCCESS;
232     }
233   }
234 
235   return EFI_NOT_FOUND;
236 }
237 
238 /**
239  * This function is automatically invoked when the driver exits
240  * It frees all the non-allocated memory buffer.
241  * This function is not responsible to free allocated buffer (eg: case of memory leak,
242  * runtime allocation).
243  */
244 EFI_STATUS
245 EFIAPI
UncachedMemoryAllocationLibDestructor(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)246 UncachedMemoryAllocationLibDestructor (
247   IN EFI_HANDLE        ImageHandle,
248   IN EFI_SYSTEM_TABLE  *SystemTable
249   )
250 {
251   LIST_ENTRY      *Link;
252   FREE_PAGE_NODE  *OldNode;
253 
254   // Test if the list is empty
255   Link = mPageList.ForwardLink;
256   if (Link == &mPageList) {
257     return EFI_SUCCESS;
258   }
259 
260   // Free all the pages and nodes
261   do {
262     OldNode = BASE_CR (Link, FREE_PAGE_NODE, Link);
263     // Point to the next entry
264     Link = Link->ForwardLink;
265 
266     // We only free the non-allocated buffer
267     if (OldNode->Allocated == FALSE) {
268       gBS->FreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)OldNode->Base, OldNode->Pages);
269       RemoveEntryList (&OldNode->Link);
270       FreePool (OldNode);
271     }
272   } while (Link != &mPageList);
273 
274   return EFI_SUCCESS;
275 }
276 
277 /**
278   Converts a cached or uncached address to a physical address suitable for use in SoC registers.
279 
280   @param  VirtualAddress                 The pointer to convert.
281 
282   @return The physical address of the supplied virtual pointer.
283 
284 **/
285 EFI_PHYSICAL_ADDRESS
ConvertToPhysicalAddress(IN VOID * VirtualAddress)286 ConvertToPhysicalAddress (
287   IN VOID *VirtualAddress
288   )
289 {
290   return (EFI_PHYSICAL_ADDRESS)(UINTN)VirtualAddress;
291 }
292 
293 
294 VOID *
UncachedInternalAllocatePages(IN EFI_MEMORY_TYPE MemoryType,IN UINTN Pages)295 UncachedInternalAllocatePages (
296   IN EFI_MEMORY_TYPE  MemoryType,
297   IN UINTN            Pages
298   )
299 {
300   return UncachedInternalAllocateAlignedPages (MemoryType, Pages, EFI_PAGE_SIZE);
301 }
302 
303 
304 VOID *
305 EFIAPI
UncachedAllocatePages(IN UINTN Pages)306 UncachedAllocatePages (
307   IN UINTN  Pages
308   )
309 {
310   return UncachedInternalAllocatePages (EfiBootServicesData, Pages);
311 }
312 
313 VOID *
314 EFIAPI
UncachedAllocateRuntimePages(IN UINTN Pages)315 UncachedAllocateRuntimePages (
316   IN UINTN  Pages
317   )
318 {
319   return UncachedInternalAllocatePages (EfiRuntimeServicesData, Pages);
320 }
321 
322 VOID *
323 EFIAPI
UncachedAllocateReservedPages(IN UINTN Pages)324 UncachedAllocateReservedPages (
325   IN UINTN  Pages
326   )
327 {
328   return UncachedInternalAllocatePages (EfiReservedMemoryType, Pages);
329 }
330 
331 
332 
333 VOID
334 EFIAPI
UncachedFreePages(IN VOID * Buffer,IN UINTN Pages)335 UncachedFreePages (
336   IN VOID   *Buffer,
337   IN UINTN  Pages
338   )
339 {
340   UncachedFreeAlignedPages (Buffer, Pages);
341   return;
342 }
343 
344 
345 VOID *
UncachedInternalAllocateAlignedPages(IN EFI_MEMORY_TYPE MemoryType,IN UINTN Pages,IN UINTN Alignment)346 UncachedInternalAllocateAlignedPages (
347   IN EFI_MEMORY_TYPE  MemoryType,
348   IN UINTN            Pages,
349   IN UINTN            Alignment
350   )
351 {
352   EFI_STATUS Status;
353   VOID   *Allocation;
354 
355   if (Pages == 0) {
356     return NULL;
357   }
358 
359   Allocation = NULL;
360   Status = AllocatePagesFromList (MemoryType, Pages, Alignment, &Allocation);
361   if (EFI_ERROR (Status)) {
362     ASSERT_EFI_ERROR (Status);
363     return NULL;
364   } else {
365     return Allocation;
366   }
367 }
368 
369 
370 VOID
371 EFIAPI
UncachedFreeAlignedPages(IN VOID * Buffer,IN UINTN Pages)372 UncachedFreeAlignedPages (
373   IN VOID   *Buffer,
374   IN UINTN  Pages
375   )
376 {
377   FreePagesFromList (Buffer);
378 }
379 
380 
381 VOID *
UncachedInternalAllocateAlignedPool(IN EFI_MEMORY_TYPE PoolType,IN UINTN AllocationSize,IN UINTN Alignment)382 UncachedInternalAllocateAlignedPool (
383   IN EFI_MEMORY_TYPE  PoolType,
384   IN UINTN            AllocationSize,
385   IN UINTN            Alignment
386   )
387 {
388   VOID      *AlignedAddress;
389 
390   //
391   // Alignment must be a power of two or zero.
392   //
393   ASSERT ((Alignment & (Alignment - 1)) == 0);
394 
395   if (Alignment < EFI_PAGE_SIZE) {
396     Alignment = EFI_PAGE_SIZE;
397   }
398 
399   AlignedAddress = UncachedInternalAllocateAlignedPages (PoolType, EFI_SIZE_TO_PAGES (AllocationSize), Alignment);
400   if (AlignedAddress == NULL) {
401     return NULL;
402   }
403 
404   return (VOID *) AlignedAddress;
405 }
406 
407 VOID *
408 EFIAPI
UncachedAllocateAlignedPool(IN UINTN AllocationSize,IN UINTN Alignment)409 UncachedAllocateAlignedPool (
410   IN UINTN  AllocationSize,
411   IN UINTN  Alignment
412   )
413 {
414   return UncachedInternalAllocateAlignedPool (EfiBootServicesData, AllocationSize, Alignment);
415 }
416 
417 VOID *
418 EFIAPI
UncachedAllocateAlignedRuntimePool(IN UINTN AllocationSize,IN UINTN Alignment)419 UncachedAllocateAlignedRuntimePool (
420   IN UINTN  AllocationSize,
421   IN UINTN  Alignment
422   )
423 {
424   return UncachedInternalAllocateAlignedPool (EfiRuntimeServicesData, AllocationSize, Alignment);
425 }
426 
427 VOID *
428 EFIAPI
UncachedAllocateAlignedReservedPool(IN UINTN AllocationSize,IN UINTN Alignment)429 UncachedAllocateAlignedReservedPool (
430   IN UINTN  AllocationSize,
431   IN UINTN  Alignment
432   )
433 {
434   return UncachedInternalAllocateAlignedPool (EfiReservedMemoryType, AllocationSize, Alignment);
435 }
436 
437 VOID *
UncachedInternalAllocateAlignedZeroPool(IN EFI_MEMORY_TYPE PoolType,IN UINTN AllocationSize,IN UINTN Alignment)438 UncachedInternalAllocateAlignedZeroPool (
439   IN EFI_MEMORY_TYPE  PoolType,
440   IN UINTN            AllocationSize,
441   IN UINTN            Alignment
442   )
443 {
444   VOID    *Memory;
445   Memory = UncachedInternalAllocateAlignedPool (PoolType, AllocationSize, Alignment);
446   if (Memory != NULL) {
447     Memory = ZeroMem (Memory, AllocationSize);
448   }
449   return Memory;
450 }
451 
452 VOID *
453 EFIAPI
UncachedAllocateAlignedZeroPool(IN UINTN AllocationSize,IN UINTN Alignment)454 UncachedAllocateAlignedZeroPool (
455   IN UINTN  AllocationSize,
456   IN UINTN  Alignment
457   )
458 {
459   return UncachedInternalAllocateAlignedZeroPool (EfiBootServicesData, AllocationSize, Alignment);
460 }
461 
462 VOID *
463 EFIAPI
UncachedAllocateAlignedRuntimeZeroPool(IN UINTN AllocationSize,IN UINTN Alignment)464 UncachedAllocateAlignedRuntimeZeroPool (
465   IN UINTN  AllocationSize,
466   IN UINTN  Alignment
467   )
468 {
469   return UncachedInternalAllocateAlignedZeroPool (EfiRuntimeServicesData, AllocationSize, Alignment);
470 }
471 
472 VOID *
473 EFIAPI
UncachedAllocateAlignedReservedZeroPool(IN UINTN AllocationSize,IN UINTN Alignment)474 UncachedAllocateAlignedReservedZeroPool (
475   IN UINTN  AllocationSize,
476   IN UINTN  Alignment
477   )
478 {
479   return UncachedInternalAllocateAlignedZeroPool (EfiReservedMemoryType, AllocationSize, Alignment);
480 }
481 
482 VOID *
UncachedInternalAllocateAlignedCopyPool(IN EFI_MEMORY_TYPE PoolType,IN UINTN AllocationSize,IN CONST VOID * Buffer,IN UINTN Alignment)483 UncachedInternalAllocateAlignedCopyPool (
484   IN EFI_MEMORY_TYPE  PoolType,
485   IN UINTN            AllocationSize,
486   IN CONST VOID       *Buffer,
487   IN UINTN            Alignment
488   )
489 {
490   VOID  *Memory;
491 
492   ASSERT (Buffer != NULL);
493   ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN) Buffer + 1));
494 
495   Memory = UncachedInternalAllocateAlignedPool (PoolType, AllocationSize, Alignment);
496   if (Memory != NULL) {
497     Memory = CopyMem (Memory, Buffer, AllocationSize);
498   }
499   return Memory;
500 }
501 
502 VOID *
503 EFIAPI
UncachedAllocateAlignedCopyPool(IN UINTN AllocationSize,IN CONST VOID * Buffer,IN UINTN Alignment)504 UncachedAllocateAlignedCopyPool (
505   IN UINTN       AllocationSize,
506   IN CONST VOID  *Buffer,
507   IN UINTN       Alignment
508   )
509 {
510   return UncachedInternalAllocateAlignedCopyPool (EfiBootServicesData, AllocationSize, Buffer, Alignment);
511 }
512 
513 VOID *
514 EFIAPI
UncachedAllocateAlignedRuntimeCopyPool(IN UINTN AllocationSize,IN CONST VOID * Buffer,IN UINTN Alignment)515 UncachedAllocateAlignedRuntimeCopyPool (
516   IN UINTN       AllocationSize,
517   IN CONST VOID  *Buffer,
518   IN UINTN       Alignment
519   )
520 {
521   return UncachedInternalAllocateAlignedCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer, Alignment);
522 }
523 
524 VOID *
525 EFIAPI
UncachedAllocateAlignedReservedCopyPool(IN UINTN AllocationSize,IN CONST VOID * Buffer,IN UINTN Alignment)526 UncachedAllocateAlignedReservedCopyPool (
527   IN UINTN       AllocationSize,
528   IN CONST VOID  *Buffer,
529   IN UINTN       Alignment
530   )
531 {
532   return UncachedInternalAllocateAlignedCopyPool (EfiReservedMemoryType, AllocationSize, Buffer, Alignment);
533 }
534 
535 VOID
536 EFIAPI
UncachedFreeAlignedPool(IN VOID * Allocation)537 UncachedFreeAlignedPool (
538   IN VOID   *Allocation
539   )
540 {
541   UncachedFreePages (Allocation, 0);
542 }
543 
544 VOID *
UncachedInternalAllocatePool(IN EFI_MEMORY_TYPE MemoryType,IN UINTN AllocationSize)545 UncachedInternalAllocatePool (
546   IN EFI_MEMORY_TYPE  MemoryType,
547   IN UINTN            AllocationSize
548   )
549 {
550   UINTN CacheLineLength = ArmDataCacheLineLength ();
551   return UncachedInternalAllocateAlignedPool (MemoryType, AllocationSize, CacheLineLength);
552 }
553 
554 VOID *
555 EFIAPI
UncachedAllocatePool(IN UINTN AllocationSize)556 UncachedAllocatePool (
557   IN UINTN  AllocationSize
558   )
559 {
560   return UncachedInternalAllocatePool (EfiBootServicesData, AllocationSize);
561 }
562 
563 VOID *
564 EFIAPI
UncachedAllocateRuntimePool(IN UINTN AllocationSize)565 UncachedAllocateRuntimePool (
566   IN UINTN  AllocationSize
567   )
568 {
569   return UncachedInternalAllocatePool (EfiRuntimeServicesData, AllocationSize);
570 }
571 
572 VOID *
573 EFIAPI
UncachedAllocateReservedPool(IN UINTN AllocationSize)574 UncachedAllocateReservedPool (
575   IN UINTN  AllocationSize
576   )
577 {
578   return UncachedInternalAllocatePool (EfiReservedMemoryType, AllocationSize);
579 }
580 
581 VOID *
UncachedInternalAllocateZeroPool(IN EFI_MEMORY_TYPE PoolType,IN UINTN AllocationSize)582 UncachedInternalAllocateZeroPool (
583   IN EFI_MEMORY_TYPE  PoolType,
584   IN UINTN            AllocationSize
585   )
586 {
587   VOID  *Memory;
588 
589   Memory = UncachedInternalAllocatePool (PoolType, AllocationSize);
590   if (Memory != NULL) {
591     Memory = ZeroMem (Memory, AllocationSize);
592   }
593   return Memory;
594 }
595 
596 VOID *
597 EFIAPI
UncachedAllocateZeroPool(IN UINTN AllocationSize)598 UncachedAllocateZeroPool (
599   IN UINTN  AllocationSize
600   )
601 {
602   return UncachedInternalAllocateZeroPool (EfiBootServicesData, AllocationSize);
603 }
604 
605 VOID *
606 EFIAPI
UncachedAllocateRuntimeZeroPool(IN UINTN AllocationSize)607 UncachedAllocateRuntimeZeroPool (
608   IN UINTN  AllocationSize
609   )
610 {
611   return UncachedInternalAllocateZeroPool (EfiRuntimeServicesData, AllocationSize);
612 }
613 
614 VOID *
615 EFIAPI
UncachedAllocateReservedZeroPool(IN UINTN AllocationSize)616 UncachedAllocateReservedZeroPool (
617   IN UINTN  AllocationSize
618   )
619 {
620   return UncachedInternalAllocateZeroPool (EfiReservedMemoryType, AllocationSize);
621 }
622 
623 VOID *
UncachedInternalAllocateCopyPool(IN EFI_MEMORY_TYPE PoolType,IN UINTN AllocationSize,IN CONST VOID * Buffer)624 UncachedInternalAllocateCopyPool (
625   IN EFI_MEMORY_TYPE  PoolType,
626   IN UINTN            AllocationSize,
627   IN CONST VOID       *Buffer
628   )
629 {
630   VOID  *Memory;
631 
632   ASSERT (Buffer != NULL);
633   ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN) Buffer + 1));
634 
635   Memory = UncachedInternalAllocatePool (PoolType, AllocationSize);
636   if (Memory != NULL) {
637      Memory = CopyMem (Memory, Buffer, AllocationSize);
638   }
639   return Memory;
640 }
641 
642 VOID *
643 EFIAPI
UncachedAllocateCopyPool(IN UINTN AllocationSize,IN CONST VOID * Buffer)644 UncachedAllocateCopyPool (
645   IN UINTN       AllocationSize,
646   IN CONST VOID  *Buffer
647   )
648 {
649   return UncachedInternalAllocateCopyPool (EfiBootServicesData, AllocationSize, Buffer);
650 }
651 
652 VOID *
653 EFIAPI
UncachedAllocateRuntimeCopyPool(IN UINTN AllocationSize,IN CONST VOID * Buffer)654 UncachedAllocateRuntimeCopyPool (
655   IN UINTN       AllocationSize,
656   IN CONST VOID  *Buffer
657   )
658 {
659   return UncachedInternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer);
660 }
661 
662 VOID *
663 EFIAPI
UncachedAllocateReservedCopyPool(IN UINTN AllocationSize,IN CONST VOID * Buffer)664 UncachedAllocateReservedCopyPool (
665   IN UINTN       AllocationSize,
666   IN CONST VOID  *Buffer
667   )
668 {
669   return UncachedInternalAllocateCopyPool (EfiReservedMemoryType, AllocationSize, Buffer);
670 }
671 
672 VOID
673 EFIAPI
UncachedFreePool(IN VOID * Buffer)674 UncachedFreePool (
675   IN VOID   *Buffer
676   )
677 {
678   UncachedFreeAlignedPool (Buffer);
679 }
680 
681 VOID
682 EFIAPI
UncachedSafeFreePool(IN VOID * Buffer)683 UncachedSafeFreePool (
684   IN VOID   *Buffer
685   )
686 {
687   if (Buffer != NULL) {
688     UncachedFreePool (Buffer);
689     Buffer = NULL;
690   }
691 }
692 
693