4 Copyright (c) 2020, Arm Limited. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
9 #include <AmlNodeDefines.h>
11 #include <AcpiTableGenerator.h>
13 #include <AmlCoreInterface.h>
14 #include <AmlEncoding/Aml.h>
15 #include <Tree/AmlNode.h>
16 #include <Tree/AmlTree.h>
17 #include <String/AmlString.h>
18 #include <Utils/AmlUtility.h>
20 /** Utility function to link a node when returning from a CodeGen function.
22 @param [in] Node Newly created node.
23 @param [in] ParentNode If provided, set ParentNode as the parent
25 @param [out] NewObjectNode If not NULL:
26 - and Success, contains the created Node.
27 - and Error, reset to NULL.
29 @retval EFI_SUCCESS The function completed successfully.
30 @retval EFI_INVALID_PARAMETER Invalid parameter.
36 IN AML_OBJECT_NODE
* Node
,
37 IN AML_NODE_HEADER
* ParentNode
,
38 OUT AML_OBJECT_NODE
** NewObjectNode
43 if (NewObjectNode
!= NULL
) {
44 *NewObjectNode
= NULL
;
47 // Add RdNode as the last element.
48 if (ParentNode
!= NULL
) {
49 Status
= AmlVarListAddTail (ParentNode
, (AML_NODE_HEADER
*)Node
);
50 if (EFI_ERROR (Status
)) {
56 if (NewObjectNode
!= NULL
) {
57 *NewObjectNode
= Node
;
63 /** AML code generation for DefinitionBlock.
65 Create a Root Node handle.
66 It is the caller's responsibility to free the allocated memory
67 with the AmlDeleteTree function.
69 AmlCodeGenDefinitionBlock (TableSignature, OemID, TableID, OEMRevision) is
70 equivalent to the following ASL code:
71 DefinitionBlock (AMLFileName, TableSignature, ComplianceRevision,
72 OemID, TableID, OEMRevision) {}
73 with the ComplianceRevision set to 2 and the AMLFileName is ignored.
75 @param[in] TableSignature 4-character ACPI signature.
76 Must be 'DSDT' or 'SSDT'.
77 @param[in] OemId 6-character string OEM identifier.
78 @param[in] OemTableId 8-character string OEM table identifier.
79 @param[in] OemRevision OEM revision number.
80 @param[out] NewRootNode Pointer to the root node representing a
83 @retval EFI_SUCCESS Success.
84 @retval EFI_INVALID_PARAMETER Invalid parameter.
85 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
89 AmlCodeGenDefinitionBlock (
90 IN CONST CHAR8
* TableSignature
,
91 IN CONST CHAR8
* OemId
,
92 IN CONST CHAR8
* OemTableId
,
93 IN UINT32 OemRevision
,
94 OUT AML_ROOT_NODE
** NewRootNode
98 EFI_ACPI_DESCRIPTION_HEADER AcpiHeader
;
100 if ((TableSignature
== NULL
) ||
102 (OemTableId
== NULL
) ||
103 (NewRootNode
== NULL
)) {
105 return EFI_INVALID_PARAMETER
;
108 CopyMem (&AcpiHeader
.Signature
, TableSignature
, 4);
109 AcpiHeader
.Length
= sizeof (EFI_ACPI_DESCRIPTION_HEADER
);
110 AcpiHeader
.Revision
= 2;
111 CopyMem (&AcpiHeader
.OemId
, OemId
, 6);
112 CopyMem (&AcpiHeader
.OemTableId
, OemTableId
, 8);
113 AcpiHeader
.OemRevision
= OemRevision
;
114 AcpiHeader
.CreatorId
= TABLE_GENERATOR_CREATOR_ID_ARM
;
115 AcpiHeader
.CreatorRevision
= CREATE_REVISION (1, 0);
117 Status
= AmlCreateRootNode (&AcpiHeader
, NewRootNode
);
118 ASSERT_EFI_ERROR (Status
);
123 /** AML code generation for a String object node.
125 @param [in] String Pointer to a NULL terminated string.
126 @param [out] NewObjectNode If success, contains the created
129 @retval EFI_SUCCESS Success.
130 @retval EFI_INVALID_PARAMETER Invalid parameter.
131 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
138 OUT AML_OBJECT_NODE
** NewObjectNode
142 AML_OBJECT_NODE
* ObjectNode
;
143 AML_DATA_NODE
* DataNode
;
145 if ((String
== NULL
) ||
146 (NewObjectNode
== NULL
)) {
148 return EFI_INVALID_PARAMETER
;
153 Status
= AmlCreateObjectNode (
154 AmlGetByteEncodingByOpCode (AML_STRING_PREFIX
, 0),
158 if (EFI_ERROR (Status
)) {
163 Status
= AmlCreateDataNode (
164 EAmlNodeDataTypeString
,
166 (UINT32
)AsciiStrLen (String
) + 1,
169 if (EFI_ERROR (Status
)) {
174 Status
= AmlSetFixedArgument (
177 (AML_NODE_HEADER
*)DataNode
179 if (EFI_ERROR (Status
)) {
181 AmlDeleteTree ((AML_NODE_HEADER
*)DataNode
);
185 *NewObjectNode
= ObjectNode
;
189 AmlDeleteTree ((AML_NODE_HEADER
*)ObjectNode
);
193 /** AML code generation for an Integer object node.
195 @param [in] Integer Integer of the Integer object node.
196 @param [out] NewObjectNode If success, contains the created
199 @retval EFI_SUCCESS Success.
200 @retval EFI_INVALID_PARAMETER Invalid parameter.
201 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
208 OUT AML_OBJECT_NODE
** NewObjectNode
214 if (NewObjectNode
== NULL
) {
216 return EFI_INVALID_PARAMETER
;
219 // Create an object node containing Zero.
220 Status
= AmlCreateObjectNode (
221 AmlGetByteEncodingByOpCode (AML_ZERO_OP
, 0),
225 if (EFI_ERROR (Status
)) {
230 // Update the object node with integer value.
231 Status
= AmlNodeSetIntegerValue (*NewObjectNode
, Integer
, &ValueWidthDiff
);
232 if (EFI_ERROR (Status
)) {
234 AmlDeleteTree ((AML_NODE_HEADER
*)*NewObjectNode
);
240 /** AML code generation for a Name object node.
242 @param [in] NameString The new variable name.
243 Must be a NULL-terminated ASL NameString
244 e.g.: "DEV0", "DV15.DEV0", etc.
245 This input string is copied.
246 @param [in] Object Object associated to the NameString.
247 @param [in] ParentNode If provided, set ParentNode as the parent
249 @param [out] NewObjectNode If success, contains the created node.
251 @retval EFI_SUCCESS Success.
252 @retval EFI_INVALID_PARAMETER Invalid parameter.
253 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
259 IN CONST CHAR8
* NameString
,
260 IN AML_OBJECT_NODE
* Object
,
261 IN AML_NODE_HEADER
* ParentNode
, OPTIONAL
262 OUT AML_OBJECT_NODE
** NewObjectNode OPTIONAL
266 AML_OBJECT_NODE
* ObjectNode
;
267 AML_DATA_NODE
* DataNode
;
268 CHAR8
* AmlNameString
;
269 UINT32 AmlNameStringSize
;
271 if ((NameString
== NULL
) ||
273 ((ParentNode
== NULL
) && (NewObjectNode
== NULL
))) {
275 return EFI_INVALID_PARAMETER
;
280 AmlNameString
= NULL
;
282 Status
= ConvertAslNameToAmlName (NameString
, &AmlNameString
);
283 if (EFI_ERROR (Status
)) {
288 Status
= AmlGetNameStringSize (AmlNameString
, &AmlNameStringSize
);
289 if (EFI_ERROR (Status
)) {
294 Status
= AmlCreateObjectNode (
295 AmlGetByteEncodingByOpCode (AML_NAME_OP
, 0),
299 if (EFI_ERROR (Status
)) {
304 Status
= AmlCreateDataNode (
305 EAmlNodeDataTypeNameString
,
306 (UINT8
*)AmlNameString
,
310 if (EFI_ERROR (Status
)) {
315 Status
= AmlSetFixedArgument (
318 (AML_NODE_HEADER
*)DataNode
320 if (EFI_ERROR (Status
)) {
322 AmlDeleteTree ((AML_NODE_HEADER
*)DataNode
);
326 Status
= AmlSetFixedArgument (
329 (AML_NODE_HEADER
*)Object
331 if (EFI_ERROR (Status
)) {
341 if (EFI_ERROR (Status
)) {
346 // Free AmlNameString before returning as it is copied
347 // in the call to AmlCreateDataNode().
351 if (ObjectNode
!= NULL
) {
352 AmlDeleteTree ((AML_NODE_HEADER
*)ObjectNode
);
356 if (AmlNameString
!= NULL
) {
357 FreePool (AmlNameString
);
363 /** AML code generation for a Name object node, containing a String.
365 AmlCodeGenNameString ("_HID", "HID0000", ParentNode, NewObjectNode) is
366 equivalent of the following ASL code:
367 Name(_HID, "HID0000")
369 @param [in] NameString The new variable name.
370 Must be a NULL-terminated ASL NameString
371 e.g.: "DEV0", "DV15.DEV0", etc.
372 The input string is copied.
373 @param [in] String NULL terminated String to associate to the
375 @param [in] ParentNode If provided, set ParentNode as the parent
377 @param [out] NewObjectNode If success, contains the created node.
379 @retval EFI_SUCCESS Success.
380 @retval EFI_INVALID_PARAMETER Invalid parameter.
381 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
385 AmlCodeGenNameString (
386 IN CONST CHAR8
* NameString
,
388 IN AML_NODE_HEADER
* ParentNode
, OPTIONAL
389 OUT AML_OBJECT_NODE
** NewObjectNode OPTIONAL
393 AML_OBJECT_NODE
* ObjectNode
;
395 if ((NameString
== NULL
) ||
397 ((ParentNode
== NULL
) && (NewObjectNode
== NULL
))) {
399 return EFI_INVALID_PARAMETER
;
402 Status
= AmlCodeGenString (String
, &ObjectNode
);
403 if (EFI_ERROR (Status
)) {
408 Status
= AmlCodeGenName (
414 if (EFI_ERROR (Status
)) {
416 AmlDeleteTree ((AML_NODE_HEADER
*)ObjectNode
);
422 /** AML code generation for a Name object node, containing an Integer.
424 AmlCodeGenNameInteger ("_UID", 1, ParentNode, NewObjectNode) is
425 equivalent of the following ASL code:
428 @param [in] NameString The new variable name.
429 Must be a NULL-terminated ASL NameString
430 e.g.: "DEV0", "DV15.DEV0", etc.
431 The input string is copied.
432 @param [in] Integer Integer to associate to the NameString.
433 @param [in] ParentNode If provided, set ParentNode as the parent
435 @param [out] NewObjectNode If success, contains the created node.
437 @retval EFI_SUCCESS Success.
438 @retval EFI_INVALID_PARAMETER Invalid parameter.
439 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
443 AmlCodeGenNameInteger (
444 IN CONST CHAR8
* NameString
,
446 IN AML_NODE_HEADER
* ParentNode
, OPTIONAL
447 OUT AML_OBJECT_NODE
** NewObjectNode OPTIONAL
451 AML_OBJECT_NODE
* ObjectNode
;
453 if ((NameString
== NULL
) ||
454 ((ParentNode
== NULL
) && (NewObjectNode
== NULL
))) {
456 return EFI_INVALID_PARAMETER
;
459 Status
= AmlCodeGenInteger (Integer
, &ObjectNode
);
460 if (EFI_ERROR (Status
)) {
465 Status
= AmlCodeGenName (
471 if (EFI_ERROR (Status
)) {
473 AmlDeleteTree ((AML_NODE_HEADER
*)ObjectNode
);
479 /** AML code generation for a Device object node.
481 AmlCodeGenDevice ("COM0", ParentNode, NewObjectNode) is
482 equivalent of the following ASL code:
485 @param [in] NameString The new Device's name.
486 Must be a NULL-terminated ASL NameString
487 e.g.: "DEV0", "DV15.DEV0", etc.
488 The input string is copied.
489 @param [in] ParentNode If provided, set ParentNode as the parent
491 @param [out] NewObjectNode If success, contains the created node.
493 @retval EFI_SUCCESS Success.
494 @retval EFI_INVALID_PARAMETER Invalid parameter.
495 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
500 IN CONST CHAR8
* NameString
,
501 IN AML_NODE_HEADER
* ParentNode
, OPTIONAL
502 OUT AML_OBJECT_NODE
** NewObjectNode OPTIONAL
506 AML_OBJECT_NODE
* ObjectNode
;
507 AML_DATA_NODE
* DataNode
;
508 CHAR8
* AmlNameString
;
509 UINT32 AmlNameStringSize
;
511 if ((NameString
== NULL
) ||
512 ((ParentNode
== NULL
) && (NewObjectNode
== NULL
))) {
514 return EFI_INVALID_PARAMETER
;
519 AmlNameString
= NULL
;
521 Status
= ConvertAslNameToAmlName (NameString
, &AmlNameString
);
522 if (EFI_ERROR (Status
)) {
527 Status
= AmlGetNameStringSize (AmlNameString
, &AmlNameStringSize
);
528 if (EFI_ERROR (Status
)) {
533 Status
= AmlCreateObjectNode (
534 AmlGetByteEncodingByOpCode (AML_EXT_OP
, AML_EXT_DEVICE_OP
),
535 AmlNameStringSize
+ AmlComputePkgLengthWidth (AmlNameStringSize
),
538 if (EFI_ERROR (Status
)) {
543 Status
= AmlCreateDataNode (
544 EAmlNodeDataTypeNameString
,
545 (UINT8
*)AmlNameString
,
549 if (EFI_ERROR (Status
)) {
554 Status
= AmlSetFixedArgument (
557 (AML_NODE_HEADER
*)DataNode
559 if (EFI_ERROR (Status
)) {
561 AmlDeleteTree ((AML_NODE_HEADER
*)DataNode
);
570 if (EFI_ERROR (Status
)) {
575 // Free AmlNameString before returning as it is copied
576 // in the call to AmlCreateDataNode().
580 if (ObjectNode
!= NULL
) {
581 AmlDeleteTree ((AML_NODE_HEADER
*)ObjectNode
);
585 if (AmlNameString
!= NULL
) {
586 FreePool (AmlNameString
);
592 /** AML code generation for a Scope object node.
594 AmlCodeGenScope ("_SB", ParentNode, NewObjectNode) is
595 equivalent of the following ASL code:
598 @param [in] NameString The new Scope's name.
599 Must be a NULL-terminated ASL NameString
600 e.g.: "DEV0", "DV15.DEV0", etc.
601 The input string is copied.
602 @param [in] ParentNode If provided, set ParentNode as the parent
604 @param [out] NewObjectNode If success, contains the created node.
606 @retval EFI_SUCCESS Success.
607 @retval EFI_INVALID_PARAMETER Invalid parameter.
608 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
613 IN CONST CHAR8
* NameString
,
614 IN AML_NODE_HEADER
* ParentNode
, OPTIONAL
615 OUT AML_OBJECT_NODE
** NewObjectNode OPTIONAL
619 AML_OBJECT_NODE
* ObjectNode
;
620 AML_DATA_NODE
* DataNode
;
621 CHAR8
* AmlNameString
;
622 UINT32 AmlNameStringSize
;
624 if ((NameString
== NULL
) ||
625 ((ParentNode
== NULL
) && (NewObjectNode
== NULL
))) {
627 return EFI_INVALID_PARAMETER
;
632 AmlNameString
= NULL
;
634 Status
= ConvertAslNameToAmlName (NameString
, &AmlNameString
);
635 if (EFI_ERROR (Status
)) {
640 Status
= AmlGetNameStringSize (AmlNameString
, &AmlNameStringSize
);
641 if (EFI_ERROR (Status
)) {
646 Status
= AmlCreateObjectNode (
647 AmlGetByteEncodingByOpCode (AML_SCOPE_OP
, 0),
648 AmlNameStringSize
+ AmlComputePkgLengthWidth (AmlNameStringSize
),
651 if (EFI_ERROR (Status
)) {
656 Status
= AmlCreateDataNode (
657 EAmlNodeDataTypeNameString
,
658 (UINT8
*)AmlNameString
,
662 if (EFI_ERROR (Status
)) {
667 Status
= AmlSetFixedArgument (
670 (AML_NODE_HEADER
*)DataNode
672 if (EFI_ERROR (Status
)) {
674 AmlDeleteTree ((AML_NODE_HEADER
*)DataNode
);
683 if (EFI_ERROR (Status
)) {
688 // Free AmlNameString before returning as it is copied
689 // in the call to AmlCreateDataNode().
693 if (ObjectNode
!= NULL
) {
694 AmlDeleteTree ((AML_NODE_HEADER
*)ObjectNode
);
698 if (AmlNameString
!= NULL
) {
699 FreePool (AmlNameString
);