4 Copyright (c) 2019 - 2020, Arm Limited. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
13 @mainpage Dynamic AML Generation
17 ACPI tables are categorized as data tables and definition block
18 tables. Dynamic Tables Framework currently supports generation of ACPI
19 data tables. Generation of definition block tables is difficult as these
20 tables are encoded in ACPI Machine Language (AML), which has a complex
23 Dynamic AML Generation is an extension to the Dynamic tables Framework.
24 One of the techniques used to simplify definition block generation is to
25 fixup a template SSDT table.
27 Dynamic AML aims to provide a framework that allows fixing up of an ACPI
28 SSDT template with appropriate information about the hardware.
30 This framework consists of an:
31 - AMLLib core that implements a rich set of interfaces to parse, traverse
33 - AMLLib library APIs that provides interfaces to search and updates nodes
39 #include <IndustryStandard/Acpi.h>
45 typedef void* AML_NODE_HANDLE
;
49 typedef void* AML_ROOT_NODE_HANDLE
;
51 /** Object Node handle.
53 typedef void* AML_OBJECT_NODE_HANDLE
;
57 typedef void* AML_DATA_NODE_HANDLE
;
61 /** Parse the definition block.
63 The function parses the whole AML blob. It starts with the ACPI DSDT/SSDT
64 header and then parses the AML bytestream.
65 A tree structure is returned via the RootPtr.
66 The tree must be deleted with the AmlDeleteTree function.
70 @param [in] DefinitionBlock Pointer to the definition block.
71 @param [out] RootPtr Pointer to the root node of the AML tree.
73 @retval EFI_SUCCESS The function completed successfully.
74 @retval EFI_BUFFER_TOO_SMALL No space left in the buffer.
75 @retval EFI_INVALID_PARAMETER Invalid parameter.
76 @retval EFI_OUT_OF_RESOURCES Could not allocate memory.
80 AmlParseDefinitionBlock (
81 IN CONST EFI_ACPI_DESCRIPTION_HEADER
* DefinitionBlock
,
82 OUT AML_ROOT_NODE_HANDLE
* RootPtr
85 /** Serialize an AML definition block.
87 This functions allocates memory with the "AllocateZeroPool ()"
88 function. This memory is used to serialize the AML tree and is
89 returned in the Table.
93 @param [in] RootNode Root node of the tree.
94 @param [out] Table On return, hold the serialized
97 @retval EFI_SUCCESS The function completed successfully.
98 @retval EFI_INVALID_PARAMETER Invalid parameter.
99 @retval EFI_OUT_OF_RESOURCES Could not allocate memory.
103 AmlSerializeDefinitionBlock (
104 IN AML_ROOT_NODE_HANDLE RootNode
,
105 OUT EFI_ACPI_DESCRIPTION_HEADER
** Table
108 /** Clone a node and its children (clone a tree branch).
110 The cloned branch returned is not attached to any tree.
114 @param [in] Node Pointer to a node.
115 Node is the head of the branch to clone.
116 @param [out] ClonedNode Pointer holding the head of the created cloned
119 @retval EFI_SUCCESS The function completed successfully.
120 @retval EFI_INVALID_PARAMETER Invalid parameter.
121 @retval EFI_OUT_OF_RESOURCES Could not allocate memory.
126 IN AML_NODE_HANDLE Node
,
127 OUT AML_NODE_HANDLE
* ClonedNode
130 /** Delete a Node and its children.
132 The Node must be removed from the tree first,
133 or must be the root node.
137 @param [in] Node Pointer to the node to delete.
139 @retval EFI_SUCCESS The function completed successfully.
140 @retval EFI_INVALID_PARAMETER Invalid parameter.
145 IN AML_NODE_HANDLE Node
148 /** Detach the Node from the tree.
150 The function will fail if the Node is in its parent's fixed
152 The Node is not deleted. The deletion is done separately
157 @param [in] Node Pointer to a Node.
158 Must be a data node or an object node.
160 @retval EFI_SUCCESS The function completed successfully.
161 @retval EFI_INVALID_PARAMETER Invalid parameter.
166 IN AML_NODE_HANDLE Node
169 /** Find a node in the AML namespace, given an ASL path and a reference Node.
171 - The AslPath can be an absolute path, or a relative path from the
173 - Node must be a root node or a namespace node;
174 - A root node is expected to be at the top of the tree.
177 For the following AML namespace, with the ReferenceNode being the node with
179 - the node with the name "BBBB" can be found by looking for the ASL
181 - the root node can be found by looking for the ASL relative path "^",
182 or the absolute path "\\".
186 \-AAAA <- ReferenceNode
189 @ingroup NameSpaceApis
191 @param [in] ReferenceNode Reference node.
192 If a relative path is given, the
193 search is done from this node. If
194 an absolute path is given, the
195 search is done from the root node.
196 Must be a root node or an object
197 node which is part of the
199 @param [in] AslPath ASL path to the searched node in
200 the namespace. An ASL path name is
201 NULL terminated. Can be a relative
203 E.g.: "\\_SB.CLU0.CPU0" or "^CPU0"
204 @param [out] OutNode Pointer to the found node.
205 Contains NULL if not found.
207 @retval EFI_SUCCESS The function completed successfully.
208 @retval EFI_BUFFER_TOO_SMALL No space left in the buffer.
209 @retval EFI_INVALID_PARAMETER Invalid parameter.
210 @retval EFI_OUT_OF_RESOURCES Out of memory.
215 IN AML_NODE_HANDLE ReferenceNode
,
217 OUT AML_NODE_HANDLE
* OutNode
221 @defgroup UserApis User APIs
223 User APIs are implemented to ease most common actions that might be done
224 using the AmlLib. They allow to find specific objects like "_UID" or
225 "_CRS" and to update their value. It also shows what can be done using
230 /** Update the name of a DeviceOp object node.
234 @param [in] DeviceOpNode Object node representing a Device.
235 Must have an OpCode=AML_NAME_OP, SubOpCode=0.
237 DeviceOp object nodes are defined in ASL
238 using the "Device ()" function.
239 @param [in] NewNameString The new Device's name.
240 Must be a NULL-terminated ASL NameString
241 e.g.: "DEV0", "DV15.DEV0", etc.
242 The input string is copied.
244 @retval EFI_SUCCESS The function completed successfully.
245 @retval EFI_INVALID_PARAMETER Invalid parameter.
249 AmlDeviceOpUpdateName (
250 IN AML_OBJECT_NODE_HANDLE DeviceOpNode
,
251 IN CHAR8
* NewNameString
254 /** Update an integer value defined by a NameOp object node.
256 For compatibility reasons, the NameOpNode must initially
261 @param [in] NameOpNode NameOp object node.
262 Must have an OpCode=AML_NAME_OP, SubOpCode=0.
263 NameOp object nodes are defined in ASL
264 using the "Name ()" function.
265 @param [in] NewInt New Integer value to assign.
268 @retval EFI_SUCCESS The function completed successfully.
269 @retval EFI_INVALID_PARAMETER Invalid parameter.
273 AmlNameOpUpdateInteger (
274 IN AML_OBJECT_NODE_HANDLE NameOpNode
,
278 /** Update a string value defined by a NameOp object node.
280 The NameOpNode must initially contain a string.
281 The EISAID ASL macro converts a string to an integer. This, it is
286 @param [in] NameOpNode NameOp object node.
287 Must have an OpCode=AML_NAME_OP, SubOpCode=0.
288 NameOp object nodes are defined in ASL
289 using the "Name ()" function.
290 @param [in] NewName New NULL terminated string to assign to
292 The input string is copied.
294 @retval EFI_SUCCESS The function completed successfully.
295 @retval EFI_INVALID_PARAMETER Invalid parameter.
299 AmlNameOpUpdateString (
300 IN AML_OBJECT_NODE_HANDLE NameOpNode
,
301 IN CONST CHAR8
* NewName
304 /** Get the first Resource Data element contained in a "_CRS" object.
306 In the following ASL code, the function will return the Resource Data
307 node corresponding to the "QWordMemory ()" ASL macro.
308 Name (_CRS, ResourceTemplate() {
309 QWordMemory (...) {...},
310 Interrupt (...) {...}
315 - The "_CRS" object must be declared using ASL "Name (Declare Named Object)".
316 - "_CRS" declared using ASL "Method (Declare Control Method)" is not
321 @param [in] NameOpCrsNode NameOp object node defining a "_CRS" object.
322 Must have an OpCode=AML_NAME_OP, SubOpCode=0.
323 NameOp object nodes are defined in ASL
324 using the "Name ()" function.
325 @param [out] OutRdNode Pointer to the first Resource Data element of
326 the "_CRS" object. A Resource Data element
327 is stored in a data node.
329 @retval EFI_SUCCESS The function completed successfully.
330 @retval EFI_INVALID_PARAMETER Invalid parameter.
334 AmlNameOpCrsGetFirstRdNode (
335 IN AML_OBJECT_NODE_HANDLE NameOpCrsNode
,
336 OUT AML_DATA_NODE_HANDLE
* OutRdNode
339 /** Get the Resource Data element following the CurrRdNode Resource Data.
341 In the following ASL code, if CurrRdNode corresponds to the first
342 "QWordMemory ()" ASL macro, the function will return the Resource Data
343 node corresponding to the "Interrupt ()" ASL macro.
344 Name (_CRS, ResourceTemplate() {
345 QwordMemory (...) {...},
346 Interrupt (...) {...}
350 The CurrRdNode Resource Data node must be defined in an object named "_CRS"
351 and defined by a "Name ()" ASL function.
355 @param [in] CurrRdNode Pointer to the current Resource Data element of
357 @param [out] OutRdNode Pointer to the Resource Data element following
359 Contain a NULL pointer if CurrRdNode is the
360 last Resource Data element in the list.
361 The "End Tag" is not considered as a resource
362 data element and is not returned.
364 @retval EFI_SUCCESS The function completed successfully.
365 @retval EFI_INVALID_PARAMETER Invalid parameter.
369 AmlNameOpCrsGetNextRdNode (
370 IN AML_DATA_NODE_HANDLE CurrRdNode
,
371 OUT AML_DATA_NODE_HANDLE
* OutRdNode
374 /** Update the first interrupt of an Interrupt resource data node.
376 The flags of the Interrupt resource data are left unchanged.
378 The InterruptRdNode corresponds to the Resource Data created by the
379 "Interrupt ()" ASL macro. It is an Extended Interrupt Resource Data.
380 See ACPI 6.3 specification, s6.4.3.6 "Extended Interrupt Descriptor"
381 for more information about Extended Interrupt Resource Data.
385 @param [in] InterruptRdNode Pointer to the an extended interrupt
387 @param [in] Irq Interrupt value to update.
389 @retval EFI_SUCCESS The function completed successfully.
390 @retval EFI_INVALID_PARAMETER Invalid parameter.
391 @retval EFI_OUT_OF_RESOURCES Out of resources.
395 AmlUpdateRdInterrupt (
396 IN AML_DATA_NODE_HANDLE InterruptRdNode
,
400 /** Update the base address and length of a QWord resource data node.
404 @param [in] QWordRdNode Pointer a QWord resource data
406 @param [in] BaseAddress Base address.
407 @param [in] BaseAddressLength Base address length.
409 @retval EFI_SUCCESS The function completed successfully.
410 @retval EFI_INVALID_PARAMETER Invalid parameter.
411 @retval EFI_OUT_OF_RESOURCES Out of resources.
416 IN AML_DATA_NODE_HANDLE QWordRdNode
,
417 IN UINT64 BaseAddress
,
418 IN UINT64 BaseAddressLength
421 /** Add an Interrupt Resource Data node.
423 This function creates a Resource Data element corresponding to the
424 "Interrupt ()" ASL function, stores it in an AML Data Node.
426 It then adds it after the input CurrRdNode in the list of resource data
429 The Resource Data effectively created is an Extended Interrupt Resource
430 Data. See ACPI 6.3 specification, s6.4.3.6 "Extended Interrupt Descriptor"
431 for more information about Extended Interrupt Resource Data.
433 The Extended Interrupt contains one single interrupt.
435 This function allocates memory to create a data node. It is the caller's
436 responsibility to either:
437 - attach this node to an AML tree;
440 Note: The _CRS node must be defined using the ASL Name () function.
441 e.g. Name (_CRS, ResourceTemplate () {
447 @param [in] NameOpCrsNode NameOp object node defining a "_CRS" object.
448 Must have an OpCode=AML_NAME_OP, SubOpCode=0.
449 NameOp object nodes are defined in ASL
450 using the "Name ()" function.
451 @param [in] ResourceConsumer The device consumes the specified interrupt
452 or produces it for use by a child device.
453 @param [in] EdgeTriggered The interrupt is edge triggered or
455 @param [in] ActiveLow The interrupt is active-high or active-low.
456 @param [in] Shared The interrupt can be shared with other
457 devices or not (Exclusive).
458 @param [in] IrqList Interrupt list. Must be non-NULL.
459 @param [in] IrqCount Interrupt count. Must be non-zero.
462 @retval EFI_SUCCESS The function completed successfully.
463 @retval EFI_INVALID_PARAMETER Invalid parameter.
464 @retval EFI_OUT_OF_RESOURCES Could not allocate memory.
468 AmlCodeGenCrsAddRdInterrupt (
469 IN AML_OBJECT_NODE_HANDLE NameOpCrsNode
,
470 IN BOOLEAN ResourceConsumer
,
471 IN BOOLEAN EdgeTriggered
,
472 IN BOOLEAN ActiveLow
,
478 /** AML code generation for DefinitionBlock.
480 Create a Root Node handle.
481 It is the caller's responsibility to free the allocated memory
482 with the AmlDeleteTree function.
484 AmlCodeGenDefinitionBlock (TableSignature, OemId, TableID, OEMRevision) is
485 equivalent to the following ASL code:
486 DefinitionBlock (AMLFileName, TableSignature, ComplianceRevision,
487 OemId, TableID, OEMRevision) {}
488 with the ComplianceRevision set to 2 and the AMLFileName is ignored.
492 @param[in] TableSignature 4-character ACPI signature.
493 Must be 'DSDT' or 'SSDT'.
494 @param[in] OemId 6-character string OEM identifier.
495 @param[in] OemTableId 8-character string OEM table identifier.
496 @param[in] OemRevision OEM revision number.
497 @param[out] DefinitionBlockTerm The ASL Term handle representing a
500 @retval EFI_SUCCESS Success.
501 @retval EFI_INVALID_PARAMETER Invalid parameter.
502 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
506 AmlCodeGenDefinitionBlock (
507 IN CONST CHAR8
* TableSignature
,
508 IN CONST CHAR8
* OemId
,
509 IN CONST CHAR8
* OemTableId
,
510 IN UINT32 OemRevision
,
511 OUT AML_ROOT_NODE_HANDLE
* NewRootNode
514 /** AML code generation for a Name object node, containing a String.
516 AmlCodeGenNameString ("_HID", "HID0000", ParentNode, NewObjectNode) is
517 equivalent of the following ASL code:
518 Name(_HID, "HID0000")
522 @param [in] NameString The new variable name.
523 Must be a NULL-terminated ASL NameString
524 e.g.: "DEV0", "DV15.DEV0", etc.
525 The input string is copied.
526 @param [in] String NULL terminated String to associate to the
528 @param [in] ParentNode If provided, set ParentNode as the parent
530 @param [out] NewObjectNode If success, contains the created node.
532 @retval EFI_SUCCESS Success.
533 @retval EFI_INVALID_PARAMETER Invalid parameter.
534 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
538 AmlCodeGenNameString (
539 IN CONST CHAR8
* NameString
,
541 IN AML_NODE_HANDLE ParentNode
, OPTIONAL
542 OUT AML_OBJECT_NODE_HANDLE
* NewObjectNode OPTIONAL
545 /** AML code generation for a Name object node, containing an Integer.
547 AmlCodeGenNameInteger ("_UID", 1, ParentNode, NewObjectNode) is
548 equivalent of the following ASL code:
553 @param [in] NameString The new variable name.
554 Must be a NULL-terminated ASL NameString
555 e.g.: "DEV0", "DV15.DEV0", etc.
556 The input string is copied.
557 @param [in] Integer Integer to associate to the NameString.
558 @param [in] ParentNode If provided, set ParentNode as the parent
560 @param [out] NewObjectNode If success, contains the created node.
562 @retval EFI_SUCCESS Success.
563 @retval EFI_INVALID_PARAMETER Invalid parameter.
564 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
568 AmlCodeGenNameInteger (
569 IN CONST CHAR8
* NameString
,
571 IN AML_NODE_HANDLE ParentNode
, OPTIONAL
572 OUT AML_OBJECT_NODE_HANDLE
* NewObjectNode OPTIONAL
575 /** AML code generation for a Device object node.
577 AmlCodeGenDevice ("COM0", ParentNode, NewObjectNode) is
578 equivalent of the following ASL code:
583 @param [in] NameString The new Device's name.
584 Must be a NULL-terminated ASL NameString
585 e.g.: "DEV0", "DV15.DEV0", etc.
586 The input string is copied.
587 @param [in] ParentNode If provided, set ParentNode as the parent
589 @param [out] NewObjectNode If success, contains the created node.
591 @retval EFI_SUCCESS Success.
592 @retval EFI_INVALID_PARAMETER Invalid parameter.
593 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
598 IN CONST CHAR8
* NameString
,
599 IN AML_NODE_HANDLE ParentNode
, OPTIONAL
600 OUT AML_OBJECT_NODE_HANDLE
* NewObjectNode OPTIONAL
603 /** AML code generation for a Scope object node.
605 AmlCodeGenScope ("_SB", ParentNode, NewObjectNode) is
606 equivalent of the following ASL code:
611 @param [in] NameString The new Scope's name.
612 Must be a NULL-terminated ASL NameString
613 e.g.: "DEV0", "DV15.DEV0", etc.
614 The input string is copied.
615 @param [in] ParentNode If provided, set ParentNode as the parent
617 @param [out] NewObjectNode If success, contains the created node.
619 @retval EFI_SUCCESS Success.
620 @retval EFI_INVALID_PARAMETER Invalid parameter.
621 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
626 IN CONST CHAR8
* NameString
,
627 IN AML_NODE_HANDLE ParentNode
, OPTIONAL
628 OUT AML_OBJECT_NODE_HANDLE
* NewObjectNode OPTIONAL