For Pcc address space, the AccessSize field of a Register is used to delcare the Pcc Subspace Id. This Id can be up to 256. Cf. ACPI 6.4, s14.7 Referencing the PCC address space Signed-off-by: Pierre Gondois <Pierre.Gondois@arm.com> Reviewed-by: Sami Mujawar <sami.mujawar@arm.com>
		
			
				
	
	
		
			1414 lines
		
	
	
		
			52 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			1414 lines
		
	
	
		
			52 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /** @file
 | |
|   AML Resource Data Code Generation.
 | |
| 
 | |
|   Copyright (c) 2020 - 2021, Arm Limited. All rights reserved.<BR>
 | |
| 
 | |
|   SPDX-License-Identifier: BSD-2-Clause-Patent
 | |
| 
 | |
|   @par Glossary:
 | |
|   - Rd or RD   - Resource Data
 | |
|   - Rds or RDS - Resource Data Small
 | |
|   - Rdl or RDL - Resource Data Large
 | |
| **/
 | |
| 
 | |
| #include <AmlNodeDefines.h>
 | |
| #include <CodeGen/AmlResourceDataCodeGen.h>
 | |
| 
 | |
| #include <AmlCoreInterface.h>
 | |
| #include <AmlDefines.h>
 | |
| #include <Api/AmlApiHelper.h>
 | |
| #include <Tree/AmlNode.h>
 | |
| #include <ResourceData/AmlResourceData.h>
 | |
| 
 | |
| /** If ParentNode is not NULL, append RdNode.
 | |
|     If NewRdNode is not NULL, update its value to RdNode.
 | |
| 
 | |
|   @param [in]  RdNode       Newly created Resource Data node.
 | |
|                             RdNode is deleted if an error occurs.
 | |
|   @param [in]  ParentNode   If not NULL, ParentNode must:
 | |
|                              - be a NameOp node, i.e. have the AML_NAME_OP
 | |
|                                opcode (cf "Name ()" ASL statement)
 | |
|                              - contain a list of resource data elements
 | |
|                                (cf "ResourceTemplate ()" ASL statement)
 | |
|                             RdNode is then added at the end of the variable
 | |
|                             list of resource data elements, but before the
 | |
|                             "End Tag" Resource Data.
 | |
|   @param [out] NewRdNode    If not NULL:
 | |
|                              - and Success, contains RdNode.
 | |
|                              - and Error, reset to NULL.
 | |
| 
 | |
|   @retval  EFI_SUCCESS            The function completed successfully.
 | |
|   @retval  EFI_INVALID_PARAMETER  Invalid parameter.
 | |
| **/
 | |
