--- /dev/null
+/** @file\r
+ AML Resource Data Code Generation.\r
+\r
+ Copyright (c) 2020, Arm Limited. All rights reserved.<BR>\r
+\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+ @par Glossary:\r
+ - Rd or RD - Resource Data\r
+ - Rds or RDS - Resource Data Small\r
+ - Rdl or RDL - Resource Data Large\r
+**/\r
+\r
+#include <AmlNodeDefines.h>\r
+#include <CodeGen/AmlResourceDataCodeGen.h>\r
+\r
+#include <AmlCoreInterface.h>\r
+#include <AmlDefines.h>\r
+#include <Api/AmlApiHelper.h>\r
+#include <Tree/AmlNode.h>\r
+#include <ResourceData/AmlResourceData.h>\r
+\r
+/** If ParentNode is not NULL, append RdNode.\r
+ If NewRdNode is not NULL, update its value to RdNode.\r
+\r
+ @param [in] RdNode Newly created Resource Data node.\r
+ @param [in] ParentNode If not NULL, add the generated node\r
+ to the end of the variable list of\r
+ argument of the ParentNode, but\r
+ before the "End Tag" Resource Data.\r
+ Must be a BufferOpNode.\r
+ @param [out] NewRdNode If not NULL, update the its value to RdNode.\r
+\r
+ @retval EFI_SUCCESS The function completed successfully.\r
+ @retval EFI_INVALID_PARAMETER Invalid parameter.\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+EFIAPI\r
+LinkRdNode (\r
+ IN AML_DATA_NODE * RdNode,\r
+ IN AML_OBJECT_NODE * ParentNode,\r
+ IN AML_DATA_NODE ** NewRdNode\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_STATUS Status1;\r
+\r
+ if (NewRdNode != NULL) {\r
+ *NewRdNode = RdNode;\r
+ }\r
+\r
+ // Add RdNode as the last element, but before the EndTag.\r
+ if (ParentNode != NULL) {\r
+ Status = AmlAppendRdNode (ParentNode, RdNode);\r
+ if (EFI_ERROR (Status)) {\r
+ ASSERT (0);\r
+ Status1 = AmlDeleteTree ((AML_NODE_HEADER*)RdNode);\r
+ ASSERT_EFI_ERROR (Status1);\r
+ // Return original error.\r
+ return Status;\r
+ }\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/** Code generation for the "Interrupt ()" ASL function.\r
+\r
+ This function creates a Resource Data element corresponding to the\r
+ "Interrupt ()" ASL function and stores it in an AML Data Node.\r
+\r
+ The Resource Data effectively created is an Extended Interrupt Resource\r
+ Data. See ACPI 6.3 specification, s6.4.3.6 "Extended Interrupt Descriptor"\r
+ for more information about Extended Interrupt Resource Data.\r
+\r
+ This function allocates memory to create a data node. It is the caller's\r
+ responsibility to either:\r
+ - attach this node to an AML tree;\r
+ - delete this node.\r
+\r
+ @param [in] ResourceConsumer The device consumes the specified interrupt\r
+ or produces it for use by a child device.\r
+ @param [in] EdgeTriggered The interrupt is edge triggered or\r
+ level triggered.\r
+ @param [in] ActiveLow The interrupt is active-high or active-low.\r
+ @param [in] Shared The interrupt can be shared with other\r
+ devices or not (Exclusive).\r
+ @param [in] IrqList Interrupt list. Must be non-NULL.\r
+ @param [in] IrqCount Interrupt count. Must be non-zero.\r
+ @param [in] ParentNode If not NULL, add the generated node\r
+ to the end of the variable list of\r
+ argument of the ParentNode, but\r
+ before the "End Tag" Resource Data.\r
+ Must be a BufferOpNode.\r
+ @param [out] NewRdNode If success, contains the generated node.\r
+\r
+ @retval EFI_SUCCESS The function completed successfully.\r
+ @retval EFI_INVALID_PARAMETER Invalid parameter.\r
+ @retval EFI_OUT_OF_RESOURCES Could not allocate memory.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+AmlCodeGenInterrupt (\r
+ IN BOOLEAN ResourceConsumer,\r
+ IN BOOLEAN EdgeTriggered,\r
+ IN BOOLEAN ActiveLow,\r
+ IN BOOLEAN Shared,\r
+ IN UINT32 * IrqList,\r
+ IN UINT8 IrqCount,\r
+ IN AML_OBJECT_NODE * ParentNode, OPTIONAL\r
+ OUT AML_DATA_NODE ** NewRdNode OPTIONAL\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ AML_DATA_NODE * RdNode;\r
+ EFI_ACPI_EXTENDED_INTERRUPT_DESCRIPTOR RdInterrupt;\r
+ UINT32 * FirstInterrupt;\r
+\r
+ if ((IrqList == NULL) ||\r
+ (IrqCount == 0) ||\r
+ ((ParentNode == NULL) && (NewRdNode == NULL))) {\r
+ ASSERT (0);\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ RdInterrupt.Header.Header.Bits.Name =\r
+ ACPI_LARGE_EXTENDED_IRQ_DESCRIPTOR_NAME;\r
+ RdInterrupt.Header.Header.Bits.Type = ACPI_LARGE_ITEM_FLAG;\r
+ RdInterrupt.Header.Length = sizeof (EFI_ACPI_EXTENDED_INTERRUPT_DESCRIPTOR) -\r
+ sizeof (ACPI_LARGE_RESOURCE_HEADER);\r
+ RdInterrupt.InterruptVectorFlags = (ResourceConsumer ? BIT0 : 0) |\r
+ (EdgeTriggered ? BIT1 : 0) |\r
+ (ActiveLow ? BIT2 : 0) |\r
+ (Shared ? BIT3 : 0);\r
+ RdInterrupt.InterruptTableLength = IrqCount;\r
+\r
+ // Get the address of the first interrupt field.\r
+ FirstInterrupt = RdInterrupt.InterruptNumber;\r
+\r
+ // Copy the list of interrupts.\r
+ CopyMem (FirstInterrupt, IrqList, (sizeof (UINT32) * IrqCount));\r
+\r
+ Status = AmlCreateDataNode (\r
+ EAmlNodeDataTypeResourceData,\r
+ (UINT8*)&RdInterrupt,\r
+ sizeof (EFI_ACPI_EXTENDED_INTERRUPT_DESCRIPTOR),\r
+ &RdNode\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ ASSERT (0);\r
+ return Status;\r
+ }\r
+\r
+ return LinkRdNode (RdNode, ParentNode, NewRdNode);\r
+}\r
+\r
+/** Add an Interrupt Resource Data node.\r
+\r
+ This function creates a Resource Data element corresponding to the\r
+ "Interrupt ()" ASL function, stores it in an AML Data Node.\r
+\r
+ It then adds it after the input CurrRdNode in the list of resource data\r
+ element.\r
+\r
+ The Resource Data effectively created is an Extended Interrupt Resource\r
+ Data. See ACPI 6.3 specification, s6.4.3.6 "Extended Interrupt Descriptor"\r
+ for more information about Extended Interrupt Resource Data.\r
+\r
+ The Extended Interrupt contains one single interrupt.\r
+\r
+ This function allocates memory to create a data node. It is the caller's\r
+ responsibility to either:\r
+ - attach this node to an AML tree;\r
+ - delete this node.\r
+\r
+ Note: The _CRS node must be defined using the ASL Name () function.\r
+ e.g. Name (_CRS, ResourceTemplate () {\r
+ ...\r
+ }\r
+\r
+ @param [in] NameOpCrsNode NameOp object node defining a "_CRS" object.\r
+ Must have an OpCode=AML_NAME_OP, SubOpCode=0.\r
+ NameOp object nodes are defined in ASL\r
+ using the "Name ()" function.\r
+ @param [in] ResourceConsumer The device consumes the specified interrupt\r
+ or produces it for use by a child device.\r
+ @param [in] EdgeTriggered The interrupt is edge triggered or\r
+ level triggered.\r
+ @param [in] ActiveLow The interrupt is active-high or active-low.\r
+ @param [in] Shared The interrupt can be shared with other\r
+ devices or not (Exclusive).\r
+ @param [in] IrqList Interrupt list. Must be non-NULL.\r
+ @param [in] IrqCount Interrupt count. Must be non-zero.\r
+\r
+\r
+ @retval EFI_SUCCESS The function completed successfully.\r
+ @retval EFI_INVALID_PARAMETER Invalid parameter.\r
+ @retval EFI_OUT_OF_RESOURCES Could not allocate memory.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+AmlCodeGenCrsAddRdInterrupt (\r
+ IN AML_OBJECT_NODE_HANDLE NameOpCrsNode,\r
+ IN BOOLEAN ResourceConsumer,\r
+ IN BOOLEAN EdgeTriggered,\r
+ IN BOOLEAN ActiveLow,\r
+ IN BOOLEAN Shared,\r
+ IN UINT32 * IrqList,\r
+ IN UINT8 IrqCount\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ AML_OBJECT_NODE_HANDLE BufferOpNode;\r
+\r
+ if ((IrqList == NULL) ||\r
+ (IrqCount == 0) ||\r
+ (!AmlNodeHasOpCode (NameOpCrsNode, AML_NAME_OP, 0)) ||\r
+ (!AmlNameOpCompareName (NameOpCrsNode, "_CRS"))) {\r
+ ASSERT (0);\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ // Get the _CRS value which is represented as a BufferOp object node\r
+ // which is the 2nd fixed argument (i.e. index 1).\r
+ BufferOpNode = (AML_OBJECT_NODE_HANDLE)AmlGetFixedArgument (\r
+ NameOpCrsNode,\r
+ EAmlParseIndexTerm1\r
+ );\r
+ if ((BufferOpNode == NULL) ||\r
+ (AmlGetNodeType ((AML_NODE_HANDLE)BufferOpNode) != EAmlNodeObject) ||\r
+ (!AmlNodeHasOpCode (BufferOpNode, AML_BUFFER_OP, 0))) {\r
+ ASSERT (0);\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ // Generate the Extended Interrupt Resource Data node,\r
+ // and attach it as the last variable argument of the BufferOpNode.\r
+ Status = AmlCodeGenInterrupt (\r
+ ResourceConsumer,\r
+ EdgeTriggered,\r
+ ActiveLow,\r
+ Shared,\r
+ IrqList,\r
+ IrqCount,\r
+ BufferOpNode,\r
+ NULL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ ASSERT (0);\r
+ }\r
+\r
+ return Status;\r
+}\r
--- /dev/null
+/** @file\r
+ AML Resource Data Code Generation.\r
+\r
+ Copyright (c) 2019 - 2020, Arm Limited. All rights reserved.<BR>\r
+\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
+**/\r
+\r
+#ifndef AML_RESOURCE_DATA_CODE_GEN_H_\r
+#define AML_RESOURCE_DATA_CODE_GEN_H_\r
+\r
+/** Code generation for the "Interrupt ()" ASL function.\r
+\r
+ This function creates a Resource Data element corresponding to the\r
+ "Interrupt ()" ASL function and stores it in an AML Data Node.\r
+\r
+ The Resource Data effectively created is an Extended Interrupt Resource\r
+ Data. See ACPI 6.3 specification, s6.4.3.6 "Extended Interrupt Descriptor"\r
+ for more information about Extended Interrupt Resource Data.\r
+\r
+ This function allocates memory to create a data node. It is the caller's\r
+ responsibility to either:\r
+ - attach this node to an AML tree;\r
+ - delete this node.\r
+\r
+ @param [in] ResourceConsumer The device consumes the specified interrupt\r
+ or produces it for use by a child device.\r
+ @param [in] EdgeTriggered The interrupt is edge triggered or\r
+ level triggered.\r
+ @param [in] ActiveLow The interrupt is active-high or active-low.\r
+ @param [in] Shared The interrupt can be shared with other\r
+ devices or not (Exclusive).\r
+ @param [in] IrqList Interrupt list. Must be non-NULL.\r
+ @param [in] IrqCount Interrupt count. Must be non-zero.\r
+ @param [in] ParentNode If not NULL, add the generated node\r
+ to the end of the variable list of\r
+ argument of the ParentNode, but\r
+ before the "End Tag" Resource Data.\r
+ Must be a BufferOpNode.\r
+ @param [out] NewRdNode If success, contains the generated node.\r
+\r
+ @retval EFI_SUCCESS The function completed successfully.\r
+ @retval EFI_INVALID_PARAMETER Invalid parameter.\r
+ @retval EFI_OUT_OF_RESOURCES Could not allocate memory.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+AmlCodeGenInterrupt (\r
+ IN BOOLEAN ResourceConsumer,\r
+ IN BOOLEAN EdgeTriggered,\r
+ IN BOOLEAN ActiveLow,\r
+ IN BOOLEAN Shared,\r
+ IN UINT32 * IrqList,\r
+ IN UINT8 IrqCount,\r
+ IN AML_OBJECT_NODE * ParentNode, OPTIONAL\r
+ OUT AML_DATA_NODE ** NewRdNode OPTIONAL\r
+ );\r
+\r
+#endif // AML_RESOURCE_DATA_CODE_GEN_H_\r