diff --git a/DynamicTablesPkg/Include/Library/AmlLib/AmlLib.h b/DynamicTablesPkg/Include/Library/AmlLib/AmlLib.h index 9e294ac188..4ce12419e6 100644 --- a/DynamicTablesPkg/Include/Library/AmlLib/AmlLib.h +++ b/DynamicTablesPkg/Include/Library/AmlLib/AmlLib.h @@ -2107,4 +2107,46 @@ AmlCreatePssNode ( OUT AML_OBJECT_NODE_HANDLE *NewPssNode OPTIONAL ); +/** 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 + ); + #endif // AML_LIB_H_ diff --git a/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlResourceDataCodeGen.c b/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlResourceDataCodeGen.c index bf0d7b0cca..2d776ffbd4 100644 --- a/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlResourceDataCodeGen.c +++ b/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlResourceDataCodeGen.c @@ -2,7 +2,7 @@ AML Resource Data Code Generation. Copyright (c) 2020 - 2021, Arm Limited. All rights reserved.
- Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved.
+ Copyright (C) 2023 - 2025 Advanced Micro Devices, Inc. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @@ -1670,3 +1670,111 @@ error_handler: 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); +}