| STATIC
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| LinkRdNode (
 | |
|   IN  AML_DATA_NODE    *RdNode,
 | |
|   IN  AML_OBJECT_NODE  *ParentNode,
 | |
|   OUT AML_DATA_NODE    **NewRdNode
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS       Status;
 | |
|   EFI_STATUS       Status1;
 | |
|   AML_OBJECT_NODE  *BufferOpNode;
 | |
| 
 | |
|   if (NewRdNode != NULL) {
 | |
|     *NewRdNode = NULL;
 | |
|   }
 | |
| 
 | |
|   if (ParentNode != NULL) {
 | |
|     // Check this is a NameOp node.
 | |
|     if ((!AmlNodeHasOpCode (ParentNode, AML_NAME_OP, 0))) {
 | |
|       ASSERT (0);
 | |
|       Status = EFI_INVALID_PARAMETER;
 | |
|       goto error_handler;
 | |
|     }
 | |
| 
 | |
|     // Get the value which is represented as a BufferOp object node
 | |
|     // which is the 2nd fixed argument (i.e. index 1).
 | |
|     BufferOpNode = (AML_OBJECT_NODE_HANDLE)AmlGetFixedArgument (
 | |
|                                              ParentNode,
 | |
|                                              EAmlParseIndexTerm1
 | |
|                                              );
 | |
|     if ((BufferOpNode == NULL)                                             ||
 | |
|         (AmlGetNodeType ((AML_NODE_HANDLE)BufferOpNode) != EAmlNodeObject) ||
 | |
|         (!AmlNodeHasOpCode (BufferOpNode, AML_BUFFER_OP, 0)))
 | |
|     {
 | |
|       ASSERT (0);
 | |
|       Status = EFI_INVALID_PARAMETER;
 | |
|       goto error_handler;
 | |
|     }
 | |
| 
 | |
|     // Add RdNode as the last element, but before the EndTag.
 | |
|     Status = AmlAppendRdNode (BufferOpNode, RdNode);
 | |
|     if (EFI_ERROR (Status)) {
 | |
|       ASSERT (0);
 | |
|       goto error_handler;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   if (NewRdNode != NULL) {
 | |
|     *NewRdNode = RdNode;
 | |
|   }
 | |
| 
 | |
|   return EFI_SUCCESS;
 | |
| 
 | |
| error_handler:
 | |
|   Status1 = AmlDeleteTree ((AML_NODE_HEADER *)RdNode);
 | |
|   ASSERT_EFI_ERROR (Status1);
 | |
|   // Return original error.
 | |
|   return Status;
 | |
| }
 | |
| 
 | |
| /** Construct the TypeSpecificFlags field for IO ranges.
 | |
| 
 | |
|   See ACPI 6.4 spec, s19.6.34 for more.
 | |
| 
 | |
|   @param [in]  IsaRanges            Possible values are:
 | |
|                                      0-Reserved
 | |
|                                      1-NonISAOnly
 | |
|                                      2-ISAOnly
 | |
|                                      3-EntireRange
 | |
|                                     See ACPI 6.4 spec, s19.6.34 for more.
 | |
|   @param [in]  IsDenseTranslation   TranslationDensity parameter.
 | |
|   @param [in]  IsTypeStatic         TranslationType parameter.
 | |
| 
 | |
|   @return A type specific flags value.
 | |
|           MAX_UINT8 if error.
 | |
| **/
 | |
| STATIC
 | |
| UINT8
 | |
| EFIAPI
 | |
| RdIoRangeSpecificFlags (
 | |
|   IN  UINT8    IsaRanges,
 | |
|   IN  BOOLEAN  IsDenseTranslation,
 | |
|   IN  BOOLEAN  IsTypeStatic
 | |
|   )
 | |
| {
 | |
|   // Only check type specific parameters.
 | |
|   if (IsaRanges > 3) {
 | |
|     ASSERT (0);
 | |
|     return MAX_UINT8;
 | |
|   }
 | |
| 
 | |
|   // Construct TypeSpecificFlags and call the generic function.
 | |
|   // Cf ACPI 6.4 specification, Table 6.50:
 | |
|   // "Table 6.50: I/O Resource Flag (Resource Type = 1) Definitions"
 | |
|   return IsaRanges                 |
 | |
|          (IsTypeStatic ? 0 : BIT4) |
 | |
|          (IsDenseTranslation ? 0 : BIT5);
 | |
| }
 | |
| 
 | |
| /** Construct the TypeSpecificFlags field for Memory ranges.
 | |
| 
 | |
|   @param [in]  Cacheable            Possible values are:
 | |
|                                     0-The memory is non-cacheable
 | |
|                                     1-The memory is cacheable
 | |
|                                     2-The memory is cacheable and supports
 | |
|                                       write combining
 | |
|                                     3-The memory is cacheable and prefetchable
 | |
|   @param [in]  IsReadWrite          ReadAndWrite parameter.
 | |
|   @param [in]  MemoryRangeType      Possible values are:
 | |
|                                       0-AddressRangeMemory
 | |
|                                       1-AddressRangeReserved
 | |
|                                       2-AddressRangeACPI
 | |
|                                       3-AddressRangeNVS
 | |
|                                     See ACPI 6.4 spec, s19.6.35 for more.
 | |
|   @param [in]  IsTypeStatic         TranslationType parameter.
 | |
| 
 | |
|   @return A type specific flags value.
 | |
|           MAX_UINT8 if error.
 | |
| **/
 | |
| STATIC
 | |
| UINT8
 | |
| EFIAPI
 | |
| MemoryRangeSpecificFlags (
 | |
|   IN  UINT8    Cacheable,
 | |
|   IN  BOOLEAN  IsReadWrite,
 | |
|   IN  UINT8    MemoryRangeType,
 | |
|   IN  BOOLEAN  IsTypeStatic
 | |
|   )
 | |
| {
 | |
|   // Only check type specific parameters.
 | |
|   if ((Cacheable > 3) ||
 | |
|       (MemoryRangeType > 3))
 | |
|   {
 | |
|     ASSERT (0);
 | |
|     return MAX_UINT8;
 | |
|   }
 | |
| 
 | |
|   // Construct TypeSpecificFlags and call the generic function.
 | |
|   // Cf ACPI 6.4 specification, Table 6.49:
 | |
|   // "Memory Resource Flag (Resource Type = 0) Definitions"
 | |
|   return (IsReadWrite ? BIT0 : 0)  |
 | |
|          (Cacheable << 1)          |
 | |
|          (MemoryRangeType << 3)    |
 | |
|          (IsTypeStatic ? 0 : BIT5);
 | |
| }
 | |
| 
 | |
| /** Construct the GeneralFlags field of any Address Space Resource Descriptors.
 | |
| 
 | |
|   E.g.:
 | |
|   ACPI 6.4 specification, s6.4.3.5.1 "QWord Address Space Descriptor"
 | |
|   for QWord
 | |
| 
 | |
|   See ACPI 6.4 spec, s19.6.36 for more.
 | |
| 
 | |
|   @param [in]  IsPosDecode          Decode parameter
 | |
|   @param [in]  IsMinFixed           Minimum address is fixed.
 | |
|   @param [in]  IsMaxFixed           Maximum address is fixed.
 | |
| 
 | |
|   @return A type specific flags value.
 | |
| **/
 | |
| STATIC
 | |
| UINT8
 | |
| EFIAPI
 | |
| AddressSpaceGeneralFlags (
 | |
|   IN  BOOLEAN  IsPosDecode,
 | |
|   IN  BOOLEAN  IsMinFixed,
 | |
|   IN  BOOLEAN  IsMaxFixed
 | |
|   )
 | |
| {
 | |
|   return (IsPosDecode ? 0 : BIT1)    |
 | |
|          (IsMinFixed ? BIT2 : 0)     |
 | |
|          (IsMaxFixed ? BIT3 : 0);
 | |
| }
 | |
| 
 | |
| /** Check Address Space Descriptor Fields.
 | |
| 
 | |
|   Cf. ACPI 6.4 Table 6.44:
 | |
|   "Valid Combination of Address Space Descriptor Fields"
 | |
| 
 | |
|   See ACPI 6.4 spec, s19.6.36 for more.
 | |
| 
 | |
|   @param [in]  IsMinFixed           Minimum address is fixed.
 | |
|   @param [in]  IsMaxFixed           Maximum address is fixed.
 | |
|   @param [in]  AddressGranularity   Address granularity.
 | |
|   @param [in]  AddressMinimum       Minimum address.
 | |
|   @param [in]  AddressMaximum       Maximum address.
 | |
|   @param [in]  AddressTranslation   Address translation.
 | |
|   @param [in]  RangeLength          Range length.
 | |
| 
 | |
|   @retval EFI_SUCCESS             The function completed successfully.
 | |
|   @retval EFI_INVALID_PARAMETER   Invalid parameter.
 | |
| **/
 | |
| STATIC
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| CheckAddressSpaceFields (
 | |
|   IN  BOOLEAN  IsMinFixed,
 | |
|   IN  BOOLEAN  IsMaxFixed,
 | |
|   IN  UINT64   AddressGranularity,
 | |
|   IN  UINT64   AddressMinimum,
 | |
|   IN  UINT64   AddressMaximum,
 | |
|   IN  UINT64   AddressTranslation,
 | |
|   IN  UINT64   RangeLength
 | |
|   )
 | |
| {
 | |
|   if ((AddressMinimum > AddressMaximum)                     ||
 | |
|       (RangeLength > (AddressMaximum - AddressMinimum + 1)) ||
 | |
|       ((AddressGranularity != 0) &&
 | |
|        (((AddressGranularity + 1) & AddressGranularity) != 0)))
 | |
|   {
 | |
|     ASSERT (0);
 | |
|     return EFI_INVALID_PARAMETER;
 | |
|   }
 | |
| 
 | |
|   if (RangeLength != 0) {
 | |
|     if (IsMinFixed ^ IsMaxFixed) {
 | |
|       ASSERT (0);
 | |
|       return EFI_INVALID_PARAMETER;
 | |
|     } else if (IsMinFixed                 &&
 | |
|                IsMaxFixed                 &&
 | |
|                (AddressGranularity != 0)  &&
 | |
|                ((AddressMaximum - AddressMinimum + 1) != RangeLength))
 | |
|     {
 | |
|       ASSERT (0);
 | |
|       return EFI_INVALID_PARAMETER;
 | |
|     }
 | |
|   } else {
 | |
|     if (IsMinFixed && IsMaxFixed) {
 | |
|       ASSERT (0);
 | |
|       return EFI_INVALID_PARAMETER;
 | |
|     } else if (IsMinFixed &&
 | |
|                ((AddressMinimum & AddressGranularity) != 0))
 | |
|     {
 | |
|       ASSERT (0);
 | |
|       return EFI_INVALID_PARAMETER;
 | |
|     } else if (IsMaxFixed &&
 | |
|                (((AddressMaximum + 1) & AddressGranularity) != 0))
 | |
|     {
 | |
|       ASSERT (0);
 | |
|       return EFI_INVALID_PARAMETER;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   return EFI_SUCCESS;
 | |
| }
 | |
| 
 | |
| /** Code generation for the "DWordSpace ()" ASL function.
 | |
| 
 | |
|   The Resource Data effectively created is a DWord Address Space Resource
 | |
|   Data. Cf ACPI 6.4:
 | |
|    - s6.4.3.5.2 "DWord Address Space Descriptor".
 | |
|    - s19.6.36 "DWordSpace".
 | |
| 
 | |
|   The created resource data node can be:
 | |
|    - appended to the list of resource data elements of the NameOpNode.
 | |
|      In such case NameOpNode must be defined by a the "Name ()" ASL statement
 | |
|      and initially contain a "ResourceTemplate ()".
 | |
|    - returned through the NewRdNode parameter.
 | |
| 
 | |
|   See ACPI 6.4 spec, s19.6.36 for more.
 | |
| 
 | |
|   @param [in]  ResourceType         Resource type.
 | |
|                                     Possible values are:
 | |
|                                       0:        Memory range
 | |
|                                       1:        I/O range
 | |
|                                       2:        Bus number range
 | |
|                                       3-191:    Reserved
 | |
|                                       192-255:  Hardware Vendor Defined
 | |
|                                     See ACPI 6.4 spec, s6.4.3.5.2 for more.
 | |
|   @param [in]  IsResourceConsumer   ResourceUsage parameter.
 | |
|   @param [in]  IsPosDecode          Decode parameter
 | |
|   @param [in]  IsMinFixed           Minimum address is fixed.
 | |
|   @param [in]  IsMaxFixed           Maximum address is fixed.
 | |
|   @param [in]  TypeSpecificFlags    Type specific flags.
 | |
|                                     See ACPI 6.4 spec, s6.4.3.5.5
 | |
|                                     "Resource Type Specific Flags".
 | |
|   @param [in]  AddressGranularity   Address granularity.
 | |
|   @param [in]  AddressMinimum       Minimum address.
 | |
|   @param [in]  AddressMaximum       Maximum address.
 | |
|   @param [in]  AddressTranslation   Address translation.
 | |
|   @param [in]  RangeLength          Range length.
 | |
|   @param [in]  ResourceSourceIndex  Resource Source index.
 | |
|                                     Unused. Must be 0.
 | |
|   @param [in]  ResourceSource       Resource Source.
 | |
|                                     Unused. Must be NULL.
 | |
|   @param [in]  NameOpNode           NameOp object node defining a named object.
 | |
|                                     If provided, append the new resource data
 | |
|                                     node to the list of resource data elements
 | |
|                                     of this node.
 | |
|   @param [out] NewRdNode            If provided and success,
 | |
|                                     contain the created node.
 | |
| 
 | |
|   @retval EFI_SUCCESS             The function completed successfully.
 | |
|   @retval EFI_INVALID_PARAMETER   Invalid parameter.
 | |
|   @retval EFI_OUT_OF_RESOURCES    Could not allocate memory.
 | |
| **/
 | |
| STATIC
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| AmlCodeGenRdDWordSpace (
 | |
|   IN        UINT8 ResourceType,
 | |
|   IN        BOOLEAN IsResourceConsumer,
 | |
|   IN        BOOLEAN IsPosDecode,
 | |
|   IN        BOOLEAN IsMinFixed,
 | |
|   IN        BOOLEAN IsMaxFixed,
 | |
|   IN        UINT8 TypeSpecificFlags,
 | |
|   IN        UINT32 AddressGranularity,
 | |
|   IN        UINT32 AddressMinimum,
 | |
|   IN        UINT32 AddressMaximum,
 | |
|   IN        UINT32 AddressTranslation,
 | |
|   IN        UINT32 RangeLength,
 | |
|   IN        UINT8 ResourceSourceIndex,
 | |
|   IN  CONST CHAR8 *ResourceSource,
 | |
|   IN        AML_OBJECT_NODE_HANDLE NameOpNode, OPTIONAL
 | |
|   OUT       AML_DATA_NODE_HANDLE    *NewRdNode  OPTIONAL
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS                               Status;
 | |
|   AML_DATA_NODE                            *RdNode;
 | |
|   EFI_ACPI_DWORD_ADDRESS_SPACE_DESCRIPTOR  RdDWord;
 | |
| 
 | |
|   // ResourceSource and ResourceSourceIndex are unused.
 | |
|   if ((TypeSpecificFlags == MAX_UINT8)  ||
 | |
|       (ResourceSourceIndex != 0)        ||
 | |
|       (ResourceSource != NULL)          ||
 | |
|       ((NameOpNode == NULL) && (NewRdNode == NULL)))
 | |
|   {
 | |
|     ASSERT (0);
 | |
|     return EFI_INVALID_PARAMETER;
 | |
|   }
 | |
| 
 | |
|   Status = CheckAddressSpaceFields (
 | |
|              IsMinFixed,
 | |
|              IsMaxFixed,
 | |
|              AddressGranularity,
 | |
|              AddressMinimum,
 | |
|              AddressMaximum,
 | |
|              AddressTranslation,
 | |
|              RangeLength
 | |
|              );
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     ASSERT (0);
 | |
|     return Status;
 | |
|   }
 | |
| 
 | |
|   // Header
 | |
|   RdDWord.Header.Header.Bits.Name =
 | |
|     ACPI_LARGE_DWORD_ADDRESS_SPACE_DESCRIPTOR_NAME;
 | |
|   RdDWord.Header.Header.Bits.Type = ACPI_LARGE_ITEM_FLAG;
 | |
|   RdDWord.Header.Length           = sizeof (EFI_ACPI_DWORD_ADDRESS_SPACE_DESCRIPTOR) -
 | |
|                                     sizeof (ACPI_LARGE_RESOURCE_HEADER);
 | |
| 
 | |
|   // Body
 | |
|   RdDWord.ResType = ResourceType;
 | |
|   RdDWord.GenFlag = AddressSpaceGeneralFlags (
 | |
|                       IsPosDecode,
 | |
|                       IsMinFixed,
 | |
|                       IsMaxFixed
 | |
|                       );
 | |
|   RdDWord.SpecificFlag          = TypeSpecificFlags;
 | |
|   RdDWord.AddrSpaceGranularity  = AddressGranularity;
 | |
|   RdDWord.AddrRangeMin          = AddressMinimum;
 | |
|   RdDWord.AddrRangeMax          = AddressMaximum;
 | |
|   RdDWord.AddrTranslationOffset = AddressTranslation;
 | |
|   RdDWord.AddrLen               = RangeLength;
 | |
| 
 | |
|   Status = AmlCreateDataNode (
 | |
|              EAmlNodeDataTypeResourceData,
 | |
|              (UINT8 *)&RdDWord,
 | |
|              sizeof (EFI_ACPI_DWORD_ADDRESS_SPACE_DESCRIPTOR),
 | |
|              &RdNode
 | |
|              );
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     ASSERT (0);
 | |
|     return Status;
 | |
|   }
 | |
| 
 | |
|   return LinkRdNode (RdNode, NameOpNode, NewRdNode);
 | |
| }
 | |
| 
 | |
| /** Code generation for the "DWordIO ()" ASL function.
 | |
| 
 | |
|   The Resource Data effectively created is a DWord Address Space Resource
 | |
|   Data. Cf ACPI 6.4:
 | |
|    - s6.4.3.5.2 "DWord Address Space Descriptor".
 | |
|    - s19.6.34 "DWordIO".
 | |
| 
 | |
|   The created resource data node can be:
 | |
|    - appended to the list of resource data elements of the NameOpNode.
 | |
|      In such case NameOpNode must be defined by a the "Name ()" ASL statement
 | |
|      and initially contain a "ResourceTemplate ()".
 | |
|    - returned through the NewRdNode parameter.
 | |
| 
 | |
|   See ACPI 6.4 spec, s19.6.34 for more.
 | |
| 
 | |
|   @param [in]  IsResourceConsumer   ResourceUsage parameter.
 | |
|   @param [in]  IsMinFixed           Minimum address is fixed.
 | |
|   @param [in]  IsMaxFixed           Maximum address is fixed.
 | |
|   @param [in]  IsPosDecode          Decode parameter
 | |
|   @param [in]  IsaRanges            Possible values are:
 | |
|                                      0-Reserved
 | |
|                                      1-NonISAOnly
 | |
|                                      2-ISAOnly
 | |
|                                      3-EntireRange
 | |
|   @param [in]  AddressGranularity   Address granularity.
 | |
|   @param [in]  AddressMinimum       Minimum address.
 | |
|   @param [in]  AddressMaximum       Maximum address.
 | |
|   @param [in]  AddressTranslation   Address translation.
 | |
|   @param [in]  RangeLength          Range length.
 | |
|   @param [in]  ResourceSourceIndex  Resource Source index.
 | |
|                                     Unused. Must be 0.
 | |
|   @param [in]  ResourceSource       Resource Source.
 | |
|                                     Unused. Must be NULL.
 | |
|   @param [in]  IsDenseTranslation   TranslationDensity parameter.
 | |
|   @param [in]  IsTypeStatic         TranslationType parameter.
 | |
|   @param [in]  NameOpNode           NameOp object node defining a named object.
 | |
|                                     If provided, append the new resource data
 | |
|                                     node to the list of resource data elements
 | |
|                                     of this node.
 | |
|   @param [out] NewRdNode            If provided and success,
 | |
|                                     contain the created node.
 | |
| 
 | |
|   @retval EFI_SUCCESS             The function completed successfully.
 | |
|   @retval EFI_INVALID_PARAMETER   Invalid parameter.
 | |
|   @retval EFI_OUT_OF_RESOURCES    Could not allocate memory.
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| AmlCodeGenRdDWordIo (
 | |
|   IN        BOOLEAN IsResourceConsumer,
 | |
|   IN        BOOLEAN IsMinFixed,
 | |
|   IN        BOOLEAN IsMaxFixed,
 | |
|   IN        BOOLEAN IsPosDecode,
 | |
|   IN        UINT8 IsaRanges,
 | |
|   IN        UINT32 AddressGranularity,
 | |
|   IN        UINT32 AddressMinimum,
 | |
|   IN        UINT32 AddressMaximum,
 | |
|   IN        UINT32 AddressTranslation,
 | |
|   IN        UINT32 RangeLength,
 | |
|   IN        UINT8 ResourceSourceIndex,
 | |
|   IN  CONST CHAR8 *ResourceSource,
 | |
|   IN        BOOLEAN IsDenseTranslation,
 | |
|   IN        BOOLEAN IsTypeStatic,
 | |
|   IN        AML_OBJECT_NODE_HANDLE NameOpNode, OPTIONAL
 | |
|   OUT       AML_DATA_NODE_HANDLE    *NewRdNode  OPTIONAL
 | |
|   )
 | |
| {
 | |
|   return AmlCodeGenRdDWordSpace (
 | |
|            ACPI_ADDRESS_SPACE_TYPE_IO,
 | |
|            IsResourceConsumer,
 | |
|            IsPosDecode,
 | |
|            IsMinFixed,
 | |
|            IsMaxFixed,
 | |
|            RdIoRangeSpecificFlags (
 | |
|              IsaRanges,
 | |
|              IsDenseTranslation,
 | |
|              IsTypeStatic
 | |
|              ),
 | |
|            AddressGranularity,
 | |
|            AddressMinimum,
 | |
|            AddressMaximum,
 | |
|            AddressTranslation,
 | |
|            RangeLength,
 | |
|            ResourceSourceIndex,
 | |
|            ResourceSource,
 | |
|            NameOpNode,
 | |
|            NewRdNode
 | |
|            );
 | |
| }
 | |
| 
 | |
| /** Code generation for the "DWordMemory ()" ASL function.
 | |
| 
 | |
|   The Resource Data effectively created is a DWord Address Space Resource
 | |
|   Data. Cf ACPI 6.4:
 | |
|    - s6.4.3.5.2 "DWord Address Space Descriptor".
 | |
|    - s19.6.35 "DWordMemory".
 | |
| 
 | |
|   The created resource data node can be:
 | |
|    - appended to the list of resource data elements of the NameOpNode.
 | |
|      In such case NameOpNode must be defined by a the "Name ()" ASL statement
 | |
|      and initially contain a "ResourceTemplate ()".
 | |
|    - returned through the NewRdNode parameter.
 | |
| 
 | |
|   See ACPI 6.4 spec, s19.6.35 for more.
 | |
| 
 | |
|   @param [in]  IsResourceConsumer   ResourceUsage parameter.
 | |
|   @param [in]  IsPosDecode          Decode parameter
 | |
|   @param [in]  IsMinFixed           Minimum address is fixed.
 | |
|   @param [in]  IsMaxFixed           Maximum address is fixed.
 | |
|   @param [in]  Cacheable            Possible values are:
 | |
|                                     0-The memory is non-cacheable
 | |
|                                     1-The memory is cacheable
 | |
|                                     2-The memory is cacheable and supports
 | |
|                                       write combining
 | |
|                                     3-The memory is cacheable and prefetchable
 | |
|   @param [in]  IsReadWrite          ReadAndWrite parameter.
 | |
|   @param [in]  AddressGranularity   Address granularity.
 | |
|   @param [in]  AddressMinimum       Minimum address.
 | |
|   @param [in]  AddressMaximum       Maximum address.
 | |
|   @param [in]  AddressTranslation   Address translation.
 | |
|   @param [in]  RangeLength          Range length.
 | |
|   @param [in]  ResourceSourceIndex  Resource Source index.
 | |
|                                     Unused. Must be 0.
 | |
|   @param [in]  ResourceSource       Resource Source.
 | |
|                                     Unused. Must be NULL.
 | |
|   @param [in]  MemoryRangeType      Possible values are:
 | |
|                                       0-AddressRangeMemory
 | |
|                                       1-AddressRangeReserved
 | |
|                                       2-AddressRangeACPI
 | |
|                                       3-AddressRangeNVS
 | |
|   @param [in]  IsTypeStatic         TranslationType parameter.
 | |
|   @param [in]  NameOpNode           NameOp object node defining a named object.
 | |
|                                     If provided, append the new resource data
 | |
|                                     node to the list of resource data elements
 | |
|                                     of this node.
 | |
|   @param [out] NewRdNode            If provided and success,
 | |
|                                     contain the created node.
 | |
| 
 | |
|   @retval EFI_SUCCESS             The function completed successfully.
 | |
|   @retval EFI_INVALID_PARAMETER   Invalid parameter.
 | |
|   @retval EFI_OUT_OF_RESOURCES    Could not allocate memory.
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| AmlCodeGenRdDWordMemory (
 | |
|   IN        BOOLEAN IsResourceConsumer,
 | |
|   IN        BOOLEAN IsPosDecode,
 | |
|   IN        BOOLEAN IsMinFixed,
 | |
|   IN        BOOLEAN IsMaxFixed,
 | |
|   IN        UINT8 Cacheable,
 | |
|   IN        BOOLEAN IsReadWrite,
 | |
|   IN        UINT32 AddressGranularity,
 | |
|   IN        UINT32 AddressMinimum,
 | |
|   IN        UINT32 AddressMaximum,
 | |
|   IN        UINT32 AddressTranslation,
 | |
|   IN        UINT32 RangeLength,
 | |
|   IN        UINT8 ResourceSourceIndex,
 | |
|   IN  CONST CHAR8 *ResourceSource,
 | |
|   IN        UINT8 MemoryRangeType,
 | |
|   IN        BOOLEAN IsTypeStatic,
 | |
|   IN        AML_OBJECT_NODE_HANDLE NameOpNode, OPTIONAL
 | |
|   OUT       AML_DATA_NODE_HANDLE    *NewRdNode  OPTIONAL
 | |
|   )
 | |
| {
 | |
|   return AmlCodeGenRdDWordSpace (
 | |
|            ACPI_ADDRESS_SPACE_TYPE_MEM,
 | |
|            IsResourceConsumer,
 | |
|            IsPosDecode,
 | |
|            IsMinFixed,
 | |
|            IsMaxFixed,
 | |
|            MemoryRangeSpecificFlags (
 | |
|              Cacheable,
 | |
|              IsReadWrite,
 | |
|              MemoryRangeType,
 | |
|              IsTypeStatic
 | |
|              ),
 | |
|            AddressGranularity,
 | |
|            AddressMinimum,
 | |
|            AddressMaximum,
 | |
|            AddressTranslation,
 | |
|            RangeLength,
 | |
|            ResourceSourceIndex,
 | |
|            ResourceSource,
 | |
|            NameOpNode,
 | |
|            NewRdNode
 | |
|            );
 | |
| }
 | |
| 
 | |
| /** Code generation for the "Memory32Fixed ()" ASL macro.
 | |
| 
 | |
|   The Resource Data effectively created is a 32-bit Memory Resource
 | |
|   Data. Cf ACPI 6.4:
 | |
|    - s19.6.83 "Memory Resource Descriptor Macro".
 | |
|    - s19.2.8 "Memory32FixedTerm".
 | |
| 
 | |
|   See ACPI 6.4 spec, s19.2.8 for more.
 | |
| 
 | |
|   @param [in]  IsReadWrite          ReadAndWrite parameter.
 | |
|   @param [in]  Address              AddressBase parameter.
 | |
|   @param [in]  RangeLength          Range length.
 | |
|   @param [in]  NameOpNode           NameOp object node defining a named object.
 | |
|                                     If provided, append the new resource data
 | |
|                                     node to the list of resource data elements
 | |
|                                     of this node.
 | |
|   @param [out] NewMemNode           If provided and success,
 | |
|                                     contain the created node.
 | |
| 
 | |
|   @retval EFI_SUCCESS             The function completed successfully.
 | |
|   @retval EFI_INVALID_PARAMETER   Invalid parameter.
 | |
|   @retval EFI_OUT_OF_RESOURCES    Could not allocate memory.
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| AmlCodeGenRdMemory32Fixed (
 | |
|   BOOLEAN                 IsReadWrite,
 | |
|   UINT32                  Address,
 | |
|   UINT32                  RangeLength,
 | |
|   AML_OBJECT_NODE_HANDLE  NameOpNode,
 | |
|   AML_DATA_NODE_HANDLE    *NewMemNode
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS                                     Status;
 | |
|   AML_DATA_NODE                                  *MemNode;
 | |
|   EFI_ACPI_32_BIT_FIXED_MEMORY_RANGE_DESCRIPTOR  RangeDesc;
 | |
| 
 | |
|   RangeDesc.Header.Header.Byte = ACPI_32_BIT_FIXED_MEMORY_RANGE_DESCRIPTOR;
 | |
|   RangeDesc.Header.Length      = sizeof (EFI_ACPI_32_BIT_FIXED_MEMORY_RANGE_DESCRIPTOR) -
 | |
|                                  sizeof (ACPI_LARGE_RESOURCE_HEADER);
 | |
|   RangeDesc.Information = IsReadWrite ? BIT0 : 0;
 | |
|   RangeDesc.BaseAddress = Address;
 | |
|   RangeDesc.Length      = RangeLength;
 | |
| 
 | |
|   Status = AmlCreateDataNode (
 | |
|              EAmlNodeDataTypeResourceData,
 | |
|              (UINT8 *)&RangeDesc,
 | |
|              sizeof (RangeDesc),
 | |
|              &MemNode
 | |
|              );
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     ASSERT (0);
 | |
|     return Status;
 | |
|   }
 | |
| 
 | |
|   return LinkRdNode (MemNode, NameOpNode, NewMemNode);
 | |
| }
 | |
| 
 | |
| /** Code generation for the "WordSpace ()" ASL function.
 | |
| 
 | |
|   The Resource Data effectively created is a Word Address Space Resource
 | |
|   Data. Cf ACPI 6.4:
 | |
|    - s6.4.3.5.3 "Word Address Space Descriptor".
 | |
|    - s19.6.151 "WordSpace".
 | |
| 
 | |
|   The created resource data node can be:
 | |
|    - appended to the list of resource data elements of the NameOpNode.
 | |
|      In such case NameOpNode must be defined by a the "Name ()" ASL statement
 | |
|      and initially contain a "ResourceTemplate ()".
 | |
|    - returned through the NewRdNode parameter.
 | |
| 
 | |
|   See ACPI 6.4 spec, s19.6.151 for more.
 | |
| 
 | |
|   @param [in]  ResourceType         Resource type.
 | |
|                                     Possible values are:
 | |
|                                       0:        Memory range
 | |
|                                       1:        I/O range
 | |
|                                       2:        Bus number range
 | |
|                                       3-191:    Reserved
 | |
|                                       192-255:  Hardware Vendor Defined
 | |
|                                     See ACPI 6.4 spec, s6.4.3.5.3 for more.
 | |
|   @param [in]  IsResourceConsumer   ResourceUsage parameter.
 | |
|   @param [in]  IsPosDecode          Decode parameter
 | |
|   @param [in]  IsMinFixed           Minimum address is fixed.
 | |
|   @param [in]  IsMaxFixed           Maximum address is fixed.
 | |
|   @param [in]  TypeSpecificFlags    Type specific flags.
 | |
|                                     See ACPI 6.4 spec, s6.4.3.5.5
 | |
|                                     "Resource Type Specific Flags".
 | |
|   @param [in]  AddressGranularity   Address granularity.
 | |
|   @param [in]  AddressMinimum       Minimum address.
 | |
|   @param [in]  AddressMaximum       Maximum address.
 | |
|   @param [in]  AddressTranslation   Address translation.
 | |
|   @param [in]  RangeLength          Range length.
 | |
|   @param [in]  ResourceSourceIndex  Resource Source index.
 | |
|                                     Unused. Must be 0.
 | |
|   @param [in]  ResourceSource       Resource Source.
 | |
|                                     Unused. Must be NULL.
 | |
|   @param [in]  NameOpNode           NameOp object node defining a named object.
 | |
|                                     If provided, append the new resource data
 | |
|                                     node to the list of resource data elements
 | |
|                                     of this node.
 | |
|   @param [out] NewRdNode            If provided and success,
 | |
|                                     contain the created node.
 | |
| 
 | |
|   @retval EFI_SUCCESS             The function completed successfully.
 | |
|   @retval EFI_INVALID_PARAMETER   Invalid parameter.
 | |
|   @retval EFI_OUT_OF_RESOURCES    Could not allocate memory.
 | |
| **/
 | |
| STATIC
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| AmlCodeGenRdWordSpace (
 | |
|   IN        UINT8 ResourceType,
 | |
|   IN        BOOLEAN IsResourceConsumer,
 | |
|   IN        BOOLEAN IsPosDecode,
 | |
|   IN        BOOLEAN IsMinFixed,
 | |
|   IN        BOOLEAN IsMaxFixed,
 | |
|   IN        UINT8 TypeSpecificFlags,
 | |
|   IN        UINT16 AddressGranularity,
 | |
|   IN        UINT16 AddressMinimum,
 | |
|   IN        UINT16 AddressMaximum,
 | |
|   IN        UINT16 AddressTranslation,
 | |
|   IN        UINT16 RangeLength,
 | |
|   IN        UINT8 ResourceSourceIndex,
 | |
|   IN  CONST CHAR8 *ResourceSource,
 | |
|   IN        AML_OBJECT_NODE_HANDLE NameOpNode, OPTIONAL
 | |
|   OUT       AML_DATA_NODE_HANDLE    *NewRdNode  OPTIONAL
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS                              Status;
 | |
|   AML_DATA_NODE                           *RdNode;
 | |
|   EFI_ACPI_WORD_ADDRESS_SPACE_DESCRIPTOR  Rdword;
 | |
| 
 | |
|   // ResourceSource and ResourceSourceIndex are unused.
 | |
|   if ((TypeSpecificFlags == MAX_UINT8)  ||
 | |
|       (ResourceSourceIndex != 0)        ||
 | |
|       (ResourceSource != NULL)          ||
 | |
|       ((NameOpNode == NULL) && (NewRdNode == NULL)))
 | |
|   {
 | |
|     ASSERT (0);
 | |
|     return EFI_INVALID_PARAMETER;
 | |
|   }
 | |
| 
 | |
|   Status = CheckAddressSpaceFields (
 | |
|              IsMinFixed,
 | |
|              IsMaxFixed,
 | |
|              AddressGranularity,
 | |
|              AddressMinimum,
 | |
|              AddressMaximum,
 | |
|              AddressTranslation,
 | |
|              RangeLength
 | |
|              );
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     ASSERT (0);
 | |
|     return Status;
 | |
|   }
 | |
| 
 | |
|   // Header
 | |
|   Rdword.Header.Header.Bits.Name =
 | |
|     ACPI_LARGE_WORD_ADDRESS_SPACE_DESCRIPTOR_NAME;
 | |
|   Rdword.Header.Header.Bits.Type = ACPI_LARGE_ITEM_FLAG;
 | |
|   Rdword.Header.Length           = sizeof (EFI_ACPI_WORD_ADDRESS_SPACE_DESCRIPTOR) -
 | |
|                                    sizeof (ACPI_LARGE_RESOURCE_HEADER);
 | |
| 
 | |
|   // Body
 | |
|   Rdword.ResType = ResourceType;
 | |
|   Rdword.GenFlag = AddressSpaceGeneralFlags (
 | |
|                      IsPosDecode,
 | |
|                      IsMinFixed,
 | |
|                      IsMaxFixed
 | |
|                      );
 | |
|   Rdword.SpecificFlag          = TypeSpecificFlags;
 | |
|   Rdword.AddrSpaceGranularity  = AddressGranularity;
 | |
|   Rdword.AddrRangeMin          = AddressMinimum;
 | |
|   Rdword.AddrRangeMax          = AddressMaximum;
 | |
|   Rdword.AddrTranslationOffset = AddressTranslation;
 | |
|   Rdword.AddrLen               = RangeLength;
 | |
| 
 | |
|   Status = AmlCreateDataNode (
 | |
|              EAmlNodeDataTypeResourceData,
 | |
|              (UINT8 *)&Rdword,
 | |
|              sizeof (EFI_ACPI_WORD_ADDRESS_SPACE_DESCRIPTOR),
 | |
|              &RdNode
 | |
|              );
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     ASSERT (0);
 | |
|     return Status;
 | |
|   }
 | |
| 
 | |
|   return LinkRdNode (RdNode, NameOpNode, NewRdNode);
 | |
| }
 | |
