1 /** @file
2   Debug version of the UncachedMemoryAllocation lib that uses the VirtualUncachedPages
3   protocol, produced by the DXE CPU driver, to produce debuggable uncached memory buffers.
4 
5   The DMA rules for EFI contain the concept of a PCI (DMA master) address for memory and
6   a CPU (C code) address for the memory buffer that don't have to be the same.  There seem to
7   be common errors out there with folks mixing up the two addresses.  This library causes
8   the PCI (DMA master) address to not be mapped into system memory so if the CPU (C code)
9   uses the wrong pointer it will generate a page fault. The CPU (C code) version of the buffer
10   has a virtual address that does not match the physical address. The virtual address has
11   PcdArmUncachedMemoryMask ored into the physical address.
12 
13   Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
14 
15   This program and the accompanying materials
16   are licensed and made available under the terms and conditions of the BSD License
17   which accompanies this distribution.  The full text of the license may be found at
18   http://opensource.org/licenses/bsd-license.php
19 
20   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
21   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
22 
23 **/
24 
25 #include <Base.h>
26 #include <Library/BaseLib.h>
27 #include <Library/BaseMemoryLib.h>
28 #include <Library/MemoryAllocationLib.h>
29 #include <Library/DebugLib.h>
30 #include <Library/UefiBootServicesTableLib.h>
31 #include <Library/UncachedMemoryAllocationLib.h>
32 #include <Library/PcdLib.h>
33 #include <Library/ArmLib.h>
34 
35 #include <Protocol/Cpu.h>
36 #include <Protocol/VirtualUncachedPages.h>
37 
38 VOID *
39 UncachedInternalAllocatePages (
40   IN EFI_MEMORY_TYPE  MemoryType,
41   IN UINTN            Pages
42   );
43 
44 VOID *
45 UncachedInternalAllocateAlignedPages (
46   IN EFI_MEMORY_TYPE  MemoryType,
47   IN UINTN            Pages,
48   IN UINTN            Alignment
49   );
50 
51 
52 
53 EFI_CPU_ARCH_PROTOCOL           *gDebugUncachedCpu;
54 VIRTUAL_UNCACHED_PAGES_PROTOCOL *gVirtualUncachedPages;
55 
56 //
57 // Assume all of memory has the same cache attributes, unless we do our magic
58 //
59 UINT64  gAttributes;
60 
61 typedef struct {
62   VOID        *Buffer;
63   VOID        *Allocation;
64   UINTN       Pages;
65   LIST_ENTRY  Link;
66 } FREE_PAGE_NODE;
67 
68 LIST_ENTRY  mPageList = INITIALIZE_LIST_HEAD_VARIABLE (mPageList);
69 
70 VOID
AddPagesToList(IN VOID * Buffer,IN VOID * Allocation,UINTN Pages)71 AddPagesToList (
72   IN VOID   *Buffer,
73   IN VOID   *Allocation,
74   UINTN     Pages
75   )
76 {
77   FREE_PAGE_NODE  *NewNode;
78 
79   NewNode = AllocatePool (sizeof (LIST_ENTRY));
80   if (NewNode == NULL) {
81     ASSERT (FALSE);
82     return;
83   }
84 
85   NewNode->Buffer     = Buffer;
86   NewNode->Allocation = Allocation;
87   NewNode->Pages      = Pages;
88 
89   InsertTailList (&mPageList, &NewNode->Link);
90 }
91 
92 
93 VOID
RemovePagesFromList(IN VOID * Buffer,OUT VOID ** Allocation,OUT UINTN * Pages)94 RemovePagesFromList (
95   IN VOID   *Buffer,
96   OUT VOID  **Allocation,
97   OUT UINTN *Pages
98   )
99 {
100   LIST_ENTRY      *Link;
101   FREE_PAGE_NODE  *OldNode;
102 
103   *Allocation = NULL;
104   *Pages = 0;
105 
106   for (Link = mPageList.ForwardLink; Link != &mPageList; Link = Link->ForwardLink) {
107     OldNode = BASE_CR (Link, FREE_PAGE_NODE, Link);
108     if (OldNode->Buffer == Buffer) {
109       *Allocation = OldNode->Allocation;
110       *Pages = OldNode->Pages;
111 
112       RemoveEntryList (&OldNode->Link);
113       FreePool (OldNode);
114       return;
115     }
116   }
117 
118   return;
119 }
120 
121 
122 
123 EFI_PHYSICAL_ADDRESS
ConvertToPhysicalAddress(IN VOID * VirtualAddress)124 ConvertToPhysicalAddress (
125   IN VOID *VirtualAddress
126   )
127 {
128   UINTN UncachedMemoryMask = (UINTN)PcdGet64 (PcdArmUncachedMemoryMask);
129   UINTN PhysicalAddress;
130 
131   PhysicalAddress = (UINTN)VirtualAddress & ~UncachedMemoryMask;
132 
133   return (EFI_PHYSICAL_ADDRESS)PhysicalAddress;
134 }
135 
136 
137 VOID *
ConvertToUncachedAddress(IN VOID * Address)138 ConvertToUncachedAddress (
139   IN VOID *Address
140   )
141 {
142   UINTN UncachedMemoryMask = (UINTN)PcdGet64 (PcdArmUncachedMemoryMask);
143   UINTN UncachedAddress;
144 
145   UncachedAddress = (UINTN)Address | UncachedMemoryMask;
146 
147   return (VOID *)UncachedAddress;
148 }
149 
150 
151 
152 VOID *
UncachedInternalAllocatePages(IN EFI_MEMORY_TYPE MemoryType,IN UINTN Pages)153 UncachedInternalAllocatePages (
154   IN EFI_MEMORY_TYPE  MemoryType,
155   IN UINTN            Pages
156   )
157 {
158   return UncachedInternalAllocateAlignedPages (MemoryType, Pages, EFI_PAGE_SIZE);
159 }
160 
161 
162 VOID *
163 EFIAPI
UncachedAllocatePages(IN UINTN Pages)164 UncachedAllocatePages (
165   IN UINTN  Pages
166   )
167 {
168   return UncachedInternalAllocatePages (EfiBootServicesData, Pages);
169 }
170 
171 VOID *
172 EFIAPI
UncachedAllocateRuntimePages(IN UINTN Pages)173 UncachedAllocateRuntimePages (
174   IN UINTN  Pages
175   )
176 {
177   return UncachedInternalAllocatePages (EfiRuntimeServicesData, Pages);
178 }
179 
180 VOID *
181 EFIAPI
UncachedAllocateReservedPages(IN UINTN Pages)182 UncachedAllocateReservedPages (
183   IN UINTN  Pages
184   )
185 {
186   return UncachedInternalAllocatePages (EfiReservedMemoryType, Pages);
187 }
188 
189 
190 
191 VOID
192 EFIAPI
UncachedFreePages(IN VOID * Buffer,IN UINTN Pages)193 UncachedFreePages (
194   IN VOID   *Buffer,
195   IN UINTN  Pages
196   )
197 {
198   UncachedFreeAlignedPages (Buffer, Pages);
199   return;
200 }
201 
202 
203 VOID *
UncachedInternalAllocateAlignedPages(IN EFI_MEMORY_TYPE MemoryType,IN UINTN Pages,IN UINTN Alignment)204 UncachedInternalAllocateAlignedPages (
205   IN EFI_MEMORY_TYPE  MemoryType,
206   IN UINTN            Pages,
207   IN UINTN            Alignment
208   )
209 {
210   EFI_STATUS            Status;
211   EFI_PHYSICAL_ADDRESS  Memory;
212   EFI_PHYSICAL_ADDRESS  AlignedMemory;
213   UINTN                 AlignmentMask;
214   UINTN                 UnalignedPages;
215   UINTN                 RealPages;
216 
217   //
218   // Alignment must be a power of two or zero.
219   //
220   ASSERT ((Alignment & (Alignment - 1)) == 0);
221 
222   if (Pages == 0) {
223     return NULL;
224   }
225   if (Alignment > EFI_PAGE_SIZE) {
226     //
227     // Caculate the total number of pages since alignment is larger than page size.
228     //
229     AlignmentMask  = Alignment - 1;
230     RealPages      = Pages + EFI_SIZE_TO_PAGES (Alignment);
231     //
232     // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow.
233     //
234     ASSERT (RealPages > Pages);
235 
236     Status         = gBS->AllocatePages (AllocateAnyPages, MemoryType, RealPages, &Memory);
237     if (EFI_ERROR (Status)) {
238       return NULL;
239     }
240     AlignedMemory  = ((UINTN) Memory + AlignmentMask) & ~AlignmentMask;
241     UnalignedPages = EFI_SIZE_TO_PAGES (AlignedMemory - (UINTN) Memory);
242     if (UnalignedPages > 0) {
243       //
244       // Free first unaligned page(s).
245       //
246       Status = gBS->FreePages (Memory, UnalignedPages);
247       ASSERT_EFI_ERROR (Status);
248     }
249     Memory         = (EFI_PHYSICAL_ADDRESS) (AlignedMemory + EFI_PAGES_TO_SIZE (Pages));
250     UnalignedPages = RealPages - Pages - UnalignedPages;
251     if (UnalignedPages > 0) {
252       //
253       // Free last unaligned page(s).
254       //
255       Status = gBS->FreePages (Memory, UnalignedPages);
256       ASSERT_EFI_ERROR (Status);
257     }
258   } else {
259     //
260     // Do not over-allocate pages in this case.
261     //
262     Status = gBS->AllocatePages (AllocateAnyPages, MemoryType, Pages, &Memory);
263     if (EFI_ERROR (Status)) {
264       return NULL;
265     }
266     AlignedMemory  = (UINTN) Memory;
267   }
268 
269   Status = gVirtualUncachedPages->ConvertPages (gVirtualUncachedPages, AlignedMemory, Pages * EFI_PAGE_SIZE, PcdGet64 (PcdArmUncachedMemoryMask), &gAttributes);
270   if (EFI_ERROR (Status)) {
271     return NULL;
272   }
273 
274   AlignedMemory = (EFI_PHYSICAL_ADDRESS)(UINTN)ConvertToUncachedAddress ((VOID *)(UINTN)AlignedMemory);
275 
276   return (VOID *)(UINTN)AlignedMemory;
277 }
278 
279 
280 VOID
281 EFIAPI
UncachedFreeAlignedPages(IN VOID * Buffer,IN UINTN Pages)282 UncachedFreeAlignedPages (
283   IN VOID   *Buffer,
284   IN UINTN  Pages
285   )
286 {
287   EFI_STATUS            Status;
288   EFI_PHYSICAL_ADDRESS  Memory;
289 
290   ASSERT (Pages != 0);
291 
292   Memory = ConvertToPhysicalAddress (Buffer);
293 
294   Status = gVirtualUncachedPages->RevertPages (gVirtualUncachedPages, Memory, Pages * EFI_PAGE_SIZE, PcdGet64 (PcdArmUncachedMemoryMask), gAttributes);
295 
296 
297   Status = gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) Memory, Pages);
298   ASSERT_EFI_ERROR (Status);
299 }
300 
301 
302 
303 
304 VOID *
UncachedInternalAllocateAlignedPool(IN EFI_MEMORY_TYPE PoolType,IN UINTN AllocationSize,IN UINTN Alignment)305 UncachedInternalAllocateAlignedPool (
306   IN EFI_MEMORY_TYPE  PoolType,
307   IN UINTN            AllocationSize,
308   IN UINTN            Alignment
309   )
310 {
311   VOID      *AlignedAddress;
312 
313   //
314   // Alignment must be a power of two or zero.
315   //
316   ASSERT ((Alignment & (Alignment - 1)) == 0);
317 
318   if (Alignment < EFI_PAGE_SIZE) {
319     Alignment = EFI_PAGE_SIZE;
320   }
321 
322   AlignedAddress = UncachedInternalAllocateAlignedPages (PoolType, EFI_SIZE_TO_PAGES (AllocationSize), Alignment);
323   if (AlignedAddress == NULL) {
324     return NULL;
325   }
326 
327   AddPagesToList ((VOID *)(UINTN)ConvertToPhysicalAddress (AlignedAddress), (VOID *)(UINTN)AlignedAddress, EFI_SIZE_TO_PAGES (AllocationSize));
328 
329   return (VOID *) AlignedAddress;
330 }
331 
332 VOID *
333 EFIAPI
UncachedAllocateAlignedPool(IN UINTN AllocationSize,IN UINTN Alignment)334 UncachedAllocateAlignedPool (
335   IN UINTN  AllocationSize,
336   IN UINTN  Alignment
337   )
338 {
339   return UncachedInternalAllocateAlignedPool (EfiBootServicesData, AllocationSize, Alignment);
340 }
341 
342 VOID *
343 EFIAPI
UncachedAllocateAlignedRuntimePool(IN UINTN AllocationSize,IN UINTN Alignment)344 UncachedAllocateAlignedRuntimePool (
345   IN UINTN  AllocationSize,
346   IN UINTN  Alignment
347   )
348 {
349   return UncachedInternalAllocateAlignedPool (EfiRuntimeServicesData, AllocationSize, Alignment);
350 }
351 
352 VOID *
353 EFIAPI
UncachedAllocateAlignedReservedPool(IN UINTN AllocationSize,IN UINTN Alignment)354 UncachedAllocateAlignedReservedPool (
355   IN UINTN  AllocationSize,
356   IN UINTN  Alignment
357   )
358 {
359   return UncachedInternalAllocateAlignedPool (EfiReservedMemoryType, AllocationSize, Alignment);
360 }
361 
362 VOID *
UncachedInternalAllocateAlignedZeroPool(IN EFI_MEMORY_TYPE PoolType,IN UINTN AllocationSize,IN UINTN Alignment)363 UncachedInternalAllocateAlignedZeroPool (
364   IN EFI_MEMORY_TYPE  PoolType,
365   IN UINTN            AllocationSize,
366   IN UINTN            Alignment
367   )
368 {
369   VOID    *Memory;
370   Memory = UncachedInternalAllocateAlignedPool (PoolType, AllocationSize, Alignment);
371   if (Memory != NULL) {
372     Memory = ZeroMem (Memory, AllocationSize);
373   }
374   return Memory;
375 }
376 
377 VOID *
378 EFIAPI
UncachedAllocateAlignedZeroPool(IN UINTN AllocationSize,IN UINTN Alignment)379 UncachedAllocateAlignedZeroPool (
380   IN UINTN  AllocationSize,
381   IN UINTN  Alignment
382   )
383 {
384   return UncachedInternalAllocateAlignedZeroPool (EfiBootServicesData, AllocationSize, Alignment);
385 }
386 
387 VOID *
388 EFIAPI
UncachedAllocateAlignedRuntimeZeroPool(IN UINTN AllocationSize,IN UINTN Alignment)389 UncachedAllocateAlignedRuntimeZeroPool (
390   IN UINTN  AllocationSize,
391   IN UINTN  Alignment
392   )
393 {
394   return UncachedInternalAllocateAlignedZeroPool (EfiRuntimeServicesData, AllocationSize, Alignment);
395 }
396 
397 VOID *
398 EFIAPI
UncachedAllocateAlignedReservedZeroPool(IN UINTN AllocationSize,IN UINTN Alignment)399 UncachedAllocateAlignedReservedZeroPool (
400   IN UINTN  AllocationSize,
401   IN UINTN  Alignment
402   )
403 {
404   return UncachedInternalAllocateAlignedZeroPool (EfiReservedMemoryType, AllocationSize, Alignment);
405 }
406 
407 VOID *
UncachedInternalAllocateAlignedCopyPool(IN EFI_MEMORY_TYPE PoolType,IN UINTN AllocationSize,IN CONST VOID * Buffer,IN UINTN Alignment)408 UncachedInternalAllocateAlignedCopyPool (
409   IN EFI_MEMORY_TYPE  PoolType,
410   IN UINTN            AllocationSize,
411   IN CONST VOID       *Buffer,
412   IN UINTN            Alignment
413   )
414 {
415   VOID  *Memory;
416 
417   ASSERT (Buffer != NULL);
418   ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN) Buffer + 1));
419 
420   Memory = UncachedInternalAllocateAlignedPool (PoolType, AllocationSize, Alignment);
421   if (Memory != NULL) {
422     Memory = CopyMem (Memory, Buffer, AllocationSize);
423   }
424   return Memory;
425 }
426 
427 VOID *
428 EFIAPI
UncachedAllocateAlignedCopyPool(IN UINTN AllocationSize,IN CONST VOID * Buffer,IN UINTN Alignment)429 UncachedAllocateAlignedCopyPool (
430   IN UINTN       AllocationSize,
431   IN CONST VOID  *Buffer,
432   IN UINTN       Alignment
433   )
434 {
435   return UncachedInternalAllocateAlignedCopyPool (EfiBootServicesData, AllocationSize, Buffer, Alignment);
436 }
437 
438 VOID *
439 EFIAPI
UncachedAllocateAlignedRuntimeCopyPool(IN UINTN AllocationSize,IN CONST VOID * Buffer,IN UINTN Alignment)440 UncachedAllocateAlignedRuntimeCopyPool (
441   IN UINTN       AllocationSize,
442   IN CONST VOID  *Buffer,
443   IN UINTN       Alignment
444   )
445 {
446   return UncachedInternalAllocateAlignedCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer, Alignment);
447 }
448 
449 VOID *
450 EFIAPI
UncachedAllocateAlignedReservedCopyPool(IN UINTN AllocationSize,IN CONST VOID * Buffer,IN UINTN Alignment)451 UncachedAllocateAlignedReservedCopyPool (
452   IN UINTN       AllocationSize,
453   IN CONST VOID  *Buffer,
454   IN UINTN       Alignment
455   )
456 {
457   return UncachedInternalAllocateAlignedCopyPool (EfiReservedMemoryType, AllocationSize, Buffer, Alignment);
458 }
459 
460 VOID
461 EFIAPI
UncachedFreeAlignedPool(IN VOID * Buffer)462 UncachedFreeAlignedPool (
463   IN VOID   *Buffer
464   )
465 {
466   VOID    *Allocation;
467   UINTN   Pages;
468 
469   RemovePagesFromList (Buffer, &Allocation, &Pages);
470 
471   UncachedFreePages (Allocation, Pages);
472 }
473 
474 VOID *
UncachedInternalAllocatePool(IN EFI_MEMORY_TYPE MemoryType,IN UINTN AllocationSize)475 UncachedInternalAllocatePool (
476   IN EFI_MEMORY_TYPE  MemoryType,
477   IN UINTN            AllocationSize
478   )
479 {
480   UINTN CacheLineLength = ArmDataCacheLineLength ();
481   return UncachedInternalAllocateAlignedPool (MemoryType, AllocationSize, CacheLineLength);
482 }
483 
484 VOID *
485 EFIAPI
UncachedAllocatePool(IN UINTN AllocationSize)486 UncachedAllocatePool (
487   IN UINTN  AllocationSize
488   )
489 {
490   return UncachedInternalAllocatePool (EfiBootServicesData, AllocationSize);
491 }
492 
493 VOID *
494 EFIAPI
UncachedAllocateRuntimePool(IN UINTN AllocationSize)495 UncachedAllocateRuntimePool (
496   IN UINTN  AllocationSize
497   )
498 {
499   return UncachedInternalAllocatePool (EfiRuntimeServicesData, AllocationSize);
500 }
501 
502 VOID *
503 EFIAPI
UncachedAllocateReservedPool(IN UINTN AllocationSize)504 UncachedAllocateReservedPool (
505   IN UINTN  AllocationSize
506   )
507 {
508   return UncachedInternalAllocatePool (EfiReservedMemoryType, AllocationSize);
509 }
510 
511 VOID *
UncachedInternalAllocateZeroPool(IN EFI_MEMORY_TYPE PoolType,IN UINTN AllocationSize)512 UncachedInternalAllocateZeroPool (
513   IN EFI_MEMORY_TYPE  PoolType,
514   IN UINTN            AllocationSize
515   )
516 {
517   VOID  *Memory;
518 
519   Memory = UncachedInternalAllocatePool (PoolType, AllocationSize);
520   if (Memory != NULL) {
521     Memory = ZeroMem (Memory, AllocationSize);
522   }
523   return Memory;
524 }
525 
526 VOID *
527 EFIAPI
UncachedAllocateZeroPool(IN UINTN AllocationSize)528 UncachedAllocateZeroPool (
529   IN UINTN  AllocationSize
530   )
531 {
532   return UncachedInternalAllocateZeroPool (EfiBootServicesData, AllocationSize);
533 }
534 
535 VOID *
536 EFIAPI
UncachedAllocateRuntimeZeroPool(IN UINTN AllocationSize)537 UncachedAllocateRuntimeZeroPool (
538   IN UINTN  AllocationSize
539   )
540 {
541   return UncachedInternalAllocateZeroPool (EfiRuntimeServicesData, AllocationSize);
542 }
543 
544 VOID *
545 EFIAPI
UncachedAllocateReservedZeroPool(IN UINTN AllocationSize)546 UncachedAllocateReservedZeroPool (
547   IN UINTN  AllocationSize
548   )
549 {
550   return UncachedInternalAllocateZeroPool (EfiReservedMemoryType, AllocationSize);
551 }
552 
553 VOID *
UncachedInternalAllocateCopyPool(IN EFI_MEMORY_TYPE PoolType,IN UINTN AllocationSize,IN CONST VOID * Buffer)554 UncachedInternalAllocateCopyPool (
555   IN EFI_MEMORY_TYPE  PoolType,
556   IN UINTN            AllocationSize,
557   IN CONST VOID       *Buffer
558   )
559 {
560   VOID  *Memory;
561 
562   ASSERT (Buffer != NULL);
563   ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN) Buffer + 1));
564 
565   Memory = UncachedInternalAllocatePool (PoolType, AllocationSize);
566   if (Memory != NULL) {
567      Memory = CopyMem (Memory, Buffer, AllocationSize);
568   }
569   return Memory;
570 }
571 
572 VOID *
573 EFIAPI
UncachedAllocateCopyPool(IN UINTN AllocationSize,IN CONST VOID * Buffer)574 UncachedAllocateCopyPool (
575   IN UINTN       AllocationSize,
576   IN CONST VOID  *Buffer
577   )
578 {
579   return UncachedInternalAllocateCopyPool (EfiBootServicesData, AllocationSize, Buffer);
580 }
581 
582 VOID *
583 EFIAPI
UncachedAllocateRuntimeCopyPool(IN UINTN AllocationSize,IN CONST VOID * Buffer)584 UncachedAllocateRuntimeCopyPool (
585   IN UINTN       AllocationSize,
586   IN CONST VOID  *Buffer
587   )
588 {
589   return UncachedInternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer);
590 }
591 
592 VOID *
593 EFIAPI
UncachedAllocateReservedCopyPool(IN UINTN AllocationSize,IN CONST VOID * Buffer)594 UncachedAllocateReservedCopyPool (
595   IN UINTN       AllocationSize,
596   IN CONST VOID  *Buffer
597   )
598 {
599   return UncachedInternalAllocateCopyPool (EfiReservedMemoryType, AllocationSize, Buffer);
600 }
601 
602 VOID
603 EFIAPI
UncachedFreePool(IN VOID * Buffer)604 UncachedFreePool (
605   IN VOID   *Buffer
606   )
607 {
608   UncachedFreeAlignedPool (Buffer);
609 }
610 
611 VOID
612 EFIAPI
UncachedSafeFreePool(IN VOID * Buffer)613 UncachedSafeFreePool (
614   IN VOID   *Buffer
615   )
616 {
617   if (Buffer != NULL) {
618     UncachedFreePool (Buffer);
619     Buffer = NULL;
620   }
621 }
622 
623 /**
624   The constructor function caches the pointer of DXE Services Table.
625 
626   The constructor function caches the pointer of DXE Services Table.
627   It will ASSERT() if that operation fails.
628   It will ASSERT() if the pointer of DXE Services Table is NULL.
629   It will always return EFI_SUCCESS.
630 
631   @param  ImageHandle   The firmware allocated handle for the EFI image.
632   @param  SystemTable   A pointer to the EFI System Table.
633 
634   @retval EFI_SUCCESS   The constructor always returns EFI_SUCCESS.
635 
636 **/
637 EFI_STATUS
638 EFIAPI
DebugUncachedMemoryAllocationLibConstructor(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)639 DebugUncachedMemoryAllocationLibConstructor (
640   IN EFI_HANDLE        ImageHandle,
641   IN EFI_SYSTEM_TABLE  *SystemTable
642   )
643 {
644   EFI_STATUS    Status;
645 
646   Status = gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID **)&gDebugUncachedCpu);
647   ASSERT_EFI_ERROR(Status);
648 
649   Status = gBS->LocateProtocol (&gVirtualUncachedPagesProtocolGuid, NULL, (VOID **)&gVirtualUncachedPages);
650   ASSERT_EFI_ERROR(Status);
651 
652   return Status;
653 }
654 
655 
656 
657