Adding a Debug version of the UncachedMemoryAllocationLib that will make the PCI...
authorAJFISH <AJFISH@6f19259b-4bc3-4df7-8a09-765794883524>
Wed, 13 Jan 2010 15:18:34 +0000 (15:18 +0000)
committerAJFISH <AJFISH@6f19259b-4bc3-4df7-8a09-765794883524>
Wed, 13 Jan 2010 15:18:34 +0000 (15:18 +0000)
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@9725 6f19259b-4bc3-4df7-8a09-765794883524

ArmPkg/ArmPkg.dsc
ArmPkg/Library/DebugUncachedMemoryAllocationLib/DebugUncachedMemoryAllocationLib.c [new file with mode: 0644]
ArmPkg/Library/DebugUncachedMemoryAllocationLib/DebugUncachedMemoryAllocationLib.inf [new file with mode: 0644]

index e73d770..7cd6018 100644 (file)
@@ -80,6 +80,7 @@
   ArmPkg/Library/SemiHostingSerialPortLib/SemiHostingSerialPortLib.inf
   ArmPkg/Library/SemihostLib/SemihostLib.inf
   ArmPkg/Library/UncachedMemoryAllocationLib/UncachedMemoryAllocationLib.inf
+  ArmPkg/Library/DebugUncachedMemoryAllocationLib/DebugUncachedMemoryAllocationLib.inf
 
   ArmPkg/Drivers/CpuDxe/CpuDxe.inf
   ArmPkg/Drivers/DebugSupportDxe/DebugSupportDxe.inf
