REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3737 Apply uncrustify changes to .c/.h files in the DynamicTablesPkg package Cc: Andrew Fish <afish@apple.com> Cc: Leif Lindholm <leif@nuviainc.com> Cc: Michael D Kinney <michael.d.kinney@intel.com> Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com> Reviewed-by: Sami Mujawar <sami.mujawar@arm.com>
		
			
				
	
	
		
			1038 lines
		
	
	
		
			25 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			1038 lines
		
	
	
		
			25 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /** @file
 | |
|   AML String.
 | |
| 
 | |
|   Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved. <BR>
 | |
|   Copyright (c) 2019 - 2020, Arm Limited. All rights reserved.<BR>
 | |
| 
 | |
|   SPDX-License-Identifier: BSD-2-Clause-Patent
 | |
| **/
 | |
| 
 | |
| #include <String/AmlString.h>
 | |
| 
 | |
| #include <AmlDefines.h>
 | |
| #include <IndustryStandard/AcpiAml.h>
 | |
| 
 | |
| /** Check NameString/path information is valid.
 | |
| 
 | |
|   Root, ParentPrefix and SegCount cannot be 0 at the same time.
 | |
|   This function works for ASL and AML name strings.
 | |
| 
 | |
|   @param [in]   Root          Number of root char.
 | |
|                               Must be 0 or 1.
 | |
|   @param [in]   ParentPrefix  Number of carets char ('^').
 | |
|                               Must be [0-255].
 | |
|   @param [in]   SegCount      Number of NameSeg (s).
 | |
|                               Must be [0-255].
 | |
| 
 | |
|   @retval TRUE id the input information is in the right boundaries.
 | |
|           FALSE otherwise.
 | |
| **/
 | |
| BOOLEAN
 | |
| EFIAPI
 | |
| AmlIsNameString (
 | |
|   IN  UINT32  Root,
 | |
|   IN  UINT32  ParentPrefix,
 | |
|   IN  UINT32  SegCount
 | |
|   )
 | |
| {
 | |
|   if (((Root == 0) || (Root == 1))            &&
 | |
|       (ParentPrefix <= MAX_UINT8)             &&
 | |
|       (!((ParentPrefix != 0) && (Root != 0))) &&
 | |
|       (SegCount <= MAX_UINT8)                 &&
 | |
|       ((SegCount + Root + ParentPrefix) != 0))
 | |
|   {
 | |
|     return TRUE;
 | |
|   }
 | |
| 
 | |
|   return FALSE;
 | |
| }
 | |
| 
 | |
| /** Copy bytes from SrcBuffer to DstBuffer and convert to upper case.
 | |
|     Don't copy more than MaxDstBufferSize bytes.
 | |
| 
 | |
|   @param  [out] DstBuffer         Destination buffer.
 | |
|   @param  [in]  MaxDstBufferSize  Maximum size of DstBuffer.
 | |
|                                   Must be non-zero.
 | |
|   @param  [in]  SrcBuffer         Source buffer.
 | |
|   @param  [in]  Count             Count of bytes to copy from SrcBuffer.
 | |
|                                   Return success if 0.
 | |
| 
 | |
|   @retval EFI_SUCCESS             The function completed successfully.
 | |
|   @retval EFI_INVALID_PARAMETER   Invalid parameter.
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| AmlUpperCaseMemCpyS (
 | |
|   OUT       CHAR8   *DstBuffer,
 | |
|   IN        UINT32  MaxDstBufferSize,
 | |
|   IN  CONST CHAR8   *SrcBuffer,
 | |
|   IN        UINT32  Count
 | |
|   )
 | |
| {
 | |
|   UINT32  Index;
 | |
| 
 | |
|   if ((DstBuffer == NULL) ||
 | |
|       (SrcBuffer == NULL))
 | |
|   {
 | |
|     ASSERT (0);
 | |
|     return EFI_INVALID_PARAMETER;
 | |
|   }
 | |
| 
 | |
|   if (Count == 0) {
 | |
|     return EFI_SUCCESS;
 | |
|   }
 | |
| 
 | |
|   if (Count > MaxDstBufferSize) {
 | |
|     Count = MaxDstBufferSize;
 | |
|   }
 | |
| 
 | |
|   for (Index = 0; Index < Count; Index++) {
 | |
|     if ((SrcBuffer[Index] >= 'a') && (SrcBuffer[Index] <= 'z')) {
 | |
|       DstBuffer[Index] = (CHAR8)((UINT8)SrcBuffer[Index] - ('a' - 'A'));
 | |
|     } else {
 | |
|       DstBuffer[Index] = SrcBuffer[Index];
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   return EFI_SUCCESS;
 | |
| }
 | |
| 
 | |
| /** Check whether Buffer is a root path ('\').
 | |
| 
 | |
|   This function works for both ASL and AML pathnames.
 | |
|   Buffer must be at least 2 bytes long.
 | |
| 
 | |
|   @param  [in]  Buffer   An ASL/AML path.
 | |
| 
 | |
|   @retval TRUE    Buffer is a root path
 | |
|   @retval FALSE   Buffer is not a root path.
 | |
| **/
 | |
| BOOLEAN
 | |
| EFIAPI
 | |
| AmlIsRootPath (
 | |
|   IN  CONST  CHAR8  *Buffer
 | |
|   )
 | |
