]> git.proxmox.com Git - mirror_edk2.git/commitdiff
DynamicTablesPkg: AML and ASL string helper
authorPierre Gondois <pierre.gondois@arm.com>
Tue, 4 Aug 2020 08:08:47 +0000 (09:08 +0100)
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Thu, 13 Aug 2020 18:00:06 +0000 (18:00 +0000)
Dynamic AML requires encoding/decoding and conversion of
AML and ASL strings. A collection of helper functions
have been provided for internal use in the AmlLib Library.

Signed-off-by: Pierre Gondois <pierre.gondois@arm.com>
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
Reviewed-by: Alexei Fedorov <Alexei.Fedorov@arm.com>
DynamicTablesPkg/Library/Common/AmlLib/String/AmlString.c [new file with mode: 0644]
DynamicTablesPkg/Library/Common/AmlLib/String/AmlString.h [new file with mode: 0644]

diff --git a/DynamicTablesPkg/Library/Common/AmlLib/String/AmlString.c b/DynamicTablesPkg/Library/Common/AmlLib/String/AmlString.c
new file mode 100644 (file)
index 0000000..e9d36f4
--- /dev/null
@@ -0,0 +1,1022 @@
+/** @file\r
+  AML String.\r
+\r
+  Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved. <BR>\r
+  Copyright (c) 2019 - 2020, Arm Limited. All rights reserved.<BR>\r
+\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
+**/\r
+\r
+#include <String/AmlString.h>\r
+\r
+#include <AmlDefines.h>\r
+#include <IndustryStandard/AcpiAml.h>\r
+\r
+/** Check NameString/path information is valid.\r
+\r
+  Root, ParentPrefix and SegCount cannot be 0 at the same time.\r
+  This function works for ASL and AML name strings.\r
+\r
+  @param [in]   Root          Number of root char.\r
+                              Must be 0 or 1.\r
+  @param [in]   ParentPrefix  Number of carets char ('^').\r
+                              Must be [0-255].\r
+  @param [in]   SegCount      Number of NameSeg (s).\r
+                              Must be [0-255].\r
+\r
+  @retval TRUE id the input information is in the right boundaries.\r
+          FALSE otherwise.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+AmlIsNameString (\r
+  IN  UINT32    Root,\r
+  IN  UINT32    ParentPrefix,\r
+  IN  UINT32    SegCount\r
+  )\r
+{\r
+  if (((Root == 0) || (Root == 1))            &&\r
+      (ParentPrefix <= MAX_UINT8)             &&\r
+      (!((ParentPrefix != 0) && (Root != 0))) &&\r
+      (SegCount <= MAX_UINT8)                 &&\r
+      ((SegCount + Root + ParentPrefix) != 0)) {\r
+    return TRUE;\r
+  }\r
+  return FALSE;\r
+}\r
+\r
+/** Copy bytes from SrcBuffer to DstBuffer and convert to upper case.\r
+    Don't copy more than MaxDstBufferSize bytes.\r
+\r
+  @param  [out] DstBuffer         Destination buffer.\r
+  @param  [in]  MaxDstBufferSize  Maximum size of DstBuffer.\r
+                                  Must be non-zero.\r
+  @param  [in]  SrcBuffer         Source buffer.\r
+  @param  [in]  Count             Count of bytes to copy from SrcBuffer.\r
+                                  Return success if 0.\r
+\r
+  @retval EFI_SUCCESS             The function completed successfully.\r
+  @retval EFI_INVALID_PARAMETER   Invalid parameter.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+AmlUpperCaseMemCpyS (\r
+  OUT       CHAR8   * DstBuffer,\r
+  IN        UINT32    MaxDstBufferSize,\r
+  IN  CONST CHAR8   * SrcBuffer,\r
+  IN        UINT32    Count\r
+  )\r
+{\r
+  UINT32 Index;\r
+\r
+  if ((DstBuffer == NULL) ||\r
+      (SrcBuffer == NULL)) {\r
+    ASSERT (0);\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (Count == 0) {\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  if (Count > MaxDstBufferSize) {\r
+    Count = MaxDstBufferSize;\r
+  }\r
+\r
+  for (Index = 0; Index < Count; Index++) {\r
+    if ((SrcBuffer[Index] >= 'a') && (SrcBuffer[Index] <= 'z')) {\r
+      DstBuffer[Index] = (CHAR8)((UINT8)SrcBuffer[Index] - ('a' - 'A'));\r
+    } else {\r
+      DstBuffer[Index] = SrcBuffer[Index];\r
+    }\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/** Check whether Buffer is a root path ('\').\r
+\r
+  This function works for both ASL and AML pathnames.\r
+  Buffer must be at least 2 bytes long.\r
+\r
+  @param  [in]  Buffer   An ASL/AML path.\r
+\r
+  @retval TRUE    Buffer is a root path\r
+  @retval FALSE   Buffer is not a root path.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+AmlIsRootPath (\r
+  IN  CONST  CHAR8  * Buffer\r
+  )\r
+{\r
+  if (Buffer == NULL) {\r
+    return FALSE;\r
+  }\r
+\r
+  if ((Buffer[0] == AML_ROOT_CHAR) && (Buffer[1] == '\0')) {\r
+    return TRUE;\r
+  } else {\r
+    return FALSE;\r
+  }\r
+}\r
+\r
+/** Check whether Ch is an ASL/AML LeadName.\r
+\r
+  This function works for both ASL and AML pathnames.\r
+\r
+  ACPI 6.3 specification, s19.2.2. "ASL Name and Pathname Terms":\r
+  LeadNameChar := 'A'-'Z' | 'a'-'z' | '_'\r
+\r
+  ACPI 6.3 specification, s20.2.2. "Name Objects Encoding":\r
+  LeadNameChar := 'A'-'Z' | 'a'-'z' | '_'\r
+\r
+  @param  [in]  Ch    The char to test.\r
+\r
+  @retval TRUE    Ch is an ASL/AML LeadName.\r
+  @retval FALSE   Ch is not an ASL/AML LeadName.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+AmlIsLeadNameChar (\r
+  IN  CHAR8   Ch\r
+  )\r
+{\r
+  if ((Ch == '_') || (Ch >= 'A' && Ch <= 'Z') || (Ch >= 'a' && Ch <= 'z')) {\r
+    return TRUE;\r
+  } else {\r
+    return FALSE;\r
+  }\r
+}\r
+\r
+/** Check whether Ch is an ASL/AML NameChar.\r
+\r
+  This function works for both ASL and AML pathnames.\r
+\r
+  ACPI 6.3 specification, s19.2.2. "ASL Name and Pathname Terms":\r
+  NameChar := DigitChar | LeadNameChar\r
+  LeadNameChar := 'A'-'Z' | 'a'-'z' | '_'\r
+  DigitChar := '0'-'9'\r
+\r
+  ACPI 6.3 specification, s20.2.2. "Name Objects Encoding":\r
+  NameChar := DigitChar | LeadNameChar\r
+  LeadNameChar := 'A'-'Z' | 'a'-'z' | '_'\r
+  DigitChar := '0'-'9'\r
+\r
+  @param  [in]  Ch    The char to test.\r
+\r
+  @retval TRUE    Ch is an ASL/AML NameChar.\r
+  @retval FALSE   Ch is not an ASL/AML NameChar.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+AmlIsNameChar (\r
+  IN  CHAR8  Ch\r
+  )\r
+{\r
+  if (AmlIsLeadNameChar (Ch) || (Ch >= '0' && Ch <= '9')) {\r
+    return TRUE;\r
+  } else {\r
+    return FALSE;\r
+  }\r
+}\r
+\r
+/** Check whether AslBuffer is an ASL NameSeg.\r
+\r
+  This function only works for ASL NameStrings/pathnames.\r
+  ASL NameStrings/pathnames are at most 4 chars long.\r
+\r
+  @param [in]   AslBuffer   Pointer in an ASL NameString/pathname.\r
+  @param [out]  Size        Size of the NameSeg.\r
+\r
+  @retval TRUE    AslBuffer is an ASL NameSeg.\r
+  @retval FALSE   AslBuffer is not an ASL NameSeg.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+AslIsNameSeg (\r
+  IN  CONST  CHAR8    * AslBuffer,\r
+  OUT        UINT32   * Size\r
+  )\r
+{\r
+  UINT32    Index;\r
+\r
+  if ((AslBuffer == NULL) ||\r
+      (Size == NULL)) {\r
+    return FALSE;\r
+  }\r
+\r
+  if (!AmlIsLeadNameChar (AslBuffer[0])) {\r
+    return FALSE;\r
+  }\r
+\r
+  for (Index = 1; Index < AML_NAME_SEG_SIZE; Index++) {\r
+    if ((AslBuffer[Index] == '.')   ||\r
+        (AslBuffer[Index] == '\0')) {\r
+      *Size = Index;\r
+      return TRUE;\r
+    } else if (!AmlIsNameChar (AslBuffer[Index])) {\r
+      return FALSE;\r
+    }\r
+  }\r
+\r
+  *Size = Index;\r
+  return TRUE;\r
+}\r
+\r
+/** Check whether AmlBuffer is an AML NameSeg.\r
+\r
+  This function only works for AML NameStrings/pathnames.\r
+  AML NameStrings/pathnames must be 4 chars long.\r
+\r
+  @param [in] AmlBuffer   Pointer in an AML NameString/pathname.\r
+\r
+  @retval TRUE    AmlBuffer is an AML NameSeg.\r
+  @retval FALSE   AmlBuffer is not an AML NameSeg.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+AmlIsNameSeg (\r
+  IN  CONST  CHAR8    * AmlBuffer\r
+  )\r
+{\r
+  UINT32    Index;\r
+\r
+  if (AmlBuffer == NULL) {\r
+    return FALSE;\r
+  }\r
+\r
+  if (!AmlIsLeadNameChar (AmlBuffer[0])) {\r
+    return FALSE;\r
+  }\r
+\r
+  for (Index = 1; Index < AML_NAME_SEG_SIZE; Index++) {\r
+    if (!AmlIsNameChar (AmlBuffer[Index])) {\r
+      return FALSE;\r
+    }\r
+  }\r
+\r
+  return TRUE;\r
+}\r
+\r
+/** Parse an ASL NameString/path.\r
+\r
+  An ASL NameString/path must be NULL terminated.\r
+  Information found in the ASL NameString/path is returned via pointers:\r
+  Root, ParentPrefix, SegCount.\r
+\r
+  @param [in]    Buffer       ASL NameString/path.\r
+  @param [out]   Root         Pointer holding the number of root char.\r
+                              Can be 0 or 1.\r
+  @param [out]   ParentPrefix Pointer holding the number of carets char ('^').\r
+                              Can be [0-255].\r
+  @param [out]   SegCount     Pointer holding the number of NameSeg (s).\r
+                              Can be [0-255].\r
+\r
+  @retval EFI_SUCCESS             The function completed successfully.\r
+  @retval EFI_INVALID_PARAMETER   Invalid parameter.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+AslParseNameStringInfo (\r
+  IN  CONST CHAR8     * Buffer,\r
+  OUT       UINT32    * Root,\r
+  OUT       UINT32    * ParentPrefix,\r
+  OUT       UINT32    * SegCount\r
+  )\r
+{\r
+  UINT32      NameSegSize;\r
+\r
+  if ((Buffer == NULL)        ||\r
+      (Root == NULL)          ||\r
+      (ParentPrefix == NULL)  ||\r
+      (SegCount == NULL)) {\r
+    ASSERT (0);\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  *Root = 0;\r
+  *ParentPrefix = 0;\r
+  *SegCount = 0;\r
+\r
+  // Handle Root and ParentPrefix(s).\r
+  if (*Buffer == AML_ROOT_CHAR) {\r
+    *Root = 1;\r
+    Buffer++;\r
+  } else if (*Buffer == AML_PARENT_PREFIX_CHAR) {\r
+    do {\r
+      Buffer++;\r
+      (*ParentPrefix)++;\r
+    } while (*Buffer == AML_PARENT_PREFIX_CHAR);\r
+  }\r
+\r
+  // Handle SegCount(s).\r
+  while (AslIsNameSeg (Buffer, &NameSegSize)) {\r
+    // Safety checks on NameSegSize.\r
+    if ((NameSegSize == 0) || (NameSegSize > AML_NAME_SEG_SIZE)) {\r
+      ASSERT (0);\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+\r
+    // Increment the NameSeg count.\r
+    (*SegCount)++;\r
+    Buffer += NameSegSize;\r
+\r
+    // Skip the '.' separator if present.\r
+    if (*Buffer == '.') {\r
+      Buffer++;\r
+    }\r
+  } // while\r
+\r
+  // An ASL NameString/path must be NULL terminated.\r
+  if (*Buffer != '\0') {\r
+    ASSERT (0);\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (!AmlIsNameString (*Root, *ParentPrefix, *SegCount)) {\r
+    ASSERT (0);\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/** Parse an AML NameString/path.\r
+\r
+  It is possible to determine the size of an AML NameString/path just\r
+  by sight reading it. So no overflow can occur.\r
+  Information found in the AML NameString/path is returned via pointers:\r
+  Root, ParentPrefix, SegCount.\r
+\r
+  @param [in]    Buffer         AML NameString/path.\r
+  @param [out]   Root           Pointer holding the number of root char.\r
+                                Can be 0 or 1.\r
+  @param [out]   ParentPrefix   Pointer holding the number of carets char ('^').\r
+                                Can be [0-255].\r
+  @param [out]   SegCount       Pointer holding the number of NameSeg(s).\r
+                                Can be [0-255].\r
+\r
+  @retval EFI_SUCCESS             The function completed successfully.\r
+  @retval EFI_INVALID_PARAMETER   Invalid parameter.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+AmlParseNameStringInfo (\r
+  IN  CONST CHAR8   * Buffer,\r
+  OUT       UINT32  * Root,\r
+  OUT       UINT32  * ParentPrefix,\r
+  OUT       UINT32  * SegCount\r
+  )\r
+{\r
+  if ((Buffer == NULL) ||\r
+      (Root == NULL)   ||\r
+      (ParentPrefix == NULL) ||\r
+      (SegCount == NULL)) {\r
+    ASSERT (0);\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  *Root = 0;\r
+  *ParentPrefix = 0;\r
+  *SegCount = 0;\r
+\r
+  // Handle Root and ParentPrefix(s).\r
+  if (*Buffer == AML_ROOT_CHAR) {\r
+    *Root = 1;\r
+    Buffer++;\r
+  } else if (*Buffer == AML_PARENT_PREFIX_CHAR) {\r
+    do {\r
+      Buffer++;\r
+      (*ParentPrefix)++;\r
+    } while (*Buffer == AML_PARENT_PREFIX_CHAR);\r
+  }\r
+\r
+  // Handle SegCount(s).\r
+  if (*Buffer == AML_DUAL_NAME_PREFIX) {\r
+    *SegCount = 2;\r
+  } else if (*Buffer == AML_MULTI_NAME_PREFIX) {\r
+    *SegCount = *((UINT8*)(Buffer + 1));\r
+  } else if (AmlIsNameSeg (Buffer)) {\r
+    *SegCount = 1;\r
+  } else if (*Buffer == AML_ZERO_OP) {\r
+    *SegCount = 0;\r
+  } else {\r
+    ASSERT (0);\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  // Safety checks on exit.\r
+  if (!AmlIsNameString (*Root, *ParentPrefix, *SegCount)) {\r
+    ASSERT (0);\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/** Compute the ASL NameString/path size from NameString\r
+    information (Root, ParentPrefix, SegCount).\r
+\r
+  @param [in] Root          Number of root char.\r
+                            Can be 0 or 1.\r
+  @param [in] ParentPrefix  Number of carets char ('^').\r
+                            Can be [0-255].\r
+  @param [in] SegCount      Pointer holding the number of NameSeg(s).\r
+                            Can be [0-255].\r
+\r
+  @return Size of the ASL NameString/path.\r
+**/\r
+UINT32\r
+EFIAPI\r
+AslComputeNameStringSize (\r
+  IN  UINT32    Root,\r
+  IN  UINT32    ParentPrefix,\r
+  IN  UINT32    SegCount\r
+  )\r
+{\r
+  UINT32    TotalSize;\r
+\r
+  if (!AmlIsNameString (Root, ParentPrefix, SegCount)) {\r
+    ASSERT (0);\r
+    return 0;\r
+  }\r
+\r
+  // Root and ParentPrefix(s).\r
+  TotalSize = Root + ParentPrefix;\r
+\r
+  // Add size required for NameSeg(s).\r
+  TotalSize += (SegCount * AML_NAME_SEG_SIZE);\r
+\r
+  // Add size required for '.' separator(s).\r
+  TotalSize += (SegCount > 1) ? (SegCount - 1) : 0;\r
+\r
+  // Add 1 byte for NULL termination '\0'.\r
+  TotalSize += 1;\r
+\r
+  return TotalSize;\r
+}\r
+\r
+/** Compute the AML NameString/path size from NameString\r
+    information (Root, ParentPrefix, SegCount).\r
+\r
+  @param [in] Root          Number of root char.\r
+                            Can be 0 or 1.\r
+  @param [in] ParentPrefix  Number of carets char ('^').\r
+                            Can be [0-255].\r
+  @param [in] SegCount      Pointer holding the number of NameSeg(s).\r
+                            Can be [0-255].\r
+\r
+  @return Size of the AML NameString/path.\r
+**/\r
+UINT32\r
+EFIAPI\r
+AmlComputeNameStringSize (\r
+  IN  UINT32    Root,\r
+  IN  UINT32    ParentPrefix,\r
+  IN  UINT32    SegCount\r
+  )\r
+{\r
+  UINT32    TotalSize;\r
+\r
+  if (!AmlIsNameString (Root, ParentPrefix, SegCount)) {\r
+    ASSERT (0);\r
+    return 0;\r
+  }\r
+\r
+  // Root and ParentPrefix(s).\r
+  TotalSize = Root + ParentPrefix;\r
+\r
+  // If SegCount == 0, '\0' must end the AML NameString/path.\r
+  TotalSize += (SegCount == 0) ? 1 : (SegCount * AML_NAME_SEG_SIZE);\r
+\r
+  // AML prefix. SegCount > 2 = MultiNamePrefix, SegCount = 2 DualNamePrefix.\r
+  TotalSize += (SegCount > 2) ? 2 : ((SegCount == 2) ? 1 : 0);\r
+\r
+  return TotalSize;\r
+}\r
+\r
+/** Get the ASL NameString/path size.\r
+\r
+  @param [in]   AslPath         An ASL NameString/path.\r
+  @param [out]  AslPathSizePtr  Pointer holding the ASL NameString/path size.\r
+\r
+  @retval EFI_SUCCESS             Success.\r
+  @retval EFI_INVALID_PARAMETER   Invalid parameter.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+AslGetNameStringSize (\r
+  IN  CONST CHAR8   * AslPath,\r
+  OUT       UINT32  * AslPathSizePtr\r
+  )\r
+{\r
+  if ((AslPath == NULL) ||\r
+      (AslPathSizePtr == NULL)) {\r
+    ASSERT (0);\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  *AslPathSizePtr = 0;\r
+  do {\r
+    (*AslPathSizePtr)++;\r
+    AslPath++;\r
+  } while (*AslPath != '\0');\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/** Get the AML NameString/path size.\r
+\r
+  @param [in]   AmlPath         An AML NameString/path.\r
+  @param [out]  AmlPathSizePtr  Pointer holding the AML NameString/path size.\r
+\r
+  @retval EFI_SUCCESS             Success.\r
+  @retval EFI_INVALID_PARAMETER   Invalid parameter.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+AmlGetNameStringSize (\r
+  IN   CONST  CHAR8   * AmlPath,\r
+  OUT         UINT32  * AmlPathSizePtr\r
+  )\r
+{\r
+  EFI_STATUS    Status;\r
+\r
+  UINT32        Root;\r
+  UINT32        ParentPrefix;\r
+  UINT32        SegCount;\r
+\r
+  if ((AmlPath == NULL) ||\r
+      (AmlPathSizePtr == NULL)) {\r
+    ASSERT (0);\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  Status = AmlParseNameStringInfo (\r
+             AmlPath,\r
+             &Root,\r
+             &ParentPrefix,\r
+             &SegCount\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    ASSERT (0);\r
+    return Status;\r
+  }\r
+\r
+  *AmlPathSizePtr = AmlComputeNameStringSize (Root, ParentPrefix, SegCount);\r
+  if (*AmlPathSizePtr == 0) {\r
+    ASSERT (0);\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/** Convert an ASL NameString/path to an AML NameString/path.\r
+    The caller must free the memory allocated in this function\r
+    for AmlPath using FreePool ().\r
+\r
+  @param  [in]  AslPath     An ASL NameString/path.\r
+  @param  [out] OutAmlPath  Buffer containing the AML path.\r
+\r
+  @retval EFI_SUCCESS             Success.\r
+  @retval EFI_INVALID_PARAMETER   Invalid parameter.\r
+  @retval EFI_OUT_OF_RESOURCES    Failed to allocate memory.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ConvertAslNameToAmlName (\r
+  IN  CONST  CHAR8   * AslPath,\r
+  OUT        CHAR8  ** OutAmlPath\r
+  )\r
+{\r
+  EFI_STATUS      Status;\r
+\r
+  UINT32          Root;\r
+  UINT32          ParentPrefix;\r
+  UINT32          SegCount;\r
+  UINT32          TotalSize;\r
+  UINT32          NameSegSize;\r
+\r
+  CONST CHAR8   * AslBuffer;\r
+  CHAR8         * AmlBuffer;\r
+  CHAR8         * AmlPath;\r
+\r
+  if ((AslPath == NULL) ||\r
+      (OutAmlPath == NULL)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  // Analyze AslPath. AslPath is checked in the call.\r
+  Status = AslParseNameStringInfo (AslPath, &Root, &ParentPrefix, &SegCount);\r
+  if (EFI_ERROR (Status)) {\r
+    ASSERT (0);\r
+    return Status;\r
+  }\r
+\r
+  // Compute TotalSize.\r
+  TotalSize = AmlComputeNameStringSize (Root, ParentPrefix, SegCount);\r
+  if (TotalSize == 0) {\r
+    ASSERT (0);\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  // Allocate memory.\r
+  AmlPath = AllocateZeroPool (TotalSize);\r
+  if (AmlPath == NULL) {\r
+    ASSERT (0);\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  AmlBuffer = AmlPath;\r
+  AslBuffer = AslPath;\r
+\r
+  // Handle Root and ParentPrefix(s).\r
+  if (Root == 1) {\r
+    *AmlBuffer = AML_ROOT_CHAR;\r
+    AmlBuffer++;\r
+    AslBuffer++;\r
+  } else if (ParentPrefix > 0) {\r
+    SetMem (AmlBuffer, ParentPrefix, AML_PARENT_PREFIX_CHAR);\r
+    AmlBuffer += ParentPrefix;\r
+    AslBuffer += ParentPrefix;\r
+  }\r
+\r
+  // Handle prefix and SegCount(s).\r
+  if (SegCount > 2) {\r
+    *AmlBuffer = AML_MULTI_NAME_PREFIX;\r
+    AmlBuffer++;\r
+    *AmlBuffer = (UINT8)SegCount;\r
+    AmlBuffer++;\r
+  } else if (SegCount == 2) {\r
+    *AmlBuffer = AML_DUAL_NAME_PREFIX;\r
+    AmlBuffer++;\r
+  }\r
+\r
+  if (SegCount != 0) {\r
+    // Write NameSeg(s).\r
+    while (1) {\r
+      SegCount--;\r
+\r
+      // Get the NameSeg size.\r
+      if (!AslIsNameSeg (AslBuffer, &NameSegSize)) {\r
+        ASSERT (0);\r
+        Status = EFI_INVALID_PARAMETER;\r
+        goto error_handler;\r
+      }\r
+\r
+      // Convert to Upper case and copy.\r
+      Status = AmlUpperCaseMemCpyS (\r
+                 AmlBuffer,\r
+                 TotalSize,\r
+                 AslBuffer,\r
+                 NameSegSize\r
+                 );\r
+      if (EFI_ERROR (Status)) {\r
+        ASSERT (0);\r
+        goto error_handler;\r
+      }\r
+\r
+      // Complete the NameSeg with an underscore ('_') if shorter than 4 bytes.\r
+      SetMem (\r
+        AmlBuffer + NameSegSize,\r
+        AML_NAME_SEG_SIZE - NameSegSize,\r
+        AML_NAME_CHAR__\r
+        );\r
+\r
+      // Go to the next NameSeg.\r
+      AmlBuffer += AML_NAME_SEG_SIZE;\r
+      AslBuffer += NameSegSize;\r
+\r
+      // Skip the '.' separator.\r
+      if (SegCount != 0) {\r
+        if (*AslBuffer == '.') {\r
+          AslBuffer++;\r
+        } else {\r
+          ASSERT (0);\r
+          Status = EFI_INVALID_PARAMETER;\r
+          goto error_handler;\r
+        }\r
+      } else {\r
+        // (SegCount == 0)\r
+        if (*AslBuffer == '\0') {\r
+          break;\r
+        } else {\r
+          ASSERT (0);\r
+          Status = EFI_INVALID_PARAMETER;\r
+          goto error_handler;\r
+        }\r
+      }\r
+    } // while\r
+\r
+  } else {\r
+    // (SegCount == 0)\r
+    // '\0' needs to end the AML NameString/path.\r
+    *AmlBuffer = AML_ZERO_OP;\r
+    AmlBuffer++;\r
+  }\r
+\r
+  // Safety checks on exit.\r
+  // Check that AmlPath has been filled with TotalSize bytes.\r
+  if ((SegCount != 0)               ||\r
+      (*AslBuffer != AML_ZERO_OP)   ||\r
+      (((UINT32)(AmlBuffer - AmlPath)) != TotalSize)) {\r
+      ASSERT (0);\r
+      Status = EFI_INVALID_PARAMETER;\r
+      goto error_handler;\r
+  }\r
+\r
+  *OutAmlPath = AmlPath;\r
+  return EFI_SUCCESS;\r
+\r
+error_handler:\r
+  FreePool (AmlPath);\r
+  return Status;\r
+}\r
+\r
+/** Convert an AML NameString/path to an ASL NameString/path.\r
+    The caller must free the memory allocated in this function.\r
+    using FreePool ().\r
+\r
+  @param  [in]  AmlPath     An AML NameString/path.\r
+  @param  [out] OutAslPath  Buffer containing the ASL path.\r
+\r
+  @retval EFI_SUCCESS             Success.\r
+  @retval EFI_INVALID_PARAMETER   Invalid parameter.\r
+  @retval EFI_OUT_OF_RESOURCES    Failed to allocate memory.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ConvertAmlNameToAslName (\r
+  IN  CONST CHAR8     * AmlPath,\r
+  OUT       CHAR8    ** OutAslPath\r
+  )\r
+{\r
+  EFI_STATUS      Status;\r
+\r
+  UINT32          Root;\r
+  UINT32          ParentPrefix;\r
+  UINT32          SegCount;\r
+  UINT32          TotalSize;\r
+\r
+  CONST CHAR8   * AmlBuffer;\r
+  CHAR8         * AslBuffer;\r
+  CHAR8         * AslPath;\r
+\r
+  if ((AmlPath == NULL)   ||\r
+      (OutAslPath == NULL)) {\r
+    ASSERT (0);\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  // Analyze AslPath. AmlPath is checked in the call.\r
+  Status = AmlParseNameStringInfo (AmlPath, &Root, &ParentPrefix, &SegCount);\r
+  if (EFI_ERROR (Status)) {\r
+    ASSERT (0);\r
+    return Status;\r
+  }\r
+\r
+  // Compute TotalSize.\r
+  TotalSize = AslComputeNameStringSize (Root, ParentPrefix, SegCount);\r
+  if (TotalSize == 0) {\r
+    ASSERT (0);\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  // Allocate memory.\r
+  AslPath = AllocateZeroPool (TotalSize);\r
+  if (AslPath == NULL) {\r
+    ASSERT (0);\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  AmlBuffer = AmlPath;\r
+  AslBuffer = AslPath;\r
+\r
+  // Handle prefix and SegCount(s).\r
+  if (Root == 1) {\r
+    *AslBuffer = AML_ROOT_CHAR;\r
+    AslBuffer++;\r
+    AmlBuffer++;\r
+  } else if (ParentPrefix > 0) {\r
+    SetMem (AslBuffer, ParentPrefix, AML_PARENT_PREFIX_CHAR);\r
+    AslBuffer += ParentPrefix;\r
+    AmlBuffer += ParentPrefix;\r
+  }\r
+\r
+  // Handle Root and Parent(s).\r
+  // Skip the MultiName or DualName prefix chars.\r
+  if (SegCount > 2) {\r
+    AmlBuffer += 2;\r
+  } else if (SegCount == 2) {\r
+    AmlBuffer += 1;\r
+  }\r
+\r
+  // Write NameSeg(s).\r
+  while (SegCount) {\r
+    // NameSeg is already in upper case and always 4 bytes long.\r
+    CopyMem (AslBuffer, AmlBuffer, AML_NAME_SEG_SIZE);\r
+    AslBuffer += AML_NAME_SEG_SIZE;\r
+    AmlBuffer += AML_NAME_SEG_SIZE;\r
+\r
+    SegCount--;\r
+\r
+    // Write the '.' separator if there is another NameSeg following.\r
+    if (SegCount != 0) {\r
+      *AslBuffer = '.';\r
+      AslBuffer++;\r
+    }\r
+  } // while\r
+\r
+  // NULL terminate the ASL NameString.\r
+  *AslBuffer = '\0';\r
+  AslBuffer++;\r
+\r
+  // Safety checks on exit.\r
+  // Check that AslPath has been filled with TotalSize bytes.\r
+  if (((UINT32)(AslBuffer - AslPath)) != TotalSize) {\r
+    ASSERT (0);\r
+    Status = EFI_INVALID_PARAMETER;\r
+    goto error_handler;\r
+  }\r
+\r
+  *OutAslPath = AslPath;\r
+  return EFI_SUCCESS;\r
+\r
+error_handler:\r
+  FreePool (AslPath);\r
+  return Status;\r
+}\r
+\r
+/** Compare two ASL NameStrings.\r
+\r
+  @param [in] AslName1    First NameString to compare.\r
+  @param [in] AslName2    Second NameString to compare.\r
+\r
+  @retval TRUE if the two strings are identical.\r
+  @retval FALSE otherwise, or if error.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+AslCompareNameString (\r
+  IN  CONST CHAR8 *   AslName1,\r
+  IN  CONST CHAR8 *   AslName2\r
+  )\r
+{\r
+  EFI_STATUS    Status;\r
+  UINT32        AslName1Len;\r
+  UINT32        AslName2Len;\r
+\r
+  if ((AslName1 == NULL) ||\r
+      (AslName2 == NULL)) {\r
+    ASSERT (0);\r
+    return FALSE;\r
+  }\r
+\r
+  Status = AslGetNameStringSize (AslName1, &AslName1Len);\r
+  if (EFI_ERROR (Status)) {\r
+    ASSERT (0);\r
+    return FALSE;\r
+  }\r
+\r
+  Status = AslGetNameStringSize (AslName2, &AslName2Len);\r
+  if (EFI_ERROR (Status)) {\r
+    ASSERT (0);\r
+    return FALSE;\r
+  }\r
+\r
+  // AslName1 and AslName2 don't have the same length\r
+  if (AslName1Len != AslName2Len) {\r
+    return FALSE;\r
+  }\r
+\r
+  return (CompareMem (AslName1, AslName2, AslName1Len) == 0);\r
+}\r
+\r
+/** Compare two AML NameStrings.\r
+\r
+  @param [in] AmlName1    First NameString to compare.\r
+  @param [in] AmlName2    Second NameString to compare.\r
+\r
+  @retval TRUE if the two strings are identical.\r
+  @retval FALSE otherwise, or if error.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+AmlCompareNameString (\r
+  IN  CONST CHAR8 *   AmlName1,\r
+  IN  CONST CHAR8 *   AmlName2\r
+  )\r
+{\r
+  EFI_STATUS    Status;\r
+  UINT32        AmlName1Len;\r
+  UINT32        AmlName2Len;\r
+\r
+  if ((AmlName1 == NULL) ||\r
+      (AmlName2 == NULL)) {\r
+    ASSERT (0);\r
+    return FALSE;\r
+  }\r
+\r
+  Status = AmlGetNameStringSize (AmlName1, &AmlName1Len);\r
+  if (EFI_ERROR (Status)) {\r
+    ASSERT (0);\r
+    return FALSE;\r
+  }\r
+\r
+  Status = AmlGetNameStringSize (AmlName2, &AmlName2Len);\r
+  if (EFI_ERROR (Status)) {\r
+    ASSERT (0);\r
+    return FALSE;\r
+  }\r
+\r
+  // AmlName1 and AmlName2 don't have the same length\r
+  if (AmlName1Len != AmlName2Len) {\r
+    return FALSE;\r
+  }\r
+\r
+  return (CompareMem (AmlName1, AmlName2, AmlName1Len) == 0);\r
+}\r
+\r
+/** Compare an AML NameString and an ASL NameString.\r
+\r
+  The ASL NameString is converted to an AML NameString before\r
+  being compared with the ASL NameString. This allows to expand\r
+  NameSegs shorter than 4 chars.\r
+  E.g.: AslName: "DEV" will be expanded to "DEV_" before being\r
+        compared.\r
+\r
+  @param [in] AmlName1   AML NameString to compare.\r
+  @param [in] AslName2   ASL NameString to compare.\r
+\r
+  @retval TRUE if the two strings are identical.\r
+  @retval FALSE otherwise, or if error.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+CompareAmlWithAslNameString (\r
+  IN  CONST CHAR8 *   AmlName1,\r
+  IN  CONST CHAR8 *   AslName2\r
+  )\r
+{\r
+  EFI_STATUS    Status;\r
+\r
+  CHAR8       * AmlName2;\r
+  BOOLEAN       RetVal;\r
+\r
+  if ((AmlName1 == NULL) ||\r
+      (AslName2 == NULL)) {\r
+    ASSERT (0);\r
+    return FALSE;\r
+  }\r
+\r
+  // Convert the AslName2 to an AmlName2.\r
+  // AmlName2 must be freed.\r
+  Status = ConvertAmlNameToAslName (AslName2, &AmlName2);\r
+  if (EFI_ERROR (Status)) {\r
+    ASSERT (0);\r
+    return FALSE;\r
+  }\r
+\r
+  RetVal = AmlCompareNameString (AmlName1, AmlName2);\r
+\r
+  // Free AmlName2.\r
+  FreePool (AmlName2);\r
+\r
+  return RetVal;\r
+}\r
+/** Given an AmlPath, return the address of the first NameSeg.\r
+\r
+  It is possible to determine the size of an AML NameString/path just\r
+  by sight reading it. So no overflow can occur.\r
+\r
+  @param  [in]  AmlPath       The AML pathname.\r
+  @param  [in]  Root          The AML pathname starts with a root char.\r
+                              It is an absolute path.\r
+  @param  [in]  ParentPrefix  The AML pathname has ParentPrefix\r
+                              carets in its name.\r
+\r
+  @return Pointer to the first NameSeg of the NameString.\r
+          Return NULL if AmlPath is NULL.\r
+**/\r
+CONST\r
+CHAR8 *\r
+EFIAPI\r
+AmlGetFirstNameSeg (\r
+  IN  CONST  CHAR8    * AmlPath,\r
+  IN         UINT32     Root,\r
+  IN         UINT32     ParentPrefix\r
+  )\r
+{\r
+  if (AmlPath == NULL) {\r
+    ASSERT (0);\r
+    return NULL;\r
+  }\r
+\r
+  AmlPath += Root;\r
+  AmlPath += ParentPrefix;\r
+  AmlPath += ((*AmlPath == AML_MULTI_NAME_PREFIX) ? 2\r
+               : (*AmlPath == AML_DUAL_NAME_PREFIX) ? 1 : 0);\r
+  return AmlPath;\r
+}\r
diff --git a/DynamicTablesPkg/Library/Common/AmlLib/String/AmlString.h b/DynamicTablesPkg/Library/Common/AmlLib/String/AmlString.h
new file mode 100644 (file)
index 0000000..86d9df5
--- /dev/null
@@ -0,0 +1,401 @@
+/** @file\r
+  AML String.\r
+\r
+  Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved. <BR>\r
+  Copyright (c) 2019 - 2020, Arm Limited. All rights reserved.<BR>\r
+\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
+**/\r
+\r
+#ifndef AML_STRING_H_\r
+#define AML_STRING_H_\r
+\r
+/* This header file does not include internal Node definition,\r
+   i.e. AML_ROOT_NODE, AML_OBJECT_NODE, etc. The node definitions\r
+   must be included by the caller file. The function prototypes must\r
+   only expose AML_NODE_HANDLE, AML_ROOT_NODE_HANDLE, etc. node\r
+   definitions.\r
+   This allows to keep the functions defined here both internal and\r
+   potentially external. If necessary, any function of this file can\r
+   be exposed externally.\r
+   The Api folder is internal to the AmlLib, but should only use these\r
+   functions. They provide a "safe" way to interact with the AmlLib.\r
+*/\r
+\r
+#include <AmlInclude.h>\r
+\r
+/** Check NameString/path information is valid.\r
+\r
+  Root, ParentPrefix and SegCount cannot be 0 at the same time.\r
+  This function works for ASL and AML name strings.\r
+\r
+  @param [in]   Root          Number of root char.\r
+                              Must be 0 or 1.\r
+  @param [in]   ParentPrefix  Number of carets char ('^').\r
+                              Must be [0-255].\r
+  @param [in]   SegCount      Number of NameSeg (s).\r
+                              Must be [0-255].\r
+\r
+  @retval TRUE id the input information is in the right boundaries.\r
+          FALSE otherwise.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+AmlIsNameString (\r
+  IN  UINT32    Root,\r
+  IN  UINT32    ParentPrefix,\r
+  IN  UINT32    SegCount\r
+  );\r
+\r
+/** Copy bytes from SrcBuffer to DstBuffer and convert to upper case.\r
+    Don't copy more than MaxDstBufferSize bytes.\r
+\r
+  @param  [out] DstBuffer         Destination buffer.\r
+  @param  [in]  MaxDstBufferSize  Maximum size of DstBuffer.\r
+                                  Must be non-zero.\r
+  @param  [in]  SrcBuffer         Source buffer.\r
+  @param  [in]  Count             Count of bytes to copy from SrcBuffer.\r
+                                  Return success if 0.\r
+\r
+  @retval EFI_SUCCESS             The function completed successfully.\r
+  @retval EFI_INVALID_PARAMETER   Invalid parameter.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+AmlUpperCaseMemCpyS (\r
+  OUT       CHAR8   * DstBuffer,\r
+  IN        UINT32    MaxDstBufferSize,\r
+  IN  CONST CHAR8   * SrcBuffer,\r
+  IN        UINT32    Count\r
+  );\r
+\r
+/** Check whether Buffer is a root path ('\').\r
+\r
+  This function works for both ASL and AML pathnames.\r
+  Buffer must be at least 2 bytes long.\r
+\r
+  @param  [in]  Buffer   An ASL/AML path.\r
+\r
+  @retval TRUE    Buffer is a root path\r
+  @retval FALSE   Buffer is not a root path.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+AmlIsRootPath (\r
+  IN  CONST  CHAR8  * Buffer\r
+  );\r
+\r
+/** Check whether Ch is an ASL/AML LeadName.\r
+\r
+  This function works for both ASL and AML pathnames.\r
+\r
+  ACPI 6.3 specification, s19.2.2. "ASL Name and Pathname Terms":\r
+  LeadNameChar := 'A'-'Z' | 'a'-'z' | '_'\r
+\r
+  ACPI 6.3 specification, s20.2.2. "Name Objects Encoding":\r
+  LeadNameChar := 'A'-'Z' | 'a'-'z' | '_'\r
+\r
+  @param  [in]  Ch    The char to test.\r
+\r
+  @retval TRUE    Ch is an ASL/AML LeadName.\r
+  @retval FALSE   Ch is not an ASL/AML LeadName.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+AmlIsLeadNameChar (\r
+  IN  CHAR8   Ch\r
+  );\r
+\r
+/** Check whether Ch is an ASL/AML NameChar.\r
+\r
+  This function works for both ASL and AML pathnames.\r
+\r
+  ACPI 6.3 specification, s19.2.2. "ASL Name and Pathname Terms":\r
+  NameChar := DigitChar | LeadNameChar\r
+  LeadNameChar := 'A'-'Z' | 'a'-'z' | '_'\r
+  DigitChar := '0'-'9'\r
+\r
+  ACPI 6.3 specification, s20.2.2. "Name Objects Encoding":\r
+  NameChar := DigitChar | LeadNameChar\r
+  LeadNameChar := 'A'-'Z' | 'a'-'z' | '_'\r
+  DigitChar := '0'-'9'\r
+\r
+  @param  [in]  Ch    The char to test.\r
+\r
+  @retval TRUE    Ch is an ASL/AML NameChar.\r
+  @retval FALSE   Ch is not an ASL/AML NameChar.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+AmlIsNameChar (\r
+  IN  CHAR8  Ch\r
+  );\r
+\r
+/** Check whether AslBuffer is an ASL NameSeg.\r
+\r
+  This function only works for ASL NameStrings/pathnames.\r
+  ASL NameStrings/pathnames are at most 4 chars long.\r
+\r
+  @param [in]   AslBuffer   Pointer in an ASL NameString/pathname.\r
+  @param [out]  Size        Size of the NameSeg.\r
+\r
+  @retval TRUE    AslBuffer is an ASL NameSeg.\r
+  @retval FALSE   AslBuffer is not an ASL NameSeg.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+AslIsNameSeg (\r
+  IN  CONST  CHAR8    * AslBuffer,\r
+  OUT        UINT32   * Size\r
+  );\r
+\r
+/** Check whether AmlBuffer is an AML NameSeg.\r
+\r
+  This function only works for AML NameStrings/pathnames.\r
+  AML NameStrings/pathnames must be 4 chars long.\r
+\r
+  @param [in] AmlBuffer   Pointer in an AML NameString/pathname.\r
+\r
+  @retval TRUE    AmlBuffer is an AML NameSeg.\r
+  @retval FALSE   AmlBuffer is not an AML NameSeg.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+AmlIsNameSeg (\r
+  IN  CONST  CHAR8    * AmlBuffer\r
+  );\r
+\r
+/** Parse an ASL NameString/path.\r
+\r
+  An ASL NameString/path must be NULL terminated.\r
+  Information found in the ASL NameString/path is returned via pointers:\r
+  Root, ParentPrefix, SegCount.\r
+\r
+  @param [in]    Buffer       ASL NameString/path.\r
+  @param [out]   Root         Pointer holding the number of root char.\r
+                              Can be 0 or 1.\r
+  @param [out]   ParentPrefix Pointer holding the number of carets char ('^').\r
+                              Can be [0-255].\r
+  @param [out]   SegCount     Pointer holding the number of NameSeg (s).\r
+                              Can be [0-255].\r
+\r
+  @retval EFI_SUCCESS             The function completed successfully.\r
+  @retval EFI_INVALID_PARAMETER   Invalid parameter.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+AslParseNameStringInfo (\r
+  IN  CONST CHAR8     * Buffer,\r
+  OUT       UINT32    * Root,\r
+  OUT       UINT32    * ParentPrefix,\r
+  OUT       UINT32    * SegCount\r
+  );\r
+\r
+/** Parse an AML NameString/path.\r
+\r
+  It is possible to determine the size of an AML NameString/path just\r
+  by sight reading it. So no overflow can occur.\r
+  Information found in the AML NameString/path is returned via pointers:\r
+  Root, ParentPrefix, SegCount.\r
+\r
+  @param [in]    Buffer         AML NameString/path.\r
+  @param [out]   Root           Pointer holding the number of root char.\r
+                                Can be 0 or 1.\r
+  @param [out]   ParentPrefix   Pointer holding the number of carets char ('^').\r
+                                Can be [0-255].\r
+  @param [out]   SegCount       Pointer holding the number of NameSeg(s).\r
+                                Can be [0-255].\r
+\r
+  @retval EFI_SUCCESS             The function completed successfully.\r
+  @retval EFI_INVALID_PARAMETER   Invalid parameter.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+AmlParseNameStringInfo (\r
+  IN  CONST CHAR8   * Buffer,\r
+  OUT       UINT32  * Root,\r
+  OUT       UINT32  * ParentPrefix,\r
+  OUT       UINT32  * SegCount\r
+  );\r
+\r
+/** Compute the ASL NameString/path size from NameString\r
+    information (Root, ParentPrefix, SegCount).\r
+\r
+  @param [in] Root          Number of root char.\r
+                            Can be 0 or 1.\r
+  @param [in] ParentPrefix  Number of carets char ('^').\r
+                            Can be [0-255].\r
+  @param [in] SegCount      Pointer holding the number of NameSeg(s).\r
+                            Can be [0-255].\r
+\r
+  @return Size of the ASL NameString/path.\r
+**/\r
+UINT32\r
+EFIAPI\r
+AslComputeNameStringSize (\r
+  IN  UINT32    Root,\r
+  IN  UINT32    ParentPrefix,\r
+  IN  UINT32    SegCount\r
+  );\r
+\r
+/** Compute the AML NameString/path size from NameString\r
+    information (Root, ParentPrefix, SegCount).\r
+\r
+  @param [in] Root          Number of root char.\r
+                            Can be 0 or 1.\r
+  @param [in] ParentPrefix  Number of carets char ('^').\r
+                            Can be [0-255].\r
+  @param [in] SegCount      Pointer holding the number of NameSeg(s).\r
+                            Can be [0-255].\r
+\r
+  @return Size of the AML NameString/path.\r
+**/\r
+UINT32\r
+EFIAPI\r
+AmlComputeNameStringSize (\r
+  IN  UINT32    Root,\r
+  IN  UINT32    ParentPrefix,\r
+  IN  UINT32    SegCount\r
+  );\r
+\r
+/** Get the ASL NameString/path size.\r
+\r
+  @param [in]   AslPath         An ASL NameString/path.\r
+  @param [out]  AslPathSizePtr  Pointer holding the ASL NameString/path size.\r
+\r
+  @retval EFI_SUCCESS             Success.\r
+  @retval EFI_INVALID_PARAMETER   Invalid parameter.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+AslGetNameStringSize (\r
+  IN  CONST CHAR8   * AslPath,\r
+  OUT       UINT32  * AslPathSizePtr\r
+  );\r
+\r
+/** Get the AML NameString/path size.\r
+\r
+  @param [in]   AmlPath         An AML NameString/path.\r
+  @param [out]  AmlPathSizePtr  Pointer holding the AML NameString/path size.\r
+\r
+  @retval EFI_SUCCESS             Success.\r
+  @retval EFI_INVALID_PARAMETER   Invalid parameter.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+AmlGetNameStringSize (\r
+  IN   CONST  CHAR8   * AmlPath,\r
+  OUT         UINT32  * AmlPathSizePtr\r
+  );\r
+\r
+/** Convert an ASL NameString/path to an AML NameString/path.\r
+    The caller must free the memory allocated in this function\r
+    for AmlPath using FreePool ().\r
+\r
+  @param  [in]  AslPath     An ASL NameString/path.\r
+  @param  [out] OutAmlPath  Buffer containing the AML path.\r
+\r
+  @retval EFI_SUCCESS             Success.\r
+  @retval EFI_INVALID_PARAMETER   Invalid parameter.\r
+  @retval EFI_OUT_OF_RESOURCES    Failed to allocate memory.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ConvertAslNameToAmlName (\r
+  IN  CONST  CHAR8   * AslPath,\r
+  OUT        CHAR8  ** OutAmlPath\r
+  );\r
+\r
+/** Convert an AML NameString/path to an ASL NameString/path.\r
+    The caller must free the memory allocated in this function.\r
+    using FreePool ().\r
+\r
+  @param  [in]  AmlPath     An AML NameString/path.\r
+  @param  [out] OutAslPath  Buffer containing the ASL path.\r
+\r
+  @retval EFI_SUCCESS             Success.\r
+  @retval EFI_INVALID_PARAMETER   Invalid parameter.\r
+  @retval EFI_OUT_OF_RESOURCES    Failed to allocate memory.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ConvertAmlNameToAslName (\r
+  IN  CONST CHAR8     * AmlPath,\r
+  OUT       CHAR8    ** OutAslPath\r
+  );\r
+\r
+/** Compare two ASL NameStrings.\r
+\r
+  @param [in] AslName1    First NameString to compare.\r
+  @param [in] AslName2    Second NameString to compare.\r
+\r
+  @retval TRUE if the two strings are identical.\r
+  @retval FALSE otherwise, or if error.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+AslCompareNameString (\r
+  IN  CONST CHAR8 *   AslName1,\r
+  IN  CONST CHAR8 *   AslName2\r
+  );\r
+\r
+/** Compare two AML NameStrings.\r
+\r
+  @param [in] AmlName1    First NameString to compare.\r
+  @param [in] AmlName2    Second NameString to compare.\r
+\r
+  @retval TRUE if the two strings are identical.\r
+  @retval FALSE otherwise, or if error.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+AmlCompareNameString (\r
+  IN  CONST CHAR8 *   AmlName1,\r
+  IN  CONST CHAR8 *   AmlName2\r
+  );\r
+\r
+/** Compare an AML NameString and an ASL NameString.\r
+\r
+  The ASL NameString is converted to an AML NameString before\r
+  being compared with the ASL NameString. This allows to expand\r
+  NameSegs shorter than 4 chars.\r
+  E.g.: AslName: "DEV" will be expanded to "DEV_" before being\r
+        compared.\r
+\r
+  @param [in] AmlName1   AML NameString to compare.\r
+  @param [in] AslName2   ASL NameString to compare.\r
+\r
+  @retval TRUE if the two strings are identical.\r
+  @retval FALSE otherwise, or if error.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+CompareAmlWithAslNameString (\r
+  IN  CONST CHAR8 *   AmlName1,\r
+  IN  CONST CHAR8 *   AslName2\r
+  );\r
+\r
+/** Given an AmlPath, return the address of the first NameSeg.\r
+\r
+  It is possible to determine the size of an AML NameString/path just\r
+  by sight reading it. So no overflow can occur.\r
+\r
+  @param  [in]  AmlPath       The AML pathname.\r
+  @param  [in]  Root          The AML pathname starts with a root char.\r
+                              It is an absolute path.\r
+  @param  [in]  ParentPrefix  The AML pathname has ParentPrefix\r
+                              carets in its name.\r
+\r
+  @return Pointer to the first NameSeg of the NameString.\r
+          Return NULL if AmlPath is NULL.\r
+**/\r
+CONST\r
+CHAR8 *\r
+EFIAPI\r
+AmlGetFirstNameSeg (\r
+  IN  CONST  CHAR8    * AmlPath,\r
+  IN         UINT32     Root,\r
+  IN         UINT32     ParentPrefix\r
+  );\r
+\r
+#endif // AML_STRING_H_\r