| 
 | |
| /** Code generation for the "WordBusNumber ()" ASL function.
 | |
| 
 | |
|   The Resource Data effectively created is a Word Address Space Resource
 | |
|   Data. Cf ACPI 6.4:
 | |
|    - s6.4.3.5.3 "Word Address Space Descriptor".
 | |
|    - s19.6.149 "WordBusNumber".
 | |
| 
 | |
|   The created resource data node can be:
 | |
|    - appended to the list of resource data elements of the NameOpNode.
 | |
|      In such case NameOpNode must be defined by a the "Name ()" ASL statement
 | |
|      and initially contain a "ResourceTemplate ()".
 | |
|    - returned through the NewRdNode parameter.
 | |
| 
 | |
|   See ACPI 6.4 spec, s19.6.149 for more.
 | |
| 
 | |
|   @param [in]  IsResourceConsumer   ResourceUsage parameter.
 | |
|   @param [in]  IsMinFixed           Minimum address is fixed.
 | |
|   @param [in]  IsMaxFixed           Maximum address is fixed.
 | |
|   @param [in]  IsPosDecode          Decode parameter
 | |
|   @param [in]  AddressGranularity   Address granularity.
 | |
|   @param [in]  AddressMinimum       Minimum address.
 | |
|   @param [in]  AddressMaximum       Maximum address.
 | |
|   @param [in]  AddressTranslation   Address translation.
 | |
|   @param [in]  RangeLength          Range length.
 | |
|   @param [in]  ResourceSourceIndex  Resource Source index.
 | |
|                                     Unused. Must be 0.
 | |
|   @param [in]  ResourceSource       Resource Source.
 | |
|                                     Unused. Must be NULL.
 | |
|   @param [in]  NameOpNode           NameOp object node defining a named object.
 | |
|                                     If provided, append the new resource data
 | |
|                                     node to the list of resource data elements
 | |
|                                     of this node.
 | |
|   @param [out] NewRdNode            If provided and success,
 | |
|                                     contain the created node.
 | |
| 
 | |
|   @retval EFI_SUCCESS             The function completed successfully.
 | |
|   @retval EFI_INVALID_PARAMETER   Invalid parameter.
 | |
|   @retval EFI_OUT_OF_RESOURCES    Could not allocate memory.
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| AmlCodeGenRdWordBusNumber (
 | |
|   IN        BOOLEAN IsResourceConsumer,
 | |
|   IN        BOOLEAN IsMinFixed,
 | |
|   IN        BOOLEAN IsMaxFixed,
 | |
|   IN        BOOLEAN IsPosDecode,
 | |
|   IN        UINT32 AddressGranularity,
 | |
|   IN        UINT32 AddressMinimum,
 | |
|   IN        UINT32 AddressMaximum,
 | |
|   IN        UINT32 AddressTranslation,
 | |
|   IN        UINT32 RangeLength,
 | |
|   IN        UINT8 ResourceSourceIndex,
 | |
|   IN  CONST CHAR8 *ResourceSource,
 | |
|   IN        AML_OBJECT_NODE_HANDLE NameOpNode, OPTIONAL
 | |
|   OUT       AML_DATA_NODE_HANDLE    *NewRdNode  OPTIONAL
 | |
|   )
 | |
| {
 | |
|   // There is no Type Specific Flags for buses.
 | |
|   return AmlCodeGenRdWordSpace (
 | |
|            ACPI_ADDRESS_SPACE_TYPE_BUS,
 | |
|            IsResourceConsumer,
 | |
|            IsPosDecode,
 | |
|            IsMinFixed,
 | |
|            IsMaxFixed,
 | |
|            0,
 | |
|            AddressGranularity,
 | |
|            AddressMinimum,
 | |
|            AddressMaximum,
 | |
|            AddressTranslation,
 | |
|            RangeLength,
 | |
|            ResourceSourceIndex,
 | |
|            ResourceSource,
 | |
|            NameOpNode,
 | |
|            NewRdNode
 | |
|            );
 | |
| }
 | |
| 
 | |
| /** Code generation for the "QWordSpace ()" ASL function.
 | |
| 
 | |
|   The Resource Data effectively created is a QWord Address Space Resource
 | |
|   Data. Cf ACPI 6.4:
 | |
|    - s6.4.3.5.1 "QWord Address Space Descriptor".
 | |
|    - s19.6.111 "QWordSpace".
 | |
| 
 | |
|   The created resource data node can be:
 | |
|    - appended to the list of resource data elements of the NameOpNode.
 | |
|      In such case NameOpNode must be defined by a the "Name ()" ASL statement
 | |
|      and initially contain a "ResourceTemplate ()".
 | |
|    - returned through the NewRdNode parameter.
 | |
| 
 | |
|   See ACPI 6.4 spec, s19.6.111 for more.
 | |
| 
 | |
|   @param [in]  ResourceType         Resource type.
 | |
|                                     Possible values are:
 | |
|                                       0:        Memory range
 | |
|                                       1:        I/O range
 | |
|                                       2:        Bus number range
 | |
|                                       3-191:    Reserved
 | |
|                                       192-255:  Hardware Vendor Defined
 | |
|                                     See ACPI 6.4 spec, s6.4.3.5.1 for more.
 | |
|   @param [in]  IsResourceConsumer   ResourceUsage parameter.
 | |
|   @param [in]  IsPosDecode          Decode parameter
 | |
|   @param [in]  IsMinFixed           Minimum address is fixed.
 | |
|   @param [in]  IsMaxFixed           Maximum address is fixed.
 | |
|   @param [in]  TypeSpecificFlags    Type specific flags.
 | |
|                                     See ACPI 6.4 spec, s6.4.3.5.5
 | |
|                                     "Resource Type Specific Flags".
 | |
|   @param [in]  AddressGranularity   Address granularity.
 | |
|   @param [in]  AddressMinimum       Minimum address.
 | |
|   @param [in]  AddressMaximum       Maximum address.
 | |
|   @param [in]  AddressTranslation   Address translation.
 | |
|   @param [in]  RangeLength          Range length.
 | |
|   @param [in]  ResourceSourceIndex  Resource Source index.
 | |
|                                     Unused. Must be 0.
 | |
|   @param [in]  ResourceSource       Resource Source.
 | |
|                                     Unused. Must be NULL.
 | |
|   @param [in]  NameOpNode           NameOp object node defining a named object.
 | |
|                                     If provided, append the new resource data
 | |
|                                     node to the list of resource data elements
 | |
|                                     of this node.
 | |
|   @param [out] NewRdNode            If provided and success,
 | |
|                                     contain the created node.
 | |
| 
 | |
|   @retval EFI_SUCCESS             The function completed successfully.
 | |
|   @retval EFI_INVALID_PARAMETER   Invalid parameter.
 | |
|   @retval EFI_OUT_OF_RESOURCES    Could not allocate memory.
 | |
| **/
 | |
