2 AML Resource Data Code Generation.
4 Copyright (c) 2020 - 2021, Arm Limited. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
9 - Rd or RD - Resource Data
10 - Rds or RDS - Resource Data Small
11 - Rdl or RDL - Resource Data Large
14 #include <AmlNodeDefines.h>
15 #include <CodeGen/AmlResourceDataCodeGen.h>
17 #include <AmlCoreInterface.h>
18 #include <AmlDefines.h>
19 #include <Api/AmlApiHelper.h>
20 #include <Tree/AmlNode.h>
21 #include <ResourceData/AmlResourceData.h>
23 /** If ParentNode is not NULL, append RdNode.
24 If NewRdNode is not NULL, update its value to RdNode.
26 @param [in] RdNode Newly created Resource Data node.
27 RdNode is deleted if an error occurs.
28 @param [in] ParentNode If not NULL, ParentNode must:
29 - be a NameOp node, i.e. have the AML_NAME_OP
30 opcode (cf "Name ()" ASL statement)
31 - contain a list of resource data elements
32 (cf "ResourceTemplate ()" ASL statement)
33 RdNode is then added at the end of the variable
34 list of resource data elements, but before the
35 "End Tag" Resource Data.
36 @param [out] NewRdNode If not NULL:
37 - and Success, contains RdNode.
38 - and Error, reset to NULL.
40 @retval EFI_SUCCESS The function completed successfully.
41 @retval EFI_INVALID_PARAMETER Invalid parameter.
47 IN AML_DATA_NODE
*RdNode
,
48 IN AML_OBJECT_NODE
*ParentNode
,
49 OUT AML_DATA_NODE
**NewRdNode
54 AML_OBJECT_NODE
*BufferOpNode
;
56 if (NewRdNode
!= NULL
) {
60 if (ParentNode
!= NULL
) {
61 // Check this is a NameOp node.
62 if ((!AmlNodeHasOpCode (ParentNode
, AML_NAME_OP
, 0))) {
64 Status
= EFI_INVALID_PARAMETER
;
68 // Get the value which is represented as a BufferOp object node
69 // which is the 2nd fixed argument (i.e. index 1).
70 BufferOpNode
= (AML_OBJECT_NODE_HANDLE
)AmlGetFixedArgument (
74 if ((BufferOpNode
== NULL
) ||
75 (AmlGetNodeType ((AML_NODE_HANDLE
)BufferOpNode
) != EAmlNodeObject
) ||
76 (!AmlNodeHasOpCode (BufferOpNode
, AML_BUFFER_OP
, 0)))
79 Status
= EFI_INVALID_PARAMETER
;
83 // Add RdNode as the last element, but before the EndTag.
84 Status
= AmlAppendRdNode (BufferOpNode
, RdNode
);
85 if (EFI_ERROR (Status
)) {
91 if (NewRdNode
!= NULL
) {
98 Status1
= AmlDeleteTree ((AML_NODE_HEADER
*)RdNode
);
99 ASSERT_EFI_ERROR (Status1
);
100 // Return original error.
104 /** Construct the TypeSpecificFlags field for IO ranges.
106 See ACPI 6.4 spec, s19.6.34 for more.
108 @param [in] IsaRanges Possible values are:
113 See ACPI 6.4 spec, s19.6.34 for more.
114 @param [in] IsDenseTranslation TranslationDensity parameter.
115 @param [in] IsTypeStatic TranslationType parameter.
117 @return A type specific flags value.
123 RdIoRangeSpecificFlags (
125 IN BOOLEAN IsDenseTranslation
,
126 IN BOOLEAN IsTypeStatic
129 // Only check type specific parameters.
135 // Construct TypeSpecificFlags and call the generic function.
136 // Cf ACPI 6.4 specification, Table 6.50:
137 // "Table 6.50: I/O Resource Flag (Resource Type = 1) Definitions"
139 (IsTypeStatic
? 0 : BIT4
) |
140 (IsDenseTranslation
? 0 : BIT5
);
143 /** Construct the TypeSpecificFlags field for Memory ranges.
145 @param [in] Cacheable Possible values are:
146 0-The memory is non-cacheable
147 1-The memory is cacheable
148 2-The memory is cacheable and supports
150 3-The memory is cacheable and prefetchable
151 @param [in] IsReadWrite ReadAndWrite parameter.
152 @param [in] MemoryRangeType Possible values are:
154 1-AddressRangeReserved
157 See ACPI 6.4 spec, s19.6.35 for more.
158 @param [in] IsTypeStatic TranslationType parameter.
160 @return A type specific flags value.
166 MemoryRangeSpecificFlags (
168 IN BOOLEAN IsReadWrite
,
169 IN UINT8 MemoryRangeType
,
170 IN BOOLEAN IsTypeStatic
173 // Only check type specific parameters.
174 if ((Cacheable
> 3) ||
175 (MemoryRangeType
> 3))
181 // Construct TypeSpecificFlags and call the generic function.
182 // Cf ACPI 6.4 specification, Table 6.49:
183 // "Memory Resource Flag (Resource Type = 0) Definitions"
184 return (IsReadWrite
? BIT0
: 0) |
186 (MemoryRangeType
<< 3) |
187 (IsTypeStatic
? 0 : BIT5
);
190 /** Construct the GeneralFlags field of any Address Space Resource Descriptors.
193 ACPI 6.4 specification, s6.4.3.5.1 "QWord Address Space Descriptor"
196 See ACPI 6.4 spec, s19.6.36 for more.
198 @param [in] IsPosDecode Decode parameter
199 @param [in] IsMinFixed Minimum address is fixed.
200 @param [in] IsMaxFixed Maximum address is fixed.
202 @return A type specific flags value.
207 AddressSpaceGeneralFlags (
208 IN BOOLEAN IsPosDecode
,
209 IN BOOLEAN IsMinFixed
,
210 IN BOOLEAN IsMaxFixed
213 return (IsPosDecode
? 0 : BIT1
) |
214 (IsMinFixed
? BIT2
: 0) |
215 (IsMaxFixed
? BIT3
: 0);
218 /** Check Address Space Descriptor Fields.
220 Cf. ACPI 6.4 Table 6.44:
221 "Valid Combination of Address Space Descriptor Fields"
223 See ACPI 6.4 spec, s19.6.36 for more.
225 @param [in] IsMinFixed Minimum address is fixed.
226 @param [in] IsMaxFixed Maximum address is fixed.
227 @param [in] AddressGranularity Address granularity.
228 @param [in] AddressMinimum Minimum address.
229 @param [in] AddressMaximum Maximum address.
230 @param [in] AddressTranslation Address translation.
231 @param [in] RangeLength Range length.
233 @retval EFI_SUCCESS The function completed successfully.
234 @retval EFI_INVALID_PARAMETER Invalid parameter.
239 CheckAddressSpaceFields (
240 IN BOOLEAN IsMinFixed
,
241 IN BOOLEAN IsMaxFixed
,
242 IN UINT64 AddressGranularity
,
243 IN UINT64 AddressMinimum
,
244 IN UINT64 AddressMaximum
,
245 IN UINT64 AddressTranslation
,
246 IN UINT64 RangeLength
249 if ((AddressMinimum
> AddressMaximum
) ||
250 (RangeLength
> (AddressMaximum
- AddressMinimum
+ 1)) ||
251 ((AddressGranularity
!= 0) &&
252 (((AddressGranularity
+ 1) & AddressGranularity
) != 0)))
255 return EFI_INVALID_PARAMETER
;
258 if (RangeLength
!= 0) {
259 if (IsMinFixed
^ IsMaxFixed
) {
261 return EFI_INVALID_PARAMETER
;
262 } else if (IsMinFixed
&&
264 (AddressGranularity
!= 0) &&
265 ((AddressMaximum
- AddressMinimum
+ 1) != RangeLength
))
268 return EFI_INVALID_PARAMETER
;
271 if (IsMinFixed
&& IsMaxFixed
) {
273 return EFI_INVALID_PARAMETER
;
274 } else if (IsMinFixed
&&
275 ((AddressMinimum
& AddressGranularity
) != 0))
278 return EFI_INVALID_PARAMETER
;
279 } else if (IsMaxFixed
&&
280 (((AddressMaximum
+ 1) & AddressGranularity
) != 0))
283 return EFI_INVALID_PARAMETER
;
290 /** Code generation for the "DWordSpace ()" ASL function.
292 The Resource Data effectively created is a DWord Address Space Resource
294 - s6.4.3.5.2 "DWord Address Space Descriptor".
295 - s19.6.36 "DWordSpace".
297 The created resource data node can be:
298 - appended to the list of resource data elements of the NameOpNode.
299 In such case NameOpNode must be defined by a the "Name ()" ASL statement
300 and initially contain a "ResourceTemplate ()".
301 - returned through the NewRdNode parameter.
303 See ACPI 6.4 spec, s19.6.36 for more.
305 @param [in] ResourceType Resource type.
311 192-255: Hardware Vendor Defined
312 See ACPI 6.4 spec, s6.4.3.5.2 for more.
313 @param [in] IsResourceConsumer ResourceUsage parameter.
314 @param [in] IsPosDecode Decode parameter
315 @param [in] IsMinFixed Minimum address is fixed.
316 @param [in] IsMaxFixed Maximum address is fixed.
317 @param [in] TypeSpecificFlags Type specific flags.
318 See ACPI 6.4 spec, s6.4.3.5.5
319 "Resource Type Specific Flags".
320 @param [in] AddressGranularity Address granularity.
321 @param [in] AddressMinimum Minimum address.
322 @param [in] AddressMaximum Maximum address.
323 @param [in] AddressTranslation Address translation.
324 @param [in] RangeLength Range length.
325 @param [in] ResourceSourceIndex Resource Source index.
327 @param [in] ResourceSource Resource Source.
328 Unused. Must be NULL.
329 @param [in] NameOpNode NameOp object node defining a named object.
330 If provided, append the new resource data
331 node to the list of resource data elements
333 @param [out] NewRdNode If provided and success,
334 contain the created node.
336 @retval EFI_SUCCESS The function completed successfully.
337 @retval EFI_INVALID_PARAMETER Invalid parameter.
338 @retval EFI_OUT_OF_RESOURCES Could not allocate memory.
343 AmlCodeGenRdDWordSpace (
344 IN UINT8 ResourceType
,
345 IN BOOLEAN IsResourceConsumer
,
346 IN BOOLEAN IsPosDecode
,
347 IN BOOLEAN IsMinFixed
,
348 IN BOOLEAN IsMaxFixed
,
349 IN UINT8 TypeSpecificFlags
,
350 IN UINT32 AddressGranularity
,
351 IN UINT32 AddressMinimum
,
352 IN UINT32 AddressMaximum
,
353 IN UINT32 AddressTranslation
,
354 IN UINT32 RangeLength
,
355 IN UINT8 ResourceSourceIndex
,
356 IN CONST CHAR8
*ResourceSource
,
357 IN AML_OBJECT_NODE_HANDLE NameOpNode
, OPTIONAL
358 OUT AML_DATA_NODE_HANDLE
*NewRdNode OPTIONAL
362 AML_DATA_NODE
*RdNode
;
363 EFI_ACPI_DWORD_ADDRESS_SPACE_DESCRIPTOR RdDWord
;
365 // ResourceSource and ResourceSourceIndex are unused.
366 if ((TypeSpecificFlags
== MAX_UINT8
) ||
367 (ResourceSourceIndex
!= 0) ||
368 (ResourceSource
!= NULL
) ||
369 ((NameOpNode
== NULL
) && (NewRdNode
== NULL
)))
372 return EFI_INVALID_PARAMETER
;
375 Status
= CheckAddressSpaceFields (
384 if (EFI_ERROR (Status
)) {
390 RdDWord
.Header
.Header
.Bits
.Name
=
391 ACPI_LARGE_DWORD_ADDRESS_SPACE_DESCRIPTOR_NAME
;
392 RdDWord
.Header
.Header
.Bits
.Type
= ACPI_LARGE_ITEM_FLAG
;
393 RdDWord
.Header
.Length
= sizeof (EFI_ACPI_DWORD_ADDRESS_SPACE_DESCRIPTOR
) -
394 sizeof (ACPI_LARGE_RESOURCE_HEADER
);
397 RdDWord
.ResType
= ResourceType
;
398 RdDWord
.GenFlag
= AddressSpaceGeneralFlags (
403 RdDWord
.SpecificFlag
= TypeSpecificFlags
;
404 RdDWord
.AddrSpaceGranularity
= AddressGranularity
;
405 RdDWord
.AddrRangeMin
= AddressMinimum
;
406 RdDWord
.AddrRangeMax
= AddressMaximum
;
407 RdDWord
.AddrTranslationOffset
= AddressTranslation
;
408 RdDWord
.AddrLen
= RangeLength
;
410 Status
= AmlCreateDataNode (
411 EAmlNodeDataTypeResourceData
,
413 sizeof (EFI_ACPI_DWORD_ADDRESS_SPACE_DESCRIPTOR
),
416 if (EFI_ERROR (Status
)) {
421 return LinkRdNode (RdNode
, NameOpNode
, NewRdNode
);
424 /** Code generation for the "DWordIO ()" ASL function.
426 The Resource Data effectively created is a DWord Address Space Resource
428 - s6.4.3.5.2 "DWord Address Space Descriptor".
429 - s19.6.34 "DWordIO".
431 The created resource data node can be:
432 - appended to the list of resource data elements of the NameOpNode.
433 In such case NameOpNode must be defined by a the "Name ()" ASL statement
434 and initially contain a "ResourceTemplate ()".
435 - returned through the NewRdNode parameter.
437 See ACPI 6.4 spec, s19.6.34 for more.
439 @param [in] IsResourceConsumer ResourceUsage parameter.
440 @param [in] IsMinFixed Minimum address is fixed.
441 @param [in] IsMaxFixed Maximum address is fixed.
442 @param [in] IsPosDecode Decode parameter
443 @param [in] IsaRanges Possible values are:
448 @param [in] AddressGranularity Address granularity.
449 @param [in] AddressMinimum Minimum address.
450 @param [in] AddressMaximum Maximum address.
451 @param [in] AddressTranslation Address translation.
452 @param [in] RangeLength Range length.
453 @param [in] ResourceSourceIndex Resource Source index.
455 @param [in] ResourceSource Resource Source.
456 Unused. Must be NULL.
457 @param [in] IsDenseTranslation TranslationDensity parameter.
458 @param [in] IsTypeStatic TranslationType parameter.
459 @param [in] NameOpNode NameOp object node defining a named object.
460 If provided, append the new resource data
461 node to the list of resource data elements
463 @param [out] NewRdNode If provided and success,
464 contain the created node.
466 @retval EFI_SUCCESS The function completed successfully.
467 @retval EFI_INVALID_PARAMETER Invalid parameter.
468 @retval EFI_OUT_OF_RESOURCES Could not allocate memory.
472 AmlCodeGenRdDWordIo (
473 IN BOOLEAN IsResourceConsumer
,
474 IN BOOLEAN IsMinFixed
,
475 IN BOOLEAN IsMaxFixed
,
476 IN BOOLEAN IsPosDecode
,
478 IN UINT32 AddressGranularity
,
479 IN UINT32 AddressMinimum
,
480 IN UINT32 AddressMaximum
,
481 IN UINT32 AddressTranslation
,
482 IN UINT32 RangeLength
,
483 IN UINT8 ResourceSourceIndex
,
484 IN CONST CHAR8
*ResourceSource
,
485 IN BOOLEAN IsDenseTranslation
,
486 IN BOOLEAN IsTypeStatic
,
487 IN AML_OBJECT_NODE_HANDLE NameOpNode
, OPTIONAL
488 OUT AML_DATA_NODE_HANDLE
*NewRdNode OPTIONAL
491 return AmlCodeGenRdDWordSpace (
492 ACPI_ADDRESS_SPACE_TYPE_IO
,
497 RdIoRangeSpecificFlags (
514 /** Code generation for the "DWordMemory ()" ASL function.
516 The Resource Data effectively created is a DWord Address Space Resource
518 - s6.4.3.5.2 "DWord Address Space Descriptor".
519 - s19.6.35 "DWordMemory".
521 The created resource data node can be:
522 - appended to the list of resource data elements of the NameOpNode.
523 In such case NameOpNode must be defined by a the "Name ()" ASL statement
524 and initially contain a "ResourceTemplate ()".
525 - returned through the NewRdNode parameter.
527 See ACPI 6.4 spec, s19.6.35 for more.
529 @param [in] IsResourceConsumer ResourceUsage parameter.
530 @param [in] IsPosDecode Decode parameter
531 @param [in] IsMinFixed Minimum address is fixed.
532 @param [in] IsMaxFixed Maximum address is fixed.
533 @param [in] Cacheable Possible values are:
534 0-The memory is non-cacheable
535 1-The memory is cacheable
536 2-The memory is cacheable and supports
538 3-The memory is cacheable and prefetchable
539 @param [in] IsReadWrite ReadAndWrite parameter.
540 @param [in] AddressGranularity Address granularity.
541 @param [in] AddressMinimum Minimum address.
542 @param [in] AddressMaximum Maximum address.
543 @param [in] AddressTranslation Address translation.
544 @param [in] RangeLength Range length.
545 @param [in] ResourceSourceIndex Resource Source index.
547 @param [in] ResourceSource Resource Source.
548 Unused. Must be NULL.
549 @param [in] MemoryRangeType Possible values are:
551 1-AddressRangeReserved
554 @param [in] IsTypeStatic TranslationType parameter.
555 @param [in] NameOpNode NameOp object node defining a named object.
556 If provided, append the new resource data
557 node to the list of resource data elements
559 @param [out] NewRdNode If provided and success,
560 contain the created node.
562 @retval EFI_SUCCESS The function completed successfully.
563 @retval EFI_INVALID_PARAMETER Invalid parameter.
564 @retval EFI_OUT_OF_RESOURCES Could not allocate memory.
568 AmlCodeGenRdDWordMemory (
569 IN BOOLEAN IsResourceConsumer
,
570 IN BOOLEAN IsPosDecode
,
571 IN BOOLEAN IsMinFixed
,
572 IN BOOLEAN IsMaxFixed
,
574 IN BOOLEAN IsReadWrite
,
575 IN UINT32 AddressGranularity
,
576 IN UINT32 AddressMinimum
,
577 IN UINT32 AddressMaximum
,
578 IN UINT32 AddressTranslation
,
579 IN UINT32 RangeLength
,
580 IN UINT8 ResourceSourceIndex
,
581 IN CONST CHAR8
*ResourceSource
,
582 IN UINT8 MemoryRangeType
,
583 IN BOOLEAN IsTypeStatic
,
584 IN AML_OBJECT_NODE_HANDLE NameOpNode
, OPTIONAL
585 OUT AML_DATA_NODE_HANDLE
*NewRdNode OPTIONAL
588 return AmlCodeGenRdDWordSpace (
589 ACPI_ADDRESS_SPACE_TYPE_MEM
,
594 MemoryRangeSpecificFlags (
612 /** Code generation for the "Memory32Fixed ()" ASL macro.
614 The Resource Data effectively created is a 32-bit Memory Resource
616 - s19.6.83 "Memory Resource Descriptor Macro".
617 - s19.2.8 "Memory32FixedTerm".
619 See ACPI 6.4 spec, s19.2.8 for more.
621 @param [in] IsReadWrite ReadAndWrite parameter.
622 @param [in] Address AddressBase parameter.
623 @param [in] RangeLength Range length.
624 @param [in] NameOpNode NameOp object node defining a named object.
625 If provided, append the new resource data
626 node to the list of resource data elements
628 @param [out] NewMemNode If provided and success,
629 contain the created node.
631 @retval EFI_SUCCESS The function completed successfully.
632 @retval EFI_INVALID_PARAMETER Invalid parameter.
633 @retval EFI_OUT_OF_RESOURCES Could not allocate memory.
637 AmlCodeGenRdMemory32Fixed (
641 AML_OBJECT_NODE_HANDLE NameOpNode
,
642 AML_DATA_NODE_HANDLE
*NewMemNode
646 AML_DATA_NODE
*MemNode
;
647 EFI_ACPI_32_BIT_FIXED_MEMORY_RANGE_DESCRIPTOR RangeDesc
;
649 RangeDesc
.Header
.Header
.Byte
= ACPI_32_BIT_FIXED_MEMORY_RANGE_DESCRIPTOR
;
650 RangeDesc
.Header
.Length
= sizeof (EFI_ACPI_32_BIT_FIXED_MEMORY_RANGE_DESCRIPTOR
) -
651 sizeof (ACPI_LARGE_RESOURCE_HEADER
);
652 RangeDesc
.Information
= IsReadWrite
? BIT0
: 0;
653 RangeDesc
.BaseAddress
= Address
;
654 RangeDesc
.Length
= RangeLength
;
656 Status
= AmlCreateDataNode (
657 EAmlNodeDataTypeResourceData
,
662 if (EFI_ERROR (Status
)) {
667 return LinkRdNode (MemNode
, NameOpNode
, NewMemNode
);
670 /** Code generation for the "WordSpace ()" ASL function.
672 The Resource Data effectively created is a Word Address Space Resource
674 - s6.4.3.5.3 "Word Address Space Descriptor".
675 - s19.6.151 "WordSpace".
677 The created resource data node can be:
678 - appended to the list of resource data elements of the NameOpNode.
679 In such case NameOpNode must be defined by a the "Name ()" ASL statement
680 and initially contain a "ResourceTemplate ()".
681 - returned through the NewRdNode parameter.
683 See ACPI 6.4 spec, s19.6.151 for more.
685 @param [in] ResourceType Resource type.
691 192-255: Hardware Vendor Defined
692 See ACPI 6.4 spec, s6.4.3.5.3 for more.
693 @param [in] IsResourceConsumer ResourceUsage parameter.
694 @param [in] IsPosDecode Decode parameter
695 @param [in] IsMinFixed Minimum address is fixed.
696 @param [in] IsMaxFixed Maximum address is fixed.
697 @param [in] TypeSpecificFlags Type specific flags.
698 See ACPI 6.4 spec, s6.4.3.5.5
699 "Resource Type Specific Flags".
700 @param [in] AddressGranularity Address granularity.
701 @param [in] AddressMinimum Minimum address.
702 @param [in] AddressMaximum Maximum address.
703 @param [in] AddressTranslation Address translation.
704 @param [in] RangeLength Range length.
705 @param [in] ResourceSourceIndex Resource Source index.
707 @param [in] ResourceSource Resource Source.
708 Unused. Must be NULL.
709 @param [in] NameOpNode NameOp object node defining a named object.
710 If provided, append the new resource data
711 node to the list of resource data elements
713 @param [out] NewRdNode If provided and success,
714 contain the created node.
716 @retval EFI_SUCCESS The function completed successfully.
717 @retval EFI_INVALID_PARAMETER Invalid parameter.
718 @retval EFI_OUT_OF_RESOURCES Could not allocate memory.
723 AmlCodeGenRdWordSpace (
724 IN UINT8 ResourceType
,
725 IN BOOLEAN IsResourceConsumer
,
726 IN BOOLEAN IsPosDecode
,
727 IN BOOLEAN IsMinFixed
,
728 IN BOOLEAN IsMaxFixed
,
729 IN UINT8 TypeSpecificFlags
,
730 IN UINT16 AddressGranularity
,
731 IN UINT16 AddressMinimum
,
732 IN UINT16 AddressMaximum
,
733 IN UINT16 AddressTranslation
,
734 IN UINT16 RangeLength
,
735 IN UINT8 ResourceSourceIndex
,
736 IN CONST CHAR8
*ResourceSource
,
737 IN AML_OBJECT_NODE_HANDLE NameOpNode
, OPTIONAL
738 OUT AML_DATA_NODE_HANDLE
*NewRdNode OPTIONAL
742 AML_DATA_NODE
*RdNode
;
743 EFI_ACPI_WORD_ADDRESS_SPACE_DESCRIPTOR Rdword
;
745 // ResourceSource and ResourceSourceIndex are unused.
746 if ((TypeSpecificFlags
== MAX_UINT8
) ||
747 (ResourceSourceIndex
!= 0) ||
748 (ResourceSource
!= NULL
) ||
749 ((NameOpNode
== NULL
) && (NewRdNode
== NULL
)))
752 return EFI_INVALID_PARAMETER
;
755 Status
= CheckAddressSpaceFields (
764 if (EFI_ERROR (Status
)) {
770 Rdword
.Header
.Header
.Bits
.Name
=
771 ACPI_LARGE_WORD_ADDRESS_SPACE_DESCRIPTOR_NAME
;
772 Rdword
.Header
.Header
.Bits
.Type
= ACPI_LARGE_ITEM_FLAG
;
773 Rdword
.Header
.Length
= sizeof (EFI_ACPI_WORD_ADDRESS_SPACE_DESCRIPTOR
) -
774 sizeof (ACPI_LARGE_RESOURCE_HEADER
);
777 Rdword
.ResType
= ResourceType
;
778 Rdword
.GenFlag
= AddressSpaceGeneralFlags (
783 Rdword
.SpecificFlag
= TypeSpecificFlags
;
784 Rdword
.AddrSpaceGranularity
= AddressGranularity
;
785 Rdword
.AddrRangeMin
= AddressMinimum
;
786 Rdword
.AddrRangeMax
= AddressMaximum
;
787 Rdword
.AddrTranslationOffset
= AddressTranslation
;
788 Rdword
.AddrLen
= RangeLength
;
790 Status
= AmlCreateDataNode (
791 EAmlNodeDataTypeResourceData
,
793 sizeof (EFI_ACPI_WORD_ADDRESS_SPACE_DESCRIPTOR
),
796 if (EFI_ERROR (Status
)) {
801 return LinkRdNode (RdNode
, NameOpNode
, NewRdNode
);
804 /** Code generation for the "WordBusNumber ()" ASL function.
806 The Resource Data effectively created is a Word Address Space Resource
808 - s6.4.3.5.3 "Word Address Space Descriptor".
809 - s19.6.149 "WordBusNumber".
811 The created resource data node can be:
812 - appended to the list of resource data elements of the NameOpNode.
813 In such case NameOpNode must be defined by a the "Name ()" ASL statement
814 and initially contain a "ResourceTemplate ()".
815 - returned through the NewRdNode parameter.
817 See ACPI 6.4 spec, s19.6.149 for more.
819 @param [in] IsResourceConsumer ResourceUsage parameter.
820 @param [in] IsMinFixed Minimum address is fixed.
821 @param [in] IsMaxFixed Maximum address is fixed.
822 @param [in] IsPosDecode Decode parameter
823 @param [in] AddressGranularity Address granularity.
824 @param [in] AddressMinimum Minimum address.
825 @param [in] AddressMaximum Maximum address.
826 @param [in] AddressTranslation Address translation.
827 @param [in] RangeLength Range length.
828 @param [in] ResourceSourceIndex Resource Source index.
830 @param [in] ResourceSource Resource Source.
831 Unused. Must be NULL.
832 @param [in] NameOpNode NameOp object node defining a named object.
833 If provided, append the new resource data
834 node to the list of resource data elements
836 @param [out] NewRdNode If provided and success,
837 contain the created node.
839 @retval EFI_SUCCESS The function completed successfully.
840 @retval EFI_INVALID_PARAMETER Invalid parameter.
841 @retval EFI_OUT_OF_RESOURCES Could not allocate memory.
845 AmlCodeGenRdWordBusNumber (
846 IN BOOLEAN IsResourceConsumer
,
847 IN BOOLEAN IsMinFixed
,
848 IN BOOLEAN IsMaxFixed
,
849 IN BOOLEAN IsPosDecode
,
850 IN UINT32 AddressGranularity
,
851 IN UINT32 AddressMinimum
,
852 IN UINT32 AddressMaximum
,
853 IN UINT32 AddressTranslation
,
854 IN UINT32 RangeLength
,
855 IN UINT8 ResourceSourceIndex
,
856 IN CONST CHAR8
*ResourceSource
,
857 IN AML_OBJECT_NODE_HANDLE NameOpNode
, OPTIONAL
858 OUT AML_DATA_NODE_HANDLE
*NewRdNode OPTIONAL
861 // There is no Type Specific Flags for buses.
862 return AmlCodeGenRdWordSpace (
863 ACPI_ADDRESS_SPACE_TYPE_BUS
,
881 /** Code generation for the "QWordSpace ()" ASL function.
883 The Resource Data effectively created is a QWord Address Space Resource
885 - s6.4.3.5.1 "QWord Address Space Descriptor".
886 - s19.6.111 "QWordSpace".
888 The created resource data node can be:
889 - appended to the list of resource data elements of the NameOpNode.
890 In such case NameOpNode must be defined by a the "Name ()" ASL statement
891 and initially contain a "ResourceTemplate ()".
892 - returned through the NewRdNode parameter.
894 See ACPI 6.4 spec, s19.6.111 for more.
896 @param [in] ResourceType Resource type.
902 192-255: Hardware Vendor Defined
903 See ACPI 6.4 spec, s6.4.3.5.1 for more.
904 @param [in] IsResourceConsumer ResourceUsage parameter.
905 @param [in] IsPosDecode Decode parameter
906 @param [in] IsMinFixed Minimum address is fixed.
907 @param [in] IsMaxFixed Maximum address is fixed.
908 @param [in] TypeSpecificFlags Type specific flags.
909 See ACPI 6.4 spec, s6.4.3.5.5
910 "Resource Type Specific Flags".
911 @param [in] AddressGranularity Address granularity.
912 @param [in] AddressMinimum Minimum address.
913 @param [in] AddressMaximum Maximum address.
914 @param [in] AddressTranslation Address translation.
915 @param [in] RangeLength Range length.
916 @param [in] ResourceSourceIndex Resource Source index.
918 @param [in] ResourceSource Resource Source.
919 Unused. Must be NULL.
920 @param [in] NameOpNode NameOp object node defining a named object.
921 If provided, append the new resource data
922 node to the list of resource data elements
924 @param [out] NewRdNode If provided and success,
925 contain the created node.
927 @retval EFI_SUCCESS The function completed successfully.
928 @retval EFI_INVALID_PARAMETER Invalid parameter.
929 @retval EFI_OUT_OF_RESOURCES Could not allocate memory.
934 AmlCodeGenRdQWordSpace (
935 IN UINT8 ResourceType
,
936 IN BOOLEAN IsResourceConsumer
,
937 IN BOOLEAN IsPosDecode
,
938 IN BOOLEAN IsMinFixed
,
939 IN BOOLEAN IsMaxFixed
,
940 IN UINT8 TypeSpecificFlags
,
941 IN UINT64 AddressGranularity
,
942 IN UINT64 AddressMinimum
,
943 IN UINT64 AddressMaximum
,
944 IN UINT64 AddressTranslation
,
945 IN UINT64 RangeLength
,
946 IN UINT8 ResourceSourceIndex
,
947 IN CONST CHAR8
*ResourceSource
,
948 IN AML_OBJECT_NODE_HANDLE NameOpNode
, OPTIONAL
949 OUT AML_DATA_NODE_HANDLE
*NewRdNode OPTIONAL
953 AML_DATA_NODE
*RdNode
;
954 EFI_ACPI_QWORD_ADDRESS_SPACE_DESCRIPTOR RdQword
;
956 // ResourceSource and ResourceSourceIndex are unused.
957 if ((TypeSpecificFlags
== MAX_UINT8
) ||
958 (ResourceSourceIndex
!= 0) ||
959 (ResourceSource
!= NULL
) ||
960 ((NameOpNode
== NULL
) && (NewRdNode
== NULL
)))
963 return EFI_INVALID_PARAMETER
;
966 Status
= CheckAddressSpaceFields (
975 if (EFI_ERROR (Status
)) {
981 RdQword
.Header
.Header
.Bits
.Name
=
982 ACPI_LARGE_QWORD_ADDRESS_SPACE_DESCRIPTOR_NAME
;
983 RdQword
.Header
.Header
.Bits
.Type
= ACPI_LARGE_ITEM_FLAG
;
984 RdQword
.Header
.Length
= sizeof (EFI_ACPI_QWORD_ADDRESS_SPACE_DESCRIPTOR
) -
985 sizeof (ACPI_LARGE_RESOURCE_HEADER
);
988 RdQword
.ResType
= ResourceType
;
989 RdQword
.GenFlag
= AddressSpaceGeneralFlags (
994 RdQword
.SpecificFlag
= TypeSpecificFlags
;
995 RdQword
.AddrSpaceGranularity
= AddressGranularity
;
996 RdQword
.AddrRangeMin
= AddressMinimum
;
997 RdQword
.AddrRangeMax
= AddressMaximum
;
998 RdQword
.AddrTranslationOffset
= AddressTranslation
;
999 RdQword
.AddrLen
= RangeLength
;
1001 Status
= AmlCreateDataNode (
1002 EAmlNodeDataTypeResourceData
,
1004 sizeof (EFI_ACPI_QWORD_ADDRESS_SPACE_DESCRIPTOR
),
1007 if (EFI_ERROR (Status
)) {
1012 return LinkRdNode (RdNode
, NameOpNode
, NewRdNode
);
1015 /** Code generation for the "QWordMemory ()" ASL function.
1017 The Resource Data effectively created is a QWord Address Space Resource
1019 - s6.4.3.5.1 "QWord Address Space Descriptor".
1020 - s19.6.110 "QWordMemory".
1022 The created resource data node can be:
1023 - appended to the list of resource data elements of the NameOpNode.
1024 In such case NameOpNode must be defined by a the "Name ()" ASL statement
1025 and initially contain a "ResourceTemplate ()".
1026 - returned through the NewRdNode parameter.
1028 See ACPI 6.4 spec, s19.6.110 for more.
1030 @param [in] IsResourceConsumer ResourceUsage parameter.
1031 @param [in] IsPosDecode Decode parameter.
1032 @param [in] IsMinFixed Minimum address is fixed.
1033 @param [in] IsMaxFixed Maximum address is fixed.
1034 @param [in] Cacheable Possible values are:
1035 0-The memory is non-cacheable
1036 1-The memory is cacheable
1037 2-The memory is cacheable and supports
1039 3-The memory is cacheable and prefetchable
1040 @param [in] IsReadWrite ReadAndWrite parameter.
1041 @param [in] AddressGranularity Address granularity.
1042 @param [in] AddressMinimum Minimum address.
1043 @param [in] AddressMaximum Maximum address.
1044 @param [in] AddressTranslation Address translation.
1045 @param [in] RangeLength Range length.
1046 @param [in] ResourceSourceIndex Resource Source index.
1048 @param [in] ResourceSource Resource Source.
1049 Unused. Must be NULL.
1050 @param [in] MemoryRangeType Possible values are:
1051 0-AddressRangeMemory
1052 1-AddressRangeReserved
1055 @param [in] IsTypeStatic TranslationType parameter.
1056 @param [in] NameOpNode NameOp object node defining a named object.
1057 If provided, append the new resource data
1058 node to the list of resource data elements
1060 @param [out] NewRdNode If provided and success,
1061 contain the created node.
1063 @retval EFI_SUCCESS The function completed successfully.
1064 @retval EFI_INVALID_PARAMETER Invalid parameter.
1065 @retval EFI_OUT_OF_RESOURCES Could not allocate memory.
1069 AmlCodeGenRdQWordMemory (
1070 IN BOOLEAN IsResourceConsumer
,
1071 IN BOOLEAN IsPosDecode
,
1072 IN BOOLEAN IsMinFixed
,
1073 IN BOOLEAN IsMaxFixed
,
1075 IN BOOLEAN IsReadWrite
,
1076 IN UINT64 AddressGranularity
,
1077 IN UINT64 AddressMinimum
,
1078 IN UINT64 AddressMaximum
,
1079 IN UINT64 AddressTranslation
,
1080 IN UINT64 RangeLength
,
1081 IN UINT8 ResourceSourceIndex
,
1082 IN CONST CHAR8
*ResourceSource
,
1083 IN UINT8 MemoryRangeType
,
1084 IN BOOLEAN IsTypeStatic
,
1085 IN AML_OBJECT_NODE_HANDLE NameOpNode
, OPTIONAL
1086 OUT AML_DATA_NODE_HANDLE
*NewRdNode OPTIONAL
1089 return AmlCodeGenRdQWordSpace (
1090 ACPI_ADDRESS_SPACE_TYPE_MEM
,
1095 MemoryRangeSpecificFlags (
1106 ResourceSourceIndex
,
1113 /** Code generation for the "Interrupt ()" ASL function.
1115 The Resource Data effectively created is an Extended Interrupt Resource
1117 - s6.4.3.6 "Extended Interrupt Descriptor"
1118 - s19.6.64 "Interrupt (Interrupt Resource Descriptor Macro)"
1120 The created resource data node can be:
1121 - appended to the list of resource data elements of the NameOpNode.
1122 In such case NameOpNode must be defined by a the "Name ()" ASL statement
1123 and initially contain a "ResourceTemplate ()".
1124 - returned through the NewRdNode parameter.
1126 @param [in] ResourceConsumer The device consumes the specified interrupt
1127 or produces it for use by a child device.
1128 @param [in] EdgeTriggered The interrupt is edge triggered or
1130 @param [in] ActiveLow The interrupt is active-high or active-low.
1131 @param [in] Shared The interrupt can be shared with other
1132 devices or not (Exclusive).
1133 @param [in] IrqList Interrupt list. Must be non-NULL.
1134 @param [in] IrqCount Interrupt count. Must be non-zero.
1135 @param [in] NameOpNode NameOp object node defining a named object.
1136 If provided, append the new resource data node
1137 to the list of resource data elements of this
1139 @param [out] NewRdNode If provided and success,
1140 contain the created node.
1142 @retval EFI_SUCCESS The function completed successfully.
1143 @retval EFI_INVALID_PARAMETER Invalid parameter.
1144 @retval EFI_OUT_OF_RESOURCES Could not allocate memory.
1148 AmlCodeGenRdInterrupt (
1149 IN BOOLEAN ResourceConsumer
,
1150 IN BOOLEAN EdgeTriggered
,
1151 IN BOOLEAN ActiveLow
,
1155 IN AML_OBJECT_NODE_HANDLE NameOpNode OPTIONAL
,
1156 OUT AML_DATA_NODE_HANDLE
*NewRdNode OPTIONAL
1161 AML_DATA_NODE
*RdNode
;
1162 EFI_ACPI_EXTENDED_INTERRUPT_DESCRIPTOR RdInterrupt
;
1163 UINT32
*FirstInterrupt
;
1165 if ((IrqList
== NULL
) ||
1167 ((NameOpNode
== NULL
) && (NewRdNode
== NULL
)))
1170 return EFI_INVALID_PARAMETER
;
1174 RdInterrupt
.Header
.Header
.Bits
.Name
=
1175 ACPI_LARGE_EXTENDED_IRQ_DESCRIPTOR_NAME
;
1176 RdInterrupt
.Header
.Header
.Bits
.Type
= ACPI_LARGE_ITEM_FLAG
;
1177 RdInterrupt
.Header
.Length
= sizeof (EFI_ACPI_EXTENDED_INTERRUPT_DESCRIPTOR
) -
1178 sizeof (ACPI_LARGE_RESOURCE_HEADER
);
1181 RdInterrupt
.InterruptVectorFlags
= (ResourceConsumer
? BIT0
: 0) |
1182 (EdgeTriggered
? BIT1
: 0) |
1183 (ActiveLow
? BIT2
: 0) |
1184 (Shared
? BIT3
: 0);
1185 RdInterrupt
.InterruptTableLength
= IrqCount
;
1187 // Get the address of the first interrupt field.
1188 FirstInterrupt
= RdInterrupt
.InterruptNumber
;
1190 // Copy the list of interrupts.
1191 CopyMem (FirstInterrupt
, IrqList
, (sizeof (UINT32
) * IrqCount
));
1193 Status
= AmlCreateDataNode (
1194 EAmlNodeDataTypeResourceData
,
1195 (UINT8
*)&RdInterrupt
,
1196 sizeof (EFI_ACPI_EXTENDED_INTERRUPT_DESCRIPTOR
),
1199 if (EFI_ERROR (Status
)) {
1204 return LinkRdNode (RdNode
, NameOpNode
, NewRdNode
);
1207 /** Code generation for the "Register ()" ASL function.
1209 The Resource Data effectively created is a Generic Register Descriptor.
1211 - s6.4.3.7 "Generic Register Descriptor".
1212 - s19.6.114 "Register".
1214 The created resource data node can be:
1215 - appended to the list of resource data elements of the NameOpNode.
1216 In such case NameOpNode must be defined by a the "Name ()" ASL statement
1217 and initially contain a "ResourceTemplate ()".
1218 - returned through the NewRdNode parameter.
1220 @param [in] AddressSpace Address space where the register exists.
1221 Can be one of I/O space, System Memory, etc.
1222 @param [in] BitWidth Number of bits in the register.
1223 @param [in] BitOffset Offset in bits from the start of the register
1224 indicated by the Address.
1225 @param [in] Address Register address.
1226 @param [in] AccessSize Size of data values used when accessing the
1227 address space. Can be one of:
1228 0 - Undefined, legacy (EFI_ACPI_6_4_UNDEFINED)
1229 1 - Byte access (EFI_ACPI_6_4_BYTE)
1230 2 - Word access (EFI_ACPI_6_4_WORD)
1231 3 - DWord access (EFI_ACPI_6_4_DWORD)
1232 4 - QWord access (EFI_ACPI_6_4_QWORD)
1233 @param [in] NameOpNode NameOp object node defining a named object.
1234 If provided, append the new resource data node
1235 to the list of resource data elements of this
1237 @param [out] NewRdNode If provided and success,
1238 contain the created node.
1240 @retval EFI_SUCCESS The function completed successfully.
1241 @retval EFI_INVALID_PARAMETER Invalid parameter.
1242 @retval EFI_OUT_OF_RESOURCES Could not allocate memory.
1246 AmlCodeGenRdRegister (
1247 IN UINT8 AddressSpace
,
1251 IN UINT8 AccessSize
,
1252 IN AML_OBJECT_NODE_HANDLE NameOpNode OPTIONAL
,
1253 OUT AML_DATA_NODE_HANDLE
*NewRdNode OPTIONAL
1257 AML_DATA_NODE
*RdNode
;
1258 EFI_ACPI_GENERIC_REGISTER_DESCRIPTOR RdRegister
;
1260 // Cf. ACPI 6.4, s14.7 Referencing the PCC address space
1261 // The AccessSize represents the Subspace Id for the PCC address space.
1262 if (((AddressSpace
== EFI_ACPI_6_4_PLATFORM_COMMUNICATION_CHANNEL
) &&
1263 (AccessSize
> 256)) ||
1264 ((AddressSpace
!= EFI_ACPI_6_4_PLATFORM_COMMUNICATION_CHANNEL
) &&
1265 (AccessSize
> EFI_ACPI_6_4_QWORD
)) ||
1266 ((NameOpNode
== NULL
) && (NewRdNode
== NULL
)))
1269 return EFI_INVALID_PARAMETER
;
1273 RdRegister
.Header
.Header
.Bits
.Name
=
1274 ACPI_LARGE_GENERIC_REGISTER_DESCRIPTOR_NAME
;
1275 RdRegister
.Header
.Header
.Bits
.Type
= ACPI_LARGE_ITEM_FLAG
;
1276 RdRegister
.Header
.Length
= sizeof (EFI_ACPI_GENERIC_REGISTER_DESCRIPTOR
) -
1277 sizeof (ACPI_LARGE_RESOURCE_HEADER
);
1280 RdRegister
.AddressSpaceId
= AddressSpace
;
1281 RdRegister
.RegisterBitWidth
= BitWidth
;
1282 RdRegister
.RegisterBitOffset
= BitOffset
;
1283 RdRegister
.AddressSize
= AccessSize
;
1284 RdRegister
.RegisterAddress
= Address
;
1286 Status
= AmlCreateDataNode (
1287 EAmlNodeDataTypeResourceData
,
1288 (UINT8
*)&RdRegister
,
1289 sizeof (EFI_ACPI_GENERIC_REGISTER_DESCRIPTOR
),
1292 if (EFI_ERROR (Status
)) {
1297 return LinkRdNode (RdNode
, NameOpNode
, NewRdNode
);
1300 /** Code generation for the EndTag resource data.
1302 The EndTag resource data is automatically generated by the ASL compiler
1303 at the end of a list of resource data elements. Thus, it doesn't have
1304 a corresponding ASL function.
1306 This function allocates memory to create a data node. It is the caller's
1307 responsibility to either:
1308 - attach this node to an AML tree;
1311 ACPI 6.4, s6.4.2.9 "End Tag":
1312 "This checksum is generated such that adding it to the sum of all the data
1313 bytes will produce a zero sum."
1314 "If the checksum field is zero, the resource data is treated as if the
1315 checksum operation succeeded. Configuration proceeds normally."
1317 To avoid re-computing checksums, if a new resource data elements is
1318 added/removed/modified in a list of resource data elements, the AmlLib
1319 resets the checksum to 0.
1321 @param [in] CheckSum CheckSum to store in the EndTag.
1322 To ignore/avoid computing the checksum,
1324 @param [in] ParentNode If not NULL, add the generated node
1325 to the end of the variable list of
1326 argument of the ParentNode.
1327 The ParentNode must not initially contain
1328 an EndTag resource data element.
1329 @param [out] NewRdNode If success, contains the generated node.
1331 @retval EFI_SUCCESS The function completed successfully.
1332 @retval EFI_INVALID_PARAMETER Invalid parameter.
1333 @retval EFI_OUT_OF_RESOURCES Could not allocate memory.
1338 IN UINT8 CheckSum OPTIONAL
,
1339 IN AML_OBJECT_NODE
*ParentNode OPTIONAL
,
1340 OUT AML_DATA_NODE
**NewRdNode OPTIONAL
1344 AML_DATA_NODE
*RdNode
;
1345 EFI_ACPI_END_TAG_DESCRIPTOR EndTag
;
1346 ACPI_SMALL_RESOURCE_HEADER SmallResHdr
;
1348 if ((ParentNode
== NULL
) && (NewRdNode
== NULL
)) {
1350 return EFI_INVALID_PARAMETER
;
1356 SmallResHdr
.Bits
.Length
= sizeof (EFI_ACPI_END_TAG_DESCRIPTOR
) -
1357 sizeof (ACPI_SMALL_RESOURCE_HEADER
);
1358 SmallResHdr
.Bits
.Name
= ACPI_SMALL_END_TAG_DESCRIPTOR_NAME
;
1359 SmallResHdr
.Bits
.Type
= ACPI_SMALL_ITEM_FLAG
;
1362 EndTag
.Desc
= SmallResHdr
.Byte
;
1363 EndTag
.Checksum
= CheckSum
;
1365 Status
= AmlCreateDataNode (
1366 EAmlNodeDataTypeResourceData
,
1368 sizeof (EFI_ACPI_END_TAG_DESCRIPTOR
),
1371 if (EFI_ERROR (Status
)) {
1376 if (NewRdNode
!= NULL
) {
1377 *NewRdNode
= RdNode
;
1380 if (ParentNode
!= NULL
) {
1381 // Check the BufferOp doesn't contain any resource data yet.
1382 // This is a hard check: do not allow to add an EndTag if the BufferNode
1383 // already has resource data elements attached. Indeed, the EndTag should
1384 // have already been added.
1385 if (AmlGetNextVariableArgument ((AML_NODE_HEADER
*)ParentNode
, NULL
) !=
1389 Status
= EFI_INVALID_PARAMETER
;
1393 // Add the EndTag RdNode. Indeed, the AmlAppendRdNode function
1394 // is looking for an EndTag, which we are adding here.
1395 Status
= AmlVarListAddTail (
1396 (AML_NODE_HEADER
*)ParentNode
,
1397 (AML_NODE_HEADER
*)RdNode
1399 if (EFI_ERROR (Status
)) {
1408 if (RdNode
!= NULL
) {
1409 AmlDeleteTree ((AML_NODE_HEADER
*)RdNode
);