/** @file AML Resource Data Code Generation. Copyright (c) 2020 - 2021, Arm Limited. All rights reserved.
Copyright (C) 2023 - 2025 Advanced Micro Devices, Inc. All rights reserved.
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 #include #include #include #include #include #include /** 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 AML_MEMORY_ATTRIBUTES_MEM 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 AML_MEMORY_ATTRIBUTES_MTP 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 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 ) { // 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 "WordIO ()" ASL function. The Resource Data effectively created is a Word Address Space Resource Data. Cf ACPI 6.5: - s6.4.3.5.3 "Word Address Space Descriptor". 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] 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. Not supported. Must be 0. @param [in] ResourceSource Resource Source. Not supported. 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 AmlCodeGenRdWordIo ( IN BOOLEAN IsResourceConsumer, IN BOOLEAN IsMinFixed, IN BOOLEAN IsMaxFixed, IN BOOLEAN IsPosDecode, IN UINT8 IsaRanges, IN UINT16 AddressGranularity, IN UINT16 AddressMinimum, IN UINT16 AddressMaximum, IN UINT16 AddressTranslation, IN UINT16 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 AmlCodeGenRdWordSpace ( 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 "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 "QWordIO ()" 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.109 "QWordIO". 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.109 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 AmlCodeGenRdQWordIo ( IN BOOLEAN IsResourceConsumer, IN BOOLEAN IsMinFixed, IN BOOLEAN IsMaxFixed, IN BOOLEAN IsPosDecode, IN UINT8 IsaRanges, IN UINT64 AddressGranularity, IN UINT64 AddressMinimum, IN UINT64 AddressMaximum, IN UINT64 AddressTranslation, IN UINT64 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 AmlCodeGenRdQWordSpace ( 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 "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 AML_MEMORY_ATTRIBUTES_MEM 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 AML_MEMORY_ATTRIBUTES_MTP 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 > 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 "IO ()" ASL function. The Resource Data effectively created is a IO Resource Data. Cf ACPI 6.5: - s19.6.65 IO (IO Resource Descriptor Macro) - s6.4.2.5 I/O Port Descriptor 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] IsDecoder16 Decoder parameter. TRUE if 16-bit decoder. FALSE if 10-bit decoder. @param [in] AddressMinimum Minimum address. @param [in] AddressMaximum Maximum address. @param [in] Alignment Alignment. @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] NewRdNode If provided and success, contain the created node. @retval EFI_SUCCESS The function completed successfully. @retval EFI_INVALID_PARAMETER Invalid parameter. **/ EFI_STATUS EFIAPI AmlCodeGenRdIo ( IN BOOLEAN IsDecoder16, IN UINT16 AddressMinimum, IN UINT16 AddressMaximum, IN UINT8 Alignment, IN UINT8 RangeLength, IN AML_OBJECT_NODE_HANDLE NameOpNode, OPTIONAL OUT AML_DATA_NODE_HANDLE *NewRdNode OPTIONAL ) { EFI_STATUS Status; EFI_ACPI_IO_PORT_DESCRIPTOR IoDesc; AML_DATA_NODE *IoNode; if (AddressMinimum > AddressMaximum) { return EFI_INVALID_PARAMETER; } if (Alignment != 0) { /// check the alignment if ((AddressMinimum % Alignment) != 0) { return EFI_INVALID_PARAMETER; } if ((AddressMaximum % Alignment) != 0) { return EFI_INVALID_PARAMETER; } } IoDesc.Header.Byte = ACPI_IO_PORT_DESCRIPTOR; IoDesc.Information = IsDecoder16 ? BIT0 : 0; IoDesc.BaseAddressMin = AddressMinimum; IoDesc.BaseAddressMax = AddressMaximum; IoDesc.Alignment = Alignment; IoDesc.Length = RangeLength; Status = AmlCreateDataNode ( EAmlNodeDataTypeResourceData, (UINT8 *)&IoDesc, sizeof (IoDesc), &IoNode ); if (EFI_ERROR (Status)) { ASSERT (0); return Status; } return LinkRdNode (IoNode, 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; } /** Code generation for the IRQ Descriptor. The Resource Data effectively created is an IRQ Resource Data. Cf ACPI 6.5 specification: - s6.4.2.1 "IRQ Descriptor" - s19.6.66 "IRQ (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] IsEdgeTriggered The interrupt is edge triggered or level triggered. @param [in] IsActiveLow The interrupt is active-high or active-low. @param [in] IsShared The interrupt can be shared with other devices or not (Exclusive). @param [in] IrqList List of IRQ numbers. Must be non-NULL. @param [in] IrqCount Number of IRQs in IrqList. Must be > 0 and <= 16. @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 various Other errors as indicated. **/ EFI_STATUS EFIAPI AmlCodeGenRdIrq ( IN BOOLEAN IsEdgeTriggered, IN BOOLEAN IsActiveLow, IN BOOLEAN IsShared, IN UINT8 *IrqList, IN UINT8 IrqCount, IN AML_OBJECT_NODE_HANDLE NameOpNode OPTIONAL, OUT AML_DATA_NODE_HANDLE *NewRdNode OPTIONAL ) { AML_DATA_NODE *RdNode; EFI_ACPI_IRQ_DESCRIPTOR IrqDesc; EFI_STATUS Status; UINT8 Index; UINT16 Mask; if ((NameOpNode == NULL) && (NewRdNode == NULL)) { ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER); return EFI_INVALID_PARAMETER; } if ((IsEdgeTriggered && !IsActiveLow) || (!IsEdgeTriggered && IsActiveLow)) { ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER); return EFI_INVALID_PARAMETER; } if ((IrqList == NULL) || (IrqCount == 0) || (IrqCount > 16)) { ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER); return EFI_INVALID_PARAMETER; } Mask = 0; for (Index = 0; Index < IrqCount; Index++) { if (IrqList[Index] > 16) { ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER); return EFI_INVALID_PARAMETER; } if ((Mask & (1 << IrqList[Index])) != 0) { ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER); return EFI_INVALID_PARAMETER; } Mask |= (1 << IrqList[Index]); } if (Mask == 0) { ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER); return EFI_INVALID_PARAMETER; } IrqDesc.Header.Bits.Type = ACPI_SMALL_ITEM_FLAG; IrqDesc.Header.Bits.Name = ACPI_SMALL_IRQ_DESCRIPTOR_NAME; IrqDesc.Header.Bits.Length = sizeof (EFI_ACPI_IRQ_DESCRIPTOR) - sizeof (ACPI_SMALL_RESOURCE_HEADER); IrqDesc.Mask = Mask; IrqDesc.Information = (IsEdgeTriggered ? BIT0 : 0) | (IsActiveLow ? BIT3 : 0) | (IsShared ? BIT4 : 0); Status = AmlCreateDataNode ( EAmlNodeDataTypeResourceData, (UINT8 *)&IrqDesc, sizeof (EFI_ACPI_IRQ_DESCRIPTOR), &RdNode ); if (EFI_ERROR (Status)) { ASSERT_EFI_ERROR (Status); return Status; } return LinkRdNode (RdNode, NameOpNode, NewRdNode); } /** Code generation for the UART Serial Bus Connection Resource Descriptor. The Resource Data effectively created is a UART Serial Bus Connection Resource Descriptor Resource Data. Cf ACPI 6.5: - s19.6.143 UARTSerialBusV2 (UART Serial Bus Connection Resource Descriptor Version 2 Macro) - s6.4.3.8.2.3 UART Serial Bus Connection Resource Descriptor 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] IsResourceConsumer ResourceUsage parameter. @param [in] IsSlaveMode Indicates whether the uart operates in slave mode. @param [in] IsBigEndian Indicates whether the bit transfer is big-endian. @param [in] BitsPerByte Indicates the number of bits per byte. @param [in] StopBits Specifies the stop bits format used. @param [in] FlowControl Specifies the flow control protocol used. @param [in] BaudRate Specifies the baud rate. @param [in] RxFifo Number of bytes in the receiver FIFO. @param [in] TxFifo Number of bytes in the transmitter FIFO. @param [in] Parity Specifies the parity format used. @param [in] SerialLinesEnabled Specifies which serial lines are enabled. @param [in] VendorDefinedData VendorDefinedData parameter. @param [in] VendorDefinedDataLength VendorDefinedDataLength parameter. @param [in] ResourceSource Name of source resource used. @param [in] ResourceSourceLength Resource Source Length. @param [in] NameOpNode NameOpNode 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. @retval various Other errors as indicated. **/ STATIC EFI_STATUS EFIAPI AmlCodeGenRdUartSerialBus ( IN BOOLEAN IsResourceConsumer, IN BOOLEAN IsSlaveMode, IN BOOLEAN IsBigEndian, IN UINT8 BitsPerByte, IN UINT8 StopBits, IN UINT8 FlowControl, IN UINT32 BaudRate, IN UINT16 RxFifo, IN UINT16 TxFifo, IN UINT8 Parity, IN UINT8 SerialLinesEnabled, IN UINT8 *VendorDefinedData OPTIONAL, IN UINT16 VendorDefinedDataLength, IN CHAR8 *ResourceSource, IN UINT16 ResourceSourceLength, IN AML_OBJECT_NODE_HANDLE NameOpNode OPTIONAL, OUT AML_DATA_NODE_HANDLE *NewRdNode OPTIONAL ) { AML_DATA_NODE *RdNode; EFI_STATUS Status; UINT16 UartDescBuffLength; UINT8 *UartDescBuff; UINT8 BitsPerByteMask; EFI_ACPI_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR UartDesc; if ((NameOpNode == NULL) && (NewRdNode == NULL)) { ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER); return EFI_INVALID_PARAMETER; } if (((VendorDefinedData == NULL) && (VendorDefinedDataLength > 0)) || ((VendorDefinedData != NULL) && (VendorDefinedDataLength == 0))) { ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER); return EFI_INVALID_PARAMETER; } if ((ResourceSource == NULL) || (ResourceSourceLength <= 0)) { ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER); return EFI_INVALID_PARAMETER; } if (StopBits > EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_TSF_STOP_BIT_2) { ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER); return EFI_INVALID_PARAMETER; } if (FlowControl > EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_TSF_FC_XON_XOFF) { ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER); return EFI_INVALID_PARAMETER; } if (Parity > EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_PARITY_SPACE) { ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER); return EFI_INVALID_PARAMETER; } switch (BitsPerByte) { case 5: BitsPerByteMask = EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_TSF_5_BITS_PER_BYTE; break; case 6: BitsPerByteMask = EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_TSF_6_BITS_PER_BYTE; break; case 7: BitsPerByteMask = EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_TSF_7_BITS_PER_BYTE; break; case 8: BitsPerByteMask = EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_TSF_8_BITS_PER_BYTE; break; case 9: BitsPerByteMask = EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_TSF_9_BITS_PER_BYTE; break; default: ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER); return EFI_INVALID_PARAMETER; } /// as per spec last two bits are reserved and must be 0. if ((SerialLinesEnabled & ~(EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_LIN_RTS | EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_LIN_CTS | EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_LIN_DTR | EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_LIN_DSR | EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_LIN_RI | EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_LIN_DTD)) != 0) { ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER); return EFI_INVALID_PARAMETER; } UartDesc.Header.Header.Bits.Type = ACPI_LARGE_ITEM_FLAG; UartDesc.Header.Header.Bits.Name = ACPI_LARGE_GENERIC_SERIAL_BUS_CONNECTION_DESCRIPTOR_NAME; UartDesc.RevisionId = EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_REVISION_ID; UartDesc.ResourceSourceIndex = 0; UartDesc.SerialBusType = EFI_ACPI_SERIAL_BUS_RESOURCE_TYPE_UART; UartDesc.GeneralFlags = (IsResourceConsumer ? BIT1 : 0) | (IsSlaveMode ? BIT0 : 0); UartDesc.TypeSpecificFlags = (IsBigEndian ? BIT7 : 0) | (BitsPerByteMask << 4) | (StopBits << 2) | (FlowControl); UartDesc.TypeSpecificRevisionId = EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_REVISION_ID; /// TypeDataLength is the length of the data following the TypeDataLength, /// up to the Additional vendor supplied data (not included). UartDesc.TypeDataLength = sizeof (UartDesc.DefaultBaudRate) + sizeof (UartDesc.RxFIFO) + sizeof (UartDesc.TxFIFO) + sizeof (UartDesc.Parity) + sizeof (UartDesc.SerialLinesEnabled) + VendorDefinedDataLength; UartDesc.DefaultBaudRate = BaudRate; UartDesc.RxFIFO = RxFifo; UartDesc.TxFIFO = TxFifo; UartDesc.Parity = Parity; UartDesc.SerialLinesEnabled = SerialLinesEnabled; UartDescBuffLength = sizeof (EFI_ACPI_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR) + VendorDefinedDataLength + ResourceSourceLength; UartDesc.Header.Length = UartDescBuffLength - sizeof (ACPI_LARGE_RESOURCE_HEADER); UartDescBuff = AllocateZeroPool (UartDescBuffLength); if (UartDescBuff == NULL) { ASSERT_EFI_ERROR (EFI_OUT_OF_RESOURCES); return EFI_OUT_OF_RESOURCES; } CopyMem ( UartDescBuff, &UartDesc, sizeof (EFI_ACPI_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR) ); if (VendorDefinedData != NULL) { CopyMem ( UartDescBuff + sizeof (EFI_ACPI_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR), VendorDefinedData, VendorDefinedDataLength ); } CopyMem ( UartDescBuff + sizeof (EFI_ACPI_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR) + VendorDefinedDataLength, ResourceSource, ResourceSourceLength ); Status = AmlCreateDataNode ( EAmlNodeDataTypeResourceData, UartDescBuff, UartDescBuffLength, &RdNode ); FreePool (UartDescBuff); if (EFI_ERROR (Status)) { ASSERT_EFI_ERROR (Status); return Status; } return LinkRdNode (RdNode, NameOpNode, NewRdNode); } /** Code generation for the UARTSerialBusV2() ASL macro. The Resource Data effectively created is a UART Serial Bus Connection Resource Descriptor Resource Data. Cf ACPI 6.5: - s19.6.143 UARTSerialBusV2 (UART Serial Bus Connection Resource Descriptor Version 2 Macro) - s6.4.3.8.2.3 UART Serial Bus Connection Resource Descriptor 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] InitialBaudRate Initial baud rate. @param [in] BitsPerByte Number of bits per byte. Optional, default is 8. @param [in] StopBits Number of stop bits. Optional, default is 1. @param [in] LinesInUse Number of lines in use. @param [in] IsBigEndian Indicates whether the bit transfer is big-endian. Optional, default is FALSE (little-endian). @param [in] Parity Parity format used. Optional, default is no parity. @param [in] FlowControl Flow control protocol used. Optional, default is no flow control. @param [in] ReceiveBufferSize Size of the receive buffer. @param [in] TransmitBufferSize Size of the transmit buffer. @param [in] ResourceSource Name of source resource used. @param [in] ResourceSourceLength Length of the Resource Source. @param [in] ResourceSourceIndex Resource Source index. Optional, default is 0. @param [in] ResourceUsage Resource usage, TRUE for consumer, FALSE for producer. Optional, default is TRUE (consumer). @param [in] IsShared Indicates whether the resource is shared. Optional, default is FALSE (exclusive). @param [in] VendorDefinedData Vendor defined data. Optional, can be NULL. @param [in] VendorDefinedDataLength Length of the vendor defined data. @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 various Various failure values of called functions. **/ EFI_STATUS EFIAPI AmlCodeGenRdUartSerialBusV2 ( IN UINT32 InitialBaudRate, IN UINT8 *BitsPerByte OPTIONAL, IN UINT8 *StopBits OPTIONAL, IN UINT8 LinesInUse, IN BOOLEAN *IsBigEndian OPTIONAL, IN UINT8 *Parity OPTIONAL, IN UINT8 *FlowControl OPTIONAL, IN UINT16 ReceiveBufferSize, IN UINT16 TransmitBufferSize, IN CHAR8 *ResourceSource, IN UINT16 ResourceSourceLength, IN UINT8 *ResourceSourceIndex OPTIONAL, IN BOOLEAN *ResourceUsage OPTIONAL, IN BOOLEAN *IsShared OPTIONAL, IN UINT8 *VendorDefinedData OPTIONAL, IN UINT16 VendorDefinedDataLength, IN AML_OBJECT_NODE_HANDLE NameOpNode OPTIONAL, OUT AML_DATA_NODE_HANDLE *NewRdNode OPTIONAL ) { EFI_STATUS Status; if ((NameOpNode == NULL) && (NewRdNode == NULL)) { ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER); return EFI_INVALID_PARAMETER; } if (((VendorDefinedData == NULL) && (VendorDefinedDataLength > 0)) || ((VendorDefinedData != NULL) && (VendorDefinedDataLength == 0))) { ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER); return EFI_INVALID_PARAMETER; } if ((ResourceSource == NULL) || (ResourceSourceLength <= 0)) { ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER); return EFI_INVALID_PARAMETER; } if (ResourceSourceIndex != NULL) { if (*ResourceSourceIndex != 0) { ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER); return EFI_INVALID_PARAMETER; } } Status = AmlCodeGenRdUartSerialBus ( /// default is resource consumer (ResourceUsage != NULL) ? *ResourceUsage : TRUE, /// slave mode TRUE, /// default is little-endian (IsBigEndian != NULL) ? *IsBigEndian : FALSE, /// default is 8 bits per byte (BitsPerByte != NULL) ? *BitsPerByte : 8, /// default is 1 stop bit (StopBits != NULL) ? *StopBits : EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_TSF_STOP_BIT_1, /// default is no flow control (FlowControl != NULL) ? *FlowControl : EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_TSF_FC_NONE, InitialBaudRate, ReceiveBufferSize, TransmitBufferSize, /// default is no parity (Parity != NULL) ? *Parity : EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_PARITY_NONE, LinesInUse, VendorDefinedData, VendorDefinedDataLength, ResourceSource, ResourceSourceLength, NameOpNode, NewRdNode ); if (EFI_ERROR (Status)) { ASSERT_EFI_ERROR (Status); return Status; } return Status; }