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;
 | 
						|
}
 |