text: /** @file
  
  Copyright (c) 2017 - 2019, Intel Corporation. All rights reserved.<BR>
  SPDX-License-Identifier: BSD-2-Clause-Patent
  
  **/
  
  #include <Uefi.h>
  #include <PiDxe.h>
  #include <Library/TestPointCheckLib.h>
  #include <Library/TestPointLib.h>
  #include <Library/DebugLib.h>
  #include <Library/MemoryAllocationLib.h>
  #include <Library/DxeServicesTableLib.h>
  
  EFI_STATUS
  TestPointCheckAcpiGcdResource (
    VOID
    );
  
  CHAR8 *mGcdMemoryTypeShortName[] = {
    " NE  ",
    " RSVD",
    " SYS ",
    " MMIO",
    " PERS",
    " RELI",
  };
  
  CHAR8 mUnknownStr[11];
  
  CHAR8 *
  ShortNameOfGcdMemoryType(
    IN UINT32 Type
    )
  {
    if (Type < sizeof(mGcdMemoryTypeShortName) / sizeof(mGcdMemoryTypeShortName[0])) {
      return mGcdMemoryTypeShortName[Type];
    } else {
      return " ???? ";
    }
  }
  
  CHAR8 *mGcdIoTypeShortName[] = {
    " NE  ",
    " RSVD",
    " SYS ",
  };
  
  CHAR8 *
  ShortNameOfGcdIoType(
    IN UINT32 Type
    )
  {
    if (Type < sizeof(mGcdIoTypeShortName) / sizeof(mGcdIoTypeShortName[0])) {
      return mGcdIoTypeShortName[Type];
    } else {
      return " ???? ";
    }
  }
  
  VOID
  PrintBitMask (
    IN UINT64 Bit,
    IN UINT64 Capabilities,
    IN UINT64 Attributes
    )
  {
    if ((Capabilities & Bit) != 0) {
      if ((Attributes & Bit) != 0) {
        DEBUG ((DEBUG_INFO, "1"));
      } else {
        DEBUG ((DEBUG_INFO, "0"));
      }
    } else {
      DEBUG ((DEBUG_INFO, "-"));
    }
  }
  
  VOID
  PrintMemoryDescriptorHeader (
    VOID
    )
  {
    if (sizeof(UINT64) == sizeof(UINTN)) {
      DEBUG ((DEBUG_INFO, "                                              U                                      \n"));
      DEBUG ((DEBUG_INFO, "                                       RRMNXRWCWWWU                                  \n"));
      DEBUG ((DEBUG_INFO, "Base Address     End Address      Type TORVPPPEBTCC Image            Device          \n"));
      DEBUG ((DEBUG_INFO, "================ ================ ==== ============ ================ ================\n"));
    } else {
      DEBUG ((DEBUG_INFO, "                                              U                      \n"));
      DEBUG ((DEBUG_INFO, "                                       RRMNXRWCWWWU                  \n"));
      DEBUG ((DEBUG_INFO, "Base Address     End Address      Type TORVPPPEBTCC Image    Device  \n"));
      DEBUG ((DEBUG_INFO, "================ ================ ==== ============ ======== ========\n"));
    }
  }
  
  VOID
  PrintMemoryDescriptor (
    EFI_GCD_MEMORY_SPACE_DESCRIPTOR  *MemoryDescriptor
    )
  {
    DEBUG ((DEBUG_INFO,
      "%016lx-%016lx",
      MemoryDescriptor->BaseAddress,
      MemoryDescriptor->BaseAddress + MemoryDescriptor->Length - 1
      ));
  
    DEBUG ((DEBUG_INFO, ShortNameOfGcdMemoryType(MemoryDescriptor->GcdMemoryType)));
    DEBUG ((DEBUG_INFO, " "));
  
    if (MemoryDescriptor->GcdMemoryType != EfiGcdMemoryTypeNonExistent) {
      PrintBitMask (EFI_MEMORY_RUNTIME, MemoryDescriptor->Capabilities, MemoryDescriptor->Attributes);
      PrintBitMask (EFI_MEMORY_RO, MemoryDescriptor->Capabilities, MemoryDescriptor->Attributes);
      PrintBitMask (EFI_MEMORY_MORE_RELIABLE, MemoryDescriptor->Capabilities, MemoryDescriptor->Attributes);
      PrintBitMask (EFI_MEMORY_NV, MemoryDescriptor->Capabilities, MemoryDescriptor->Attributes);
      PrintBitMask (EFI_MEMORY_XP, MemoryDescriptor->Capabilities, MemoryDescriptor->Attributes);
      PrintBitMask (EFI_MEMORY_RP, MemoryDescriptor->Capabilities, MemoryDescriptor->Attributes);
      PrintBitMask (EFI_MEMORY_WP, MemoryDescriptor->Capabilities, MemoryDescriptor->Attributes);
      PrintBitMask (EFI_MEMORY_UCE, MemoryDescriptor->Capabilities, MemoryDescriptor->Attributes);
      PrintBitMask (EFI_MEMORY_WB, MemoryDescriptor->Capabilities, MemoryDescriptor->Attributes);
      PrintBitMask (EFI_MEMORY_WT, MemoryDescriptor->Capabilities, MemoryDescriptor->Attributes);
      PrintBitMask (EFI_MEMORY_WC, MemoryDescriptor->Capabilities, MemoryDescriptor->Attributes);
      PrintBitMask (EFI_MEMORY_UC, MemoryDescriptor->Capabilities, MemoryDescriptor->Attributes);
    } else {
      DEBUG ((DEBUG_INFO, "            "));
    }
  
    if (sizeof(UINT64) == sizeof(UINTN)) {
      if (MemoryDescriptor->ImageHandle != NULL) {
        DEBUG ((DEBUG_INFO, " %016lx", (UINT64)(UINTN)MemoryDescriptor->ImageHandle));
        if (MemoryDescriptor->DeviceHandle != NULL) {
          DEBUG ((DEBUG_INFO, " %016lx", (UINT64)(UINTN)MemoryDescriptor->ImageHandle));
        }
      }
    } else {
      if (MemoryDescriptor->ImageHandle != NULL) {
        DEBUG ((DEBUG_INFO, " %08x", MemoryDescriptor->ImageHandle));
        if (MemoryDescriptor->DeviceHandle != NULL) {
          DEBUG ((DEBUG_INFO, " %08x", MemoryDescriptor->ImageHandle));
        }
      }
    }
  
    DEBUG ((DEBUG_INFO, "\n"));
  }
  
  VOID
  PrintIoDescriptorHeader (
    VOID
    )
  {
    DEBUG ((DEBUG_INFO, "Base Address     End Address      Type Image    Device  \n"));
    DEBUG ((DEBUG_INFO, "================ ================ ==== ======== ========\n"));
  }
  
  VOID
  PrintIoDescriptor (
    EFI_GCD_IO_SPACE_DESCRIPTOR  *IoDescriptor
    )
  {
    DEBUG ((DEBUG_INFO,
      "%016lx-%016lx",
      IoDescriptor->BaseAddress,
      IoDescriptor->BaseAddress + IoDescriptor->Length - 1
      ));
  
    DEBUG ((DEBUG_INFO, ShortNameOfGcdIoType (IoDescriptor->GcdIoType)));
  
    if (IoDescriptor->ImageHandle != NULL) {
      DEBUG ((DEBUG_INFO, " %08x", IoDescriptor->ImageHandle));
      if (IoDescriptor->DeviceHandle != NULL) {
        DEBUG ((DEBUG_INFO, " %08x", IoDescriptor->ImageHandle));
      }
    }
  
    DEBUG ((DEBUG_INFO, "\n"));
  }
  
  VOID
  TestPointDumpGcd (
    OUT EFI_GCD_MEMORY_SPACE_DESCRIPTOR **GcdMemoryMap,  OPTIONAL
    OUT UINTN                           *GcdMemoryMapNumberOfDescriptors,  OPTIONAL
    OUT EFI_GCD_IO_SPACE_DESCRIPTOR     **GcdIoMap,  OPTIONAL
    OUT UINTN                           *GcdIoMapNumberOfDescriptors,  OPTIONAL
    IN  BOOLEAN                         DumpPrint
    )
  {
    EFI_STATUS                      Status;
    EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemoryMap;
    EFI_GCD_IO_SPACE_DESCRIPTOR     *IoMap;
    UINTN                           NumberOfDescriptors;
    UINTN                           Index;
  
    if (GcdMemoryMap != NULL) {
      *GcdMemoryMap = NULL;
      *GcdMemoryMapNumberOfDescriptors = 0;
    }
    if (GcdIoMap != NULL) {
      *GcdIoMap = NULL;
      *GcdIoMapNumberOfDescriptors = 0;
    }
    
    if (DumpPrint) {
      DEBUG ((DEBUG_INFO, "==== TestPointDumpGcd - Enter\n"));
      DEBUG ((DEBUG_INFO, "GCD MEM:\n"));
    }
    NumberOfDescriptors = 0;
    MemoryMap           = NULL;
    Status = gDS->GetMemorySpaceMap (
                    &NumberOfDescriptors,
                    &MemoryMap
                    );
    if (!EFI_ERROR (Status)) {
      if (DumpPrint) {
        PrintMemoryDescriptorHeader ();
        for (Index = 0; Index < NumberOfDescriptors; Index++) {
          PrintMemoryDescriptor (&MemoryMap[Index]);
        }
      }
      if (GcdMemoryMap != NULL) {
        *GcdMemoryMap = AllocateCopyPool (NumberOfDescriptors * sizeof(EFI_GCD_MEMORY_SPACE_DESCRIPTOR), MemoryMap);
        *GcdMemoryMapNumberOfDescriptors = NumberOfDescriptors;
      }
    }
  
    if (DumpPrint) {
      DEBUG ((DEBUG_INFO, "GCD IO:\n"));
    }
    NumberOfDescriptors = 0;
    IoMap               = NULL;
    Status = gDS->GetIoSpaceMap (
                    &NumberOfDescriptors,
                    &IoMap
                    );
    if (!EFI_ERROR (Status)) {
      if (DumpPrint) {
        PrintIoDescriptorHeader ();
        for (Index = 0; Index < NumberOfDescriptors; Index++) {
          PrintIoDescriptor (&IoMap[Index]);
        }
      }
      if (GcdMemoryMap != NULL) {
        if (GcdIoMap != NULL) {
          *GcdIoMap = AllocateCopyPool (NumberOfDescriptors * sizeof(EFI_GCD_IO_SPACE_DESCRIPTOR), IoMap);
        }
        *GcdIoMapNumberOfDescriptors = NumberOfDescriptors;
      }
    }
  
    if (DumpPrint) {
      DEBUG ((DEBUG_INFO, "==== TestPointDumpGcd - Exit\n"));
    }
    return ;
  }
  