| /** @file | |
| AML Helper. | |
| Copyright (c) 2020, Arm Limited. All rights reserved.<BR> | |
| SPDX-License-Identifier: BSD-2-Clause-Patent | |
| **/ | |
| /* Even though this file has access to the internal Node definition, | |
| i.e. AML_ROOT_NODE, AML_OBJECT_NODE, etc. Only the external node | |
| handle types should be used, i.e. AML_NODE_HANDLE, AML_ROOT_NODE_HANDLE, | |
| etc. | |
| Indeed, the functions in the "Api" folder should be implemented only | |
| using the "safe" functions available in the "Include" folder. This | |
| makes the functions available in the "Api" folder easy to export. | |
| */ | |
| #include <Api/AmlApiHelper.h> | |
| #include <AmlCoreInterface.h> | |
| #include <AmlInclude.h> | |
| #include <String/AmlString.h> | |
| /** Compare the NameString defined by the "Name ()" ASL function, | |
| and stored in the NameOpNode, with the input NameString. | |
| An ASL NameString is expected to be NULL terminated, and can be composed | |
| of NameSegs that have less that 4 chars, like "DEV". "DEV" will be expanded | |
| as "DEV_". | |
| An AML NameString is not NULL terminated and is only composed of | |
| 4 chars long NameSegs. | |
| @param [in] NameOpNode NameOp object node defining a variable. | |
| Must have an AML_NAME_OP/0 OpCode/SubOpCode. | |
| NameOp object nodes are defined in ASL | |
| using the "Name ()" function. | |
| @param [in] AslName ASL NameString to compare the NameOp's name with. | |
| Must be NULL terminated. | |
| @retval TRUE If the AslName and the AmlName defined by the NameOp node | |
| are similar. | |
| @retval FALSE Otherwise. | |
| **/ | |
| BOOLEAN | |
| EFIAPI | |
| AmlNameOpCompareName ( | |
| IN AML_OBJECT_NODE_HANDLE NameOpNode, | |
| IN CHAR8 *AslName | |
| ) | |
| { | |
| EFI_STATUS Status; | |
| AML_DATA_NODE_HANDLE NameDataNode; | |
| CHAR8 *AmlName; | |
| UINT32 AmlNameSize; | |
| BOOLEAN RetVal; | |
| if ((NameOpNode == NULL) || | |
| (AmlGetNodeType ((AML_NODE_HANDLE)NameOpNode) != EAmlNodeObject) || | |
| (!AmlNodeHasOpCode (NameOpNode, AML_NAME_OP, 0)) || | |
| (AslName == NULL)) | |
| { | |
| ASSERT (0); | |
| return FALSE; | |
| } | |
| // Get the NameOp name, being in a data node | |
| // which is the first fixed argument (i.e. index 0). | |
| NameDataNode = (AML_DATA_NODE_HANDLE)AmlGetFixedArgument ( | |
| NameOpNode, | |
| EAmlParseIndexTerm0 | |
| ); | |
| if ((NameDataNode == NULL) || | |
| (AmlGetNodeType ((AML_NODE_HANDLE)NameDataNode) != EAmlNodeData) || | |
| (!AmlNodeHasDataType (NameDataNode, EAmlNodeDataTypeNameString))) | |
| { | |
| ASSERT (0); | |
| return FALSE; | |
| } | |
| // Get the size of the name. | |
| Status = AmlGetDataNodeBuffer (NameDataNode, NULL, &AmlNameSize); | |
| if (EFI_ERROR (Status)) { | |
| ASSERT (0); | |
| return FALSE; | |
| } | |
| // Allocate memory to fetch the name. | |
| AmlName = AllocateZeroPool (AmlNameSize); | |
| if (AmlName == NULL) { | |
| ASSERT (0); | |
| return FALSE; | |
| } | |
| // Fetch the name. | |
| Status = AmlGetDataNodeBuffer (NameDataNode, (UINT8 *)AmlName, &AmlNameSize); | |
| if (EFI_ERROR (Status)) { | |
| FreePool (AmlName); | |
| ASSERT (0); | |
| return FALSE; | |
| } | |
| // Compare the input AslName and the AmlName stored in the NameOp node. | |
| RetVal = CompareAmlWithAslNameString (AmlName, AslName); | |
| // Free the string buffer. | |
| FreePool (AmlName); | |
| return RetVal; | |
| } | |
| /** Check whether ObjectNode has the input OpCode/SubOpcode couple. | |
| @param [in] ObjectNode Pointer to an object node. | |
| @param [in] OpCode OpCode to check | |
| @param [in] SubOpCode SubOpCode to check | |
| @retval TRUE The node is an object node and | |
| the Opcode and SubOpCode match. | |
| @retval FALSE Otherwise. | |
| **/ | |
| BOOLEAN | |
| EFIAPI | |
| AmlNodeHasOpCode ( | |
| IN AML_OBJECT_NODE_HANDLE ObjectNode, | |
| IN UINT8 OpCode, | |
| IN UINT8 SubOpCode | |
| ) | |
| { | |
| EFI_STATUS Status; | |
| UINT8 NodeOpCode; | |
| UINT8 NodeSubOpCode; | |
| // Get the Node information. | |
| Status = AmlGetObjectNodeInfo ( | |
| ObjectNode, | |
| &NodeOpCode, | |
| &NodeSubOpCode, | |
| NULL, | |
| NULL | |
| ); | |
| if (EFI_ERROR (Status)) { | |
| ASSERT (0); | |
| return FALSE; | |
| } | |
| // Check the OpCode and SubOpCode. | |
| if ((OpCode != NodeOpCode) || | |
| (SubOpCode != NodeSubOpCode)) | |
| { | |
| return FALSE; | |
| } | |
| return TRUE; | |
| } | |
| /** Check whether DataNode has the input DataType. | |
| @param [in] DataNode Pointer to a data node. | |
| @param [in] DataType DataType to check. | |
| @retval TRUE The node is a data node and | |
| the DataType match. | |
| @retval FALSE Otherwise. | |
| **/ | |
| BOOLEAN | |
| EFIAPI | |
| AmlNodeHasDataType ( | |
| IN AML_DATA_NODE_HANDLE DataNode, | |
| IN EAML_NODE_DATA_TYPE DataType | |
| ) | |
| { | |
| EFI_STATUS Status; | |
| EAML_NODE_DATA_TYPE NodeDataType; | |
| // Get the data type. | |
| Status = AmlGetNodeDataType (DataNode, &NodeDataType); | |
| if (EFI_ERROR (Status)) { | |
| ASSERT (0); | |
| return FALSE; | |
| } | |
| // Check the data type. | |
| if (NodeDataType != DataType) { | |
| return FALSE; | |
| } | |
| return TRUE; | |
| } | |
| /** Check whether RdNode has the input RdDataType. | |
| @param [in] RdNode Pointer to a data node. | |
| @param [in] RdDataType DataType to check. | |
| @retval TRUE The node is a Resource Data node and | |
| the RdDataType match. | |
| @retval FALSE Otherwise. | |
| **/ | |
| BOOLEAN | |
| EFIAPI | |
| AmlNodeHasRdDataType ( | |
| IN AML_DATA_NODE_HANDLE RdNode, | |
| IN AML_RD_HEADER RdDataType | |
| ) | |
| { | |
| EFI_STATUS Status; | |
| AML_RD_HEADER NodeRdDataType; | |
| // Get the resource data type. | |
| Status = AmlGetResourceDataType ( | |
| RdNode, | |
| &NodeRdDataType | |
| ); | |
| if (EFI_ERROR (Status)) { | |
| ASSERT (0); | |
| return FALSE; | |
| } | |
| // Check the RdDataType. | |
| return AmlRdCompareDescId (&NodeRdDataType, RdDataType); | |
| } |