diff --git a/ArmPkg/Library/DebugUncachedMemoryAllocationLib/DebugUncachedMemoryAllocationLib.c b/ArmPkg/Library/DebugUncachedMemoryAllocationLib/DebugUncachedMemoryAllocationLib.c
new file mode 100644 (file)
index 0000000..b4c1c5f
--- /dev/null
@@ -0,0 +1,654 @@
+/** @file\r
+  Debug version of the UncachedMemoryAllocation lib that uses the VirtualUncachedPages\r
+  protocol, produced by the DXE CPU driver, to produce debuggable uncached memory buffers.\r
+  \r
+  The DMA rules for EFI contain the concept of a PCI (DMA master) address for memory and\r
+  a CPU (C code) address for the memory buffer that don't have to be the same.  There seem to\r
+  be common errors out there with folks mixing up the two addresses.  This library causes\r
+  the PCI (DMA master) address to not be mapped into system memory so if the CPU (C code)\r
+  uses the wrong pointer it will generate a page fault. The CPU (C code) version of the buffer\r
+  has a virtual address that does not match the physical address. The virtual address has\r
+  PcdArmUncachedMemoryMask ored into the physical address.\r
+\r
+  Copyright (c) 2008-2010, Apple Inc. All rights reserved.\r
+  \r
+  All rights reserved. This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/UncachedMemoryAllocationLib.h>\r
+#include <Library/PcdLib.h>\r
+#include <Library/ArmLib.h>\r
+\r
+#include <Protocol/Cpu.h>\r
+#include <Protocol/VirtualUncachedPages.h>\r
+\r
+VOID *\r
+UncachedInternalAllocatePages (\r
+  IN EFI_MEMORY_TYPE  MemoryType,  \r
+  IN UINTN            Pages\r
+  );\r
+\r
+VOID *\r
+UncachedInternalAllocateAlignedPages (\r
+  IN EFI_MEMORY_TYPE  MemoryType,  \r
+  IN UINTN            Pages,\r
+  IN UINTN            Alignment\r
+  );\r
+  \r
+  \r
+\r
+EFI_CPU_ARCH_PROTOCOL           *gCpu;\r
+VIRTUAL_UNCACHED_PAGES_PROTOCOL *gVirtualUncachedPages;\r
+\r
+//\r
+// Assume all of memory has the same cache attributes, unless we do our magic\r
+//\r
+UINT64  gAttributes;\r
+\r
+typedef struct {\r
+  VOID        *Buffer;\r
+  VOID        *Allocation;\r
+  UINTN       Pages;\r
+  LIST_ENTRY  Link;\r
+} FREE_PAGE_NODE;\r
+\r
+LIST_ENTRY  mPageList = INITIALIZE_LIST_HEAD_VARIABLE (mPageList);\r
+\r
+VOID\r
+AddPagesToList (\r
+  IN VOID   *Buffer,\r
+  IN VOID   *Allocation,\r
+  UINTN     Pages\r
+  )\r
+{\r
+  FREE_PAGE_NODE  *NewNode;\r
+  \r
+  NewNode = AllocatePool (sizeof (LIST_ENTRY));\r
+  if (NewNode == NULL) {\r
+    ASSERT (FALSE);\r
+    return;\r
+  }\r
+  \r
+  NewNode->Buffer     = Buffer;\r
+  NewNode->Allocation = Allocation;\r
+  \r
+  InsertTailList (&mPageList, &NewNode->Link);\r
+}\r
+\r
+\r
+VOID\r
+RemovePagesFromList (\r
+  IN VOID   *Buffer,\r
+  OUT VOID  **Allocation,\r
+  OUT UINTN *Pages\r
+  )\r
+{\r
+  LIST_ENTRY      *Link;\r
+  FREE_PAGE_NODE  *OldNode;\r
+\r
+  *Allocation = NULL;\r
+  *Pages = 0;\r
+  \r
+  for (Link = mPageList.ForwardLink; Link != &mPageList; Link = Link->ForwardLink) {\r
+    OldNode = BASE_CR (Link, FREE_PAGE_NODE, Link);\r
+    if (OldNode->Buffer == Buffer) {\r
+      *Allocation = OldNode->Allocation;\r
+      *Pages = OldNode->Pages;\r
+      \r
+      RemoveEntryList (&OldNode->Link);\r
+      FreePool (OldNode);\r
+      return;\r
+    }\r
+  }\r
+\r
+  return;\r
+}\r
+\r
+\r
+\r
+EFI_PHYSICAL_ADDRESS\r
+ConvertToPhysicalAddress (\r
+  IN VOID *VirtualAddress\r
+  )\r
+{\r
+  UINTN UncachedMemoryMask = (UINTN)PcdGet64 (PcdArmUncachedMemoryMask);\r
+  UINTN PhysicalAddress;\r
+  \r
+  PhysicalAddress = (UINTN)VirtualAddress & ~UncachedMemoryMask;\r
+  \r
+  return (EFI_PHYSICAL_ADDRESS)PhysicalAddress;\r
+}\r
+\r
+\r
+VOID *\r
+ConvertToUncachedAddress (\r
+  IN VOID *Address\r
+  )\r
+{\r
+  UINTN UncachedMemoryMask = (UINTN)PcdGet64 (PcdArmUncachedMemoryMask);\r
+  UINTN UncachedAddress;\r
+  \r
+  UncachedAddress = (UINTN)Address | UncachedMemoryMask;\r
+  \r
+  return (VOID *)UncachedAddress;\r
+}\r
+\r
+\r
+\r
+VOID *\r
+UncachedInternalAllocatePages (\r
+  IN EFI_MEMORY_TYPE  MemoryType,  \r
+  IN UINTN            Pages\r
+  )\r
+{\r
+  return UncachedInternalAllocateAlignedPages (MemoryType, Pages, EFI_PAGE_SIZE);\r
+}\r
+\r
+\r
+VOID *\r
+EFIAPI\r
+UncachedAllocatePages (\r
+  IN UINTN  Pages\r
+  )\r
+{\r
+  return UncachedInternalAllocatePages (EfiBootServicesData, Pages);\r
+}\r
+\r
+VOID *\r
+EFIAPI\r
+UncachedAllocateRuntimePages (\r
+  IN UINTN  Pages\r
+  )\r
+{\r
+  return UncachedInternalAllocatePages (EfiRuntimeServicesData, Pages);\r
+}\r
+\r
+VOID *\r
+EFIAPI\r
+UncachedAllocateReservedPages (\r
+  IN UINTN  Pages\r
+  )\r
+{\r
+  return UncachedInternalAllocatePages (EfiReservedMemoryType, Pages);\r
+}\r
+\r
+\r
+\r
+VOID\r
+EFIAPI\r
+UncachedFreePages (\r
+  IN VOID   *Buffer,\r
+  IN UINTN  Pages\r
+  )\r
+{\r
+  UncachedFreeAlignedPages (Buffer, Pages);\r
+  return;\r
+}\r
+\r
+\r
+VOID *\r
+UncachedInternalAllocateAlignedPages (\r
+  IN EFI_MEMORY_TYPE  MemoryType,  \r
+  IN UINTN            Pages,\r
+  IN UINTN            Alignment\r
+  )\r
+{\r
+  EFI_STATUS            Status;\r
+  EFI_PHYSICAL_ADDRESS  Memory;\r
+  EFI_PHYSICAL_ADDRESS  AlignedMemory;\r
+  UINTN                 AlignmentMask;\r
+  UINTN                 UnalignedPages;\r
+  UINTN                 RealPages;\r
+\r
+  //\r
+  // Alignment must be a power of two or zero.\r
+  //\r
+  ASSERT ((Alignment & (Alignment - 1)) == 0);\r
\r
+  if (Pages == 0) {\r
+    return NULL;\r
+  }\r
+  if (Alignment > EFI_PAGE_SIZE) {\r
+    //\r
+    // Caculate the total number of pages since alignment is larger than page size.\r
+    //\r
+    AlignmentMask  = Alignment - 1;\r
+    RealPages      = Pages + EFI_SIZE_TO_PAGES (Alignment);\r
+    //\r
+    // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow.\r
+    //\r
+    ASSERT (RealPages > Pages);\r
\r
+    Status         = gBS->AllocatePages (AllocateAnyPages, MemoryType, RealPages, &Memory);\r
+    if (EFI_ERROR (Status)) {\r
+      return NULL;\r
+    }\r
+    AlignedMemory  = ((UINTN) Memory + AlignmentMask) & ~AlignmentMask;\r
+    UnalignedPages = EFI_SIZE_TO_PAGES (AlignedMemory - (UINTN) Memory);\r
+    if (UnalignedPages > 0) {\r
+      //\r
+      // Free first unaligned page(s).\r
+      //\r
+      Status = gBS->FreePages (Memory, UnalignedPages);\r
+      ASSERT_EFI_ERROR (Status);\r
+    }\r
+    Memory         = (EFI_PHYSICAL_ADDRESS) (AlignedMemory + EFI_PAGES_TO_SIZE (Pages));\r
+    UnalignedPages = RealPages - Pages - UnalignedPages;\r
+    if (UnalignedPages > 0) {\r
+      //\r
+      // Free last unaligned page(s).\r
+      //\r
+      Status = gBS->FreePages (Memory, UnalignedPages);\r
+      ASSERT_EFI_ERROR (Status);\r
+    }\r
+  } else {\r
+    //\r
+    // Do not over-allocate pages in this case.\r
+    //\r
+    Status = gBS->AllocatePages (AllocateAnyPages, MemoryType, Pages, &Memory);\r
+    if (EFI_ERROR (Status)) {\r
+      return NULL;\r
+    }\r
+    AlignedMemory  = (UINTN) Memory;\r
+  }\r
+  \r
+  Status = gVirtualUncachedPages->ConvertPages (gVirtualUncachedPages, AlignedMemory, Pages * EFI_PAGE_SIZE, PcdGet64 (PcdArmUncachedMemoryMask), &gAttributes);\r
+  if (EFI_ERROR (Status)) {\r
+    return NULL;\r
+  }\r
+  \r
+  AlignedMemory = (EFI_PHYSICAL_ADDRESS)(UINTN)ConvertToUncachedAddress ((VOID *)(UINTN)AlignedMemory);\r
+  \r
+  return (VOID *)(UINTN)AlignedMemory;\r
+}\r
+\r
+\r
+VOID\r
+EFIAPI\r
+UncachedFreeAlignedPages (\r
+  IN VOID   *Buffer,\r
+  IN UINTN  Pages\r
+  )\r
+{\r
+  EFI_STATUS            Status;\r
+  EFI_PHYSICAL_ADDRESS  Memory; \r
+\r
+  ASSERT (Pages != 0);\r
+  \r
+  Memory = ConvertToPhysicalAddress (Buffer);\r
+  \r
+  Status = gVirtualUncachedPages->RevertPages (gVirtualUncachedPages, Memory, Pages * EFI_PAGE_SIZE, PcdGet64 (PcdArmUncachedMemoryMask), gAttributes);\r
+\r
+  \r
+  Status = gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) Buffer, Pages);\r
+  ASSERT_EFI_ERROR (Status);\r
+}\r
+\r
+\r
+\r
+\r
+VOID *\r
+UncachedInternalAllocateAlignedPool (\r
+  IN EFI_MEMORY_TYPE  PoolType,\r
+  IN UINTN            AllocationSize,\r
+  IN UINTN            Alignment\r
+  )\r
+{\r
+  VOID      *AlignedAddress;\r
+  \r
+  //\r
+  // Alignment must be a power of two or zero.\r
+  //\r
+  ASSERT ((Alignment & (Alignment - 1)) == 0);\r
+\r
+  if (Alignment < EFI_PAGE_SIZE) {\r
+    Alignment = EFI_PAGE_SIZE;\r
+  }\r
+    \r
+  AlignedAddress = UncachedInternalAllocateAlignedPages (PoolType, EFI_SIZE_TO_PAGES (AllocationSize), Alignment);\r
+  if (AlignedAddress == NULL) {\r
+    return NULL;\r
+  }\r
+\r
+  AddPagesToList ((VOID *)(UINTN)ConvertToPhysicalAddress (AlignedAddress), (VOID *)(UINTN)AlignedAddress, EFI_SIZE_TO_PAGES (AllocationSize));\r
+\r
+  return (VOID *) AlignedAddress;\r
+}\r
+\r
+VOID *\r
+EFIAPI\r
+UncachedAllocateAlignedPool (\r
+  IN UINTN  AllocationSize,\r
+  IN UINTN  Alignment\r
+  )\r
+{\r
+  return UncachedInternalAllocateAlignedPool (EfiBootServicesData, AllocationSize, Alignment);\r
+}\r
+\r
+VOID *\r
+EFIAPI\r
+UncachedAllocateAlignedRuntimePool (\r
+  IN UINTN  AllocationSize,\r
+  IN UINTN  Alignment\r
+  )\r
+{\r
+  return UncachedInternalAllocateAlignedPool (EfiRuntimeServicesData, AllocationSize, Alignment);\r
+}\r
+\r
+VOID *\r
+EFIAPI\r
+UncachedAllocateAlignedReservedPool (\r
+  IN UINTN  AllocationSize,\r
+  IN UINTN  Alignment\r
+  )\r
+{\r
+  return UncachedInternalAllocateAlignedPool (EfiReservedMemoryType, AllocationSize, Alignment);\r
+}\r
+\r
+VOID *\r
+UncachedInternalAllocateAlignedZeroPool (\r
+  IN EFI_MEMORY_TYPE  PoolType,\r
+  IN UINTN            AllocationSize,\r
+  IN UINTN            Alignment\r
+  )\r
+{\r
+  VOID    *Memory;\r
+  Memory = UncachedInternalAllocateAlignedPool (PoolType, AllocationSize, Alignment);\r
+  if (Memory != NULL) {\r
+    Memory = ZeroMem (Memory, AllocationSize);\r
+  }\r
+  return Memory;\r
+}\r
+\r
+VOID *\r
+EFIAPI\r
+UncachedAllocateAlignedZeroPool (\r
+  IN UINTN  AllocationSize,\r
+  IN UINTN  Alignment\r
+  )\r
+{\r
+  return UncachedInternalAllocateAlignedZeroPool (EfiBootServicesData, AllocationSize, Alignment);\r
+}\r
+\r
+VOID *\r
+EFIAPI\r
+UncachedAllocateAlignedRuntimeZeroPool (\r
+  IN UINTN  AllocationSize,\r
+  IN UINTN  Alignment\r
+  )\r
+{\r
+  return UncachedInternalAllocateAlignedZeroPool (EfiRuntimeServicesData, AllocationSize, Alignment);\r
+}\r
+\r
+VOID *\r
+EFIAPI\r
+UncachedAllocateAlignedReservedZeroPool (\r
+  IN UINTN  AllocationSize,\r
+  IN UINTN  Alignment\r
+  )\r
+{\r
+  return UncachedInternalAllocateAlignedZeroPool (EfiReservedMemoryType, AllocationSize, Alignment);\r
+}\r
+\r
+VOID *\r
+UncachedInternalAllocateAlignedCopyPool (\r
+  IN EFI_MEMORY_TYPE  PoolType,\r
+  IN UINTN            AllocationSize,\r
+  IN CONST VOID       *Buffer,\r
+  IN UINTN            Alignment\r
+  )\r
+{\r
+  VOID  *Memory;\r
+  \r
+  ASSERT (Buffer != NULL);\r
+  ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN) Buffer + 1));\r
+\r
+  Memory = UncachedInternalAllocateAlignedPool (PoolType, AllocationSize, Alignment);\r
+  if (Memory != NULL) {\r
+    Memory = CopyMem (Memory, Buffer, AllocationSize);\r
+  }\r
+  return Memory;\r
+}\r
+\r
+VOID *\r
+EFIAPI\r
+UncachedAllocateAlignedCopyPool (\r
+  IN UINTN       AllocationSize,\r
+  IN CONST VOID  *Buffer,\r
+  IN UINTN       Alignment\r
+  )\r
+{\r
+  return UncachedInternalAllocateAlignedCopyPool (EfiBootServicesData, AllocationSize, Buffer, Alignment);\r
+}\r
+\r
+VOID *\r
+EFIAPI\r
+UncachedAllocateAlignedRuntimeCopyPool (\r
+  IN UINTN       AllocationSize,\r
+  IN CONST VOID  *Buffer,\r
+  IN UINTN       Alignment\r
+  )\r
+{\r
+  return UncachedInternalAllocateAlignedCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer, Alignment);\r
+}\r
+\r
+VOID *\r
+EFIAPI\r
+UncachedAllocateAlignedReservedCopyPool (\r
+  IN UINTN       AllocationSize,\r
+  IN CONST VOID  *Buffer,\r
+  IN UINTN       Alignment\r
+  )\r
+{\r
+  return UncachedInternalAllocateAlignedCopyPool (EfiReservedMemoryType, AllocationSize, Buffer, Alignment);\r
+}\r
+\r
+VOID\r
+EFIAPI\r
+UncachedFreeAlignedPool (\r
+  IN VOID   *Buffer\r
+  )\r
+{\r
+  VOID    *Allocation;\r
+  UINTN   Pages;\r
+  \r
+  RemovePagesFromList (Buffer, &Allocation, &Pages);\r
+\r
+  UncachedFreePages (Allocation, Pages);\r
+}\r
+\r
+VOID *\r
+UncachedInternalAllocatePool (\r
+  IN EFI_MEMORY_TYPE  MemoryType,  \r
+  IN UINTN            AllocationSize\r
+  )\r
+{\r
+  UINTN CacheLineLength = ArmDataCacheLineLength ();\r
+  return UncachedInternalAllocateAlignedPool (MemoryType, AllocationSize, CacheLineLength);\r
+}\r
+\r
+VOID *\r
+EFIAPI\r
+UncachedAllocatePool (\r
+  IN UINTN  AllocationSize\r
+  )\r
+{\r
+  return UncachedInternalAllocatePool (EfiBootServicesData, AllocationSize);\r
+}\r
+\r
+VOID *\r
+EFIAPI\r
+UncachedAllocateRuntimePool (\r
+  IN UINTN  AllocationSize\r
+  )\r
+{\r
+  return UncachedInternalAllocatePool (EfiRuntimeServicesData, AllocationSize);\r
+}\r
+\r
+VOID *\r
+EFIAPI\r
+UncachedAllocateReservedPool (\r
+  IN UINTN  AllocationSize\r
+  )\r
+{\r
+  return UncachedInternalAllocatePool (EfiReservedMemoryType, AllocationSize);\r
+}\r
+\r
+VOID *\r
+UncachedInternalAllocateZeroPool (\r
+  IN EFI_MEMORY_TYPE  PoolType,  \r
+  IN UINTN            AllocationSize\r
+  ) \r
+{\r
+  VOID  *Memory;\r
+\r
+  Memory = UncachedInternalAllocatePool (PoolType, AllocationSize);\r
+  if (Memory != NULL) {\r
+    Memory = ZeroMem (Memory, AllocationSize);\r
+  }\r
+  return Memory;\r
+}\r
+\r
+VOID *\r
+EFIAPI\r
+UncachedAllocateZeroPool (\r
+  IN UINTN  AllocationSize\r
+  )\r
+{\r
+  return UncachedInternalAllocateZeroPool (EfiBootServicesData, AllocationSize);\r
+}\r
+\r
+VOID *\r
+EFIAPI\r
+UncachedAllocateRuntimeZeroPool (\r
+  IN UINTN  AllocationSize\r
+  )\r
+{\r
+  return UncachedInternalAllocateZeroPool (EfiRuntimeServicesData, AllocationSize);\r
+}\r
+\r
+VOID *\r
+EFIAPI\r
+UncachedAllocateReservedZeroPool (\r
+  IN UINTN  AllocationSize\r
+  )\r
+{\r
+  return UncachedInternalAllocateZeroPool (EfiReservedMemoryType, AllocationSize);\r
+}\r
+\r
+VOID *\r
+UncachedInternalAllocateCopyPool (\r
+  IN EFI_MEMORY_TYPE  PoolType,  \r
+  IN UINTN            AllocationSize,\r
+  IN CONST VOID       *Buffer\r
+  ) \r
+{\r
+  VOID  *Memory;\r
+\r
+  ASSERT (Buffer != NULL);\r
+  ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN) Buffer + 1));\r
+\r
+  Memory = UncachedInternalAllocatePool (PoolType, AllocationSize);\r
+  if (Memory != NULL) {\r
+     Memory = CopyMem (Memory, Buffer, AllocationSize);\r
+  }\r
+  return Memory;\r
+} \r
+\r
+VOID *\r
+EFIAPI\r
+UncachedAllocateCopyPool (\r
+  IN UINTN       AllocationSize,\r
+  IN CONST VOID  *Buffer\r
+  )\r
+{\r
+  return UncachedInternalAllocateCopyPool (EfiBootServicesData, AllocationSize, Buffer);\r
+}\r
+\r
+VOID *\r
+EFIAPI\r
+UncachedAllocateRuntimeCopyPool (\r
+  IN UINTN       AllocationSize,\r
+  IN CONST VOID  *Buffer\r
+  )\r
+{\r
+  return UncachedInternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer);\r
+}\r
+\r
+VOID *\r
+EFIAPI\r
+UncachedAllocateReservedCopyPool (\r
+  IN UINTN       AllocationSize,\r
+  IN CONST VOID  *Buffer\r
+  )\r
+{\r
+  return UncachedInternalAllocateCopyPool (EfiReservedMemoryType, AllocationSize, Buffer);\r
+}\r
+\r
+VOID\r
+EFIAPI\r
+UncachedFreePool (\r
+  IN VOID   *Buffer\r
+  )\r
+{\r
+  UncachedFreeAlignedPool (Buffer);\r
+}\r
+\r
+VOID\r
+EFIAPI\r
+UncachedSafeFreePool (\r
+  IN VOID   *Buffer\r
+  )\r
+{\r
+  if (Buffer != NULL) {\r
+    UncachedFreePool (Buffer);\r
+    Buffer = NULL;\r
+  }\r
+}\r
+\r
+/**\r
+  The constructor function caches the pointer of DXE Services Table.\r
+\r
+  The constructor function caches the pointer of DXE Services Table.\r
+  It will ASSERT() if that operation fails.\r
+  It will ASSERT() if the pointer of DXE Services Table is NULL.\r
+  It will always return EFI_SUCCESS.\r
+\r
+  @param  ImageHandle   The firmware allocated handle for the EFI image.\r
+  @param  SystemTable   A pointer to the EFI System Table.\r
+\r
+  @retval EFI_SUCCESS   The constructor always returns EFI_SUCCESS.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+DebugUncachedMemoryAllocationLibConstructor (\r
+  IN EFI_HANDLE        ImageHandle,\r
+  IN EFI_SYSTEM_TABLE  *SystemTable\r
+  )\r
+{\r
+  EFI_STATUS    Status;\r
+  \r
+  Status = gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID **)&gCpu);\r
+  ASSERT_EFI_ERROR(Status);\r
+\r
+  Status = gBS->LocateProtocol (&gVirtualUncachedPagesProtocolGuid, NULL, (VOID **)&gVirtualUncachedPages);\r
+  ASSERT_EFI_ERROR(Status);\r
+\r
+  return Status;\r
+}\r
+\r
+\r
+\r
diff --git a/ArmPkg/Library/DebugUncachedMemoryAllocationLib/DebugUncachedMemoryAllocationLib.inf b/ArmPkg/Library/DebugUncachedMemoryAllocationLib/DebugUncachedMemoryAllocationLib.inf
new file mode 100644 (file)
index 0000000..102ef78
--- /dev/null
@@ -0,0 +1,47 @@
+#/** @file\r
+# \r
+#\r
+# Copyright (c) 2008 - 2010, Apple Inc. All rights reserved\r
+#\r
+#  All rights reserved. This program and the accompanying materials\r
+#  are licensed and made available under the terms and conditions of the BSD License\r
+#  which accompanies this distribution. The full text of the license may be found at\r
+#  http://opensource.org/licenses/bsd-license.php\r
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+#\r
+#**/\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = UncachedMemoryAllocationLib\r
+  FILE_GUID                      = 3C1EA826-696A-4E8A-B89D-3C5369B84F2A\r
+  MODULE_TYPE                    = DXE_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = UncachedMemoryAllocationLib\r
+  CONSTRUCTOR                    = DebugUncachedMemoryAllocationLibConstructor\r
+\r
+[Sources.common]\r
+  DebugUncachedMemoryAllocationLib.c\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  ArmPkg/ArmPkg.dec\r
+\r
+[Protocols]\r
+  gEfiCpuArchProtocolGuid\r
+\r
+[LibraryClasses]\r
+  BaseLib\r
+  UefiMemoryAllocationLib\r
+  ArmLib\r
+\r
+\r
+[FixedPcd]\r
+  gArmTokenSpaceGuid.PcdArmUncachedMemoryMask\r
+  \r
+  \r
+[Depex]\r
+  gEfiCpuArchProtocolGuid\r
+  gVirtualUncachedPagesProtocolGuid
\ No newline at end of file