DynamicTablesPkg: Rework AmlResourceDataCodegen.c/h

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 <sami.mujawar@arm.com>
Signed-off-by: Pierre Gondois <Pierre.Gondois@arm.com>
This commit is contained in:
Pierre Gondois
2021-09-30 08:48:21 +01:00
committed by mergify[bot]
parent 691c5f7762
commit 22873f58c4
4 changed files with 142 additions and 212 deletions

View File

@ -418,31 +418,21 @@ AmlUpdateRdQWord (
IN UINT64 BaseAddressLength IN UINT64 BaseAddressLength
); );
/** Add an Interrupt Resource Data node. /** Code generation for the "Interrupt ()" ASL function.
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 The Resource Data effectively created is an Extended Interrupt Resource
Data. See ACPI 6.3 specification, s6.4.3.6 "Extended Interrupt Descriptor" Data. Cf ACPI 6.4:
for more information about Extended Interrupt Resource Data. - s6.4.3.6 "Extended Interrupt Descriptor"
- s19.6.64 "Interrupt (Interrupt Resource Descriptor Macro)"
The Extended Interrupt contains one single interrupt. The created resource data node can be:
- appended to the list of resource data elements of the NameOpNode.
This function allocates memory to create a data node. It is the caller's In such case NameOpNode must be defined by a the "Name ()" ASL statement
responsibility to either: and initially contain a "ResourceTemplate ()".
- attach this node to an AML tree; - returned through the NewRdNode parameter.
- delete this node.
@ingroup CodeGenApis @ingroup CodeGenApis
@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 @param [in] ResourceConsumer The device consumes the specified interrupt
or produces it for use by a child device. or produces it for use by a child device.
@param [in] EdgeTriggered The interrupt is edge triggered or @param [in] EdgeTriggered The interrupt is edge triggered or
@ -452,7 +442,12 @@ AmlUpdateRdQWord (
devices or not (Exclusive). devices or not (Exclusive).
@param [in] IrqList Interrupt list. Must be non-NULL. @param [in] IrqList Interrupt list. Must be non-NULL.
@param [in] IrqCount Interrupt count. Must be non-zero. @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_SUCCESS The function completed successfully.
@retval EFI_INVALID_PARAMETER Invalid parameter. @retval EFI_INVALID_PARAMETER Invalid parameter.
@ -460,14 +455,15 @@ AmlUpdateRdQWord (
**/ **/
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
AmlCodeGenAddRdInterrupt ( AmlCodeGenRdInterrupt (
IN AML_OBJECT_NODE_HANDLE NameOpNode,
IN BOOLEAN ResourceConsumer, IN BOOLEAN ResourceConsumer,
IN BOOLEAN EdgeTriggered, IN BOOLEAN EdgeTriggered,
IN BOOLEAN ActiveLow, IN BOOLEAN ActiveLow,
IN BOOLEAN Shared, IN BOOLEAN Shared,
IN UINT32 * IrqList, IN UINT32 *IrqList,
IN UINT8 IrqCount IN UINT8 IrqCount,
IN AML_OBJECT_NODE_HANDLE NameOpNode, OPTIONAL
OUT AML_DATA_NODE_HANDLE *NewRdNode OPTIONAL
); );
/** AML code generation for DefinitionBlock. /** AML code generation for DefinitionBlock.

View File

@ -338,8 +338,8 @@ FixupCmn600Info (
// Resource Data nodes. // Resource Data nodes.
for (Index = 0; Index < Cmn600Info->DtcCount; Index++) { for (Index = 0; Index < Cmn600Info->DtcCount; Index++) {
DtcInt = &Cmn600Info->DtcInterrupt[Index]; DtcInt = &Cmn600Info->DtcInterrupt[Index];
Status = AmlCodeGenAddRdInterrupt (
NameOpCrsNode, Status = AmlCodeGenRdInterrupt (
((DtcInt->Flags & ((DtcInt->Flags &
EFI_ACPI_EXTENDED_INTERRUPT_FLAG_PRODUCER_CONSUMER_MASK) != 0), EFI_ACPI_EXTENDED_INTERRUPT_FLAG_PRODUCER_CONSUMER_MASK) != 0),
((DtcInt->Flags & ((DtcInt->Flags &
@ -349,7 +349,9 @@ FixupCmn600Info (
((DtcInt->Flags & ((DtcInt->Flags &
EFI_ACPI_EXTENDED_INTERRUPT_FLAG_SHARABLE_MASK) != 0), EFI_ACPI_EXTENDED_INTERRUPT_FLAG_SHARABLE_MASK) != 0),
(UINT32*)&DtcInt->Interrupt, (UINT32*)&DtcInt->Interrupt,
1 1,
NameOpCrsNode,
NULL
); );
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
goto error_handler; goto error_handler;

View File

@ -24,11 +24,15 @@
If NewRdNode is not NULL, update its value to RdNode. If NewRdNode is not NULL, update its value to RdNode.
@param [in] RdNode Newly created Resource Data node. @param [in] RdNode Newly created Resource Data node.
@param [in] ParentNode If not NULL, add the generated node RdNode is deleted if an error occurs.
to the end of the variable list of @param [in] ParentNode If not NULL, ParentNode must:
argument of the ParentNode, but - be a NameOp node, i.e. have the AML_NAME_OP
before the "End Tag" Resource Data. opcode (cf "Name ()" ASL statement)
Must be a BufferOpNode. - 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. @param [out] NewRdNode If not NULL, update the its value to RdNode.
@retval EFI_SUCCESS The function completed successfully. @retval EFI_SUCCESS The function completed successfully.
@ -43,57 +47,81 @@ LinkRdNode (
OUT AML_DATA_NODE ** NewRdNode OUT AML_DATA_NODE ** NewRdNode
) )
{ {
EFI_STATUS Status; EFI_STATUS Status;
EFI_STATUS Status1; EFI_STATUS Status1;
AML_OBJECT_NODE *BufferOpNode;
if (NewRdNode != NULL) { if (NewRdNode != NULL) {
*NewRdNode = RdNode; *NewRdNode = RdNode;
} }
// Add RdNode as the last element, but before the EndTag.
if (ParentNode != NULL) { 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)) { if (EFI_ERROR (Status)) {
ASSERT (0); ASSERT (0);
Status1 = AmlDeleteTree ((AML_NODE_HEADER*)RdNode); goto error_handler;
ASSERT_EFI_ERROR (Status1);
// Return original error.
return Status;
} }
} }
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. /** 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 The Resource Data effectively created is an Extended Interrupt Resource
Data. See ACPI 6.3 specification, s6.4.3.6 "Extended Interrupt Descriptor" Data. Cf ACPI 6.4:
for more information about Extended Interrupt Resource Data. - 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 The created resource data node can be:
responsibility to either: - appended to the list of resource data elements of the NameOpNode.
- attach this node to an AML tree; In such case NameOpNode must be defined by a the "Name ()" ASL statement
- delete this node. and initially contain a "ResourceTemplate ()".
- returned through the NewRdNode parameter.
@param [in] ResourceConsumer The device consumes the specified interrupt @param [in] ResourceConsumer The device consumes the specified interrupt
or produces it for use by a child device. or produces it for use by a child device.
@param [in] EdgeTriggered The interrupt is edge triggered or @param [in] EdgeTriggered The interrupt is edge triggered or
level triggered. level triggered.
@param [in] ActiveLow The interrupt is active-high or active-low. @param [in] ActiveLow The interrupt is active-high or active-low.
@param [in] Shared The interrupt can be shared with other @param [in] Shared The interrupt can be shared with other
devices or not (Exclusive). devices or not (Exclusive).
@param [in] IrqList Interrupt list. Must be non-NULL. @param [in] IrqList Interrupt list. Must be non-NULL.
@param [in] IrqCount Interrupt count. Must be non-zero. @param [in] IrqCount Interrupt count. Must be non-zero.
@param [in] ParentNode If not NULL, add the generated node @param [in] NameOpNode NameOp object node defining a named object.
to the end of the variable list of If provided, append the new resource data node
argument of the ParentNode, but to the list of resource data elements of this
before the "End Tag" Resource Data. node.
Must be a BufferOpNode. @param [out] NewRdNode If provided and success,
@param [out] NewRdNode If success, contains the generated node. contain the created node.
@retval EFI_SUCCESS The function completed successfully. @retval EFI_SUCCESS The function completed successfully.
@retval EFI_INVALID_PARAMETER Invalid parameter. @retval EFI_INVALID_PARAMETER Invalid parameter.
@ -101,15 +129,15 @@ LinkRdNode (
**/ **/
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
AmlCodeGenInterrupt ( AmlCodeGenRdInterrupt (
IN BOOLEAN ResourceConsumer, IN BOOLEAN ResourceConsumer,
IN BOOLEAN EdgeTriggered, IN BOOLEAN EdgeTriggered,
IN BOOLEAN ActiveLow, IN BOOLEAN ActiveLow,
IN BOOLEAN Shared, IN BOOLEAN Shared,
IN UINT32 * IrqList, IN UINT32 *IrqList,
IN UINT8 IrqCount, IN UINT8 IrqCount,
IN AML_OBJECT_NODE * ParentNode, OPTIONAL IN AML_OBJECT_NODE_HANDLE NameOpNode, OPTIONAL
OUT AML_DATA_NODE ** NewRdNode OPTIONAL OUT AML_DATA_NODE_HANDLE *NewRdNode OPTIONAL
) )
{ {
EFI_STATUS Status; EFI_STATUS Status;
@ -120,16 +148,19 @@ AmlCodeGenInterrupt (
if ((IrqList == NULL) || if ((IrqList == NULL) ||
(IrqCount == 0) || (IrqCount == 0) ||
((ParentNode == NULL) && (NewRdNode == NULL))) { ((NameOpNode == NULL) && (NewRdNode == NULL))) {
ASSERT (0); ASSERT (0);
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }
// Header
RdInterrupt.Header.Header.Bits.Name = RdInterrupt.Header.Header.Bits.Name =
ACPI_LARGE_EXTENDED_IRQ_DESCRIPTOR_NAME; ACPI_LARGE_EXTENDED_IRQ_DESCRIPTOR_NAME;
RdInterrupt.Header.Header.Bits.Type = ACPI_LARGE_ITEM_FLAG; RdInterrupt.Header.Header.Bits.Type = ACPI_LARGE_ITEM_FLAG;
RdInterrupt.Header.Length = sizeof (EFI_ACPI_EXTENDED_INTERRUPT_DESCRIPTOR) - RdInterrupt.Header.Length = sizeof (EFI_ACPI_EXTENDED_INTERRUPT_DESCRIPTOR) -
sizeof (ACPI_LARGE_RESOURCE_HEADER); sizeof (ACPI_LARGE_RESOURCE_HEADER);
// Body
RdInterrupt.InterruptVectorFlags = (ResourceConsumer ? BIT0 : 0) | RdInterrupt.InterruptVectorFlags = (ResourceConsumer ? BIT0 : 0) |
(EdgeTriggered ? BIT1 : 0) | (EdgeTriggered ? BIT1 : 0) |
(ActiveLow ? BIT2 : 0) | (ActiveLow ? BIT2 : 0) |
@ -153,105 +184,7 @@ AmlCodeGenInterrupt (
return Status; return Status;
} }
return LinkRdNode (RdNode, ParentNode, NewRdNode); return LinkRdNode (RdNode, NameOpNode, 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;
} }
// DEPRECATED APIS // DEPRECATED APIS
@ -316,15 +249,15 @@ AmlCodeGenCrsAddRdInterrupt (
IN UINT8 IrqCount IN UINT8 IrqCount
) )
{ {
return AmlCodeGenAddRdInterrupt ( return AmlCodeGenRdInterrupt (
NameOpCrsNode,
NameOpNode,
ResourceConsumer, ResourceConsumer,
EdgeTriggered, EdgeTriggered,
ActiveLow, ActiveLow,
Shared, Shared,
IrqList, IrqList,
IrqCount IrqCount,
NameOpCrsNode,
NULL
); );
} }

View File

@ -1,7 +1,7 @@
/** @file /** @file
AML Resource Data Code Generation. AML Resource Data Code Generation.
Copyright (c) 2019 - 2020, Arm Limited. All rights reserved.<BR> Copyright (c) 2019 - 2021, Arm Limited. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent SPDX-License-Identifier: BSD-2-Clause-Patent
**/ **/
@ -11,33 +11,32 @@
/** Code generation for the "Interrupt ()" ASL function. /** 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 The Resource Data effectively created is an Extended Interrupt Resource
Data. See ACPI 6.3 specification, s6.4.3.6 "Extended Interrupt Descriptor" Data. Cf ACPI 6.4:
for more information about Extended Interrupt Resource Data. - 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 The created resource data node can be:
responsibility to either: - appended to the list of resource data elements of the NameOpNode.
- attach this node to an AML tree; In such case NameOpNode must be defined by a the "Name ()" ASL statement
- delete this node. and initially contain a "ResourceTemplate ()".
- returned through the NewRdNode parameter.
@param [in] ResourceConsumer The device consumes the specified interrupt @param [in] ResourceConsumer The device consumes the specified interrupt
or produces it for use by a child device. or produces it for use by a child device.
@param [in] EdgeTriggered The interrupt is edge triggered or @param [in] EdgeTriggered The interrupt is edge triggered or
level triggered. level triggered.
@param [in] ActiveLow The interrupt is active-high or active-low. @param [in] ActiveLow The interrupt is active-high or active-low.
@param [in] Shared The interrupt can be shared with other @param [in] Shared The interrupt can be shared with other
devices or not (Exclusive). devices or not (Exclusive).
@param [in] IrqList Interrupt list. Must be non-NULL. @param [in] IrqList Interrupt list. Must be non-NULL.
@param [in] IrqCount Interrupt count. Must be non-zero. @param [in] IrqCount Interrupt count. Must be non-zero.
@param [in] ParentNode If not NULL, add the generated node @param [in] NameOpNode NameOp object node defining a named object.
to the end of the variable list of If provided, append the new resource data node
argument of the ParentNode, but to the list of resource data elements of this
before the "End Tag" Resource Data. node.
Must be a BufferOpNode. @param [out] NewRdNode If provided and success,
@param [out] NewRdNode If success, contains the generated node. contain the created node.
@retval EFI_SUCCESS The function completed successfully. @retval EFI_SUCCESS The function completed successfully.
@retval EFI_INVALID_PARAMETER Invalid parameter. @retval EFI_INVALID_PARAMETER Invalid parameter.
@ -45,15 +44,15 @@
**/ **/
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
AmlCodeGenInterrupt ( AmlCodeGenRdInterrupt (
IN BOOLEAN ResourceConsumer, IN BOOLEAN ResourceConsumer,
IN BOOLEAN EdgeTriggered, IN BOOLEAN EdgeTriggered,
IN BOOLEAN ActiveLow, IN BOOLEAN ActiveLow,
IN BOOLEAN Shared, IN BOOLEAN Shared,
IN UINT32 * IrqList, IN UINT32 *IrqList,
IN UINT8 IrqCount, IN UINT8 IrqCount,
IN AML_OBJECT_NODE * ParentNode, OPTIONAL IN AML_OBJECT_NODE_HANDLE NameOpNode, OPTIONAL
OUT AML_DATA_NODE ** NewRdNode OPTIONAL OUT AML_DATA_NODE_HANDLE *NewRdNode OPTIONAL
); );
#endif // AML_RESOURCE_DATA_CODE_GEN_H_ #endif // AML_RESOURCE_DATA_CODE_GEN_H_