]> git.proxmox.com Git - mirror_edk2.git/blob - DynamicTablesPkg/Include/Library/AmlLib/AmlLib.h
DynamicTablesPkg: AmlLib APIs
[mirror_edk2.git] / DynamicTablesPkg / Include / Library / AmlLib / AmlLib.h
1 /** @file
2 AML Lib.
3
4 Copyright (c) 2019 - 2020, Arm Limited. All rights reserved.<BR>
5
6 SPDX-License-Identifier: BSD-2-Clause-Patent
7 **/
8
9 #ifndef AML_LIB_H_
10 #define AML_LIB_H_
11
12 /**
13 @mainpage Dynamic AML Generation
14 @{
15 @par Summary
16 @{
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
21 grammar.
22
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.
26
27 Dynamic AML aims to provide a framework that allows fixing up of an ACPI
28 SSDT template with appropriate information about the hardware.
29
30 This framework consists of an:
31 - AMLLib core that implements a rich set of interfaces to parse, traverse
32 and update AML data.
33 - AMLLib library APIs that provides interfaces to search and updates nodes
34 in the AML namespace.
35 @}
36 @}
37 */
38
39 #include <IndustryStandard/Acpi.h>
40
41 #ifndef AML_HANDLE
42
43 /** Node handle.
44 */
45 typedef void* AML_NODE_HANDLE;
46
47 /** Root Node handle.
48 */
49 typedef void* AML_ROOT_NODE_HANDLE;
50
51 /** Object Node handle.
52 */
53 typedef void* AML_OBJECT_NODE_HANDLE;
54
55 /** Data Node handle.
56 */
57 typedef void* AML_DATA_NODE_HANDLE;
58
59 #endif // AML_HANDLE
60
61 /** Parse the definition block.
62
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.
67
68 @ingroup UserApis
69
70 @param [in] DefinitionBlock Pointer to the definition block.
71 @param [out] RootPtr Pointer to the root node of the AML tree.
72
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.
77 **/
78 EFI_STATUS
79 EFIAPI
80 AmlParseDefinitionBlock (
81 IN CONST EFI_ACPI_DESCRIPTION_HEADER * DefinitionBlock,
82 OUT AML_ROOT_NODE_HANDLE * RootPtr
83 );
84
85 /** Serialize an AML definition block.
86
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.
90
91 @ingroup UserApis
92
93 @param [in] RootNode Root node of the tree.
94 @param [out] Table On return, hold the serialized
95 definition block.
96
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.
100 **/
101 EFI_STATUS
102 EFIAPI
103 AmlSerializeDefinitionBlock (
104 IN AML_ROOT_NODE_HANDLE RootNode,
105 OUT EFI_ACPI_DESCRIPTION_HEADER ** Table
106 );
107
108 /** Clone a node and its children (clone a tree branch).
109
110 The cloned branch returned is not attached to any tree.
111
112 @ingroup UserApis
113
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
117 branch.
118
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.
122 **/
123 EFI_STATUS
124 EFIAPI
125 AmlCloneTree (
126 IN AML_NODE_HANDLE Node,
127 OUT AML_NODE_HANDLE * ClonedNode
128 );
129
130 /** Delete a Node and its children.
131
132 The Node must be removed from the tree first,
133 or must be the root node.
134
135 @ingroup UserApis
136
137 @param [in] Node Pointer to the node to delete.
138
139 @retval EFI_SUCCESS The function completed successfully.
140 @retval EFI_INVALID_PARAMETER Invalid parameter.
141 **/
142 EFI_STATUS
143 EFIAPI
144 AmlDeleteTree (
145 IN AML_NODE_HANDLE Node
146 );
147
148 /** Detach the Node from the tree.
149
150 The function will fail if the Node is in its parent's fixed
151 argument list.
152 The Node is not deleted. The deletion is done separately
153 from the removal.
154
155 @ingroup UserApis
156
157 @param [in] Node Pointer to a Node.
158 Must be a data node or an object node.
159
160 @retval EFI_SUCCESS The function completed successfully.
161 @retval EFI_INVALID_PARAMETER Invalid parameter.
162 **/
163 EFI_STATUS
164 EFIAPI
165 AmlDetachNode (
166 IN AML_NODE_HANDLE Node
167 );
168
169 /** Find a node in the AML namespace, given an ASL path and a reference Node.
170
171 - The AslPath can be an absolute path, or a relative path from the
172 reference Node;
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.
175
176 E.g.:
177 For the following AML namespace, with the ReferenceNode being the node with
178 the name "AAAA":
179 - the node with the name "BBBB" can be found by looking for the ASL
180 path "BBBB";
181 - the root node can be found by looking for the ASL relative path "^",
182 or the absolute path "\\".
183
184 AML namespace:
185 \
186 \-AAAA <- ReferenceNode
187 \-BBBB
188
189 @ingroup NameSpaceApis
190
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
198 namespace.
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
202 or absolute path.
203 E.g.: "\\_SB.CLU0.CPU0" or "^CPU0"
204 @param [out] OutNode Pointer to the found node.
205 Contains NULL if not found.
206
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.
211 **/
212 EFI_STATUS
213 EFIAPI
214 AmlFindNode (
215 IN AML_NODE_HANDLE ReferenceNode,
216 IN CHAR8 * AslPath,
217 OUT AML_NODE_HANDLE * OutNode
218 );
219
220 /**
221 @defgroup UserApis User APIs
222 @{
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
226 AmlLib functions.
227 @}
228 */
229
230 /** Update the name of a DeviceOp object node.
231
232 @ingroup UserApis
233
234 @param [in] DeviceOpNode Object node representing a Device.
235 Must have an OpCode=AML_NAME_OP, SubOpCode=0.
236 OpCode/SubOpCode.
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.
243
244 @retval EFI_SUCCESS The function completed successfully.
245 @retval EFI_INVALID_PARAMETER Invalid parameter.
246 **/
247 EFI_STATUS
248 EFIAPI
249 AmlDeviceOpUpdateName (
250 IN AML_OBJECT_NODE_HANDLE DeviceOpNode,
251 IN CHAR8 * NewNameString
252 );
253
254 /** Update an integer value defined by a NameOp object node.
255
256 For compatibility reasons, the NameOpNode must initially
257 contain an integer.
258
259 @ingroup UserApis
260
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.
266 Must be a UINT64.
267
268 @retval EFI_SUCCESS The function completed successfully.
269 @retval EFI_INVALID_PARAMETER Invalid parameter.
270 **/
271 EFI_STATUS
272 EFIAPI
273 AmlNameOpUpdateInteger (
274 IN AML_OBJECT_NODE_HANDLE NameOpNode,
275 IN UINT64 NewInt
276 );
277
278 /** Update a string value defined by a NameOp object node.
279
280 The NameOpNode must initially contain a string.
281 The EISAID ASL macro converts a string to an integer. This, it is
282 not accepted.
283
284 @ingroup UserApis
285
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
291 the NameOpNode.
292 The input string is copied.
293
294 @retval EFI_SUCCESS The function completed successfully.
295 @retval EFI_INVALID_PARAMETER Invalid parameter.
296 **/
297 EFI_STATUS
298 EFIAPI
299 AmlNameOpUpdateString (
300 IN AML_OBJECT_NODE_HANDLE NameOpNode,
301 IN CONST CHAR8 * NewName
302 );
303
304 /** Get the first Resource Data element contained in a "_CRS" object.
305
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 (...) {...}
311 }
312 )
313
314 Note:
315 - The "_CRS" object must be declared using ASL "Name (Declare Named Object)".
316 - "_CRS" declared using ASL "Method (Declare Control Method)" is not
317 supported.
318
319 @ingroup UserApis
320
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.
328
329 @retval EFI_SUCCESS The function completed successfully.
330 @retval EFI_INVALID_PARAMETER Invalid parameter.
331 **/
332 EFI_STATUS
333 EFIAPI
334 AmlNameOpCrsGetFirstRdNode (
335 IN AML_OBJECT_NODE_HANDLE NameOpCrsNode,
336 OUT AML_DATA_NODE_HANDLE * OutRdNode
337 );
338
339 /** Get the Resource Data element following the CurrRdNode Resource Data.
340
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 (...) {...}
347 }
348 )
349
350 The CurrRdNode Resource Data node must be defined in an object named "_CRS"
351 and defined by a "Name ()" ASL function.
352
353 @ingroup UserApis
354
355 @param [in] CurrRdNode Pointer to the current Resource Data element of
356 the "_CRS" variable.
357 @param [out] OutRdNode Pointer to the Resource Data element following
358 the CurrRdNode.
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.
363
364 @retval EFI_SUCCESS The function completed successfully.
365 @retval EFI_INVALID_PARAMETER Invalid parameter.
366 **/
367 EFI_STATUS
368 EFIAPI
369 AmlNameOpCrsGetNextRdNode (
370 IN AML_DATA_NODE_HANDLE CurrRdNode,
371 OUT AML_DATA_NODE_HANDLE * OutRdNode
372 );
373
374 /** Update the first interrupt of an Interrupt resource data node.
375
376 The flags of the Interrupt resource data are left unchanged.
377
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.
382
383 @ingroup UserApis
384
385 @param [in] InterruptRdNode Pointer to the an extended interrupt
386 resource data node.
387 @param [in] Irq Interrupt value to update.
388
389 @retval EFI_SUCCESS The function completed successfully.
390 @retval EFI_INVALID_PARAMETER Invalid parameter.
391 @retval EFI_OUT_OF_RESOURCES Out of resources.
392 **/
393 EFI_STATUS
394 EFIAPI
395 AmlUpdateRdInterrupt (
396 IN AML_DATA_NODE_HANDLE InterruptRdNode,
397 IN UINT32 Irq
398 );
399
400 /** Update the base address and length of a QWord resource data node.
401
402 @ingroup UserApis
403
404 @param [in] QWordRdNode Pointer a QWord resource data
405 node.
406 @param [in] BaseAddress Base address.
407 @param [in] BaseAddressLength Base address length.
408
409 @retval EFI_SUCCESS The function completed successfully.
410 @retval EFI_INVALID_PARAMETER Invalid parameter.
411 @retval EFI_OUT_OF_RESOURCES Out of resources.
412 **/
413 EFI_STATUS
414 EFIAPI
415 AmlUpdateRdQWord (
416 IN AML_DATA_NODE_HANDLE QWordRdNode,
417 IN UINT64 BaseAddress,
418 IN UINT64 BaseAddressLength
419 );
420
421 /** Add an Interrupt Resource Data node.
422
423 This function creates a Resource Data element corresponding to the
424 "Interrupt ()" ASL function, stores it in an AML Data Node.
425
426 It then adds it after the input CurrRdNode in the list of resource data
427 element.
428
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.
432
433 The Extended Interrupt contains one single interrupt.
434
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;
438 - delete this node.
439
440 Note: The _CRS node must be defined using the ASL Name () function.
441 e.g. Name (_CRS, ResourceTemplate () {
442 ...
443 }
444
445 @ingroup UserApis
446
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
454 level triggered.
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.
460
461
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.
465 **/
466 EFI_STATUS
467 EFIAPI
468 AmlCodeGenCrsAddRdInterrupt (
469 IN AML_OBJECT_NODE_HANDLE NameOpCrsNode,
470 IN BOOLEAN ResourceConsumer,
471 IN BOOLEAN EdgeTriggered,
472 IN BOOLEAN ActiveLow,
473 IN BOOLEAN Shared,
474 IN UINT32 * IrqList,
475 IN UINT8 IrqCount
476 );
477
478 /** AML code generation for DefinitionBlock.
479
480 Create a Root Node handle.
481 It is the caller's responsibility to free the allocated memory
482 with the AmlDeleteTree function.
483
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.
489
490 @ingroup CodeGenApis
491
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
498 Definition Block.
499
500 @retval EFI_SUCCESS Success.
501 @retval EFI_INVALID_PARAMETER Invalid parameter.
502 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
503 **/
504 EFI_STATUS
505 EFIAPI
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
512 );
513
514 /** AML code generation for a Name object node, containing a String.
515
516 AmlCodeGenNameString ("_HID", "HID0000", ParentNode, NewObjectNode) is
517 equivalent of the following ASL code:
518 Name(_HID, "HID0000")
519
520 @ingroup CodeGenApis
521
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
527 NameString.
528 @param [in] ParentNode If provided, set ParentNode as the parent
529 of the node created.
530 @param [out] NewObjectNode If success, contains the created node.
531
532 @retval EFI_SUCCESS Success.
533 @retval EFI_INVALID_PARAMETER Invalid parameter.
534 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
535 **/
536 EFI_STATUS
537 EFIAPI
538 AmlCodeGenNameString (
539 IN CONST CHAR8 * NameString,
540 IN CHAR8 * String,
541 IN AML_NODE_HANDLE ParentNode, OPTIONAL
542 OUT AML_OBJECT_NODE_HANDLE * NewObjectNode OPTIONAL
543 );
544
545 /** AML code generation for a Name object node, containing an Integer.
546
547 AmlCodeGenNameInteger ("_UID", 1, ParentNode, NewObjectNode) is
548 equivalent of the following ASL code:
549 Name(_UID, One)
550
551 @ingroup CodeGenApis
552
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
559 of the node created.
560 @param [out] NewObjectNode If success, contains the created node.
561
562 @retval EFI_SUCCESS Success.
563 @retval EFI_INVALID_PARAMETER Invalid parameter.
564 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
565 **/
566 EFI_STATUS
567 EFIAPI
568 AmlCodeGenNameInteger (
569 IN CONST CHAR8 * NameString,
570 IN UINT64 Integer,
571 IN AML_NODE_HANDLE ParentNode, OPTIONAL
572 OUT AML_OBJECT_NODE_HANDLE * NewObjectNode OPTIONAL
573 );
574
575 /** AML code generation for a Device object node.
576
577 AmlCodeGenDevice ("COM0", ParentNode, NewObjectNode) is
578 equivalent of the following ASL code:
579 Device(COM0) {}
580
581 @ingroup CodeGenApis
582
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
588 of the node created.
589 @param [out] NewObjectNode If success, contains the created node.
590
591 @retval EFI_SUCCESS Success.
592 @retval EFI_INVALID_PARAMETER Invalid parameter.
593 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
594 **/
595 EFI_STATUS
596 EFIAPI
597 AmlCodeGenDevice (
598 IN CONST CHAR8 * NameString,
599 IN AML_NODE_HANDLE ParentNode, OPTIONAL
600 OUT AML_OBJECT_NODE_HANDLE * NewObjectNode OPTIONAL
601 );
602
603 /** AML code generation for a Scope object node.
604
605 AmlCodeGenScope ("_SB", ParentNode, NewObjectNode) is
606 equivalent of the following ASL code:
607 Scope(_SB) {}
608
609 @ingroup CodeGenApis
610
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
616 of the node created.
617 @param [out] NewObjectNode If success, contains the created node.
618
619 @retval EFI_SUCCESS Success.
620 @retval EFI_INVALID_PARAMETER Invalid parameter.
621 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
622 **/
623 EFI_STATUS
624 EFIAPI
625 AmlCodeGenScope (
626 IN CONST CHAR8 * NameString,
627 IN AML_NODE_HANDLE ParentNode, OPTIONAL
628 OUT AML_OBJECT_NODE_HANDLE * NewObjectNode OPTIONAL
629 );
630
631 #endif // AML_LIB_H_