| {
 | |
|   if (Buffer == NULL) {
 | |
|     return FALSE;
 | |
|   }
 | |
| 
 | |
|   if ((Buffer[0] == AML_ROOT_CHAR) && (Buffer[1] == '\0')) {
 | |
|     return TRUE;
 | |
|   } else {
 | |
|     return FALSE;
 | |
|   }
 | |
| }
 | |
| 
 | |
| /** Check whether Ch is an ASL/AML LeadName.
 | |
| 
 | |
|   This function works for both ASL and AML pathnames.
 | |
| 
 | |
|   ACPI 6.3 specification, s19.2.2. "ASL Name and Pathname Terms":
 | |
|   LeadNameChar := 'A'-'Z' | 'a'-'z' | '_'
 | |
| 
 | |
|   ACPI 6.3 specification, s20.2.2. "Name Objects Encoding":
 | |
|   LeadNameChar := 'A'-'Z' | 'a'-'z' | '_'
 | |
| 
 | |
|   @param  [in]  Ch    The char to test.
 | |
| 
 | |
|   @retval TRUE    Ch is an ASL/AML LeadName.
 | |
|   @retval FALSE   Ch is not an ASL/AML LeadName.
 | |
| **/
 | |
| BOOLEAN
 | |
| EFIAPI
 | |
| AmlIsLeadNameChar (
 | |
|   IN  CHAR8  Ch
 | |
|   )
 | |
| {
 | |
|   if ((Ch == '_') || ((Ch >= 'A') && (Ch <= 'Z')) || ((Ch >= 'a') && (Ch <= 'z'))) {
 | |
|     return TRUE;
 | |
|   } else {
 | |
|     return FALSE;
 | |
|   }
 | |
| }
 | |
| 
 | |
| /** Check whether Ch is an ASL/AML NameChar.
 | |
| 
 | |
|   This function works for both ASL and AML pathnames.
 | |
| 
 | |
|   ACPI 6.3 specification, s19.2.2. "ASL Name and Pathname Terms":
 | |
|   NameChar := DigitChar | LeadNameChar
 | |
|   LeadNameChar := 'A'-'Z' | 'a'-'z' | '_'
 | |
|   DigitChar := '0'-'9'
 | |
| 
 | |
|   ACPI 6.3 specification, s20.2.2. "Name Objects Encoding":
 | |
|   NameChar := DigitChar | LeadNameChar
 | |
|   LeadNameChar := 'A'-'Z' | 'a'-'z' | '_'
 | |
|   DigitChar := '0'-'9'
 | |
| 
 | |
|   @param  [in]  Ch    The char to test.
 | |
| 
 | |
|   @retval TRUE    Ch is an ASL/AML NameChar.
 | |
|   @retval FALSE   Ch is not an ASL/AML NameChar.
 | |
| **/
 | |
| BOOLEAN
 | |
| EFIAPI
 | |
| AmlIsNameChar (
 | |
|   IN  CHAR8  Ch
 | |
|   )
 | |
| {
 | |
|   if (AmlIsLeadNameChar (Ch) || ((Ch >= '0') && (Ch <= '9'))) {
 | |
|     return TRUE;
 | |
|   } else {
 | |
|     return FALSE;
 | |
|   }
 | |
| }
 | |
| 
 | |
| /** Check whether AslBuffer is an ASL NameSeg.
 | |
| 
 | |
|   This function only works for ASL NameStrings/pathnames.
 | |
|   ASL NameStrings/pathnames are at most 4 chars long.
 | |
| 
 | |
|   @param [in]   AslBuffer   Pointer in an ASL NameString/pathname.
 | |
|   @param [out]  Size        Size of the NameSeg.
 | |
| 
 | |
|   @retval TRUE    AslBuffer is an ASL NameSeg.
 | |
|   @retval FALSE   AslBuffer is not an ASL NameSeg.
 | |
| **/
 | |
| BOOLEAN
 | |
| EFIAPI
 | |
| AslIsNameSeg (
 | |
|   IN  CONST  CHAR8   *AslBuffer,
 | |
|   OUT        UINT32  *Size
 | |
|   )
 | |