| STATIC
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| AmlCodeGenRdQWordSpace (
 | |
|   IN        UINT8 ResourceType,
 | |
|   IN        BOOLEAN IsResourceConsumer,
 | |
|   IN        BOOLEAN IsPosDecode,
 | |
|   IN        BOOLEAN IsMinFixed,
 | |
|   IN        BOOLEAN IsMaxFixed,
 | |
|   IN        UINT8 TypeSpecificFlags,
 | |
|   IN        UINT64 AddressGranularity,
 | |
|   IN        UINT64 AddressMinimum,
 | |
|   IN        UINT64 AddressMaximum,
 | |
|   IN        UINT64 AddressTranslation,
 | |
|   IN        UINT64 RangeLength,
 | |
|   IN        UINT8 ResourceSourceIndex,
 | |
|   IN  CONST CHAR8 *ResourceSource,
 | |
|   IN        AML_OBJECT_NODE_HANDLE NameOpNode, OPTIONAL
 | |
|   OUT       AML_DATA_NODE_HANDLE    *NewRdNode  OPTIONAL
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS                               Status;
 | |
|   AML_DATA_NODE                            *RdNode;
 | |
|   EFI_ACPI_QWORD_ADDRESS_SPACE_DESCRIPTOR  RdQword;
 | |
| 
 | |
|   // ResourceSource and ResourceSourceIndex are unused.
 | |
|   if ((TypeSpecificFlags == MAX_UINT8)  ||
 | |
|       (ResourceSourceIndex != 0)        ||
 | |
|       (ResourceSource != NULL)          ||
 | |
|       ((NameOpNode == NULL) && (NewRdNode == NULL)))
 | |
|   {
 | |
|     ASSERT (0);
 | |
|     return EFI_INVALID_PARAMETER;
 | |
|   }
 | |
| 
 | |
|   Status = CheckAddressSpaceFields (
 | |
|              IsMinFixed,
 | |
|              IsMaxFixed,
 | |
|              AddressGranularity,
 | |
|              AddressMinimum,
 | |
|              AddressMaximum,
 | |
|              AddressTranslation,
 | |
|              RangeLength
 | |
|              );
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     ASSERT (0);
 | |
|     return Status;
 | |
|   }
 | |
