--- /dev/null
+/** @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
--- /dev/null
+/** @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