| {
 | |
|   UINT32  Index;
 | |
| 
 | |
|   if ((AslBuffer == NULL) ||
 | |
|       (Size == NULL))
 | |
|   {
 | |
|     return FALSE;
 | |
|   }
 | |
| 
 | |
|   if (!AmlIsLeadNameChar (AslBuffer[0])) {
 | |
|     return FALSE;
 | |
|   }
 | |
| 
 | |
|   for (Index = 1; Index < AML_NAME_SEG_SIZE; Index++) {
 | |
|     if ((AslBuffer[Index] == '.')   ||
 | |
|         (AslBuffer[Index] == '\0'))
 | |
|     {
 | |
|       *Size = Index;
 | |
|       return TRUE;
 | |
|     } else if (!AmlIsNameChar (AslBuffer[Index])) {
 | |
|       return FALSE;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   *Size = Index;
 | |
|   return TRUE;
 | |
| }
 | |
| 
 | |
| /** Check whether AmlBuffer is an AML NameSeg.
 | |
| 
 | |
|   This function only works for AML NameStrings/pathnames.
 | |
|   AML NameStrings/pathnames must be 4 chars long.
 | |
| 
 | |
|   @param [in] AmlBuffer   Pointer in an AML NameString/pathname.
 | |
| 
 | |
|   @retval TRUE    AmlBuffer is an AML NameSeg.
 | |
|   @retval FALSE   AmlBuffer is not an AML NameSeg.
 | |
| **/
 | |
| BOOLEAN
 | |
| EFIAPI
 | |
| AmlIsNameSeg (
 | |
|   IN  CONST  CHAR8  *AmlBuffer
 | |
|   )
 | |
| {
 | |
|   UINT32  Index;
 | |
| 
 | |
|   if (AmlBuffer == NULL) {
 | |
|     return FALSE;
 | |
|   }
 | |
| 
 | |
|   if (!AmlIsLeadNameChar (AmlBuffer[0])) {
 | |
|     return FALSE;
 | |
|   }
 | |
| 
 | |
|   for (Index = 1; Index < AML_NAME_SEG_SIZE; Index++) {
 | |
|     if (!AmlIsNameChar (AmlBuffer[Index])) {
 | |
|       return FALSE;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   return TRUE;
 | |
| }
 | |
| 
 | |
| /** Parse an ASL NameString/path.
 | |
| 
 | |
|   An ASL NameString/path must be NULL terminated.
 | |
|   Information found in the ASL NameString/path is returned via pointers:
 | |
|   Root, ParentPrefix, SegCount.
 | |
| 
 | |
|   @param [in]    Buffer       ASL NameString/path.
 | |
|   @param [out]   Root         Pointer holding the number of root char.
 | |
|                               Can be 0 or 1.
 | |
|   @param [out]   ParentPrefix Pointer holding the number of carets char ('^').
 | |
|                               Can be [0-255].
 | |
|   @param [out]   SegCount     Pointer holding the number of NameSeg (s).
 | |
|                               Can be [0-255].
 | |
| 
 | |
|   @retval EFI_SUCCESS             The function completed successfully.
 | |
|   @retval EFI_INVALID_PARAMETER   Invalid parameter.
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| AslParseNameStringInfo (
 | |
|   IN  CONST CHAR8   *Buffer,
 | |
|   OUT       UINT32  *Root,
 | |
|   OUT       UINT32  *ParentPrefix,
 | |
|   OUT       UINT32  *SegCount
 | |
|   )
 | |
| {
 | |
|   UINT32  NameSegSize;
 | |
| 
 | |
|   if ((Buffer == NULL)        ||
 | |
|       (Root == NULL)          ||
 | |
|       (ParentPrefix == NULL)  ||
 | |
|       (SegCount == NULL))
 | |
|   {
 | |
|     ASSERT (0);
 | |
|     return EFI_INVALID_PARAMETER;
 | |
|   }
 | |
| 
 | |
|   *Root         = 0;
 | |
|   *ParentPrefix = 0;
 | |
|   *SegCount     = 0;
 | |
| 
 | |
|   // Handle Root and ParentPrefix(s).
 | |
|   if (*Buffer == AML_ROOT_CHAR) {
 | |
|     *Root = 1;
 | |
|     Buffer++;
 | |
|   } else if (*Buffer == AML_PARENT_PREFIX_CHAR) {
 | |
|     do {
 | |
|       Buffer++;
 | |
|       (*ParentPrefix)++;
 | |
|     } while (*Buffer == AML_PARENT_PREFIX_CHAR);
 | |
|   }
 | |
| 
 | |
|   // Handle SegCount(s).
 | |
|   while (AslIsNameSeg (Buffer, &NameSegSize)) {
 | |
|     // Safety checks on NameSegSize.
 | |
|     if ((NameSegSize == 0) || (NameSegSize > AML_NAME_SEG_SIZE)) {
 | |
|       ASSERT (0);
 | |
|       return EFI_INVALID_PARAMETER;
 | |
|     }
 | |
| 
 | |
|     // Increment the NameSeg count.
 | |
|     (*SegCount)++;
 | |
|     Buffer += NameSegSize;
 | |
| 
 | |
|     // Skip the '.' separator if present.
 | |
|     if (*Buffer == '.') {
 | |
|       Buffer++;
 | |
|     }
 | |
|   } // while
 | |
| 
 | |
|   // An ASL NameString/path must be NULL terminated.
 | |
|   if (*Buffer != '\0') {
 | |
|     ASSERT (0);
 | |
|     return EFI_INVALID_PARAMETER;
 | |
|   }
 | |
| 
 | |
|   if (!AmlIsNameString (*Root, *ParentPrefix, *SegCount)) {
 | |
|     ASSERT (0);
 | |
|     return EFI_INVALID_PARAMETER;
 | |
|   }
 | |
| 
 | |
|   return EFI_SUCCESS;
 | |
| }
 | |
| 
 | |
| /** Parse an AML NameString/path.
 | |
| 
 | |
|   It is possible to determine the size of an AML NameString/path just
 | |
|   by sight reading it. So no overflow can occur.
 | |
|   Information found in the AML NameString/path is returned via pointers:
 | |
|   Root, ParentPrefix, SegCount.
 | |
| 
 | |
|   @param [in]    Buffer         AML NameString/path.
 | |
|   @param [out]   Root           Pointer holding the number of root char.
 | |
|                                 Can be 0 or 1.
 | |
|   @param [out]   ParentPrefix   Pointer holding the number of carets char ('^').
 | |
|                                 Can be [0-255].
 | |
|   @param [out]   SegCount       Pointer holding the number of NameSeg(s).
 | |
|                                 Can be [0-255].
 | |
| 
 | |
|   @retval EFI_SUCCESS             The function completed successfully.
 | |
|   @retval EFI_INVALID_PARAMETER   Invalid parameter.
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| AmlParseNameStringInfo (
 | |
|   IN  CONST CHAR8   *Buffer,
 | |
|   OUT       UINT32  *Root,
 | |
|   OUT       UINT32  *ParentPrefix,
 | |
|   OUT       UINT32  *SegCount
 | |
|   )
 | |
| {
 | |
|   if ((Buffer == NULL) ||
 | |
|       (Root == NULL)   ||
 | |
|       (ParentPrefix == NULL) ||
 | |
|       (SegCount == NULL))
 | |
|   {
 | |
|     ASSERT (0);
 | |
|     return EFI_INVALID_PARAMETER;
 | |
|   }
 | |
| 
 | |
|   *Root         = 0;
 | |
|   *ParentPrefix = 0;
 | |
|   *SegCount     = 0;
 | |
| 
 | |
|   // Handle Root and ParentPrefix(s).
 | |
|   if (*Buffer == AML_ROOT_CHAR) {
 | |
|     *Root = 1;
 | |
|     Buffer++;
 | |
|   } else if (*Buffer == AML_PARENT_PREFIX_CHAR) {
 | |
|     do {
 | |
|       Buffer++;
 | |
|       (*ParentPrefix)++;
 | |
|     } while (*Buffer == AML_PARENT_PREFIX_CHAR);
 | |
|   }
 | |
| 
 | |
|   // Handle SegCount(s).
 | |
|   if (*Buffer == AML_DUAL_NAME_PREFIX) {
 | |
|     *SegCount = 2;
 | |
|   } else if (*Buffer == AML_MULTI_NAME_PREFIX) {
 | |
|     *SegCount = *((UINT8 *)(Buffer + 1));
 | |
|   } else if (AmlIsNameSeg (Buffer)) {
 | |
|     *SegCount = 1;
 | |
|   } else if (*Buffer == AML_ZERO_OP) {
 | |
|     *SegCount = 0;
 | |
|   } else {
 | |
|     ASSERT (0);
 | |
|     return EFI_INVALID_PARAMETER;
 | |
|   }
 | |
| 
 | |
|   // Safety checks on exit.
 | |
|   if (!AmlIsNameString (*Root, *ParentPrefix, *SegCount)) {
 | |
|     ASSERT (0);
 | |
|     return EFI_INVALID_PARAMETER;
 | |
|   }
 | |
| 
 | |
|   return EFI_SUCCESS;
 | |
| }
 | |
| 
 | |
| /** Compute the ASL NameString/path size from NameString
 | |
|     information (Root, ParentPrefix, SegCount).
 | |
| 
 | |
|   @param [in] Root          Number of root char.
 | |
|                             Can be 0 or 1.
 | |
|   @param [in] ParentPrefix  Number of carets char ('^').
 | |
|                             Can be [0-255].
 | |
|   @param [in] SegCount      Pointer holding the number of NameSeg(s).
 | |
|                             Can be [0-255].
 | |
| 
 | |
|   @return Size of the ASL NameString/path.
 | |
| **/
 | |
| UINT32
 | |
| EFIAPI
 | |
| AslComputeNameStringSize (
 | |
|   IN  UINT32  Root,
 | |
|   IN  UINT32  ParentPrefix,
 | |
|   IN  UINT32  SegCount
 | |
|   )
 | |
| {
 | |
|   UINT32  TotalSize;
 | |
| 
 | |
|   if (!AmlIsNameString (Root, ParentPrefix, SegCount)) {
 | |
|     ASSERT (0);
 | |
|     return 0;
 | |
|   }
 | |
| 
 | |
|   // Root and ParentPrefix(s).
 | |
|   TotalSize = Root + ParentPrefix;
 | |
| 
 | |
|   // Add size required for NameSeg(s).
 | |
|   TotalSize += (SegCount * AML_NAME_SEG_SIZE);
 | |
| 
 | |
|   // Add size required for '.' separator(s).
 | |
|   TotalSize += (SegCount > 1) ? (SegCount - 1) : 0;
 | |
| 
 | |
|   // Add 1 byte for NULL termination '\0'.
 | |
|   TotalSize += 1;
 | |
| 
 | |
|   return TotalSize;
 | |
| }
 | |
| 
 | |
| /** Compute the AML NameString/path size from NameString
 | |
|     information (Root, ParentPrefix, SegCount).
 | |
| 
 | |
|   @param [in] Root          Number of root char.
 | |
|                             Can be 0 or 1.
 | |
|   @param [in] ParentPrefix  Number of carets char ('^').
 | |
|                             Can be [0-255].
 | |
|   @param [in] SegCount      Pointer holding the number of NameSeg(s).
 | |
|                             Can be [0-255].
 | |
| 
 | |
|   @return Size of the AML NameString/path.
 | |
| **/
 | |
| UINT32
 | |
| EFIAPI
 | |
| AmlComputeNameStringSize (
 | |
|   IN  UINT32  Root,
 | |
|   IN  UINT32  ParentPrefix,
 | |
|   IN  UINT32  SegCount
 | |
|   )
 | |
| {
 | |
|   UINT32  TotalSize;
 | |
| 
 | |
|   if (!AmlIsNameString (Root, ParentPrefix, SegCount)) {
 | |
|     ASSERT (0);
 | |
|     return 0;
 | |
|   }
 | |
| 
 | |
|   // Root and ParentPrefix(s).
 | |
|   TotalSize = Root + ParentPrefix;
 | |
| 
 | |
|   // If SegCount == 0, '\0' must end the AML NameString/path.
 | |
|   TotalSize += (SegCount == 0) ? 1 : (SegCount * AML_NAME_SEG_SIZE);
 | |
| 
 | |
|   // AML prefix. SegCount > 2 = MultiNamePrefix, SegCount = 2 DualNamePrefix.
 | |
|   TotalSize += (SegCount > 2) ? 2 : ((SegCount == 2) ? 1 : 0);
 | |
| 
 | |
|   return TotalSize;
 | |
| }
 | |
| 
 | |
| /** Get the ASL NameString/path size.
 | |
| 
 | |
|   @param [in]   AslPath         An ASL NameString/path.
 | |
|   @param [out]  AslPathSizePtr  Pointer holding the ASL NameString/path size.
 | |
| 
 | |
|   @retval EFI_SUCCESS             Success.
 | |
|   @retval EFI_INVALID_PARAMETER   Invalid parameter.
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| AslGetNameStringSize (
 | |
|   IN  CONST CHAR8   *AslPath,
 | |
|   OUT       UINT32  *AslPathSizePtr
 | |
|   )
 | |
| {
 | |
|   if ((AslPath == NULL) ||
 | |
|       (AslPathSizePtr == NULL))
 | |
|   {
 | |
|     ASSERT (0);
 | |
|     return EFI_INVALID_PARAMETER;
 | |
|   }
 | |
| 
 | |
|   *AslPathSizePtr = 0;
 | |
|   do {
 | |
|     (*AslPathSizePtr)++;
 | |
|     AslPath++;
 | |
|   } while (*AslPath != '\0');
 | |
| 
 | |
|   return EFI_SUCCESS;
 | |
| }
 | |
| 
 | |
| /** Get the AML NameString/path size.
 | |
| 
 | |
|   @param [in]   AmlPath         An AML NameString/path.
 | |
|   @param [out]  AmlPathSizePtr  Pointer holding the AML NameString/path size.
 | |
| 
 | |
|   @retval EFI_SUCCESS             Success.
 | |
|   @retval EFI_INVALID_PARAMETER   Invalid parameter.
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| AmlGetNameStringSize (
 | |
|   IN   CONST  CHAR8   *AmlPath,
 | |
|   OUT         UINT32  *AmlPathSizePtr
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS  Status;
 | |
| 
 | |
|   UINT32  Root;
 | |
|   UINT32  ParentPrefix;
 | |
|   UINT32  SegCount;
 | |
| 
 | |
|   if ((AmlPath == NULL) ||
 | |
|       (AmlPathSizePtr == NULL))
 | |
|   {
 | |
|     ASSERT (0);
 | |
|     return EFI_INVALID_PARAMETER;
 | |
|   }
 | |
| 
 | |
|   Status = AmlParseNameStringInfo (
 | |
|              AmlPath,
 | |
|              &Root,
 | |
|              &ParentPrefix,
 | |
|              &SegCount
 | |
|              );
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     ASSERT (0);
 | |
|     return Status;
 | |
|   }
 | |
| 
 | |
|   *AmlPathSizePtr = AmlComputeNameStringSize (Root, ParentPrefix, SegCount);
 | |
|   if (*AmlPathSizePtr == 0) {
 | |
|     ASSERT (0);
 | |
|     return EFI_INVALID_PARAMETER;
 | |
|   }
 | |
| 
 | |
|   return Status;
 | |
| }
 | |
| 
 | |
| /** Convert an ASL NameString/path to an AML NameString/path.
 | |
|     The caller must free the memory allocated in this function
 | |
|     for AmlPath using FreePool ().
 | |
| 
 | |
|   @param  [in]  AslPath     An ASL NameString/path.
 | |
|   @param  [out] OutAmlPath  Buffer containing the AML path.
 | |
| 
 | |
|   @retval EFI_SUCCESS             Success.
 | |
|   @retval EFI_INVALID_PARAMETER   Invalid parameter.
 | |
|   @retval EFI_OUT_OF_RESOURCES    Failed to allocate memory.
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| ConvertAslNameToAmlName (
 | |
|   IN  CONST  CHAR8  *AslPath,
 | |
|   OUT        CHAR8  **OutAmlPath
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS  Status;
 | |
| 
 | |
|   UINT32  Root;
 | |
|   UINT32  ParentPrefix;
 | |
|   UINT32  SegCount;
 | |
|   UINT32  TotalSize;
 | |
|   UINT32  NameSegSize;
 | |
| 
 | |
|   CONST CHAR8  *AslBuffer;
 | |
|   CHAR8        *AmlBuffer;
 | |
|   CHAR8        *AmlPath;
 | |
| 
 | |
|   if ((AslPath == NULL) ||
 | |
|       (OutAmlPath == NULL))
 | |
|   {
 | |
|     return EFI_INVALID_PARAMETER;
 | |
|   }
 | |
| 
 | |
|   // Analyze AslPath. AslPath is checked in the call.
 | |
|   Status = AslParseNameStringInfo (AslPath, &Root, &ParentPrefix, &SegCount);
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     ASSERT (0);
 | |
|     return Status;
 | |
|   }
 | |
| 
 | |
|   // Compute TotalSize.
 | |
|   TotalSize = AmlComputeNameStringSize (Root, ParentPrefix, SegCount);
 | |
|   if (TotalSize == 0) {
 | |
|     ASSERT (0);
 | |
|     return EFI_INVALID_PARAMETER;
 | |
|   }
 | |
| 
 | |
|   // Allocate memory.
 | |
|   AmlPath = AllocateZeroPool (TotalSize);
 | |
|   if (AmlPath == NULL) {
 | |
|     ASSERT (0);
 | |
|     return EFI_OUT_OF_RESOURCES;
 | |
|   }
 | |
| 
 | |
|   AmlBuffer = AmlPath;
 | |
|   AslBuffer = AslPath;
 | |
| 
 | |
|   // Handle Root and ParentPrefix(s).
 | |
|   if (Root == 1) {
 | |
|     *AmlBuffer = AML_ROOT_CHAR;
 | |
|     AmlBuffer++;
 | |
|     AslBuffer++;
 | |
|   } else if (ParentPrefix > 0) {
 | |
|     SetMem (AmlBuffer, ParentPrefix, AML_PARENT_PREFIX_CHAR);
 | |
|     AmlBuffer += ParentPrefix;
 | |
|     AslBuffer += ParentPrefix;
 | |
|   }
 | |
| 
 | |
|   // Handle prefix and SegCount(s).
 | |
|   if (SegCount > 2) {
 | |
|     *AmlBuffer = AML_MULTI_NAME_PREFIX;
 | |
|     AmlBuffer++;
 | |
|     *AmlBuffer = (UINT8)SegCount;
 | |
|     AmlBuffer++;
 | |
|   } else if (SegCount == 2) {
 | |
|     *AmlBuffer = AML_DUAL_NAME_PREFIX;
 | |
|     AmlBuffer++;
 | |
|   }
 | |
| 
 | |
|   if (SegCount != 0) {
 | |
|     // Write NameSeg(s).
 | |
|     while (1) {
 | |
|       SegCount--;
 | |
| 
 | |
|       // Get the NameSeg size.
 | |
|       if (!AslIsNameSeg (AslBuffer, &NameSegSize)) {
 | |
|         ASSERT (0);
 | |
|         Status = EFI_INVALID_PARAMETER;
 | |
|         goto error_handler;
 | |
|       }
 | |
| 
 | |
|       // Convert to Upper case and copy.
 | |
|       Status = AmlUpperCaseMemCpyS (
 | |
|                  AmlBuffer,
 | |
|                  TotalSize,
 | |
|                  AslBuffer,
 | |
|                  NameSegSize
 | |
|                  );
 | |
|       if (EFI_ERROR (Status)) {
 | |
|         ASSERT (0);
 | |
|         goto error_handler;
 | |
|       }
 | |
| 
 | |
|       // Complete the NameSeg with an underscore ('_') if shorter than 4 bytes.
 | |
|       SetMem (
 | |
|         AmlBuffer + NameSegSize,
 | |
|         AML_NAME_SEG_SIZE - NameSegSize,
 | |
|         AML_NAME_CHAR__
 | |
|         );
 | |
| 
 | |
|       // Go to the next NameSeg.
 | |
|       AmlBuffer += AML_NAME_SEG_SIZE;
 | |
|       AslBuffer += NameSegSize;
 | |
| 
 | |
|       // Skip the '.' separator.
 | |
|       if (SegCount != 0) {
 | |
|         if (*AslBuffer == '.') {
 | |
|           AslBuffer++;
 | |
|         } else {
 | |
|           ASSERT (0);
 | |
|           Status = EFI_INVALID_PARAMETER;
 | |
|           goto error_handler;
 | |
|         }
 | |
|       } else {
 | |
|         // (SegCount == 0)
 | |
|         if (*AslBuffer == '\0') {
 | |
|           break;
 | |
|         } else {
 | |
|           ASSERT (0);
 | |
|           Status = EFI_INVALID_PARAMETER;
 | |
|           goto error_handler;
 | |
|         }
 | |
|       }
 | |
|     } // while
 | |
|   } else {
 | |
|     // (SegCount == 0)
 | |
|     // '\0' needs to end the AML NameString/path.
 | |
|     *AmlBuffer = AML_ZERO_OP;
 | |
|     AmlBuffer++;
 | |
|   }
 | |
| 
 | |
|   // Safety checks on exit.
 | |
|   // Check that AmlPath has been filled with TotalSize bytes.
 | |
|   if ((SegCount != 0)               ||
 | |
|       (*AslBuffer != AML_ZERO_OP)   ||
 | |
|       (((UINT32)(AmlBuffer - AmlPath)) != TotalSize))
 | |
|   {
 | |
|     ASSERT (0);
 | |
|     Status = EFI_INVALID_PARAMETER;
 | |
|     goto error_handler;
 | |
|   }
 | |
| 
 | |
|   *OutAmlPath = AmlPath;
 | |
|   return EFI_SUCCESS;
 | |
| 
 | |
| error_handler:
 | |
|   FreePool (AmlPath);
 | |
|   return Status;
 | |
| }
 | |
| 
 | |
| /** Convert an AML NameString/path to an ASL NameString/path.
 | |
|     The caller must free the memory allocated in this function.
 | |
|     using FreePool ().
 | |
| 
 | |
|   @param  [in]  AmlPath     An AML NameString/path.
 | |
|   @param  [out] OutAslPath  Buffer containing the ASL path.
 | |
| 
 | |
|   @retval EFI_SUCCESS             Success.
 | |
|   @retval EFI_INVALID_PARAMETER   Invalid parameter.
 | |
|   @retval EFI_OUT_OF_RESOURCES    Failed to allocate memory.
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| ConvertAmlNameToAslName (
 | |
|   IN  CONST CHAR8  *AmlPath,
 | |
|   OUT       CHAR8  **OutAslPath
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS  Status;
 | |
| 
 | |
|   UINT32  Root;
 | |
|   UINT32  ParentPrefix;
 | |
|   UINT32  SegCount;
 | |
|   UINT32  TotalSize;
 | |
| 
 | |
|   CONST CHAR8  *AmlBuffer;
 | |
|   CHAR8        *AslBuffer;
 | |
|   CHAR8        *AslPath;
 | |
| 
 | |
|   if ((AmlPath == NULL)   ||
 | |
|       (OutAslPath == NULL))
 | |
|   {
 | |
|     ASSERT (0);
 | |
|     return EFI_INVALID_PARAMETER;
 | |
|   }
 | |
| 
 | |
|   // Analyze AslPath. AmlPath is checked in the call.
 | |
|   Status = AmlParseNameStringInfo (AmlPath, &Root, &ParentPrefix, &SegCount);
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     ASSERT (0);
 | |
|     return Status;
 | |
|   }
 | |
| 
 | |
|   // Compute TotalSize.
 | |
|   TotalSize = AslComputeNameStringSize (Root, ParentPrefix, SegCount);
 | |
|   if (TotalSize == 0) {
 | |
|     ASSERT (0);
 | |
|     return EFI_INVALID_PARAMETER;
 | |
|   }
 | |
| 
 | |
|   // Allocate memory.
 | |
|   AslPath = AllocateZeroPool (TotalSize);
 | |
|   if (AslPath == NULL) {
 | |
|     ASSERT (0);
 | |
|     return EFI_OUT_OF_RESOURCES;
 | |
|   }
 | |
| 
 | |
|   AmlBuffer = AmlPath;
 | |
|   AslBuffer = AslPath;
 | |
| 
 | |
|   // Handle prefix and SegCount(s).
 | |
|   if (Root == 1) {
 | |
|     *AslBuffer = AML_ROOT_CHAR;
 | |
|     AslBuffer++;
 | |
|     AmlBuffer++;
 | |
|   } else if (ParentPrefix > 0) {
 | |
|     SetMem (AslBuffer, ParentPrefix, AML_PARENT_PREFIX_CHAR);
 | |
|     AslBuffer += ParentPrefix;
 | |
|     AmlBuffer += ParentPrefix;
 | |
|   }
 | |
| 
 | |
|   // Handle Root and Parent(s).
 | |
|   // Skip the MultiName or DualName prefix chars.
 | |
|   if (SegCount > 2) {
 | |
|     AmlBuffer += 2;
 | |
|   } else if (SegCount == 2) {
 | |
|     AmlBuffer += 1;
 | |
|   }
 | |
| 
 | |
|   // Write NameSeg(s).
 | |
|   while (SegCount) {
 | |
|     // NameSeg is already in upper case and always 4 bytes long.
 | |
|     CopyMem (AslBuffer, AmlBuffer, AML_NAME_SEG_SIZE);
 | |
|     AslBuffer += AML_NAME_SEG_SIZE;
 | |
|     AmlBuffer += AML_NAME_SEG_SIZE;
 | |
| 
 | |
|     SegCount--;
 | |
| 
 | |
|     // Write the '.' separator if there is another NameSeg following.
 | |
|     if (SegCount != 0) {
 | |
|       *AslBuffer = '.';
 | |
|       AslBuffer++;
 | |
|     }
 | |
|   } // while
 | |
| 
 | |
|   // NULL terminate the ASL NameString.
 | |
|   *AslBuffer = '\0';
 | |
|   AslBuffer++;
 | |
| 
 | |
|   // Safety checks on exit.
 | |
|   // Check that AslPath has been filled with TotalSize bytes.
 | |
|   if (((UINT32)(AslBuffer - AslPath)) != TotalSize) {
 | |
|     ASSERT (0);
 | |
|     Status = EFI_INVALID_PARAMETER;
 | |
|     goto error_handler;
 | |
|   }
 | |
| 
 | |
|   *OutAslPath = AslPath;
 | |
|   return EFI_SUCCESS;
 | |
| 
 | |
| error_handler:
 | |
|   FreePool (AslPath);
 | |
|   return Status;
 | |
| }
 | |
| 
 | |
| /** Compare two ASL NameStrings.
 | |
| 
 | |
|   @param [in] AslName1    First NameString to compare.
 | |
|   @param [in] AslName2    Second NameString to compare.
 | |
| 
 | |
|   @retval TRUE if the two strings are identical.
 | |
|   @retval FALSE otherwise, or if error.
 | |
| **/
 | |
| BOOLEAN
 | |
| EFIAPI
 | |
| AslCompareNameString (
 | |
|   IN  CONST CHAR8  *AslName1,
 | |
|   IN  CONST CHAR8  *AslName2
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS  Status;
 | |
|   UINT32      AslName1Len;
 | |
|   UINT32      AslName2Len;
 | |
| 
 | |
|   if ((AslName1 == NULL) ||
 | |
|       (AslName2 == NULL))
 | |
|   {
 | |
|     ASSERT (0);
 | |
|     return FALSE;
 | |
|   }
 | |
| 
 | |
|   Status = AslGetNameStringSize (AslName1, &AslName1Len);
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     ASSERT (0);
 | |
|     return FALSE;
 | |
|   }
 | |
| 
 | |
|   Status = AslGetNameStringSize (AslName2, &AslName2Len);
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     ASSERT (0);
 | |
|     return FALSE;
 | |
|   }
 | |
| 
 | |
|   // AslName1 and AslName2 don't have the same length
 | |
|   if (AslName1Len != AslName2Len) {
 | |
|     return FALSE;
 | |
|   }
 | |
| 
 | |
|   return (CompareMem (AslName1, AslName2, AslName1Len) == 0);
 | |
| }
 | |
| 
 | |
| /** Compare two AML NameStrings.
 | |
| 
 | |
|   @param [in] AmlName1    First NameString to compare.
 | |
|   @param [in] AmlName2    Second NameString to compare.
 | |
| 
 | |
|   @retval TRUE if the two strings are identical.
 | |
|   @retval FALSE otherwise, or if error.
 | |
| **/
 | |
| BOOLEAN
 | |
| EFIAPI
 | |
| AmlCompareNameString (
 | |
|   IN  CONST CHAR8  *AmlName1,
 | |
|   IN  CONST CHAR8  *AmlName2
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS  Status;
 | |
|   UINT32      AmlName1Len;
 | |
|   UINT32      AmlName2Len;
 | |
| 
 | |
|   if ((AmlName1 == NULL) ||
 | |
|       (AmlName2 == NULL))
 | |
|   {
 | |
|     ASSERT (0);
 | |
|     return FALSE;
 | |
|   }
 | |
| 
 | |
|   Status = AmlGetNameStringSize (AmlName1, &AmlName1Len);
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     ASSERT (0);
 | |
|     return FALSE;
 | |
|   }
 | |
| 
 | |
|   Status = AmlGetNameStringSize (AmlName2, &AmlName2Len);
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     ASSERT (0);
 | |
|     return FALSE;
 | |
|   }
 | |
| 
 | |
|   // AmlName1 and AmlName2 don't have the same length
 | |
|   if (AmlName1Len != AmlName2Len) {
 | |
|     return FALSE;
 | |
|   }
 | |
| 
 | |
|   return (CompareMem (AmlName1, AmlName2, AmlName1Len) == 0);
 | |
| }
 | |
