| /** @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; | |
| } |