From 3dc8585e0a9fd4b2cb383f3ceb4961c7a88a8e71 Mon Sep 17 00:00:00 2001 From: jyao1 Date: Tue, 18 May 2010 02:26:49 +0000 Subject: MdeModulePkg: Add ACPI SDT support. Introduce PcdInstallAcpiSdtProtocol, default FALSE. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@10501 6f19259b-4bc3-4df7-8a09-765794883524 --- .../Universal/Acpi/AcpiTableDxe/AmlString.c | 549 +++++++++++++++++++++ 1 file changed, 549 insertions(+) create mode 100644 MdeModulePkg/Universal/Acpi/AcpiTableDxe/AmlString.c (limited to 'MdeModulePkg/Universal/Acpi/AcpiTableDxe/AmlString.c') diff --git a/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AmlString.c b/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AmlString.c new file mode 100644 index 0000000000..fe2c7613e5 --- /dev/null +++ b/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AmlString.c @@ -0,0 +1,549 @@ +/** @file + ACPI Sdt Protocol Driver + + Copyright (c) 2010, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "AcpiTable.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; + UINT8 *Name; + + Name = Buffer; + 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 = AllocatePool (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) { + SetMem (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); + SetMem (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 + ) +{ + DEBUG ((EFI_D_ERROR, "%c", Buffer[0])); + if ((Buffer[1] == '_') && (Buffer[2] == '_') && (Buffer[3] == '_')) { + return ; + } + DEBUG ((EFI_D_ERROR, "%c", Buffer[1])); + if ((Buffer[2] == '_') && (Buffer[3] == '_')) { + return ; + } + DEBUG ((EFI_D_ERROR, "%c", Buffer[2])); + if (Buffer[3] == '_') { + return ; + } + DEBUG ((EFI_D_ERROR, "%c", Buffer[3])); + return ; +} + +/** + Print AML NameString. + + @param[in] Buffer AML NameString. +**/ +VOID +AmlPrintNameString ( + IN UINT8 *Buffer + ) +{ + UINT8 SegCount; + UINT8 Index; + UINT8 *Name; + + Name = Buffer; + if (*Buffer == AML_ROOT_CHAR) { + // + // RootChar + // + Buffer ++; + DEBUG ((EFI_D_ERROR, "\\")); + } else if (*Buffer == AML_PARENT_PREFIX_CHAR) { + // + // ParentPrefixChar + // + do { + Buffer ++; + DEBUG ((EFI_D_ERROR, "^")); + } 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++) { + DEBUG ((EFI_D_ERROR, ".")); + AmlPrintNameSeg (Buffer); + Buffer += AML_NAME_SEG_SIZE; + } + + return ; +} -- cgit v1.2.3