| 
 | |
| /** Compare an AML NameString and an ASL NameString.
 | |
| 
 | |
|   The ASL NameString is converted to an AML NameString before
 | |
|   being compared with the ASL NameString. This allows to expand
 | |
|   NameSegs shorter than 4 chars.
 | |
|   E.g.: AslName: "DEV" will be expanded to "DEV_" before being
 | |
|         compared.
 | |
| 
 | |
|   @param [in] AmlName1   AML NameString to compare.
 | |
|   @param [in] AslName2   ASL NameString to compare.
 | |
| 
 | |
|   @retval TRUE if the two strings are identical.
 | |
|   @retval FALSE otherwise, or if error.
 | |
| **/
 | |
| BOOLEAN
 | |
| EFIAPI
 | |
| CompareAmlWithAslNameString (
 | |
|   IN  CONST CHAR8  *AmlName1,
 | |
|   IN  CONST CHAR8  *AslName2
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS  Status;
 | |
| 
 | |
|   CHAR8    *AmlName2;
 | |
|   BOOLEAN  RetVal;
 | |
| 
 | |
|   if ((AmlName1 == NULL) ||
 | |
|       (AslName2 == NULL))
 | |
|   {
 | |
|     ASSERT (0);
 | |
|     return FALSE;
 | |
|   }
 | |
| 
 | |
|   // Convert the AslName2 to an AmlName2.
 | |
|   // AmlName2 must be freed.
 | |
|   Status = ConvertAmlNameToAslName (AslName2, &AmlName2);
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     ASSERT (0);
 | |
|     return FALSE;
 | |
|   }
 | |
