4 Copyright (c) 2020 - 2021, Arm Limited. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
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,
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.
17 #include <AmlNodeDefines.h>
19 #include <AmlCoreInterface.h>
20 #include <AmlInclude.h>
21 #include <Api/AmlApiHelper.h>
22 #include <String/AmlString.h>
24 /** Update the name of a DeviceOp object node.
26 @param [in] DeviceOpNode Object node representing a Device.
27 Must have an OpCode=AML_NAME_OP, SubOpCode=0.
29 DeviceOp object nodes are defined in ASL
30 using the "Device ()" function.
31 @param [in] NewNameString The new Device's name.
32 Must be a NULL-terminated ASL NameString
33 e.g.: "DEV0", "DV15.DEV0", etc.
34 The input string is copied.
36 @retval EFI_SUCCESS The function completed successfully.
37 @retval EFI_INVALID_PARAMETER Invalid parameter.
41 AmlDeviceOpUpdateName (
42 IN AML_OBJECT_NODE_HANDLE DeviceOpNode
,
43 IN CHAR8
* NewNameString
48 AML_DATA_NODE_HANDLE DeviceNameDataNode
;
49 CHAR8
* NewAmlNameString
;
50 UINT32 NewAmlNameStringSize
;
52 // Check the input node is an object node.
53 if ((DeviceOpNode
== NULL
) ||
54 (AmlGetNodeType ((AML_NODE_HANDLE
)DeviceOpNode
) != EAmlNodeObject
) ||
55 (!AmlNodeHasOpCode (DeviceOpNode
, AML_EXT_OP
, AML_EXT_DEVICE_OP
)) ||
56 (NewNameString
== NULL
)) {
58 return EFI_INVALID_PARAMETER
;
61 // Get the Device's name, being a data node
62 // which is the 1st fixed argument (i.e. index 0).
63 DeviceNameDataNode
= (AML_DATA_NODE_HANDLE
)AmlGetFixedArgument (
67 if ((DeviceNameDataNode
== NULL
) ||
68 (AmlGetNodeType ((AML_NODE_HANDLE
)DeviceNameDataNode
) != EAmlNodeData
) ||
69 (!AmlNodeHasDataType (DeviceNameDataNode
, EAmlNodeDataTypeNameString
))) {
71 return EFI_INVALID_PARAMETER
;
74 Status
= ConvertAslNameToAmlName (NewNameString
, &NewAmlNameString
);
75 if (EFI_ERROR (Status
)) {
80 Status
= AmlGetNameStringSize (NewAmlNameString
, &NewAmlNameStringSize
);
81 if (EFI_ERROR (Status
)) {
86 // Update the Device's name node.
87 Status
= AmlUpdateDataNode (
89 EAmlNodeDataTypeNameString
,
90 (UINT8
*)NewAmlNameString
,
93 ASSERT_EFI_ERROR (Status
);
96 FreePool (NewAmlNameString
);
100 /** Update an integer value defined by a NameOp object node.
102 For compatibility reasons, the NameOpNode must initially
105 @param [in] NameOpNode NameOp object node.
106 Must have an OpCode=AML_NAME_OP, SubOpCode=0.
107 NameOp object nodes are defined in ASL
108 using the "Name ()" function.
109 @param [in] NewInt New Integer value to assign.
112 @retval EFI_SUCCESS The function completed successfully.
113 @retval EFI_INVALID_PARAMETER Invalid parameter.
117 AmlNameOpUpdateInteger (
118 IN AML_OBJECT_NODE_HANDLE NameOpNode
,
123 AML_OBJECT_NODE_HANDLE IntegerOpNode
;
125 if ((NameOpNode
== NULL
) ||
126 (AmlGetNodeType ((AML_NODE_HANDLE
)NameOpNode
) != EAmlNodeObject
) ||
127 (!AmlNodeHasOpCode (NameOpNode
, AML_NAME_OP
, 0))) {
129 return EFI_INVALID_PARAMETER
;
132 // Get the Integer object node defined by the "Name ()" function:
133 // it must have an Integer OpCode (Byte/Word/DWord/QWord).
134 // It is the 2nd fixed argument (i.e. index 1) of the NameOp node.
135 // This can also be a ZeroOp or OneOp node.
136 IntegerOpNode
= (AML_OBJECT_NODE_HANDLE
)AmlGetFixedArgument (
140 if ((IntegerOpNode
== NULL
) ||
141 (AmlGetNodeType ((AML_NODE_HANDLE
)IntegerOpNode
) != EAmlNodeObject
)) {
143 return EFI_INVALID_PARAMETER
;
146 // Update the Integer value.
147 Status
= AmlUpdateInteger (IntegerOpNode
, NewInt
);
148 ASSERT_EFI_ERROR (Status
);
153 /** Update a string value defined by a NameOp object node.
155 The NameOpNode must initially contain a string.
156 The EISAID ASL macro converts a string to an integer. This, it is
159 @param [in] NameOpNode NameOp object node.
160 Must have an OpCode=AML_NAME_OP, SubOpCode=0.
161 NameOp object nodes are defined in ASL
162 using the "Name ()" function.
163 @param [in] NewName New NULL terminated string to assign to
165 The input string is copied.
167 @retval EFI_SUCCESS The function completed successfully.
168 @retval EFI_INVALID_PARAMETER Invalid parameter.
172 AmlNameOpUpdateString (
173 IN AML_OBJECT_NODE_HANDLE NameOpNode
,
174 IN CONST CHAR8
* NewName
178 AML_OBJECT_NODE_HANDLE StringOpNode
;
179 AML_DATA_NODE_HANDLE StringDataNode
;
181 if ((NameOpNode
== NULL
) ||
182 (AmlGetNodeType ((AML_NODE_HANDLE
)NameOpNode
) != EAmlNodeObject
) ||
183 (!AmlNodeHasOpCode (NameOpNode
, AML_NAME_OP
, 0))) {
185 return EFI_INVALID_PARAMETER
;
188 // Get the String object node defined by the "Name ()" function:
189 // it must have a string OpCode.
190 // It is the 2nd fixed argument (i.e. index 1) of the NameOp node.
191 StringOpNode
= (AML_OBJECT_NODE_HANDLE
)AmlGetFixedArgument (
195 if ((StringOpNode
== NULL
) ||
196 (AmlGetNodeType ((AML_NODE_HANDLE
)StringOpNode
) != EAmlNodeObject
)) {
198 return EFI_INVALID_PARAMETER
;
201 // Get the string data node.
202 // It is the 1st fixed argument (i.e. index 0) of the StringOpNode node.
203 StringDataNode
= (AML_DATA_NODE_HANDLE
)AmlGetFixedArgument (
207 if ((StringDataNode
== NULL
) ||
208 (AmlGetNodeType ((AML_NODE_HANDLE
)StringDataNode
) != EAmlNodeData
)) {
210 return EFI_INVALID_PARAMETER
;
213 // Update the string value.
214 Status
= AmlUpdateDataNode (
216 EAmlNodeDataTypeString
,
218 (UINT32
)AsciiStrLen (NewName
) + 1
220 ASSERT_EFI_ERROR (Status
);
225 /** Get the first Resource Data element contained in a named object.
227 In the following ASL code, the function will return the Resource Data
228 node corresponding to the "QWordMemory ()" ASL macro.
229 Name (_CRS, ResourceTemplate() {
230 QWordMemory (...) {...},
231 Interrupt (...) {...}
236 "_CRS" names defined as methods are not handled by this function.
237 They must be defined as names, using the "Name ()" statement.
239 @param [in] NameOpNode NameOp object node defining a named object.
240 Must have an OpCode=AML_NAME_OP, SubOpCode=0.
241 NameOp object nodes are defined in ASL
242 using the "Name ()" function.
243 @param [out] OutRdNode Pointer to the first Resource Data element of
244 the named object. A Resource Data element
245 is stored in a data node.
247 @retval EFI_SUCCESS The function completed successfully.
248 @retval EFI_INVALID_PARAMETER Invalid parameter.
252 AmlNameOpGetFirstRdNode (
253 IN AML_OBJECT_NODE_HANDLE NameOpNode
,
254 OUT AML_DATA_NODE_HANDLE
* OutRdNode
257 AML_OBJECT_NODE_HANDLE BufferOpNode
;
258 AML_DATA_NODE_HANDLE FirstRdNode
;
260 if ((NameOpNode
== NULL
) ||
261 (AmlGetNodeType ((AML_NODE_HANDLE
)NameOpNode
) != EAmlNodeObject
) ||
262 (!AmlNodeHasOpCode (NameOpNode
, AML_NAME_OP
, 0)) ||
263 (OutRdNode
== NULL
)) {
265 return EFI_INVALID_PARAMETER
;
270 // Get the value of the variable which is represented as a BufferOp object
271 // node which is the 2nd fixed argument (i.e. index 1).
272 BufferOpNode
= (AML_OBJECT_NODE_HANDLE
)AmlGetFixedArgument (
276 if ((BufferOpNode
== NULL
) ||
277 (AmlGetNodeType ((AML_NODE_HANDLE
)BufferOpNode
) != EAmlNodeObject
) ||
278 (!AmlNodeHasOpCode (BufferOpNode
, AML_BUFFER_OP
, 0))) {
280 return EFI_INVALID_PARAMETER
;
283 // Get the first Resource data node in the variable list of
284 // argument of the BufferOp node.
285 FirstRdNode
= (AML_DATA_NODE_HANDLE
)AmlGetNextVariableArgument (
286 (AML_NODE_HANDLE
)BufferOpNode
,
289 if ((FirstRdNode
== NULL
) ||
290 (AmlGetNodeType ((AML_NODE_HANDLE
)FirstRdNode
) != EAmlNodeData
) ||
291 (!AmlNodeHasDataType (FirstRdNode
, EAmlNodeDataTypeResourceData
))) {
293 return EFI_INVALID_PARAMETER
;
296 *OutRdNode
= FirstRdNode
;
300 /** Get the Resource Data element following the CurrRdNode Resource Data.
302 In the following ASL code, if CurrRdNode corresponds to the first
303 "QWordMemory ()" ASL macro, the function will return the Resource Data
304 node corresponding to the "Interrupt ()" ASL macro.
305 Name (_CRS, ResourceTemplate() {
306 QwordMemory (...) {...},
307 Interrupt (...) {...}
312 "_CRS" names defined as methods are not handled by this function.
313 They must be defined as names, using the "Name ()" statement.
315 @param [in] CurrRdNode Pointer to the current Resource Data element of
317 @param [out] OutRdNode Pointer to the Resource Data element following
319 Contain a NULL pointer if CurrRdNode is the
320 last Resource Data element in the list.
321 The "End Tag" is not considered as a resource
322 data element and is not returned.
324 @retval EFI_SUCCESS The function completed successfully.
325 @retval EFI_INVALID_PARAMETER Invalid parameter.
329 AmlNameOpGetNextRdNode (
330 IN AML_DATA_NODE_HANDLE CurrRdNode
,
331 OUT AML_DATA_NODE_HANDLE
* OutRdNode
334 AML_OBJECT_NODE_HANDLE NameOpNode
;
335 AML_OBJECT_NODE_HANDLE BufferOpNode
;
337 if ((CurrRdNode
== NULL
) ||
338 (AmlGetNodeType ((AML_NODE_HANDLE
)CurrRdNode
) != EAmlNodeData
) ||
339 (!AmlNodeHasDataType (CurrRdNode
, EAmlNodeDataTypeResourceData
)) ||
340 (OutRdNode
== NULL
)) {
342 return EFI_INVALID_PARAMETER
;
347 // The parent of the CurrRdNode must be a BufferOp node.
348 BufferOpNode
= (AML_OBJECT_NODE_HANDLE
)AmlGetParent (
349 (AML_NODE_HANDLE
)CurrRdNode
351 if ((BufferOpNode
== NULL
) ||
352 (!AmlNodeHasOpCode (BufferOpNode
, AML_BUFFER_OP
, 0))) {
354 return EFI_INVALID_PARAMETER
;
357 // The parent of the BufferOpNode must be a NameOp node.
358 NameOpNode
= (AML_OBJECT_NODE_HANDLE
)AmlGetParent (
359 (AML_NODE_HANDLE
)BufferOpNode
361 if ((NameOpNode
== NULL
) ||
362 (!AmlNodeHasOpCode (NameOpNode
, AML_NAME_OP
, 0))) {
364 return EFI_INVALID_PARAMETER
;
367 *OutRdNode
= (AML_DATA_NODE_HANDLE
)AmlGetNextVariableArgument (
368 (AML_NODE_HANDLE
)BufferOpNode
,
369 (AML_NODE_HANDLE
)CurrRdNode
372 // If the Resource Data is an End Tag, return NULL.
373 if (AmlNodeHasRdDataType (
375 AML_RD_BUILD_SMALL_DESC_ID (ACPI_SMALL_END_TAG_DESCRIPTOR_NAME
))) {
383 #ifndef DISABLE_NEW_DEPRECATED_INTERFACES
387 Get the first Resource Data element contained in a "_CRS" object.
389 In the following ASL code, the function will return the Resource Data
390 node corresponding to the "QWordMemory ()" ASL macro.
391 Name (_CRS, ResourceTemplate() {
392 QWordMemory (...) {...},
393 Interrupt (...) {...}
398 - The "_CRS" object must be declared using ASL "Name (Declare Named Object)".
399 - "_CRS" declared using ASL "Method (Declare Control Method)" is not
404 @param [in] NameOpCrsNode NameOp object node defining a "_CRS" object.
405 Must have an OpCode=AML_NAME_OP, SubOpCode=0.
406 NameOp object nodes are defined in ASL
407 using the "Name ()" function.
408 @param [out] OutRdNode Pointer to the first Resource Data element of
409 the "_CRS" object. A Resource Data element
410 is stored in a data node.
412 @retval EFI_SUCCESS The function completed successfully.
413 @retval EFI_INVALID_PARAMETER Invalid parameter.
417 AmlNameOpCrsGetFirstRdNode (
418 IN AML_OBJECT_NODE_HANDLE NameOpCrsNode
,
419 OUT AML_DATA_NODE_HANDLE
* OutRdNode
422 return AmlNameOpGetFirstRdNode (NameOpCrsNode
, OutRdNode
);
427 Get the Resource Data element following the CurrRdNode Resource Data.
429 In the following ASL code, if CurrRdNode corresponds to the first
430 "QWordMemory ()" ASL macro, the function will return the Resource Data
431 node corresponding to the "Interrupt ()" ASL macro.
432 Name (_CRS, ResourceTemplate() {
433 QwordMemory (...) {...},
434 Interrupt (...) {...}
438 The CurrRdNode Resource Data node must be defined in an object named "_CRS"
439 and defined by a "Name ()" ASL function.
443 @param [in] CurrRdNode Pointer to the current Resource Data element of
445 @param [out] OutRdNode Pointer to the Resource Data element following
447 Contain a NULL pointer if CurrRdNode is the
448 last Resource Data element in the list.
449 The "End Tag" is not considered as a resource
450 data element and is not returned.
452 @retval EFI_SUCCESS The function completed successfully.
453 @retval EFI_INVALID_PARAMETER Invalid parameter.
457 AmlNameOpCrsGetNextRdNode (
458 IN AML_DATA_NODE_HANDLE CurrRdNode
,
459 OUT AML_DATA_NODE_HANDLE
* OutRdNode
462 return AmlNameOpGetNextRdNode (CurrRdNode
, OutRdNode
);
465 #endif // DISABLE_NEW_DEPRECATED_INTERFACES