text: /*
   * Copyright (c) 2018, Intel Corporation.
   * SPDX-License-Identifier: BSD-3-Clause
   */
  
  #include <Debug.h>
  #include <Library/BaseMemoryLib.h>
  #include <Convert.h>
  #include "CommandParser.h"
  #include "Common.h"
  #include "ShowPcdCommand.h"
  #include <PcdCommon.h>
  #include <LbaCommon.h>
  
  /**
    Command syntax definition
  **/
  struct Command ShowPcdCommand =
  {
    SHOW_VERB,                                                          //!< verb
    {                                                                   //!< options
    {VERBOSE_OPTION_SHORT, VERBOSE_OPTION, L"", L"", HELP_VERBOSE_DETAILS_TEXT, FALSE, ValueEmpty},
      {L"", PROTOCOL_OPTION_DDRT, L"", L"",HELP_DDRT_DETAILS_TEXT, FALSE, ValueEmpty},
      {L"", PROTOCOL_OPTION_SMBUS, L"", L"",HELP_SMBUS_DETAILS_TEXT, FALSE, ValueEmpty},
      {L"", LARGE_PAYLOAD_OPTION, L"", L"", HELP_LPAYLOAD_DETAILS_TEXT, FALSE, ValueEmpty},
      {L"", SMALL_PAYLOAD_OPTION, L"", L"", HELP_SPAYLOAD_DETAILS_TEXT, FALSE, ValueEmpty},
  #ifdef OS_BUILD
    { OUTPUT_OPTION_SHORT, OUTPUT_OPTION, L"", OUTPUT_OPTION_HELP, HELP_OPTIONS_DETAILS_TEXT, FALSE, ValueRequired }
  #else
    {L"", L"", L"", L"",L"", FALSE, ValueOptional}
  #endif
    },
    {                                                                   //!< targets
      {DIMM_TARGET, L"", HELP_TEXT_DIMM_IDS, FALSE, ValueOptional},
      {PCD_TARGET, L"", PCD_CONFIG_TARGET_VALUE L"|" PCD_LSA_TARGET_VALUE, TRUE, ValueOptional}
    },
    {{L"", L"", L"", FALSE, ValueOptional}},                                    //!< properties
    L"Show platform configuration data (PCD) stored on one or more " PMEM_MODULES_STR L".",    //!< help
    ShowPcd,
    TRUE
  };
  
  #define DS_ROOT_PATH                      L"/PcdList"
  #define DS_DIMM_PATH                      L"/PcdList/Dimm"
  #define DS_DIMM_INDEX_PATH                L"/PcdList/Dimm[%d]"
  #define DS_PCD_PATH                       L"/PcdList/Dimm/Pcd"
  #define DS_PCD_INDEX_PATH                 L"/PcdList/Dimm[%d]/Pcd[%d]"
  #define DS_TABLE_PATH                     L"/PcdList/Dimm/Pcd/Table"
  #define DS_TABLE_INDEX_PATH               L"/PcdList/Dimm[%d]/Pcd[%d]/Table[%d]"
  #define DS_PCD_PCAT_TABLE_INDEX_PATH      L"/PcdList/Dimm[%d]/Pcd[%d]/Table[%d]/PcatTable[%d]"
  #define DS_IDENTIFICATION_INFO_INDEX_PATH L"/PcdList/Dimm[%d]/Pcd[%d]/Table[%d]/PcatTable[%d]/IdentificationInfoTable[%d]"
  
  #define PCD_TARGET_CONFIG_STR             L"Target cfg "
  #define PCD_TARGET_NAMESPACE_STR          L"Target namespace "
  #define PCD_TABLE_STR                     L"Table"
  #define PCD_STR                           L"Pcd"
  #define PCD_PCAT_TABLE_STR                L"PcatTable"
  #define PCD_IDENTIFICATION_INFO_STR       L"IdentificationInfoTable"
  
  #define COLUMN_IN_HEX_DUMP      16
  
  CHAR16 *gpPathLba = NULL;
  PRINT_CONTEXT *gpPrinterCtxLbaCommon = NULL;
  
  UINT16 gDimmIndex = 0;
  UINT8 ConfigIndex = 0;
  
  PRINTER_LIST_ATTRIB ShowPcdListAttributes =
  {
   {
      {
        DIMM_NODE_STR,                                                                                                           //GROUP LEVEL TYPE
        L"--" DIMM_ID_STR L":$(" DIMM_ID_STR L")--",                                                                             //NULL or GROUP LEVEL HEADER
        SHOW_LIST_IDENT FORMAT_STR L": " FORMAT_STR,                                                                             //NULL or KEY VAL FORMAT STR
        DIMM_ID_STR                                                                                                              //NULL or IGNORE KEY LIST (K1;K2)
      },
      {
        PCD_STR,                                                                                                                 //GROUP LEVEL TYPE
        L"--" PCD_STR L":$(" PCD_STR L")--",                                                                                     //NULL or GROUP LEVEL HEADER
        SHOW_LIST_IDENT FORMAT_STR L": " FORMAT_STR,                                                                             //NULL or KEY VAL FORMAT STR
        PCD_STR                                                                                                                  //NULL or IGNORE KEY LIST (K1;K2)
      },
      {
        PCD_TABLE_STR,                                                                                                           //GROUP LEVEL TYPE
        SHOW_LIST_IDENT L"---" PCD_TABLE_STR L": $(" PCD_TABLE_STR L")---",                                                      //NULL or GROUP LEVEL HEADER
        SHOW_LIST_IDENT SHOW_LIST_IDENT FORMAT_STR L": " FORMAT_STR,                                                             //NULL or KEY VAL FORMAT STR
        PCD_TABLE_STR                                                                                                            //NULL or IGNORE KEY LIST (K1;K2)
      },
      {
        PCD_PCAT_TABLE_STR,                                                                                             //GROUP LEVEL TYPE
        SHOW_LIST_IDENT SHOW_LIST_IDENT PCD_PCAT_TABLE_STR SHOW_LIST_IDENT L": $(" PCD_PCAT_TABLE_STR L")",    //NULL or GROUP LEVEL HEADER
        SHOW_LIST_IDENT SHOW_LIST_IDENT FORMAT_STR L": " FORMAT_STR,                                                             //NULL or KEY VAL FORMAT STR
        PCD_PCAT_TABLE_STR                                                                                              //NULL or IGNORE KEY LIST (K1;K2)
      },
      {
        PCD_IDENTIFICATION_INFO_STR,                                                                                             //GROUP LEVEL TYPE
        SHOW_LIST_IDENT SHOW_LIST_IDENT PCD_IDENTIFICATION_INFO_STR SHOW_LIST_IDENT L": $(" PCD_IDENTIFICATION_INFO_STR L")",    //NULL or GROUP LEVEL HEADER
        SHOW_LIST_IDENT SHOW_LIST_IDENT FORMAT_STR L": " FORMAT_STR,                                                             //NULL or KEY VAL FORMAT STR
        PCD_IDENTIFICATION_INFO_STR                                                                                              //NULL or IGNORE KEY LIST (K1;K2)
      }
   }
  };
  
  PRINTER_DATA_SET_ATTRIBS ShowPcdDataSetAttribs =
  {
    &ShowPcdListAttributes,
    NULL
  };
  
  /**
    Register the Show PCD command
  
    @retval EFI_SUCCESS success
    @retval EFI_ABORTED registering failure
    @retval EFI_OUT_OF_RESOURCES memory allocation failure
  **/
  EFI_STATUS
  RegisterShowPcdCommand(
  )
  {
    EFI_STATUS ReturnCode = EFI_SUCCESS;
  
    NVDIMM_ENTRY();
  
    ReturnCode = RegisterCommand(&ShowPcdCommand);
  
    NVDIMM_EXIT_I64(ReturnCode);
    return ReturnCode;
  }
  
  STATIC
  EFI_STATUS
  GetPcdTarget(
    IN     CHAR16 *pTargetValue,
    OUT UINT8 *pPcdTarget
  )
  {
    EFI_STATUS ReturnCode = EFI_INVALID_PARAMETER;
  
    NVDIMM_ENTRY();
  
    if (pTargetValue == NULL || pPcdTarget == NULL) {
      goto Finish;
    }
  
    if (StrLen(pTargetValue) == 0) {
      *pPcdTarget = PCD_TARGET_ALL;
    }
    else if (StrICmp(pTargetValue, PCD_CONFIG_TARGET_VALUE) == 0) {
      *pPcdTarget = PCD_TARGET_CONFIG;
    }
    else if (StrICmp(pTargetValue, PCD_LSA_TARGET_VALUE) == 0) {
      *pPcdTarget = PCD_TARGET_NAMESPACES;
    }
    else {
      ReturnCode = EFI_INVALID_PARAMETER;
      goto Finish;
    }
  
    ReturnCode = EFI_SUCCESS;
  
  Finish:
    NVDIMM_EXIT_I64(ReturnCode);
    return ReturnCode;
  }
  
  /**
    Execute the Show PCD command
  
    @param[in] pCmd command from CLI
  
    @retval EFI_SUCCESS success
    @retval EFI_INVALID_PARAMETER pCmd is NULL or invalid command line parameters
    @retval EFI_NOT_FOUND couldn't open Config Protocol
    @retval EFI_ABORTED internal
  **/
  EFI_STATUS
  ShowPcd(
    IN     struct Command *pCmd
    )
  {
    EFI_STATUS ReturnCode = EFI_INVALID_PARAMETER;
    COMMAND_STATUS *pCommandStatus = NULL;
    EFI_DCPMM_CONFIG2_PROTOCOL *pNvmDimmConfigProtocol = NULL;
    DIMM_PCD_INFO *pDimmPcdInfo = NULL;
    UINT32 DimmPcdInfoCount = 0;
    UINT16 *pDimmIds = NULL;
    UINT32 DimmIdsCount = 0;
    CHAR16 *pTargetValue = NULL;
    UINT8 PcdTarget = PCD_TARGET_ALL;
    UINT32 Index = 0;
    DIMM_INFO *pDimms = NULL;
    UINT32 DimmCount = 0;
    CHAR16 DimmStr[MAX_DIMM_UID_LENGTH];
    PRINT_CONTEXT *pPrinterCtx = NULL;
    CHAR16 *pPath = NULL;
  
    NVDIMM_ENTRY();
  
    SetDisplayInfo(L"ShowPcd", ResultsView, NULL);
  
    ZeroMem(DimmStr, sizeof(DimmStr));
  
    if (pCmd == NULL) {
      ReturnCode = EFI_INVALID_PARAMETER;
      PRINTER_SET_MSG(pPrinterCtx, ReturnCode, CLI_ERR_NO_COMMAND);
      goto Finish;
    }
  
    /**
      Printing will still work via compatibility mode if NULL so no need to check for NULL.
    **/
    pPrinterCtx = pCmd->pPrintCtx;
  
    /** Get config protocol **/
    ReturnCode = OpenNvmDimmProtocol(gNvmDimmConfigProtocolGuid, (VOID **)&pNvmDimmConfigProtocol, NULL);
    if (EFI_ERROR(ReturnCode)) {
      ReturnCode = EFI_NOT_FOUND;
      PRINTER_SET_MSG(pPrinterCtx, ReturnCode, CLI_ERR_OPENING_CONFIG_PROTOCOL);
      goto Finish;
    }
  
    // Populate the list of DIMM_INFO structures with relevant information
    ReturnCode = GetDimmList(pNvmDimmConfigProtocol, pCmd, DIMM_INFO_CATEGORY_NONE, &pDimms, &DimmCount);
    if (EFI_ERROR(ReturnCode)) {
      if (ReturnCode == EFI_NOT_FOUND) {
        PRINTER_SET_MSG(pCmd->pPrintCtx, ReturnCode, CLI_INFO_NO_FUNCTIONAL_DIMMS);
      }
      goto Finish;
    }
  
    ReturnCode = InitializeCommandStatus(&pCommandStatus);
    if (EFI_ERROR(ReturnCode)) {
      goto Finish;
    }
  
    if (ContainTarget(pCmd, DIMM_TARGET)) {
      pTargetValue = GetTargetValue(pCmd, DIMM_TARGET);
      ReturnCode = GetDimmIdsFromString(pCmd, pTargetValue, pDimms, DimmCount, &pDimmIds, &DimmIdsCount);
      if (EFI_ERROR(ReturnCode)) {
        goto Finish;
      }
      if (!AllDimmsInListAreManageable(pDimms, DimmCount, pDimmIds, DimmIdsCount)) {
        ReturnCode = EFI_INVALID_PARAMETER;
        PRINTER_SET_MSG(pPrinterCtx, ReturnCode, FORMAT_STR_NL, CLI_ERR_UNMANAGEABLE_DIMM);
        goto Finish;
      }
    }
  
    pTargetValue = GetTargetValue(pCmd, PCD_TARGET);
    ReturnCode = GetPcdTarget(pTargetValue, &PcdTarget);
    if (EFI_ERROR(ReturnCode)) {
      ReturnCode = EFI_INVALID_PARAMETER;
      PRINTER_SET_MSG(pPrinterCtx, ReturnCode, FORMAT_STR_NL, CLI_ERR_INCORRECT_VALUE_TARGET_PCD);
      goto Finish;
    }
  
    ReturnCode = pNvmDimmConfigProtocol->GetPcd(pNvmDimmConfigProtocol, PcdTarget, pDimmIds, DimmIdsCount,
      &pDimmPcdInfo, &DimmPcdInfoCount, pCommandStatus);
    if (EFI_ERROR(ReturnCode)) {
      ReturnCode = MatchCliReturnCode(pCommandStatus->GeneralStatus);
      goto Finish;
    }
  
    for (Index = 0; Index < DimmPcdInfoCount; Index++) {
      ReturnCode = GetPreferredDimmIdAsString(pDimmPcdInfo[Index].DimmId, pDimmPcdInfo[Index].DimmUid,
        DimmStr, MAX_DIMM_UID_LENGTH);
      if (EFI_ERROR(ReturnCode)) {
        goto Finish;
      }
  
      PRINTER_BUILD_KEY_PATH(pPath, DS_DIMM_INDEX_PATH, Index);
      PRINTER_SET_KEY_VAL_WIDE_STR(pPrinterCtx, pPath, DIMM_ID_STR, DimmStr);
  
      if (PcdTarget == PCD_TARGET_ALL || PcdTarget == PCD_TARGET_NAMESPACES) {
        PRINTER_BUILD_KEY_PATH(pPath, DS_PCD_INDEX_PATH, Index, 0);
        PRINTER_SET_KEY_VAL_WIDE_STR(pPrinterCtx, pPath, PCD_STR, L"LSA");
        PrintLabelStorageArea(pDimmPcdInfo[Index].pLabelStorageArea, pPrinterCtx, pPath);
      }
  
      if (PcdTarget == PCD_TARGET_ALL || PcdTarget == PCD_TARGET_CONFIG) {
        PRINTER_BUILD_KEY_PATH(pPath, DS_PCD_INDEX_PATH, Index, 1);
        PRINTER_SET_KEY_VAL_WIDE_STR(pPrinterCtx, pPath, PCD_STR, L"Config");
        PrintPcdConfigurationHeader(pDimmPcdInfo[Index].pConfHeader, pPrinterCtx, pPath);
      }
      gDimmIndex++;
    }
  
    ReturnCode = EFI_SUCCESS;
  
    PRINTER_CONFIGURE_DATA_ATTRIBUTES(pPrinterCtx, DS_ROOT_PATH, &ShowPcdDataSetAttribs);
    PRINTER_ENABLE_LIST_TABLE_FORMAT(pPrinterCtx);
    pPrinterCtx->DoNotPrintGeneralStatusSuccessCode = TRUE;
  Finish:
    PRINTER_SET_COMMAND_STATUS(pPrinterCtx, ReturnCode, CLI_INFO_SHOW_PCD, CLI_INFO_ON, pCommandStatus);
    PRINTER_PROCESS_SET_BUFFER(pPrinterCtx);
    FreeCommandStatus(&pCommandStatus);
    FreeDimmPcdInfoArray(pDimmPcdInfo, DimmPcdInfoCount);
    pDimmPcdInfo = NULL;
    FREE_POOL_SAFE(pDimmIds);
    FREE_POOL_SAFE(pDimms);
    FREE_POOL_SAFE(pPath);
    NVDIMM_EXIT_I64(ReturnCode);
    return ReturnCode;
  }
  
  /**
    Print Platform Config Data table header
  
    @param[in] pHeader table header
    @param[in] pPrinterCtx pointer for printer
    @param[in] pPath
  **/
  VOID
  PrintPcdTableHeader(
    IN     TABLE_HEADER *pHeader,
    IN     PRINT_CONTEXT *pPrinterCtx,
    IN     CHAR16 *pPath
  )
  {
    PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(pPrinterCtx,
      pPath,
      L"Signature                 ",
      L"%c%c%c%c",
      pHeader->Signature & 0xFF,
      (pHeader->Signature >> 8) & 0xFF,
      (pHeader->Signature >> 16) & 0xFF,
      (pHeader->Signature >> 24) & 0xFF);
    PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(pPrinterCtx, pPath, L"Length                    ", FORMAT_HEX_NOWIDTH, pHeader->Length);
    PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(pPrinterCtx, pPath, L"Revision                  ", FORMAT_HEX_NOWIDTH, pHeader->Revision);
    PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(pPrinterCtx, pPath, L"Checksum                  ", FORMAT_HEX_NOWIDTH, pHeader->Checksum);
    PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(pPrinterCtx, pPath, L"OemId                     ", L"%c%c%c%c%c%c",
      pHeader->OemId[0],
      pHeader->OemId[1],
      pHeader->OemId[2],
      pHeader->OemId[3],
      pHeader->OemId[4],
      pHeader->OemId[5]);
    PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(pPrinterCtx, pPath, L"OemTableId                ", L"%c%c%c%c%c%c",
      ((UINT8 *)&pHeader->OemTableId)[0],
      ((UINT8 *)&pHeader->OemTableId)[1],
      ((UINT8 *)&pHeader->OemTableId)[2],
      ((UINT8 *)&pHeader->OemTableId)[3],
      ((UINT8 *)&pHeader->OemTableId)[4],
      ((UINT8 *)&pHeader->OemTableId)[5]);
    PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(pPrinterCtx, pPath, L"OemRevision               ", FORMAT_HEX_NOWIDTH, pHeader->OemRevision);
    PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(pPrinterCtx, pPath, L"CreatorId                 ", L"%c%c%c%c",
      ((UINT8 *)&pHeader->CreatorId)[0],
      ((UINT8 *)&pHeader->CreatorId)[1],
      ((UINT8 *)&pHeader->CreatorId)[2],
      ((UINT8 *)&pHeader->CreatorId)[3]);
    PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(pPrinterCtx, pPath, L"CreatorRevision           ", FORMAT_HEX_NOWIDTH, pHeader->CreatorRevision);
  }
  
  /**
    Print Platform Config Data PCAT table header
  
    @param[in] pHeader PCAT table header
    @param[in] pPrinterCtx pointer for printer
    @param[in] pPath
  **/
  VOID
  PrintPcdPcatTableHeader(
    IN     PCAT_TABLE_HEADER *pHeader,
    IN     PRINT_CONTEXT *pPrinterCtx,
    IN     CHAR16 *pPath
  )
  {
    PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(pPrinterCtx, pPath, L"Type                      ", FORMAT_HEX_NOWIDTH, pHeader->Type);
    PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(pPrinterCtx, pPath, L"Length                    ", FORMAT_HEX_NOWIDTH, pHeader->Length);
  }
  
  /**
    Print Platform Config Data Partition Size Change table
  
    @param[in] pPartitionSizeChange Partition Size Change table
    @param[in] pPrinterCtx pointer for printer
    @param[in] pPath
  **/
  VOID
  PrintPcdPartitionSizeChange(
    IN     NVDIMM_PARTITION_SIZE_CHANGE *pPartitionSizeChange,
    IN     PRINT_CONTEXT *pPrinterCtx,
    IN     CHAR16 *pPath
  )
  {
    PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(pPrinterCtx, pPath, PCD_PCAT_TABLE_STR, L"PCD Partition Size Change");
    PrintPcdPcatTableHeader(&pPartitionSizeChange->Header, pPrinterCtx, pPath);
    PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(pPrinterCtx, pPath, L"PartitionSizeChangeStatus ", FORMAT_HEX_NOWIDTH, pPartitionSizeChange->PartitionSizeChangeStatus);
    PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(pPrinterCtx, pPath, L"PartitionSize             ", FORMAT_UINT64_HEX_NOWIDTH, pPartitionSizeChange->PmPartitionSize);
    PRINTER_APPEND_KEY_VAL_WIDE_STR(pPrinterCtx, pPath, L"PartitionSize             ", L"\n");
  }
  
  /**
    Print  Platform Config Data Identification Information table
  
    @param[in] pIdentificationInfo Identification Information table
    @param[in] PcdConfigTableRevision Revision of the PCD Config tables
    @param[in] pPrinterCtx pointer for printer
    @param[in] pPath
  **/
  VOID
  PrintPcdIdentificationInformation(
    IN     VOID *pIdentificationInfoTable,
    IN     ACPI_REVISION PcdConfigTableRevision,
    IN     PRINT_CONTEXT *pPrinterCtx,
    IN     CHAR16 *pPath
  )
  {
    CHAR16 PartNumber[PART_NUMBER_SIZE + 1];
    CHAR16 *pTmpDimmUid = NULL;
  
    PRINTER_SET_KEY_VAL_WIDE_STR(pPrinterCtx, pPath, PCD_IDENTIFICATION_INFO_STR, L"PCD Identification Info");
  
    if (IS_ACPI_REV_MAJ_0_MIN_VALID(PcdConfigTableRevision)) {
      NVDIMM_IDENTIFICATION_INFORMATION *pIdentificationInfo = (NVDIMM_IDENTIFICATION_INFORMATION *)pIdentificationInfoTable;
      ZeroMem(PartNumber, sizeof(PartNumber));
      AsciiStrToUnicodeStrS(pIdentificationInfo->DimmIdentification.Version1.DimmPartNumber, PartNumber, PART_NUMBER_SIZE + 1);
      if (IS_ACPI_REV_MAJ_0_MIN_1(PcdConfigTableRevision)) {
        PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(pPrinterCtx, pPath, L"DimmManufacturerId        ", FORMAT_HEX_NOWIDTH,
          EndianSwapUint16(pIdentificationInfo->DimmIdentification.Version1.DimmManufacturerId));
        PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(pPrinterCtx, pPath, L"DimmSerialNumber          ", FORMAT_HEX_NOWIDTH,
          EndianSwapUint32(pIdentificationInfo->DimmIdentification.Version1.DimmSerialNumber));
        PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(pPrinterCtx, pPath, L"DimmPartNumber            ", FORMAT_STR, PartNumber);
      }
      else {
        pTmpDimmUid = CatSPrint(NULL, L"%04x-%02x-%04x-%08x", EndianSwapUint16(pIdentificationInfo->DimmIdentification.Version2.Uid.ManufacturerId),
          pIdentificationInfo->DimmIdentification.Version2.Uid.ManufacturingLocation,
          EndianSwapUint16(pIdentificationInfo->DimmIdentification.Version2.Uid.ManufacturingDate),
          EndianSwapUint32(pIdentificationInfo->DimmIdentification.Version2.Uid.SerialNumber));
        PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(pPrinterCtx, pPath, L"DimmUniqueIdentifer       ", FORMAT_STR, pTmpDimmUid);
      }
      PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(pPrinterCtx, pPath, L"PartitionOffset           ", FORMAT_UINT64_HEX_NOWIDTH, pIdentificationInfo->PartitionOffset);
      PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(pPrinterCtx, pPath, L"PmPartitionSize           ", FORMAT_UINT64_HEX_NOWIDTH L"\n", pIdentificationInfo->PmPartitionSize);
    }
    else if (IS_ACPI_REV_MAJ_1_MIN_VALID(PcdConfigTableRevision)) {
      NVDIMM_IDENTIFICATION_INFORMATION3 *pIdentificationInfo = (NVDIMM_IDENTIFICATION_INFORMATION3 *)pIdentificationInfoTable;
      pTmpDimmUid = CatSPrint(NULL, L"%04x-%02x-%04x-%08x", EndianSwapUint16(pIdentificationInfo->DimmIdentification.ManufacturerId),
        pIdentificationInfo->DimmIdentification.ManufacturingLocation,
        EndianSwapUint16(pIdentificationInfo->DimmIdentification.ManufacturingDate),
        EndianSwapUint32(pIdentificationInfo->DimmIdentification.SerialNumber));
      PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(pPrinterCtx, pPath, L"DimmUniqueIdentifer       ", FORMAT_STR, pTmpDimmUid);
      PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(pPrinterCtx, pPath, L"DimmLocation              ", FORMAT_UINT64_HEX_NOWIDTH, pIdentificationInfo->DimmLocation.AsUint64);
      PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(pPrinterCtx, pPath, L"PartitionOffset           ", FORMAT_UINT64_HEX_NOWIDTH, pIdentificationInfo->PartitionOffset);
      PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(pPrinterCtx, pPath, L"PmPartitionSize           ", FORMAT_UINT64_HEX_NOWIDTH L"\n", pIdentificationInfo->PmPartitionSize);
    }
  
    if (pTmpDimmUid != NULL) {
      FREE_POOL_SAFE(pTmpDimmUid);
    }
  }
  
  /**
    Print Platform Config Data Interleave Information table and its extension tables
  
    @param[in] pInterleaveInfo Interleave Information table
    @param[in] PcdConfigTableRevision Revision of the PCD Config tables
    @param[in] pPrinterCtx pointer for printer
    @param[in] pPath
  **/
  VOID
  PrintPcdInterleaveInformation(
    IN     PCAT_TABLE_HEADER *pInterleaveInfoTable,
    IN     ACPI_REVISION PcdConfigTableRevision,
    IN     PRINT_CONTEXT *pPrinterCtx,
    IN     CHAR16 *pPath
  )
  {
    UINT32 Index = 0;
    UINT32 IdentificationInfoIndex = 0;
    CHAR16 *pPathPcdIdentificationInfo = NULL;
  
    PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(pPrinterCtx, pPath, PCD_PCAT_TABLE_STR, L"PCD Interleave Info");
    if (IS_ACPI_REV_MAJ_0_MIN_VALID(PcdConfigTableRevision)) {
      NVDIMM_INTERLEAVE_INFORMATION *pInterleaveInfo = (NVDIMM_INTERLEAVE_INFORMATION *)pInterleaveInfoTable;
      PrintPcdPcatTableHeader(&pInterleaveInfo->Header, pPrinterCtx, pPath);
      PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(pPrinterCtx, pPath, L"InterleaveSetIndex        ", FORMAT_HEX_NOWIDTH, pInterleaveInfo->InterleaveSetIndex);
      PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(pPrinterCtx, pPath, L"NumOfDimmsInInterleaveSet ", FORMAT_HEX_NOWIDTH, pInterleaveInfo->NumOfDimmsInInterleaveSet);
      PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(pPrinterCtx, pPath, L"InterleaveMemoryType      ", FORMAT_HEX_NOWIDTH, pInterleaveInfo->InterleaveMemoryType);
      PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(pPrinterCtx, pPath, L"InterleaveFormatChannel   ", FORMAT_HEX_NOWIDTH, pInterleaveInfo->InterleaveFormatChannel);
      PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(pPrinterCtx, pPath, L"InterleaveFormatImc       ", FORMAT_HEX_NOWIDTH, pInterleaveInfo->InterleaveFormatImc);
      PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(pPrinterCtx, pPath, L"InterleaveFormatWays      ", FORMAT_HEX_NOWIDTH, pInterleaveInfo->InterleaveFormatWays);
      PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(pPrinterCtx, pPath, L"MirrorEnable              ", FORMAT_HEX_NOWIDTH, pInterleaveInfo->MirrorEnable);
      PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(pPrinterCtx, pPath, L"InterleaveChangeStatus    ", FORMAT_HEX_NOWIDTH L"\n", pInterleaveInfo->InterleaveChangeStatus);
  
      NVDIMM_IDENTIFICATION_INFORMATION *pCurrentIdentInfo = (NVDIMM_IDENTIFICATION_INFORMATION *)&pInterleaveInfo->pIdentificationInfoList;
      for (Index = 0; Index < pInterleaveInfo->NumOfDimmsInInterleaveSet; Index++) {
        PRINTER_BUILD_KEY_PATH(pPathPcdIdentificationInfo, DS_IDENTIFICATION_INFO_INDEX_PATH, gDimmIndex, 1, ConfigIndex, 1, Index);
        IdentificationInfoIndex++;
        PrintPcdIdentificationInformation(pCurrentIdentInfo, PcdConfigTableRevision, pPrinterCtx, pPathPcdIdentificationInfo);
        pCurrentIdentInfo++;
      }
    }
    else if (IS_ACPI_REV_MAJ_1_MIN_VALID(PcdConfigTableRevision)) {
      NVDIMM_INTERLEAVE_INFORMATION3 *pInterleaveInfo = (NVDIMM_INTERLEAVE_INFORMATION3 *)pInterleaveInfoTable;
      PrintPcdPcatTableHeader(&pInterleaveInfo->Header, pPrinterCtx, pPath);
      PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(pPrinterCtx, pPath, L"InterleaveSetIndex        ", FORMAT_HEX_NOWIDTH, pInterleaveInfo->InterleaveSetIndex);
      PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(pPrinterCtx, pPath, L"NumOfDimmsInInterleaveSet ", FORMAT_HEX_NOWIDTH, pInterleaveInfo->NumOfDimmsInInterleaveSet);
      PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(pPrinterCtx, pPath, L"InterleaveMemoryType      ", FORMAT_HEX_NOWIDTH, pInterleaveInfo->InterleaveMemoryType);
      PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(pPrinterCtx, pPath, L"InterleaveSizeChannel     ", FORMAT_HEX_NOWIDTH, pInterleaveInfo->InterleaveFormatChannel);
      PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(pPrinterCtx, pPath, L"InterleaveSizeImc         ", FORMAT_HEX_NOWIDTH, pInterleaveInfo->InterleaveFormatImc);
      PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(pPrinterCtx, pPath, L"InterleaveChangeStatus    ", FORMAT_HEX_NOWIDTH L"\n", pInterleaveInfo->InterleaveChangeStatus);
  
      NVDIMM_IDENTIFICATION_INFORMATION3 *pCurrentIdentInfo = (NVDIMM_IDENTIFICATION_INFORMATION3 *)&pInterleaveInfo->pIdentificationInfoList;
      for (Index = 0; Index < pInterleaveInfo->NumOfDimmsInInterleaveSet; Index++) {
        PRINTER_BUILD_KEY_PATH(pPathPcdIdentificationInfo, DS_IDENTIFICATION_INFO_INDEX_PATH, gDimmIndex, 1, ConfigIndex, 1, Index);
        IdentificationInfoIndex++;
        PrintPcdIdentificationInformation(pCurrentIdentInfo, PcdConfigTableRevision, pPrinterCtx, pPathPcdIdentificationInfo);
        pCurrentIdentInfo++;
      }
    }
    FREE_POOL_SAFE(pPathPcdIdentificationInfo);
  }
  
  VOID
  PrintPcdConfigManagementAttributesInformation(
    IN    CONFIG_MANAGEMENT_ATTRIBUTES_EXTENSION_TABLE *pConfigManagementAttributesInfo,
    IN     PRINT_CONTEXT *pPrinterCtx,
    IN     CHAR16 *pPath
  )
  {
    INTEL_DIMM_CONFIG *pIntelDIMMConfig = NULL;
    EFI_GUID IntelDimmConfigVariableGuid = INTEL_DIMM_CONFIG_VARIABLE_GUID;
    CHAR16 *pGuidStr = NULL;
  
    pGuidStr = GuidToStr(&pConfigManagementAttributesInfo->Guid);
  
    PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(pPrinterCtx, pPath, L"Mngmt Table            ", L"PCD Cfg Mngmt Attr Extension");
    PrintPcdPcatTableHeader(&pConfigManagementAttributesInfo->Header, pPrinterCtx, pPath);
    PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(pPrinterCtx, pPath, L"VendorID               ", FORMAT_HEX_NOWIDTH, pConfigManagementAttributesInfo->VendorId);
    PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(pPrinterCtx, pPath, L"GUID                   ", FORMAT_STR_NL, pGuidStr);
  
    if (CompareGuid(&pConfigManagementAttributesInfo->Guid, &IntelDimmConfigVariableGuid)) {
      pIntelDIMMConfig = (INTEL_DIMM_CONFIG *)pConfigManagementAttributesInfo->pGuidData;
      PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(pPrinterCtx, pPath, L"Revision                ", FORMAT_INT32, pIntelDIMMConfig->Revision);
      PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(pPrinterCtx, pPath, L"ProvisionCapacityMode   ", FORMAT_INT32, pIntelDIMMConfig->ProvisionCapacityMode);
      PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(pPrinterCtx, pPath, L"MemorySize              ", FORMAT_INT32, pIntelDIMMConfig->MemorySize);
      PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(pPrinterCtx, pPath, L"PMType                  ", FORMAT_INT32, pIntelDIMMConfig->PMType);
      PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(pPrinterCtx, pPath, L"ProvisionNamespaceMode  ", FORMAT_INT32, pIntelDIMMConfig->ProvisionNamespaceMode);
      PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(pPrinterCtx, pPath, L"NamespaceFlags          ", FORMAT_INT32, pIntelDIMMConfig->NamespaceFlags);
      PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(pPrinterCtx, pPath, L"NamespaceLabelVersion   ", FORMAT_INT32, pIntelDIMMConfig->NamespaceLabelVersion);
    }
  
    FREE_POOL_SAFE(pGuidStr);
  }
  
  /**
    Print Platform Config Data Current Config table and its PCAT tables
  
    @param[in] pCurrentConfig Current Config table
    @param[in] pPrinterCtx pointer for printer
    @param[in] pPath
  **/
  VOID
  PrintPcdCurrentConfig(
    IN     NVDIMM_CURRENT_CONFIG *pCurrentConfig,
    IN     PRINT_CONTEXT *pPrinterCtx,
    IN     CHAR16 *pPath
  )
  {
    NVDIMM_PARTITION_SIZE_CHANGE *pPartSizeChange = NULL;
    CONFIG_MANAGEMENT_ATTRIBUTES_EXTENSION_TABLE *pConfigManagementAttributesInfo = NULL;
    PCAT_TABLE_HEADER *pCurPcatTable = NULL;
    UINT32 SizeOfPcatTables = 0;
    EFI_STATUS ReturnCode = EFI_SUCCESS;
    CHAR16 *pPathPcdPcatTable = NULL;
  
    if (IS_ACPI_HEADER_REV_INVALID(pCurrentConfig)){
      ReturnCode = EFI_INVALID_PARAMETER;
      PRINTER_SET_MSG(pPrinterCtx, ReturnCode, L"Error: Invalid revision value %d for PCD current config table.", pCurrentConfig->Header.Revision);
      return;
    }
  
    PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(pPrinterCtx, pPath, PCD_TABLE_STR, L"PCD Current Config");
    PrintPcdTableHeader(&pCurrentConfig->Header, pPrinterCtx, pPath);
    PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(pPrinterCtx, pPath, L"ConfigStatus              ", FORMAT_HEX_NOWIDTH, pCurrentConfig->ConfigStatus);
    PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(pPrinterCtx, pPath, L"VolatileMemSizeIntoSpa    ", FORMAT_UINT64_HEX_NOWIDTH, pCurrentConfig->VolatileMemSizeIntoSpa);
    PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(pPrinterCtx, pPath, L"PersistentMemSizeIntoSpa  ", FORMAT_UINT64_HEX_NOWIDTH, pCurrentConfig->PersistentMemSizeIntoSpa);
    PRINTER_APPEND_KEY_VAL_WIDE_STR(pPrinterCtx, pPath, L"PersistentMemSizeIntoSpa  ", L"\n");
  
    /**
      Check if there is at least one PCAT table
    **/
    if (pCurrentConfig->Header.Length <= sizeof(*pCurrentConfig)) {
      return;
    }
  
    pCurPcatTable = (PCAT_TABLE_HEADER *)&pCurrentConfig->pPcatTables;
    SizeOfPcatTables = pCurrentConfig->Header.Length - (UINT32)((UINT8 *)pCurPcatTable - (UINT8 *)pCurrentConfig);
  
    /**
      Example of the use of the while loop condition
      PCAT table #1   offset:  0   size: 10
      PCAT table #2   offset: 10   size:  5
      Size of PCAT tables: 15 (10 + 5)
  
      Iteration #1:   offset: 0
      Iteration #2:   offset: 10
      Iteration #3:   offset: 15   stop the loop: offset isn't less than size
    **/
    while ((UINT32)((UINT8 *)pCurPcatTable - (UINT8 *)&pCurrentConfig->pPcatTables) < SizeOfPcatTables) {
      if (pCurPcatTable->Type == PCAT_TYPE_PARTITION_SIZE_CHANGE_TABLE) {
        PRINTER_BUILD_KEY_PATH(pPathPcdPcatTable, DS_PCD_PCAT_TABLE_INDEX_PATH, gDimmIndex, 1, ConfigIndex, 0);
  
        pPartSizeChange = (NVDIMM_PARTITION_SIZE_CHANGE *)pCurPcatTable;
  
        PrintPcdPartitionSizeChange(pPartSizeChange, pPrinterCtx, pPathPcdPcatTable);
  
        pCurPcatTable = GET_VOID_PTR_OFFSET(pCurPcatTable, pPartSizeChange->Header.Length);
      }
      else if (pCurPcatTable->Type == PCAT_TYPE_INTERLEAVE_INFORMATION_TABLE) {
        PRINTER_BUILD_KEY_PATH(pPathPcdPcatTable, DS_PCD_PCAT_TABLE_INDEX_PATH, gDimmIndex, 1, ConfigIndex, 1);
  
        PrintPcdInterleaveInformation(pCurPcatTable, pCurrentConfig->Header.Revision, pPrinterCtx, pPathPcdPcatTable);
  
        pCurPcatTable = GET_VOID_PTR_OFFSET(pCurPcatTable, pCurPcatTable->Length);
      }
      else if (pCurPcatTable->Type == PCAT_TYPE_CONFIG_MANAGEMENT_ATTRIBUTES_TABLE) {
        pConfigManagementAttributesInfo = (CONFIG_MANAGEMENT_ATTRIBUTES_EXTENSION_TABLE *)pCurPcatTable;
  
        pCurPcatTable = GET_VOID_PTR_OFFSET(pCurPcatTable, pConfigManagementAttributesInfo->Header.Length);
      }
      else {
        ReturnCode = EFI_INVALID_PARAMETER;
        PRINTER_SET_MSG(pPrinterCtx, ReturnCode, L"Error: wrong PCAT table type");
        break;
      }
      FREE_POOL_SAFE(pPathPcdPcatTable);
    }
  }
  
  /**
    Print Platform Config Data Config Input table and its PCAT tables
  
    @param[in] pConfigInput Config Input table
    @param[in] pPrinterCtx pointer for printer
    @param[in] pPath
  **/
  VOID
  PrintPcdConfInput(
    IN     NVDIMM_PLATFORM_CONFIG_INPUT *pConfigInput,
    IN     PRINT_CONTEXT *pPrinterCtx,
    IN     CHAR16 *pPath
  )
  {
    NVDIMM_PARTITION_SIZE_CHANGE *pPartSizeChange = NULL;
    CONFIG_MANAGEMENT_ATTRIBUTES_EXTENSION_TABLE *pConfigManagementAttributesInfo = NULL;
    PCAT_TABLE_HEADER *pCurPcatTable = NULL;
    UINT32 SizeOfPcatTables = 0;
    EFI_STATUS ReturnCode = EFI_SUCCESS;
    CHAR16 *pPathPcdPcatTable = NULL;
  
    if (IS_ACPI_HEADER_REV_INVALID(pConfigInput)) {
      ReturnCode = EFI_INVALID_PARAMETER;
      PRINTER_SET_MSG(pPrinterCtx, ReturnCode, L"Error: Invalid revision value %d for PCD config input table.", pConfigInput->Header.Revision);
      return;
    }
  
    PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(pPrinterCtx, pPath, PCD_TABLE_STR, L"Platform Config Data Conf Input table");
    PrintPcdTableHeader(&pConfigInput->Header, pPrinterCtx, pPath);
    PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(pPrinterCtx, pPath, L"SequenceNumber             ", FORMAT_HEX_NOWIDTH, pConfigInput->SequenceNumber);
    PRINTER_APPEND_KEY_VAL_WIDE_STR(pPrinterCtx, pPath, L"SequenceNumber             ", L"\n");
  
    /**
      Check if there is at least one PCAT table
    **/
    if (pConfigInput->Header.Length <= sizeof(*pConfigInput)) {
      return;
    }
  
    pCurPcatTable = (PCAT_TABLE_HEADER *)&pConfigInput->pPcatTables;
    SizeOfPcatTables = pConfigInput->Header.Length - (UINT32)((UINT8 *)pCurPcatTable - (UINT8 *)pConfigInput);
  
    /**
      Example of the use of the while loop condition
      PCAT table #1   offset:  0   size: 10
      PCAT table #2   offset: 10   size:  5
      Size of PCAT tables: 15 (10 + 5)
  
      Iteration #1:   offset: 0
      Iteration #2:   offset: 10
      Iteration #3:   offset: 15   stop the loop: offset isn't less than size
    **/
    while ((UINT32)((UINT8 *)pCurPcatTable - (UINT8 *)&pConfigInput->pPcatTables) < SizeOfPcatTables) {
      if (pCurPcatTable->Type == PCAT_TYPE_PARTITION_SIZE_CHANGE_TABLE) {
        PRINTER_BUILD_KEY_PATH(pPathPcdPcatTable, DS_PCD_PCAT_TABLE_INDEX_PATH, gDimmIndex, 1, ConfigIndex, 0);
  
        pPartSizeChange = (NVDIMM_PARTITION_SIZE_CHANGE *)pCurPcatTable;
  
        PrintPcdPartitionSizeChange(pPartSizeChange, pPrinterCtx, pPathPcdPcatTable);
  
        pCurPcatTable = GET_VOID_PTR_OFFSET(pCurPcatTable, pPartSizeChange->Header.Length);
      }
      else if (pCurPcatTable->Type == PCAT_TYPE_INTERLEAVE_INFORMATION_TABLE) {
        PRINTER_BUILD_KEY_PATH(pPathPcdPcatTable, DS_PCD_PCAT_TABLE_INDEX_PATH, gDimmIndex, 1, ConfigIndex, 1);
  
        PrintPcdInterleaveInformation(pCurPcatTable, pConfigInput->Header.Revision, pPrinterCtx, pPathPcdPcatTable);
  
        pCurPcatTable = GET_VOID_PTR_OFFSET(pCurPcatTable, pCurPcatTable->Length);
      }
      else if (pCurPcatTable->Type == PCAT_TYPE_CONFIG_MANAGEMENT_ATTRIBUTES_TABLE) {
        PRINTER_BUILD_KEY_PATH(pPathPcdPcatTable, DS_PCD_PCAT_TABLE_INDEX_PATH, gDimmIndex, 1, ConfigIndex, 2);
  
        pConfigManagementAttributesInfo = (CONFIG_MANAGEMENT_ATTRIBUTES_EXTENSION_TABLE *)pCurPcatTable;
  
        PrintPcdConfigManagementAttributesInformation(pConfigManagementAttributesInfo, pPrinterCtx, pPathPcdPcatTable);
  
        pCurPcatTable = GET_VOID_PTR_OFFSET(pCurPcatTable, pConfigManagementAttributesInfo->Header.Length);
      }
      else {
        ReturnCode = EFI_INVALID_PARAMETER;
        PRINTER_SET_MSG(pPrinterCtx, ReturnCode, L"Error: wrong PCAT table type");
        break;
      }
      FREE_POOL_SAFE(pPathPcdPcatTable);
    }
  }
  
  /**
    Print Platform Config Data Config Output table and its PCAT tables
  
    @param[in] pConfigOutput Config Output table
    @param[in] pPrinterCtx pointer for printer
    @param[in] pPath
  **/
  VOID
  PrintPcdConfOutput(
    IN     NVDIMM_PLATFORM_CONFIG_OUTPUT *pConfigOutput,
    IN     PRINT_CONTEXT *pPrinterCtx,
    IN     CHAR16 *pPath
  )
  {
    NVDIMM_PARTITION_SIZE_CHANGE *pPartSizeChange = NULL;
    CONFIG_MANAGEMENT_ATTRIBUTES_EXTENSION_TABLE *pConfigManagementAttributesInfo = NULL;
    PCAT_TABLE_HEADER *pCurPcatTable = NULL;
    UINT32 SizeOfPcatTables = 0;
    EFI_STATUS ReturnCode = EFI_SUCCESS;
    CHAR16 *pPathPcdPcatTable = NULL;
  
    if (IS_ACPI_HEADER_REV_INVALID(pConfigOutput)) {
      ReturnCode = EFI_INVALID_PARAMETER;
      PRINTER_SET_MSG(pPrinterCtx, ReturnCode, L"Error: Invalid revision value %d for PCD config output table.", pConfigOutput->Header.Revision);
      return;
    }
  
    PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(pPrinterCtx, pPath, PCD_TABLE_STR, L"Platform Config Data Conf Output table");
    PrintPcdTableHeader(&pConfigOutput->Header, pPrinterCtx, pPath);
    PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(pPrinterCtx, pPath, L"SequenceNumber             ", FORMAT_HEX_NOWIDTH, pConfigOutput->SequenceNumber);
    PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(pPrinterCtx, pPath, L"ValidationStatus           ", FORMAT_HEX_NOWIDTH, pConfigOutput->ValidationStatus);
    PRINTER_APPEND_KEY_VAL_WIDE_STR(pPrinterCtx, pPath, L"ValidationStatus           ", L"\n");
  
    /** Check if there is at least one PCAT table **/
    if (pConfigOutput->Header.Length <= sizeof(*pConfigOutput)) {
      return;
    }
  
    pCurPcatTable = (PCAT_TABLE_HEADER *)&pConfigOutput->pPcatTables;
    SizeOfPcatTables = pConfigOutput->Header.Length - (UINT32)((UINT8 *)pCurPcatTable - (UINT8 *)pConfigOutput);
  
    /**
      Example of the use of the while loop condition
      PCAT table #1   offset:  0   size: 10
      PCAT table #2   offset: 10   size:  5
      Size of PCAT tables: 15 (10 + 5)
  
      Iteration #1:   offset: 0
      Iteration #2:   offset: 10
      Iteration #3:   offset: 15   stop the loop: offset isn't less than size
    **/
    while ((UINT32)((UINT8 *)pCurPcatTable - (UINT8 *)&pConfigOutput->pPcatTables) < SizeOfPcatTables) {
      if (pCurPcatTable->Type == PCAT_TYPE_PARTITION_SIZE_CHANGE_TABLE) {
        PRINTER_BUILD_KEY_PATH(pPathPcdPcatTable, DS_PCD_PCAT_TABLE_INDEX_PATH, gDimmIndex, 1, ConfigIndex, 0);
  
        pPartSizeChange = (NVDIMM_PARTITION_SIZE_CHANGE *)pCurPcatTable;
  
        PrintPcdPartitionSizeChange(pPartSizeChange, pPrinterCtx, pPathPcdPcatTable);
  
        pCurPcatTable = GET_VOID_PTR_OFFSET(pCurPcatTable, pPartSizeChange->Header.Length);
      }
      else if (pCurPcatTable->Type == PCAT_TYPE_INTERLEAVE_INFORMATION_TABLE) {
        PRINTER_BUILD_KEY_PATH(pPathPcdPcatTable, DS_PCD_PCAT_TABLE_INDEX_PATH, gDimmIndex, 1, ConfigIndex, 1);
  
        PrintPcdInterleaveInformation(pCurPcatTable, pConfigOutput->Header.Revision, pPrinterCtx, pPathPcdPcatTable);
  
        pCurPcatTable = GET_VOID_PTR_OFFSET(pCurPcatTable, pCurPcatTable->Length);
      }
      else if (pCurPcatTable->Type == PCAT_TYPE_CONFIG_MANAGEMENT_ATTRIBUTES_TABLE) {
        pConfigManagementAttributesInfo = (CONFIG_MANAGEMENT_ATTRIBUTES_EXTENSION_TABLE *)pCurPcatTable;
  
        pCurPcatTable = GET_VOID_PTR_OFFSET(pCurPcatTable, pConfigManagementAttributesInfo->Header.Length);
      }
      else {
        ReturnCode = EFI_INVALID_PARAMETER;
        PRINTER_SET_MSG(pPrinterCtx, ReturnCode, L"Error: wrong PCAT table type");
        break;
      }
      FREE_POOL_SAFE(pPathPcdPcatTable);
    }
  }
  
  /**
     Print Platform Config Data Configuration Header table and all subtables
  
     @param[in] pConfHeader Configuration Header table
     @param[in] pPrinterCtx pointer for printer
     @param[in] pPath
  **/
  VOID
  PrintPcdConfigurationHeader(
    IN     NVDIMM_CONFIGURATION_HEADER *pConfHeader,
    IN     PRINT_CONTEXT *pPrinterCtx,
    IN     CHAR16 *pPath
  )
  {
    CHAR16 *pPathPcdTable = NULL;
  
    ConfigIndex = 0;
    PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(pPrinterCtx, pPath, L"Table                     ", L"PCD Config Header");
    PrintPcdTableHeader(&pConfHeader->Header, pPrinterCtx, pPath);
    PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(pPrinterCtx, pPath, L"CurrentConfDataSize       ", FORMAT_HEX_NOWIDTH, pConfHeader->CurrentConfDataSize);
    PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(pPrinterCtx, pPath, L"CurrentConfStartOffset    ", FORMAT_HEX_NOWIDTH, pConfHeader->CurrentConfStartOffset);
    PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(pPrinterCtx, pPath, L"ConfInputDataSize         ", FORMAT_HEX_NOWIDTH, pConfHeader->ConfInputDataSize);
    PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(pPrinterCtx, pPath, L"ConfInputDataOffset       ", FORMAT_HEX_NOWIDTH, pConfHeader->ConfInputStartOffset);
    PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(pPrinterCtx, pPath, L"ConfOutputDataSize        ", FORMAT_HEX_NOWIDTH, pConfHeader->ConfOutputDataSize);
    PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(pPrinterCtx, pPath, L"ConfOutputDataOffset      ", FORMAT_HEX_NOWIDTH, pConfHeader->ConfOutputStartOffset);
    PRINTER_APPEND_KEY_VAL_WIDE_STR(pPrinterCtx, pPath, L"ConfOutputDataOffset      ", L"\n");
  
    if (pConfHeader->CurrentConfStartOffset != 0 && pConfHeader->CurrentConfDataSize != 0) {
      PRINTER_BUILD_KEY_PATH(pPathPcdTable, DS_TABLE_INDEX_PATH, gDimmIndex, 1, ConfigIndex);
      PrintPcdCurrentConfig(GET_NVDIMM_CURRENT_CONFIG(pConfHeader), pPrinterCtx, pPathPcdTable);
      ConfigIndex++;
    }
    if (pConfHeader->ConfInputStartOffset != 0 && pConfHeader->ConfInputDataSize != 0) {
      PRINTER_BUILD_KEY_PATH(pPathPcdTable, DS_TABLE_INDEX_PATH, gDimmIndex, 1, ConfigIndex);
      PrintPcdConfInput(GET_NVDIMM_PLATFORM_CONFIG_INPUT(pConfHeader), pPrinterCtx, pPathPcdTable);
      ConfigIndex++;
    }
    if (pConfHeader->ConfOutputStartOffset != 0 && pConfHeader->ConfOutputDataSize != 0) {
      PRINTER_BUILD_KEY_PATH(pPathPcdTable, DS_TABLE_INDEX_PATH, gDimmIndex, 1, ConfigIndex);
      PrintPcdConfOutput(GET_NVDIMM_PLATFORM_CONFIG_OUTPUT(pConfHeader), pPrinterCtx, pPathPcdTable);
      ConfigIndex++;
    }
    FREE_POOL_SAFE(pPathPcdTable);
  }
  
  /**
     Print Namespace Index
  
     @param[in] pNamespaceIndex Namespace Index
  **/
  VOID
  PrintNamespaceIndex(
    IN     NAMESPACE_INDEX *pNamespaceIndex
  )
  {
    CHAR16 Buffer[NSINDEX_SIG_LEN + 1];
  
    if (pNamespaceIndex == NULL) {
      return;
    }
  
    ZeroMem(Buffer, sizeof(Buffer));
    AsciiStrToUnicodeStrS((CHAR8 *)&pNamespaceIndex->Signature, Buffer, NSINDEX_SIG_LEN + 1);
  
    PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(gpPrinterCtxLbaCommon, gpPathLba, L"Signature          ", FORMAT_STR, Buffer);
    PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(gpPrinterCtxLbaCommon, gpPathLba, L"Flags              ", FORMAT_HEX_NOWIDTH, *pNamespaceIndex->Flags);
    PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(gpPrinterCtxLbaCommon, gpPathLba, L"LabelSize          ", FORMAT_HEX_NOWIDTH, pNamespaceIndex->LabelSize);
    PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(gpPrinterCtxLbaCommon, gpPathLba, L"Sequence           ", FORMAT_HEX_NOWIDTH, pNamespaceIndex->Sequence);
    PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(gpPrinterCtxLbaCommon, gpPathLba, L"MyOffset           ", FORMAT_UINT64_HEX_NOWIDTH, pNamespaceIndex->MyOffset);
    PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(gpPrinterCtxLbaCommon, gpPathLba, L"MySize             ", FORMAT_UINT64_HEX_NOWIDTH, pNamespaceIndex->MySize);
    PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(gpPrinterCtxLbaCommon, gpPathLba, L"OtherOffset        ", FORMAT_UINT64_HEX_NOWIDTH, pNamespaceIndex->OtherOffset);
    PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(gpPrinterCtxLbaCommon, gpPathLba, L"LabelOffset        ", FORMAT_UINT64_HEX_NOWIDTH, pNamespaceIndex->LabelOffset);
    PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(gpPrinterCtxLbaCommon, gpPathLba, L"NumOfLabel         ", FORMAT_HEX_NOWIDTH, pNamespaceIndex->NumberOfLabels);
    PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(gpPrinterCtxLbaCommon, gpPathLba, L"Major              ", FORMAT_HEX_NOWIDTH, pNamespaceIndex->Major);
    PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(gpPrinterCtxLbaCommon, gpPathLba, L"Minor              ", FORMAT_HEX_NOWIDTH, pNamespaceIndex->Minor);
    PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(gpPrinterCtxLbaCommon, gpPathLba, L"Checksum           ", FORMAT_UINT64_HEX_NOWIDTH, pNamespaceIndex->Checksum);
  
    PrintLsaHex(pNamespaceIndex->pFree,
      LABELS_TO_FREE_BYTES(ROUNDUP(pNamespaceIndex->NumberOfLabels, 8)));
  }
  
  /**
     Print Namespace Label
  
     @param[in] pNamespaceLabel Namespace Label
     @param[in] pPrinterCtx pointer for printer
     @param[in] pPath
  **/
  VOID
  PrintNamespaceLabel(
    IN     NAMESPACE_LABEL *pNamespaceLabel,
    IN     PRINT_CONTEXT *pPrinterCtx,
    IN     CHAR16 *pPath
  )
  {
    CHAR16 Buffer[NLABEL_NAME_LEN_WITH_TERMINATOR];
    CHAR16 *pUuidStr = NULL;
    CHAR16 *pTypeGuidStr = NULL;
    CHAR16 *pAddrAbstrGuidStr = NULL;
  
    if (pNamespaceLabel == NULL) {
      return;
    }
  
    ZeroMem(Buffer, sizeof(Buffer));
    AsciiStrToUnicodeStrS((CHAR8 *)&pNamespaceLabel->Name, Buffer, NLABEL_NAME_LEN_WITH_TERMINATOR);
  
    pUuidStr = GuidToStr(&pNamespaceLabel->Uuid);
    pTypeGuidStr = GuidToStr(&pNamespaceLabel->TypeGuid);
    pAddrAbstrGuidStr = GuidToStr(&pNamespaceLabel->AddressAbstractionGuid);
  
    PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(pPrinterCtx, pPath, L"Uuid               ", FORMAT_STR, pUuidStr);
    PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(pPrinterCtx, pPath, L"Name               ", FORMAT_STR, Buffer);
    PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(pPrinterCtx, pPath, L"LabelFlags         ", FORMAT_HEX_NOWIDTH, pNamespaceLabel->Flags);
    PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(pPrinterCtx, pPath, L"NumOfLabels        ", FORMAT_HEX_NOWIDTH, pNamespaceLabel->NumberOfLabels);
    PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(pPrinterCtx, pPath, L"Position           ", FORMAT_HEX_NOWIDTH, pNamespaceLabel->Position);
    PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(pPrinterCtx, pPath, L"ISetCookie         ", FORMAT_UINT64_HEX_NOWIDTH, pNamespaceLabel->InterleaveSetCookie);
    PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(pPrinterCtx, pPath, L"LbaSize            ", FORMAT_UINT64_HEX_NOWIDTH, pNamespaceLabel->LbaSize);
    PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(pPrinterCtx, pPath, L"Dpa                ", FORMAT_UINT64_HEX_NOWIDTH, pNamespaceLabel->Dpa);
    PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(pPrinterCtx, pPath, L"RawSize            ", FORMAT_UINT64_HEX_NOWIDTH, pNamespaceLabel->RawSize);
    PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(pPrinterCtx, pPath, L"Slot               ", FORMAT_HEX_NOWIDTH, pNamespaceLabel->Slot);
    PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(pPrinterCtx, pPath, L"Alignment          ", FORMAT_HEX_NOWIDTH, pNamespaceLabel->Alignment);
    PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(pPrinterCtx, pPath, L"TypeGuid           ", FORMAT_STR, pTypeGuidStr);
    PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(pPrinterCtx, pPath, L"AddrAbstrGuid      ", FORMAT_STR, pAddrAbstrGuidStr);
    PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(pPrinterCtx, pPath, L"LabelChecksum      ", FORMAT_UINT64_HEX_NOWIDTH, pNamespaceLabel->Checksum);
    PRINTER_APPEND_KEY_VAL_WIDE_STR(pPrinterCtx, pPath, L"LabelChecksum      ", L"\n");
  
  
    FREE_POOL_SAFE(pUuidStr);
    FREE_POOL_SAFE(pTypeGuidStr);
    FREE_POOL_SAFE(pAddrAbstrGuidStr);
  }
  
  /**
     Print Label Storage Area and all subtables
  
     @param[in] pLba Label Storage Area
     @param[in] pPrinterCtx pointer for printer
     @param[in] pPath
  **/
  VOID
  PrintLabelStorageArea(
    IN     LABEL_STORAGE_AREA *pLba,
    IN     PRINT_CONTEXT *pPrinterCtx,
    IN     CHAR16 *pPath
  )
  {
    EFI_STATUS ReturnCode = EFI_SUCCESS;
    UINT16 Index = 0;
    UINT16 CurrentIndex = 0;
    UINT16 SlotStatus = SLOT_UNKNOWN;
    BOOLEAN First = FALSE;
    PRINT_CONTEXT *pPrinterCtxNsLable = NULL;
    CHAR16 *pPathNsLable = NULL;
  
    pPrinterCtxNsLable = pPrinterCtx;
    if (pLba == NULL) {
      return;
    }
  
    ReturnCode = GetLsaIndexes(pLba, &CurrentIndex, NULL);
    if (EFI_ERROR(ReturnCode)) {
      return;
    }
  
    PRINTER_SET_KEY_VAL_WIDE_STR(pPrinterCtx, pPath, L"Label Storage Area ", L"Current Index");
    gpPathLba = pPath;
    gpPrinterCtxLbaCommon = pPrinterCtx;
    PrintNamespaceIndex(&pLba->Index[CurrentIndex]);
  
    for (Index = 0, First = TRUE; Index < pLba->Index[CurrentIndex].NumberOfLabels; Index++) {
      CheckSlotStatus(&pLba->Index[CurrentIndex], Index, &SlotStatus);
      if (SlotStatus == SLOT_FREE) {
        continue;
      }
  
      if (First) {
        PRINTER_SET_KEY_VAL_WIDE_STR(pPrinterCtx, pPath, L"Labels", L"Label Storage Area ");
        First = FALSE;
      }
      PRINTER_BUILD_KEY_PATH(pPathNsLable, DS_TABLE_INDEX_PATH, gDimmIndex, 0, Index);
      PRINTER_SET_KEY_VAL_WIDE_STR(pPrinterCtxNsLable, pPathNsLable, PCD_TABLE_STR, L"Namespace Label Info");
      PrintNamespaceLabel(&pLba->pLabels[Index], pPrinterCtxNsLable, pPathNsLable);
    }
    FREE_POOL_SAFE(pPathNsLable);
  }
  
  /**
    Function that allows for nicely formatted HEX & ASCII console output.
    It can be used to inspect memory objects without a need for debugger or dumping raw DIMM data.
  
    @param[in] pBuffer Pointer to an arbitrary object
    @param[in] Bytes Number of bytes to display
  **/
  VOID
  PrintLsaHex(
    IN     VOID *pBuffer,
    IN     UINT32 Bytes
  )
  {
    UINT8 Byte, AsciiBuffer[COLUMN_IN_HEX_DUMP];
    UINT16 Column, NextColumn, Index, Index2;
    UINT8 *pData;
    CHAR16 *message = NULL;
    CHAR16 *messageId = NULL;
  
    if (pBuffer == NULL) {
      NVDIMM_DBG("pBuffer is NULL");
      return;
    }
    PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(gpPrinterCtxLbaCommon, gpPathLba, L"Hexdump", L"For %d bytes", Bytes);
    pData = (UINT8 *)pBuffer;
    for (Index = 0; Index < Bytes; Index++) {
      Column = Index % COLUMN_IN_HEX_DUMP;
      NextColumn = (Index + 1) % COLUMN_IN_HEX_DUMP;
      Byte = *(pData + Index);
      if (Column == 0) {
        messageId = CatSPrintClean(messageId, L"%.3d", Index);
      }
  
      if (Index % 8 == 0) {
        message = CatSPrintClean(message, L" ");
      }
  
      message = CatSPrintClean(message, L"%.2x", *(pData + Index));
      AsciiBuffer[Column] = IsAsciiAlnumCharacter(Byte) ? Byte : '.';
      if (NextColumn == 0 && Index != 0) {
        message = CatSPrintClean(message, L" ");
        for (Index2 = 0; Index2 < COLUMN_IN_HEX_DUMP; Index2++) {
          message = CatSPrintClean(message, L"%c", AsciiBuffer[Index2]);
          if (Index2 == COLUMN_IN_HEX_DUMP / 2 - 1) {
            message = CatSPrintClean(message, L" ");
          }
        }
        PRINTER_SET_KEY_VAL_WIDE_STR_FORMAT(gpPrinterCtxLbaCommon, gpPathLba, messageId, message);
        FREE_POOL_SAFE(message);
        FREE_POOL_SAFE(messageId);
      }
    }
  
    FREE_POOL_SAFE(message);
    FREE_POOL_SAFE(messageId);
  }
  