//********************************************************************** //********************************************************************** //** ** //** (C)Copyright 1985-2011, American Megatrends, Inc. ** //** ** //** All Rights Reserved. ** //** ** //** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** //** ** //** Phone: (770)-246-8600 ** //** ** //********************************************************************** //********************************************************************** //********************************************************************** // $Header: /Alaska/BIN/Modules/ACPI/Template/Core/AmlString.c 3 12/13/12 12:00p Oleksiyy $ // // $Revision: 3 $ // // $Date: 12/13/12 12:00p $ //********************************************************************** // Revision History // ---------------- // $Log: /Alaska/BIN/Modules/ACPI/Template/Core/AmlString.c $ // // 3 12/13/12 12:00p Oleksiyy // [TAG] EIP109290 // [Category] Improvement // [Description] Issues found by CppCheck in ACPI eModule // [Files] AcpiCore.c, mptable.c, AmlString.c, BootScriptSave.c and // BootScriptExecuter.c // // 2 5/14/11 2:13p Yakovlevs // [TAG] EIP 56526 // [Category] New Feature // [Description] ACPI Manipulation Protocol. PI 1.2 Spec Vol 5 Section // 9. Initial checkin. // [Files] AcpiCore.c; AcpiCore.h; AcpiSdtPrivate.h; Aml.c; AmlChild.c; // AmlNamespace.c; AmlOption.c; AmlString.c AcpiSdt.c; // Protocol\AcpiSdt.h. // //********************************************************************** //********************************************************************** // // // Name: AmlString.c // // Description: // ACPI AML Name space parsing/manipulation functions for ACPI SDT. // // //********************************************************************** #include "AcpiCore.h" /** Check if it is AML Root name @param[in] Buffer AML path. @retval TRUE AML path is root. @retval FALSE AML path is not root. **/ BOOLEAN AmlIsRootPath ( IN UINT8 *Buffer ) { if ((Buffer[0] == AML_ROOT_CHAR) && (Buffer[1] == 0)) { return TRUE; } else { return FALSE; } } /** Check if it is AML LeadName. @param[in] Ch Char. @retval TRUE Char is AML LeadName. @retval FALSE Char is not AML LeadName. **/ BOOLEAN AmlIsLeadName ( IN CHAR8 Ch ) { if ((Ch == '_') || (Ch >= 'A' && Ch <= 'Z')) { return TRUE; } else { return FALSE; } } /** Check if it is AML Name. @param[in] Ch Char. @retval TRUE Char is AML Name. @retval FALSE Char is not AML Name. **/ BOOLEAN AmlIsName ( IN CHAR8 Ch ) { if (AmlIsLeadName (Ch) || (Ch >= '0' && Ch <= '9')) { return TRUE; } else { return FALSE; } } /** Return is buffer is AML NameSeg. @param[in] Buffer AML NameSement. @retval TRUE It is AML NameSegment. @retval FALSE It is not AML NameSegment. **/ BOOLEAN AmlIsNameSeg ( IN UINT8 *Buffer ) { UINTN Index; if (!AmlIsLeadName (Buffer[0])) { return FALSE; } for (Index = 1; Index < AML_NAME_SEG_SIZE; Index++) { if (!AmlIsName (Buffer[Index])) { return FALSE; } } return TRUE; } /** Get AML NameString size. @param[in] Buffer AML NameString. @param[out] BufferSize AML NameString size @retval EFI_SUCCESS Success. @retval EFI_INVALID_PARAMETER Buffer does not refer to a valid AML NameString. **/ EFI_STATUS AmlGetNameStringSize ( IN UINT8 *Buffer, OUT UINTN *BufferSize ) { UINTN SegCount; UINTN Length; UINTN Index; Length = 0; // // Parse root or parent prefix // if (*Buffer == AML_ROOT_CHAR) { Buffer ++; Length ++; } else if (*Buffer == AML_PARENT_PREFIX_CHAR) { do { Buffer ++; Length ++; } while (*Buffer == AML_PARENT_PREFIX_CHAR); } // // Parse name segment // if (*Buffer == AML_DUAL_NAME_PREFIX) { Buffer ++; Length ++; SegCount = 2; } else if (*Buffer == AML_MULTI_NAME_PREFIX) { Buffer ++; Length ++; SegCount = *Buffer; Buffer ++; Length ++; } else if (*Buffer == 0) { // // NULL Name, only for Root // SegCount = 0; Buffer --; if ((Length == 1) && (*Buffer == AML_ROOT_CHAR)) { *BufferSize = 2; return EFI_SUCCESS; } else { return EFI_INVALID_PARAMETER; } } else { // // NameSeg // SegCount = 1; } Index = 0; do { if (!AmlIsNameSeg (Buffer)) { return EFI_INVALID_PARAMETER; } Buffer += AML_NAME_SEG_SIZE; Length += AML_NAME_SEG_SIZE; Index ++; } while (Index < SegCount); *BufferSize = Length; return EFI_SUCCESS; } /** Check if it is ASL LeadName. @param[in] Ch Char. @retval TRUE Char is ASL LeadName. @retval FALSE Char is not ASL LeadName. **/ BOOLEAN AmlIsAslLeadName ( IN CHAR8 Ch ) { if (AmlIsLeadName (Ch) || (Ch >= 'a' && Ch <= 'z')) { return TRUE; } else { return FALSE; } } /** Check if it is ASL Name. @param[in] Ch Char. @retval TRUE Char is ASL Name. @retval FALSE Char is not ASL Name. **/ BOOLEAN AmlIsAslName ( IN CHAR8 Ch ) { if (AmlIsAslLeadName (Ch) || (Ch >= '0' && Ch <= '9')) { return TRUE; } else { return FALSE; } } /** Get ASL NameString size. @param[in] Buffer ASL NameString. @return ASL NameString size. **/ UINTN AmlGetAslNameSegLength ( IN UINT8 *Buffer ) { UINTN Length; UINTN Index; if (*Buffer == 0) { return 0; } Length = 0; // // 1st // if (AmlIsAslLeadName (*Buffer)) { Length ++; Buffer ++; } if ((*Buffer == 0) || (*Buffer == '.')) { return Length; } // // 2, 3, 4 name char // for (Index = 0; Index < 3; Index++) { if (AmlIsAslName (*Buffer)) { Length ++; Buffer ++; } if ((*Buffer == 0) || (*Buffer == '.')) { return Length; } } // // Invalid ASL name // return 0; } /** Get ASL NameString size. @param[in] Buffer ASL NameString. @param[out] Root On return, points to Root char number. @param[out] Parent On return, points to Parent char number. @param[out] SegCount On return, points to Segment count. @return ASL NameString size. **/ UINTN AmlGetAslNameStringSize ( IN UINT8 *Buffer, OUT UINTN *Root, OUT UINTN *Parent, OUT UINTN *SegCount ) { UINTN NameLength; UINTN TotalLength; *Root = 0; *Parent = 0; *SegCount = 0; TotalLength = 0; NameLength = 0; if (*Buffer == AML_ROOT_CHAR) { *Root = 1; Buffer ++; } else if (*Buffer == AML_PARENT_PREFIX_CHAR) { do { Buffer ++; (*Parent) ++; } while (*Buffer == AML_PARENT_PREFIX_CHAR); } // // Now parse name // while (*Buffer != 0) { NameLength = AmlGetAslNameSegLength (Buffer); if ((NameLength == 0) || (NameLength > AML_NAME_SEG_SIZE)) { return 0; } (*SegCount) ++; Buffer += NameLength; if (*Buffer == 0) { break; } Buffer ++; } // // Check SegCoount // if (*SegCount > 0xFF) { return 0; } // // Calculate total length // TotalLength = *Root + *Parent + (*SegCount) * AML_NAME_SEG_SIZE; if (*SegCount > 2) { TotalLength += 2; } else if (*SegCount == 2) { TotalLength += 1; } // // Add NULL char // TotalLength ++; return TotalLength; } /** Copy mem, and cast all the char in dest to be upper case. @param[in] DstBuffer Destination buffer. @param[in] SrcBuffer Source buffer. @param[in] Length Buffer length. **/ VOID AmlUpperCaseCopyMem ( IN UINT8 *DstBuffer, IN UINT8 *SrcBuffer, IN UINTN Length ) { UINTN Index; for (Index = 0; Index < Length; Index++) { if (SrcBuffer[Index] >= 'a' && SrcBuffer[Index] <= 'z') { DstBuffer[Index] = (UINT8)(SrcBuffer[Index] - 'a' + 'A'); } else { DstBuffer[Index] = SrcBuffer[Index]; } } } /** Return AML name according to ASL name. The caller need free the AmlName returned. @param[in] AslPath ASL name. @return AmlName **/ UINT8 * AmlNameFromAslName ( IN UINT8 *AslPath ) { UINTN Root; UINTN Parent; UINTN SegCount; UINTN TotalLength; UINTN NameLength; UINT8 *Buffer; UINT8 *AmlPath; UINT8 *AmlBuffer; TotalLength = AmlGetAslNameStringSize (AslPath, &Root, &Parent, &SegCount); if (TotalLength == 0) { return NULL; } AmlPath = Malloc (TotalLength); ASSERT (AmlPath != NULL); AmlBuffer = AmlPath; Buffer = AslPath; // // Handle Root and Parent // if (Root == 1) { *AmlBuffer = AML_ROOT_CHAR; AmlBuffer ++; Buffer ++; } else if (Parent > 0) { MemSet (AmlBuffer, Parent, AML_PARENT_PREFIX_CHAR); AmlBuffer += Parent; Buffer += Parent; } // // Handle SegCount // if (SegCount > 2) { *AmlBuffer = AML_MULTI_NAME_PREFIX; AmlBuffer ++; *AmlBuffer = (UINT8)SegCount; AmlBuffer ++; } else if (SegCount == 2) { *AmlBuffer = AML_DUAL_NAME_PREFIX; AmlBuffer ++; } // // Now to name // while (*Buffer != 0) { NameLength = AmlGetAslNameSegLength (Buffer); ASSERT ((NameLength != 0) && (NameLength <= AML_NAME_SEG_SIZE)); AmlUpperCaseCopyMem (AmlBuffer, Buffer, NameLength); MemSet (AmlBuffer + NameLength, AML_NAME_SEG_SIZE - NameLength, AML_NAME_CHAR__); Buffer += NameLength; AmlBuffer += AML_NAME_SEG_SIZE; if (*Buffer == 0) { break; } Buffer ++; } // // Add NULL // AmlPath[TotalLength - 1] = 0; return AmlPath; } /** Print AML NameSeg. @param[in] Buffer AML NameSeg. **/ VOID AmlPrintNameSeg ( IN UINT8 *Buffer ) { TRACE ((-1, "%c", Buffer[0])); if ((Buffer[1] == '_') && (Buffer[2] == '_') && (Buffer[3] == '_')) { return ; } TRACE ((-1, "%c", Buffer[1])); if ((Buffer[2] == '_') && (Buffer[3] == '_')) { return ; } TRACE ((-1, "%c", Buffer[2])); if (Buffer[3] == '_') { return ; } TRACE ((-1, "%c", Buffer[3])); return ; } /** Print AML NameString. @param[in] Buffer AML NameString. **/ VOID AmlPrintNameString ( IN UINT8 *Buffer ) { UINT8 SegCount; UINT8 Index; if (*Buffer == AML_ROOT_CHAR) { // // RootChar // Buffer ++; TRACE ((-1, "\\")); } else if (*Buffer == AML_PARENT_PREFIX_CHAR) { // // ParentPrefixChar // do { Buffer ++; TRACE ((-1, "^")); } while (*Buffer == AML_PARENT_PREFIX_CHAR); } if (*Buffer == AML_DUAL_NAME_PREFIX) { // // DualName // Buffer ++; SegCount = 2; } else if (*Buffer == AML_MULTI_NAME_PREFIX) { // // MultiName // Buffer ++; SegCount = *Buffer; Buffer ++; } else if (*Buffer == 0) { // // NULL Name // return ; } else { // // NameSeg // SegCount = 1; } AmlPrintNameSeg (Buffer); Buffer += AML_NAME_SEG_SIZE; for (Index = 0; Index < SegCount - 1; Index++) { TRACE ((-1, ".")); AmlPrintNameSeg (Buffer); Buffer += AML_NAME_SEG_SIZE; } return ; } //********************************************************************** //********************************************************************** //** ** //** (C)Copyright 1985-2011, American Megatrends, Inc. ** //** ** //** All Rights Reserved. ** //** ** //** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** //** ** //** Phone: (770)-246-8600 ** //** ** //********************************************************************** //**********************************************************************