From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by mx.groups.io with SMTP id smtpd.web09.9383.1632988138738418636 for ; Thu, 30 Sep 2021 00:48:58 -0700 Authentication-Results: mx.groups.io; dkim=missing; spf=pass (domain: arm.com, ip: 217.140.110.172, mailfrom: pierre.gondois@arm.com) Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 4F24A106F; Thu, 30 Sep 2021 00:48:58 -0700 (PDT) Received: from e120189.home (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 46FD13F70D; Thu, 30 Sep 2021 00:48:57 -0700 (PDT) From: "PierreGondois" To: devel@edk2.groups.io, Sami Mujawar , Alexei.Fedorov@arm.com, Joey Gouly Subject: [PATCH v2 10/10] DynamicTablesPkg: Rework AmlResourceDataCodegen.c/h Date: Thu, 30 Sep 2021 08:48:21 +0100 Message-Id: <20210930074821.12546-11-Pierre.Gondois@arm.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210930074821.12546-1-Pierre.Gondois@arm.com> References: <20210930074821.12546-1-Pierre.Gondois@arm.com> From: Pierre Gondois Rework all the functions to to have a generic prototype: - First take take the resource data specific arguments. E.g.: for a Register(): the AddressSpace, BitWidth, ... - The penultimate parameter is a NameOpNode. The resource data created is appended to the ResourceTemplate() contained in the NameOpNode. - The last parameter is a pointer holding the created resource data. A least one of the two last parameter must be provided. One of them can be omitted. This generic interface allows to either: - Add the resource data to a NameOpNode. This is a common case for the Ssdt tables generator. - Get the created resource data and let the caller place it in an AML tree. Reviewed-by: Sami Mujawar Signed-off-by: Pierre Gondois --- .../Include/Library/AmlLib/AmlLib.h | 60 +++-- .../SsdtCmn600Generator.c | 8 +- .../AmlLib/CodeGen/AmlResourceDataCodeGen.c | 235 +++++++----------- .../AmlLib/CodeGen/AmlResourceDataCodeGen.h | 67 +++-- 4 files changed, 150 insertions(+), 220 deletions(-) diff --git a/DynamicTablesPkg/Include/Library/AmlLib/AmlLib.h b/DynamicTablesPkg/Include/Library/AmlLib/AmlLib.h index c40808343fce..6824cf3a6c82 100644 --- a/DynamicTablesPkg/Include/Library/AmlLib/AmlLib.h +++ b/DynamicTablesPkg/Include/Library/AmlLib/AmlLib.h @@ -418,41 +418,36 @@ AmlUpdateRdQWord ( IN UINT64 BaseAddressLength ); -/** Add an Interrupt Resource Data node. - - This function creates a Resource Data element corresponding to the - "Interrupt ()" ASL function, stores it in an AML Data Node. - - It then adds it after the input NameOpNode in the list of resource data - element. +/** Code generation for the "Interrupt ()" ASL function. The Resource Data effectively created is an Extended Interrupt Resource - Data. See ACPI 6.3 specification, s6.4.3.6 "Extended Interrupt Descriptor" - for more information about Extended Interrupt Resource Data. + Data. Cf ACPI 6.4: + - s6.4.3.6 "Extended Interrupt Descriptor" + - s19.6.64 "Interrupt (Interrupt Resource Descriptor Macro)" - The Extended Interrupt contains one single interrupt. - - 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. + 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. @ingroup CodeGenApis + @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. - Must have an OpCode=AML_NAME_OP, SubOpCode=0. - NameOp object nodes are defined in ASL - using the "Name ()" function. - @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. - + 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. @@ -460,14 +455,15 @@ AmlUpdateRdQWord ( **/ EFI_STATUS EFIAPI -AmlCodeGenAddRdInterrupt ( - IN AML_OBJECT_NODE_HANDLE NameOpNode, +AmlCodeGenRdInterrupt ( IN BOOLEAN ResourceConsumer, IN BOOLEAN EdgeTriggered, IN BOOLEAN ActiveLow, IN BOOLEAN Shared, - IN UINT32 * IrqList, - IN UINT8 IrqCount + IN UINT32 *IrqList, + IN UINT8 IrqCount, + IN AML_OBJECT_NODE_HANDLE NameOpNode, OPTIONAL + OUT AML_DATA_NODE_HANDLE *NewRdNode OPTIONAL ); /** AML code generation for DefinitionBlock. diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCmn600LibArm/SsdtCmn600Generator.c b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCmn600LibArm/SsdtCmn600Generator.c index fb93a5d2e70c..19b7b128a08d 100644 --- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCmn600LibArm/SsdtCmn600Generator.c +++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCmn600LibArm/SsdtCmn600Generator.c @@ -338,8 +338,8 @@ FixupCmn600Info ( // Resource Data nodes. for (Index = 0; Index < Cmn600Info->DtcCount; Index++) { DtcInt = &Cmn600Info->DtcInterrupt[Index]; - Status = AmlCodeGenAddRdInterrupt ( - NameOpCrsNode, + + Status = AmlCodeGenRdInterrupt ( ((DtcInt->Flags & EFI_ACPI_EXTENDED_INTERRUPT_FLAG_PRODUCER_CONSUMER_MASK) != 0), ((DtcInt->Flags & @@ -349,7 +349,9 @@ FixupCmn600Info ( ((DtcInt->Flags & EFI_ACPI_EXTENDED_INTERRUPT_FLAG_SHARABLE_MASK) != 0), (UINT32*)&DtcInt->Interrupt, - 1 + 1, + NameOpCrsNode, + NULL ); if (EFI_ERROR (Status)) { goto error_handler; diff --git a/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlResourceDataCodeGen.c b/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlResourceDataCodeGen.c index c7348aa5daf7..089597a6c906 100644 --- a/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlResourceDataCodeGen.c +++ b/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlResourceDataCodeGen.c @@ -24,11 +24,15 @@ If NewRdNode is not NULL, update its value to RdNode. @param [in] RdNode Newly created Resource Data node. - @param [in] ParentNode If not NULL, add the generated node - to the end of the variable list of - argument of the ParentNode, but - before the "End Tag" Resource Data. - Must be a BufferOpNode. + 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, update the its value to RdNode. @retval EFI_SUCCESS The function completed successfully. @@ -43,57 +47,81 @@ LinkRdNode ( OUT AML_DATA_NODE ** NewRdNode ) { - EFI_STATUS Status; - EFI_STATUS Status1; + EFI_STATUS Status; + EFI_STATUS Status1; + AML_OBJECT_NODE *BufferOpNode; if (NewRdNode != NULL) { *NewRdNode = RdNode; } - // Add RdNode as the last element, but before the EndTag. if (ParentNode != NULL) { - Status = AmlAppendRdNode (ParentNode, RdNode); + // 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); - Status1 = AmlDeleteTree ((AML_NODE_HEADER*)RdNode); - ASSERT_EFI_ERROR (Status1); - // Return original error. - return Status; + goto error_handler; } } - return EFI_SUCCESS; + return Status; + +error_handler: + Status1 = AmlDeleteTree ((AML_NODE_HEADER*)RdNode); + ASSERT_EFI_ERROR (Status1); + // Return original error. + return Status; } /** Code generation for the "Interrupt ()" ASL function. - This function creates a Resource Data element corresponding to the - "Interrupt ()" ASL function and stores it in an AML Data Node. - The Resource Data effectively created is an Extended Interrupt Resource - Data. See ACPI 6.3 specification, s6.4.3.6 "Extended Interrupt Descriptor" - for more information about Extended Interrupt Resource Data. + Data. Cf ACPI 6.4: + - s6.4.3.6 "Extended Interrupt Descriptor" + - s19.6.64 "Interrupt (Interrupt Resource Descriptor Macro)" - 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. + 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] ParentNode If not NULL, add the generated node - to the end of the variable list of - argument of the ParentNode, but - before the "End Tag" Resource Data. - Must be a BufferOpNode. - @param [out] NewRdNode If success, contains the generated node. + @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. @@ -101,15 +129,15 @@ LinkRdNode ( **/ EFI_STATUS EFIAPI -AmlCodeGenInterrupt ( - IN BOOLEAN ResourceConsumer, - IN BOOLEAN EdgeTriggered, - IN BOOLEAN ActiveLow, - IN BOOLEAN Shared, - IN UINT32 * IrqList, - IN UINT8 IrqCount, - IN AML_OBJECT_NODE * ParentNode, OPTIONAL - OUT AML_DATA_NODE ** NewRdNode OPTIONAL +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; @@ -120,16 +148,19 @@ AmlCodeGenInterrupt ( if ((IrqList == NULL) || (IrqCount == 0) || - ((ParentNode == NULL) && (NewRdNode == NULL))) { + ((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) | @@ -153,105 +184,7 @@ AmlCodeGenInterrupt ( return Status; } - return LinkRdNode (RdNode, ParentNode, NewRdNode); -} - -/** Add an Interrupt Resource Data node. - - This function creates a Resource Data element corresponding to the - "Interrupt ()" ASL function, stores it in an AML Data Node. - - It then adds it after the input NameOpNode in the list of resource data - element. - - The Resource Data effectively created is an Extended Interrupt Resource - Data. See ACPI 6.3 specification, s6.4.3.6 "Extended Interrupt Descriptor" - for more information about Extended Interrupt Resource Data. - - The Extended Interrupt contains one single interrupt. - - 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. - - Note: - The named node must be defined using the ASL "Name ()" statement. - E.g. Name (_CRS, ResourceTemplate () { ... }) - Methods cannot be modified with this function. - - @param [in] NameOpNode NameOp object node defining a named object. - Must have an OpCode=AML_NAME_OP, SubOpCode=0. - NameOp object nodes are defined in ASL - using the "Name ()" function. - @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. - - - @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 -AmlCodeGenAddRdInterrupt ( - IN AML_OBJECT_NODE_HANDLE NameOpNode, - IN BOOLEAN ResourceConsumer, - IN BOOLEAN EdgeTriggered, - IN BOOLEAN ActiveLow, - IN BOOLEAN Shared, - IN UINT32 * IrqList, - IN UINT8 IrqCount - ) -{ - EFI_STATUS Status; - - AML_OBJECT_NODE_HANDLE BufferOpNode; - - if ((IrqList == NULL) || - (IrqCount == 0) || - (!AmlNodeHasOpCode (NameOpNode, AML_NAME_OP, 0))) { - ASSERT (0); - return EFI_INVALID_PARAMETER; - } - - // 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 ( - NameOpNode, - EAmlParseIndexTerm1 - ); - if ((BufferOpNode == NULL) || - (AmlGetNodeType ((AML_NODE_HANDLE)BufferOpNode) != EAmlNodeObject) || - (!AmlNodeHasOpCode (BufferOpNode, AML_BUFFER_OP, 0))) { - ASSERT (0); - return EFI_INVALID_PARAMETER; - } - - // Generate the Extended Interrupt Resource Data node, - // and attach it as the last variable argument of the BufferOpNode. - Status = AmlCodeGenInterrupt ( - ResourceConsumer, - EdgeTriggered, - ActiveLow, - Shared, - IrqList, - IrqCount, - BufferOpNode, - NULL - ); - if (EFI_ERROR (Status)) { - ASSERT (0); - } - - return Status; + return LinkRdNode (RdNode, NameOpNode, NewRdNode); } // DEPRECATED APIS @@ -316,15 +249,15 @@ AmlCodeGenCrsAddRdInterrupt ( IN UINT8 IrqCount ) { - return AmlCodeGenAddRdInterrupt ( - NameOpCrsNode, - NameOpNode, + return AmlCodeGenRdInterrupt ( ResourceConsumer, EdgeTriggered, ActiveLow, Shared, IrqList, - IrqCount + IrqCount, + NameOpCrsNode, + NULL ); } diff --git a/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlResourceDataCodeGen.h b/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlResourceDataCodeGen.h index 08364db4431f..764051e3d7c9 100644 --- a/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlResourceDataCodeGen.h +++ b/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlResourceDataCodeGen.h @@ -1,7 +1,7 @@ /** @file AML Resource Data Code Generation. - Copyright (c) 2019 - 2020, Arm Limited. All rights reserved.
+ Copyright (c) 2019 - 2021, Arm Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -11,33 +11,32 @@ /** Code generation for the "Interrupt ()" ASL function. - This function creates a Resource Data element corresponding to the - "Interrupt ()" ASL function and stores it in an AML Data Node. - The Resource Data effectively created is an Extended Interrupt Resource - Data. See ACPI 6.3 specification, s6.4.3.6 "Extended Interrupt Descriptor" - for more information about Extended Interrupt Resource Data. + Data. Cf ACPI 6.4: + - s6.4.3.6 "Extended Interrupt Descriptor" + - s19.6.64 "Interrupt (Interrupt Resource Descriptor Macro)" - 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. + 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] ParentNode If not NULL, add the generated node - to the end of the variable list of - argument of the ParentNode, but - before the "End Tag" Resource Data. - Must be a BufferOpNode. - @param [out] NewRdNode If success, contains the generated node. + @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. @@ -45,15 +44,15 @@ **/ EFI_STATUS EFIAPI -AmlCodeGenInterrupt ( - IN BOOLEAN ResourceConsumer, - IN BOOLEAN EdgeTriggered, - IN BOOLEAN ActiveLow, - IN BOOLEAN Shared, - IN UINT32 * IrqList, - IN UINT8 IrqCount, - IN AML_OBJECT_NODE * ParentNode, OPTIONAL - OUT AML_DATA_NODE ** NewRdNode OPTIONAL +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 ); #endif // AML_RESOURCE_DATA_CODE_GEN_H_ -- 2.17.1