| 
 | |
|   // Header
 | |
|   RdQword.Header.Header.Bits.Name =
 | |
|     ACPI_LARGE_QWORD_ADDRESS_SPACE_DESCRIPTOR_NAME;
 | |
|   RdQword.Header.Header.Bits.Type = ACPI_LARGE_ITEM_FLAG;
 | |
|   RdQword.Header.Length           = sizeof (EFI_ACPI_QWORD_ADDRESS_SPACE_DESCRIPTOR) -
 | |
|                                     sizeof (ACPI_LARGE_RESOURCE_HEADER);
 | |
| 
 | |
|   // Body
 | |
|   RdQword.ResType = ResourceType;
 | |
|   RdQword.GenFlag = AddressSpaceGeneralFlags (
 | |
|                       IsPosDecode,
 | |
|                       IsMinFixed,
 | |
|                       IsMaxFixed
 | |
|                       );
 | |
|   RdQword.SpecificFlag          = TypeSpecificFlags;
 | |
|   RdQword.AddrSpaceGranularity  = AddressGranularity;
 | |
|   RdQword.AddrRangeMin          = AddressMinimum;
 | |
|   RdQword.AddrRangeMax          = AddressMaximum;
 | |
|   RdQword.AddrTranslationOffset = AddressTranslation;
 | |