| 
 | |
|   RetVal = AmlCompareNameString (AmlName1, AmlName2);
 | |
| 
 | |
|   // Free AmlName2.
 | |
|   FreePool (AmlName2);
 | |
| 
 | |
|   return RetVal;
 | |
| }
 | |
| 
 | |
| /** Given an AmlPath, return the address of the first NameSeg.
 | |
| 
 | |
|   It is possible to determine the size of an AML NameString/path just
 | |
|   by sight reading it. So no overflow can occur.
 | |
| 
 | |
|   @param  [in]  AmlPath       The AML pathname.
 | |
|   @param  [in]  Root          The AML pathname starts with a root char.
 | |
|                               It is an absolute path.
 | |
|   @param  [in]  ParentPrefix  The AML pathname has ParentPrefix
 | |
|                               carets in its name.
 | |
| 
 | |
|   @return Pointer to the first NameSeg of the NameString.
 | |
|           Return NULL if AmlPath is NULL.
 | |
| **/
 | |
| CONST
 | |
| CHAR8 *
 | |
| EFIAPI
 | |
| AmlGetFirstNameSeg (
 | |
|   IN  CONST  CHAR8   *AmlPath,
 | |
|   IN         UINT32  Root,
 | |
|   IN         UINT32  ParentPrefix
 | |
|   )
 | |
| {
 | |
|   if (AmlPath == NULL) {
 | |
|     ASSERT (0);
 | |
|     return NULL;
 | |
|   }
 | |
| 
 | |
|   AmlPath += Root;
 | |
|   AmlPath += ParentPrefix;
 | |
|   AmlPath += ((*AmlPath == AML_MULTI_NAME_PREFIX) ? 2
 | |
|                : (*AmlPath == AML_DUAL_NAME_PREFIX) ? 1 : 0);
 | |
|   return AmlPath;
 | |
| }
 |