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
This commit is contained in:
549
MdeModulePkg/Universal/Acpi/AcpiTableDxe/AmlString.c
Normal file
549
MdeModulePkg/Universal/Acpi/AcpiTableDxe/AmlString.c
Normal file
@@ -0,0 +1,549 @@
|
||||
/** @file
|
||||
ACPI Sdt Protocol Driver
|
||||
|
||||
Copyright (c) 2010, Intel Corporation. All rights reserved. <BR>
|
||||
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 ;
|
||||
}
|
Reference in New Issue
Block a user