]> git.proxmox.com Git - mirror_edk2.git/blob - DynamicTablesPkg/Library/Common/AmlLib/Api/AmlApiHelper.c
DynamicTablesPkg: AmlLib APIs
[mirror_edk2.git] / DynamicTablesPkg / Library / Common / AmlLib / Api / AmlApiHelper.c
1 /** @file
2 AML Helper.
3
4 Copyright (c) 2020, Arm Limited. All rights reserved.<BR>
5
6 SPDX-License-Identifier: BSD-2-Clause-Patent
7 **/
8
9 /* Even though this file has access to the internal Node definition,
10 i.e. AML_ROOT_NODE, AML_OBJECT_NODE, etc. Only the external node
11 handle types should be used, i.e. AML_NODE_HANDLE, AML_ROOT_NODE_HANDLE,
12 etc.
13 Indeed, the functions in the "Api" folder should be implemented only
14 using the "safe" functions available in the "Include" folder. This
15 makes the functions available in the "Api" folder easy to export.
16 */
17 #include <Api/AmlApiHelper.h>
18
19 #include <AmlCoreInterface.h>
20 #include <AmlInclude.h>
21 #include <String/AmlString.h>
22
23 /** Compare the NameString defined by the "Name ()" ASL function,
24 and stored in the NameOpNode, with the input NameString.
25
26 An ASL NameString is expected to be NULL terminated, and can be composed
27 of NameSegs that have less that 4 chars, like "DEV". "DEV" will be expanded
28 as "DEV_".
29
30 An AML NameString is not NULL terminated and is is only composed of
31 4 chars long NameSegs.
32
33 @param [in] NameOpNode NameOp object node defining a variable.
34 Must have an AML_NAME_OP/0 OpCode/SubOpCode.
35 NameOp object nodes are defined in ASL
36 using the "Name ()" function.
37 @param [in] AslName ASL NameString to compare the NameOp's name with.
38 Must be NULL terminated.
39
40 @retval TRUE If the AslName and the AmlName defined by the NameOp node
41 are similar.
42 @retval FALSE Otherwise.
43 **/
44 BOOLEAN
45 EFIAPI
46 AmlNameOpCompareName (
47 IN AML_OBJECT_NODE_HANDLE NameOpNode,
48 IN CHAR8 * AslName
49 )
50 {
51 EFI_STATUS Status;
52 AML_DATA_NODE_HANDLE NameDataNode;
53
54 CHAR8 * AmlName;
55 UINT32 AmlNameSize;
56
57 BOOLEAN RetVal;
58
59 if ((NameOpNode == NULL) ||
60 (AmlGetNodeType ((AML_NODE_HANDLE)NameOpNode) != EAmlNodeObject) ||
61 (!AmlNodeHasOpCode (NameOpNode, AML_NAME_OP, 0)) ||
62 (AslName == NULL)) {
63 ASSERT (0);
64 return FALSE;
65 }
66
67 // Get the NameOp name, being in a data node
68 // which is the first fixed argument (i.e. index 0).
69 NameDataNode = (AML_DATA_NODE_HANDLE)AmlGetFixedArgument (
70 NameOpNode,
71 EAmlParseIndexTerm0
72 );
73 if ((NameDataNode == NULL) ||
74 (AmlGetNodeType ((AML_NODE_HANDLE)NameDataNode) != EAmlNodeData) ||
75 (!AmlNodeHasDataType (NameDataNode, EAmlNodeDataTypeNameString))) {
76 ASSERT (0);
77 return FALSE;
78 }
79
80 // Get the size of the name.
81 Status = AmlGetDataNodeBuffer (NameDataNode, NULL, &AmlNameSize);
82 if (EFI_ERROR (Status)) {
83 ASSERT (0);
84 return FALSE;
85 }
86
87 // Allocate memory to fetch the name.
88 AmlName = AllocateZeroPool (AmlNameSize);
89 if (AmlName == NULL) {
90 ASSERT (0);
91 return FALSE;
92 }
93
94 // Fetch the name.
95 Status = AmlGetDataNodeBuffer (NameDataNode, (UINT8*)AmlName, &AmlNameSize);
96 if (EFI_ERROR (Status)) {
97 FreePool (AmlName);
98 ASSERT (0);
99 return FALSE;
100 }
101
102 // Compare the input AslName and the AmlName stored in the NameOp node.
103 RetVal = CompareAmlWithAslNameString (AmlName, AslName);
104
105 // Free the string buffer.
106 FreePool (AmlName);
107 return RetVal;
108 }
109
110 /** Check whether ObjectNode has the input OpCode/SubOpcode couple.
111
112 @param [in] ObjectNode Pointer to an object node.
113 @param [in] OpCode OpCode to check
114 @param [in] SubOpCode SubOpCode to check
115
116 @retval TRUE The node is an object node and
117 the Opcode and SubOpCode match.
118 @retval FALSE Otherwise.
119 **/
120 BOOLEAN
121 EFIAPI
122 AmlNodeHasOpCode (
123 IN AML_OBJECT_NODE_HANDLE ObjectNode,
124 IN UINT8 OpCode,
125 IN UINT8 SubOpCode
126 )
127 {
128 EFI_STATUS Status;
129 UINT8 NodeOpCode;
130 UINT8 NodeSubOpCode;
131
132 // Get the Node information.
133 Status = AmlGetObjectNodeInfo (
134 ObjectNode,
135 &NodeOpCode,
136 &NodeSubOpCode,
137 NULL,
138 NULL
139 );
140 if (EFI_ERROR (Status)) {
141 ASSERT (0);
142 return FALSE;
143 }
144
145 // Check the OpCode and SubOpCode.
146 if ((OpCode != NodeOpCode) ||
147 (SubOpCode != NodeSubOpCode)) {
148 return FALSE;
149 }
150
151 return TRUE;
152 }
153
154 /** Check whether DataNode has the input DataType.
155
156 @param [in] DataNode Pointer to a data node.
157 @param [in] DataType DataType to check.
158
159 @retval TRUE The node is a data node and
160 the DataType match.
161 @retval FALSE Otherwise.
162 **/
163 BOOLEAN
164 EFIAPI
165 AmlNodeHasDataType (
166 IN AML_DATA_NODE_HANDLE DataNode,
167 IN EAML_NODE_DATA_TYPE DataType
168 )
169 {
170 EFI_STATUS Status;
171 EAML_NODE_DATA_TYPE NodeDataType;
172
173 // Get the data type.
174 Status = AmlGetNodeDataType (DataNode, &NodeDataType);
175 if (EFI_ERROR (Status)) {
176 ASSERT (0);
177 return FALSE;
178 }
179
180 // Check the data type.
181 if (NodeDataType != DataType) {
182 return FALSE;
183 }
184
185 return TRUE;
186 }
187
188 /** Check whether RdNode has the input RdDataType.
189
190 @param [in] RdNode Pointer to a data node.
191 @param [in] RdDataType DataType to check.
192
193 @retval TRUE The node is a Resource Data node and
194 the RdDataType match.
195 @retval FALSE Otherwise.
196 **/
197 BOOLEAN
198 EFIAPI
199 AmlNodeHasRdDataType (
200 IN AML_DATA_NODE_HANDLE RdNode,
201 IN AML_RD_HEADER RdDataType
202 )
203 {
204 EFI_STATUS Status;
205 AML_RD_HEADER NodeRdDataType;
206
207 // Get the resource data type.
208 Status = AmlGetResourceDataType (
209 RdNode,
210 &NodeRdDataType
211 );
212 if (EFI_ERROR (Status)) {
213 ASSERT (0);
214 return FALSE;
215 }
216
217 // Check the RdDataType.
218 return AmlRdCompareDescId (&NodeRdDataType, RdDataType);
219 }