|   RdQword.AddrLen               = RangeLength;
 | |
| 
 | |
|   Status = AmlCreateDataNode (
 | |
|              EAmlNodeDataTypeResourceData,
 | |
|              (UINT8 *)&RdQword,
 | |
|              sizeof (EFI_ACPI_QWORD_ADDRESS_SPACE_DESCRIPTOR),
 | |
|              &RdNode
 | |
|              );
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     ASSERT (0);
 | |
|     return Status;
 | |
|   }
 | |
| 
 | |
|   return LinkRdNode (RdNode, NameOpNode, NewRdNode);
 | |
| }
 | |
| 
 | |
| /** Code generation for the "QWordMemory ()" ASL function.
 | |
| 
 | |
|   The Resource Data effectively created is a QWord Address Space Resource
 | |
|   Data. Cf ACPI 6.4:
 | |
|    - s6.4.3.5.1 "QWord Address Space Descriptor".
 | |
|    - s19.6.110 "QWordMemory".
 | |
| 
 | |
|   The created resource data node can be:
 | |
|    - appended to the list of resource data elements of the NameOpNode.
 | |
|      In such case NameOpNode must be defined by a the "Name ()" ASL statement
 | |
|      and initially contain a "ResourceTemplate ()".
 | |
|    - returned through the NewRdNode parameter.
 | |
| 
 | |
|   See ACPI 6.4 spec, s19.6.110 for more.
 | |
| 
 | |
|   @param [in]  IsResourceConsumer   ResourceUsage parameter.
 | |
|   @param [in]  IsPosDecode          Decode parameter.
 | |
|   @param [in]  IsMinFixed           Minimum address is fixed.
 | |
|   @param [in]  IsMaxFixed           Maximum address is fixed.
 | |
|   @param [in]  Cacheable            Possible values are:
 | |
|                                     0-The memory is non-cacheable
 | |
|                                     1-The memory is cacheable
 | |
|                                     2-The memory is cacheable and supports
 | |
|                                       write combining
 | |
|                                     3-The memory is cacheable and prefetchable
 | |
|   @param [in]  IsReadWrite          ReadAndWrite parameter.
 | |
|   @param [in]  AddressGranularity   Address granularity.
 | |
|   @param [in]  AddressMinimum       Minimum address.
 | |
|   @param [in]  AddressMaximum       Maximum address.
 | |
|   @param [in]  AddressTranslation   Address translation.
 | |
|   @param [in]  RangeLength          Range length.
 | |
|   @param [in]  ResourceSourceIndex  Resource Source index.
 | |
|                                     Unused. Must be 0.
 | |
|   @param [in]  ResourceSource       Resource Source.
 | |
|                                     Unused. Must be NULL.
 | |
|   @param [in]  MemoryRangeType      Possible values are:
 | |
|                                       0-AddressRangeMemory
 | |
|                                       1-AddressRangeReserved
 | |
|                                       2-AddressRangeACPI
 | |
|                                       3-AddressRangeNVS
 | |
|   @param [in]  IsTypeStatic         TranslationType parameter.
 | |
|   @param [in]  NameOpNode           NameOp object node defining a named object.
 | |
|                                     If provided, append the new resource data
 | |
|                                     node to the list of resource data elements
 | |
|                                     of this node.
 | |
|   @param [out] NewRdNode            If provided and success,
 | |
|                                     contain the created node.
 | |
| 
 | |
|   @retval EFI_SUCCESS             The function completed successfully.
 | |
|   @retval EFI_INVALID_PARAMETER   Invalid parameter.
 | |
|   @retval EFI_OUT_OF_RESOURCES    Could not allocate memory.
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| AmlCodeGenRdQWordMemory (
 | |
|   IN        BOOLEAN IsResourceConsumer,
 | |
|   IN        BOOLEAN IsPosDecode,
 | |
|   IN        BOOLEAN IsMinFixed,
 | |
|   IN        BOOLEAN IsMaxFixed,
 | |
|   IN        UINT8 Cacheable,
 | |
|   IN        BOOLEAN IsReadWrite,
 | |
|   IN        UINT64 AddressGranularity,
 | |
|   IN        UINT64 AddressMinimum,
 | |
|   IN        UINT64 AddressMaximum,
 | |
|   IN        UINT64 AddressTranslation,
 | |
|   IN        UINT64 RangeLength,
 | |
|   IN        UINT8 ResourceSourceIndex,
 | |
|   IN  CONST CHAR8 *ResourceSource,
 | |
|   IN        UINT8 MemoryRangeType,
 | |
|   IN        BOOLEAN IsTypeStatic,
 | |
|   IN        AML_OBJECT_NODE_HANDLE NameOpNode, OPTIONAL
 | |
|   OUT       AML_DATA_NODE_HANDLE    *NewRdNode  OPTIONAL
 | |
|   )
 | |
| {
 | |
|   return AmlCodeGenRdQWordSpace (
 | |
|            ACPI_ADDRESS_SPACE_TYPE_MEM,
 | |
|            IsResourceConsumer,
 | |
|            IsPosDecode,
 | |
|            IsMinFixed,
 | |
|            IsMaxFixed,
 | |
|            MemoryRangeSpecificFlags (
 | |
|              Cacheable,
 | |
|              IsReadWrite,
 | |
|              MemoryRangeType,
 | |
|              IsTypeStatic
 | |
|              ),
 | |
|            AddressGranularity,
 | |
|            AddressMinimum,
 | |
|            AddressMaximum,
 | |
|            AddressTranslation,
 | |
|            RangeLength,
 | |
|            ResourceSourceIndex,
 | |
|            ResourceSource,
 | |
|            NameOpNode,
 | |
|            NewRdNode
 | |
|            );
 | |
| }
 | |
| 
 | |
| /** Code generation for the "Interrupt ()" ASL function.
 | |
| 
 | |
|   The Resource Data effectively created is an Extended Interrupt Resource
 | |
|   Data. Cf ACPI 6.4:
 | |
|    - s6.4.3.6 "Extended Interrupt Descriptor"
 | |
|    - s19.6.64 "Interrupt (Interrupt Resource Descriptor Macro)"
 | |
| 
 | |
|   The created resource data node can be:
 | |
|    - appended to the list of resource data elements of the NameOpNode.
 | |
|      In such case NameOpNode must be defined by a the "Name ()" ASL statement
 | |
|      and initially contain a "ResourceTemplate ()".
 | |
|    - returned through the NewRdNode parameter.
 | |
| 
 | |
|   @param  [in]  ResourceConsumer The device consumes the specified interrupt
 | |
|                                  or produces it for use by a child device.
 | |
|   @param  [in]  EdgeTriggered    The interrupt is edge triggered or
 | |
|                                  level triggered.
 | |
|   @param  [in]  ActiveLow        The interrupt is active-high or active-low.
 | |
|   @param  [in]  Shared           The interrupt can be shared with other
 | |
|                                  devices or not (Exclusive).
 | |
|   @param  [in]  IrqList          Interrupt list. Must be non-NULL.
 | |
|   @param  [in]  IrqCount         Interrupt count. Must be non-zero.
 | |
|   @param  [in]  NameOpNode       NameOp object node defining a named object.
 | |
|                                  If provided, append the new resource data node
 | |
|                                  to the list of resource data elements of this
 | |
|                                  node.
 | |
|   @param  [out] NewRdNode        If provided and success,
 | |
|                                  contain the created node.
 | |
| 
 | |
|   @retval EFI_SUCCESS             The function completed successfully.
 | |
|   @retval EFI_INVALID_PARAMETER   Invalid parameter.
 | |
|   @retval EFI_OUT_OF_RESOURCES    Could not allocate memory.
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| AmlCodeGenRdInterrupt (
 | |
|   IN  BOOLEAN                 ResourceConsumer,
 | |
|   IN  BOOLEAN                 EdgeTriggered,
 | |
|   IN  BOOLEAN                 ActiveLow,
 | |
|   IN  BOOLEAN                 Shared,
 | |
|   IN  UINT32                  *IrqList,
 | |
|   IN  UINT8                   IrqCount,
 | |
|   IN  AML_OBJECT_NODE_HANDLE  NameOpNode  OPTIONAL,
 | |
|   OUT AML_DATA_NODE_HANDLE    *NewRdNode  OPTIONAL
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS  Status;
 | |
| 
 | |
|   AML_DATA_NODE                           *RdNode;
 | |
|   EFI_ACPI_EXTENDED_INTERRUPT_DESCRIPTOR  RdInterrupt;
 | |
|   UINT32                                  *FirstInterrupt;
 | |
| 
 | |
|   if ((IrqList == NULL) ||
 | |
|       (IrqCount == 0)   ||
 | |
|       ((NameOpNode == NULL) && (NewRdNode == NULL)))
 | |
|   {
 | |
|     ASSERT (0);
 | |
|     return EFI_INVALID_PARAMETER;
 | |
|   }
 | |
| 
 | |
|   // Header
 | |
|   RdInterrupt.Header.Header.Bits.Name =
 | |
|     ACPI_LARGE_EXTENDED_IRQ_DESCRIPTOR_NAME;
 | |
|   RdInterrupt.Header.Header.Bits.Type = ACPI_LARGE_ITEM_FLAG;
 | |
|   RdInterrupt.Header.Length           = sizeof (EFI_ACPI_EXTENDED_INTERRUPT_DESCRIPTOR) -
 | |
|                                         sizeof (ACPI_LARGE_RESOURCE_HEADER);
 | |
| 
 | |
|   // Body
 | |
|   RdInterrupt.InterruptVectorFlags = (ResourceConsumer ? BIT0 : 0) |
 | |
|                                      (EdgeTriggered ? BIT1 : 0)    |
 | |
|                                      (ActiveLow ? BIT2 : 0)        |
 | |
|                                      (Shared ? BIT3 : 0);
 | |
|   RdInterrupt.InterruptTableLength = IrqCount;
 | |
| 
 | |
|   // Get the address of the first interrupt field.
 | |
|   FirstInterrupt = RdInterrupt.InterruptNumber;
 | |
| 
 | |
|   // Copy the list of interrupts.
 | |
|   CopyMem (FirstInterrupt, IrqList, (sizeof (UINT32) * IrqCount));
 | |
| 
 | |
|   Status = AmlCreateDataNode (
 | |
|              EAmlNodeDataTypeResourceData,
 | |
|              (UINT8 *)&RdInterrupt,
 | |
|              sizeof (EFI_ACPI_EXTENDED_INTERRUPT_DESCRIPTOR),
 | |
|              &RdNode
 | |
|              );
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     ASSERT (0);
 | |
|     return Status;
 | |
|   }
 | |
| 
 | |
|   return LinkRdNode (RdNode, NameOpNode, NewRdNode);
 | |
| }
 | |
| 
 | |
| /** Code generation for the "Register ()" ASL function.
 | |
| 
 | |
|   The Resource Data effectively created is a Generic Register Descriptor.
 | |
|   Data. Cf ACPI 6.4:
 | |
|    - s6.4.3.7 "Generic Register Descriptor".
 | |
|    - s19.6.114 "Register".
 | |
| 
 | |
|   The created resource data node can be:
 | |
|    - appended to the list of resource data elements of the NameOpNode.
 | |
|      In such case NameOpNode must be defined by a the "Name ()" ASL statement
 | |
|      and initially contain a "ResourceTemplate ()".
 | |
|    - returned through the NewRdNode parameter.
 | |
| 
 | |
|   @param [in]  AddressSpace    Address space where the register exists.
 | |
|                                Can be one of I/O space, System Memory, etc.
 | |
|   @param [in]  BitWidth        Number of bits in the register.
 | |
|   @param [in]  BitOffset       Offset in bits from the start of the register
 | |
|                                indicated by the Address.
 | |
|   @param [in]  Address         Register address.
 | |
|   @param [in]  AccessSize      Size of data values used when accessing the
 | |
|                                address space. Can be one of:
 | |
|                                  0 - Undefined, legacy (EFI_ACPI_6_4_UNDEFINED)
 | |
|                                  1 - Byte access (EFI_ACPI_6_4_BYTE)
 | |
|                                  2 - Word access (EFI_ACPI_6_4_WORD)
 | |
|                                  3 - DWord access (EFI_ACPI_6_4_DWORD)
 | |
|                                  4 - QWord access (EFI_ACPI_6_4_QWORD)
 | |
|   @param  [in]  NameOpNode       NameOp object node defining a named object.
 | |
|                                  If provided, append the new resource data node
 | |
|                                  to the list of resource data elements of this
 | |
|                                  node.
 | |
|   @param  [out] NewRdNode        If provided and success,
 | |
|                                  contain the created node.
 | |
| 
 | |
|   @retval EFI_SUCCESS             The function completed successfully.
 | |
|   @retval EFI_INVALID_PARAMETER   Invalid parameter.
 | |
|   @retval EFI_OUT_OF_RESOURCES    Could not allocate memory.
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| AmlCodeGenRdRegister (
 | |
|   IN  UINT8                   AddressSpace,
 | |
|   IN  UINT8                   BitWidth,
 | |
|   IN  UINT8                   BitOffset,
 | |
|   IN  UINT64                  Address,
 | |
|   IN  UINT8                   AccessSize,
 | |
|   IN  AML_OBJECT_NODE_HANDLE  NameOpNode  OPTIONAL,
 | |
|   OUT AML_DATA_NODE_HANDLE    *NewRdNode  OPTIONAL
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS                            Status;
 | |
|   AML_DATA_NODE                         *RdNode;
 | |
|   EFI_ACPI_GENERIC_REGISTER_DESCRIPTOR  RdRegister;
 | |
| 
 | |
|   // Cf. ACPI 6.4, s14.7 Referencing the PCC address space
 | |
|   // The AccessSize represents the Subspace Id for the PCC address space.
 | |
|   if (((AddressSpace == EFI_ACPI_6_4_PLATFORM_COMMUNICATION_CHANNEL) &&
 | |
|        (AccessSize > 256)) ||
 | |
|       ((AddressSpace != EFI_ACPI_6_4_PLATFORM_COMMUNICATION_CHANNEL) &&
 | |
|        (AccessSize > EFI_ACPI_6_4_QWORD)) ||
 | |
|       ((NameOpNode == NULL) && (NewRdNode == NULL)))
 | |
|   {
 | |
|     ASSERT (0);
 | |
|     return EFI_INVALID_PARAMETER;
 | |
|   }
 | |
| 
 | |
|   // Header
 | |
|   RdRegister.Header.Header.Bits.Name =
 | |
|     ACPI_LARGE_GENERIC_REGISTER_DESCRIPTOR_NAME;
 | |
|   RdRegister.Header.Header.Bits.Type = ACPI_LARGE_ITEM_FLAG;
 | |
|   RdRegister.Header.Length           = sizeof (EFI_ACPI_GENERIC_REGISTER_DESCRIPTOR) -
 | |
|                                        sizeof (ACPI_LARGE_RESOURCE_HEADER);
 | |
| 
 | |
|   // Body
 | |
|   RdRegister.AddressSpaceId    = AddressSpace;
 | |
|   RdRegister.RegisterBitWidth  = BitWidth;
 | |
|   RdRegister.RegisterBitOffset = BitOffset;
 | |
|   RdRegister.AddressSize       = AccessSize;
 | |
|   RdRegister.RegisterAddress   = Address;
 | |
| 
 | |
|   Status = AmlCreateDataNode (
 | |
|              EAmlNodeDataTypeResourceData,
 | |
|              (UINT8 *)&RdRegister,
 | |
|              sizeof (EFI_ACPI_GENERIC_REGISTER_DESCRIPTOR),
 | |
|              &RdNode
 | |
|              );
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     ASSERT (0);
 | |
|     return Status;
 | |
|   }
 | |
| 
 | |
|   return LinkRdNode (RdNode, NameOpNode, NewRdNode);
 | |
| }
 | |
| 
 | |
| /** Code generation for the EndTag resource data.
 | |
| 
 | |
|   The EndTag resource data is automatically generated by the ASL compiler
 | |
|   at the end of a list of resource data elements. Thus, it doesn't have
 | |
|   a corresponding ASL function.
 | |
| 
 | |
|   This function allocates memory to create a data node. It is the caller's
 | |
|   responsibility to either:
 | |
|    - attach this node to an AML tree;
 | |
|    - delete this node.
 | |
| 
 | |
|   ACPI 6.4, s6.4.2.9 "End Tag":
 | |
|   "This checksum is generated such that adding it to the sum of all the data
 | |
|   bytes will produce a zero sum."
 | |
|   "If the checksum field is zero, the resource data is treated as if the
 | |
|   checksum operation succeeded. Configuration proceeds normally."
 | |
| 
 | |
|   To avoid re-computing checksums, if a new resource data elements is
 | |
|   added/removed/modified in a list of resource data elements, the AmlLib
 | |
|   resets the checksum to 0.
 | |
| 
 | |
|   @param [in]  CheckSum        CheckSum to store in the EndTag.
 | |
|                                To ignore/avoid computing the checksum,
 | |
|                                give 0.
 | |
|   @param [in]  ParentNode      If not NULL, add the generated node
 | |
|                                to the end of the variable list of
 | |
|                                argument of the ParentNode.
 | |
|                                The ParentNode must not initially contain
 | |
|                                an EndTag resource data element.
 | |
|   @param  [out] NewRdNode      If success, contains the generated node.
 | |
| 
 | |
|   @retval EFI_SUCCESS             The function completed successfully.
 | |
|   @retval EFI_INVALID_PARAMETER   Invalid parameter.
 | |
|   @retval EFI_OUT_OF_RESOURCES    Could not allocate memory.
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| AmlCodeGenEndTag (
 | |
|   IN  UINT8            CheckSum    OPTIONAL,
 | |
|   IN  AML_OBJECT_NODE  *ParentNode  OPTIONAL,
 | |
|   OUT AML_DATA_NODE    **NewRdNode   OPTIONAL
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS                   Status;
 | |
|   AML_DATA_NODE                *RdNode;
 | |
|   EFI_ACPI_END_TAG_DESCRIPTOR  EndTag;
 | |
|   ACPI_SMALL_RESOURCE_HEADER   SmallResHdr;
 | |
| 
 | |
|   if ((ParentNode == NULL) && (NewRdNode == NULL)) {
 | |
|     ASSERT (0);
 | |
|     return EFI_INVALID_PARAMETER;
 | |
|   }
 | |
| 
 | |
|   RdNode = NULL;
 | |
| 
 | |
|   // Header
 | |
|   SmallResHdr.Bits.Length = sizeof (EFI_ACPI_END_TAG_DESCRIPTOR) -
 | |
|                             sizeof (ACPI_SMALL_RESOURCE_HEADER);
 | |
|   SmallResHdr.Bits.Name = ACPI_SMALL_END_TAG_DESCRIPTOR_NAME;
 | |
|   SmallResHdr.Bits.Type = ACPI_SMALL_ITEM_FLAG;
 | |
| 
 | |
|   // Body
 | |
|   EndTag.Desc     = SmallResHdr.Byte;
 | |
|   EndTag.Checksum = CheckSum;
 | |
| 
 | |
|   Status = AmlCreateDataNode (
 | |
|              EAmlNodeDataTypeResourceData,
 | |
|              (UINT8 *)&EndTag,
 | |
|              sizeof (EFI_ACPI_END_TAG_DESCRIPTOR),
 | |
|              &RdNode
 | |
|              );
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     ASSERT (0);
 | |
|     return Status;
 | |
|   }
 | |
| 
 | |
|   if (NewRdNode != NULL) {
 | |
|     *NewRdNode = RdNode;
 | |
|   }
 | |
| 
 | |
|   if (ParentNode != NULL) {
 | |
|     // Check the BufferOp doesn't contain any resource data yet.
 | |
|     // This is a hard check: do not allow to add an EndTag if the BufferNode
 | |
|     // already has resource data elements attached. Indeed, the EndTag should
 | |
|     // have already been added.
 | |
|     if (AmlGetNextVariableArgument ((AML_NODE_HEADER *)ParentNode, NULL) !=
 | |
|         NULL)
 | |
|     {
 | |
|       ASSERT (0);
 | |
|       Status = EFI_INVALID_PARAMETER;
 | |
|       goto error_handler;
 | |
|     }
 | |
| 
 | |
|     // Add the EndTag RdNode. Indeed, the AmlAppendRdNode function
 | |
|     // is looking for an EndTag, which we are adding here.
 | |
|     Status = AmlVarListAddTail (
 | |
|                (AML_NODE_HEADER *)ParentNode,
 | |
|                (AML_NODE_HEADER *)RdNode
 | |
|                );
 | |
|     if (EFI_ERROR (Status)) {
 | |
|       ASSERT (0);
 | |
|       goto error_handler;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   return Status;
 | |
| 
 | |
| error_handler:
 | |
|   if (RdNode != NULL) {
 | |
|     AmlDeleteTree ((AML_NODE_HEADER *)RdNode);
 | |
|   }
 | |
| 
 | |
|   return Status;
 | |
| }
 |