Date   

[PATCH v3 09/21] DynamicTablesPkg: Make AmlNodeGetIntegerValue public

PierreGondois
 

From: Pierre Gondois <Pierre.Gondois@...>

Remove the STATIC qualifier for the AmlUtility function
AmlNodeGetIntegerValue() and add the definition to the
header file so that it can be used by other AmlLib
sub-modules.

Reviewed-by: Sami Mujawar <sami.mujawar@...>
Signed-off-by: Pierre Gondois <Pierre.Gondois@...>
---
.../Library/Common/AmlLib/Utils/AmlUtility.c | 3 +--
.../Library/Common/AmlLib/Utils/AmlUtility.h | 18 +++++++++++++++++-
2 files changed, 18 insertions(+), 3 deletions(-)

diff --git a/DynamicTablesPkg/Library/Common/AmlLib/Utils/AmlUtility.c b/DynamicTablesPkg/Library/Common/AmlLib/Utils/AmlUtility.c
index ef159e3b831e..8b5153f916a4 100644
--- a/DynamicTablesPkg/Library/Common/AmlLib/Utils/AmlUtility.c
+++ b/DynamicTablesPkg/Library/Common/AmlLib/Utils/AmlUtility.c
@@ -1,7 +1,7 @@
/** @file
AML Utility.

- 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
**/
@@ -192,7 +192,6 @@ AmlComputeSize (
@retval EFI_SUCCESS The function completed successfully.
@retval EFI_INVALID_PARAMETER Invalid parameter.
**/
-STATIC
EFI_STATUS
EFIAPI
AmlNodeGetIntegerValue (
diff --git a/DynamicTablesPkg/Library/Common/AmlLib/Utils/AmlUtility.h b/DynamicTablesPkg/Library/Common/AmlLib/Utils/AmlUtility.h
index 4667f57d7f08..0c42d23cbdb9 100644
--- a/DynamicTablesPkg/Library/Common/AmlLib/Utils/AmlUtility.h
+++ b/DynamicTablesPkg/Library/Common/AmlLib/Utils/AmlUtility.h
@@ -1,7 +1,7 @@
/** @file
AML Utility.

- 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
**/
@@ -39,6 +39,22 @@ AmlComputeSize (
IN OUT UINT32 * Size
);

+/** Get the value contained in an integer node.
+
+ @param [in] Node Pointer to an integer node.
+ Must be an object node.
+ @param [out] Value Value contained in the integer node.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+**/
+EFI_STATUS
+EFIAPI
+AmlNodeGetIntegerValue (
+ IN AML_OBJECT_NODE * Node,
+ OUT UINT64 * Value
+ );
+
/** Set the value contained in an integer node.

The OpCode is updated accordingly to the new value
--
2.17.1


[PATCH v3 05/21] DynamicTablesPkg: Add AmlSetRdListCheckSum()

PierreGondois
 

From: Pierre Gondois <Pierre.Gondois@...>

Lists of Resource Data elements end with an EndTag (most of the time).
This function finds the EndTag (if present) in a list of Resource Data
elements and sets the checksum.

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."

Reviewed-by: Sami Mujawar <sami.mujawar@...>
Signed-off-by: Pierre Gondois <Pierre.Gondois@...>
---
.../Library/Common/AmlLib/Utils/AmlUtility.c | 76 +++++++++++++++++++
.../Library/Common/AmlLib/Utils/AmlUtility.h | 32 ++++++++
2 files changed, 108 insertions(+)

diff --git a/DynamicTablesPkg/Library/Common/AmlLib/Utils/AmlUtility.c b/DynamicTablesPkg/Library/Common/AmlLib/Utils/AmlUtility.c
index 7ebd08f945c0..ef159e3b831e 100644
--- a/DynamicTablesPkg/Library/Common/AmlLib/Utils/AmlUtility.c
+++ b/DynamicTablesPkg/Library/Common/AmlLib/Utils/AmlUtility.c
@@ -904,3 +904,79 @@ AmlPropagateInformation (

return EFI_SUCCESS;
}
+
+/** Find and set the EndTag's Checksum of a list of Resource Data elements.
+
+ Lists of Resource Data elements end with an EndTag (most of the time). This
+ function finds the EndTag (if present) in a list of Resource Data elements
+ and sets the checksum.
+
+ 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] BufferOpNode Node having a list of Resource Data elements.
+ @param [in] CheckSum CheckSum to store in the EndTag.
+ To ignore/avoid computing the checksum,
+ give 0.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval EFI_NOT_FOUND No EndTag found.
+**/
+EFI_STATUS
+EFIAPI
+AmlSetRdListCheckSum (
+ IN AML_OBJECT_NODE * BufferOpNode,
+ IN UINT8 CheckSum
+ )
+{
+ EFI_STATUS Status;
+ AML_DATA_NODE * LastRdNode;
+ AML_RD_HEADER RdDataType;
+
+ if (!AmlNodeCompareOpCode (BufferOpNode, AML_BUFFER_OP, 0)) {
+ ASSERT (0);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // Get the last Resource data node in the variable list of
+ // argument of the BufferOp node.
+ LastRdNode = (AML_DATA_NODE*)AmlGetPreviousVariableArgument (
+ (AML_NODE_HEADER*)BufferOpNode,
+ NULL
+ );
+ if ((LastRdNode == NULL) ||
+ !IS_AML_DATA_NODE (LastRdNode) ||
+ (LastRdNode->DataType != EAmlNodeDataTypeResourceData)) {
+ ASSERT (0);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = AmlGetResourceDataType (LastRdNode, &RdDataType);
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ return Status;
+ }
+
+ // Check the LastRdNode is an EndTag.
+ // It is possible to have only one Resource Data in a BufferOp with
+ // no EndTag. Return EFI_NOT_FOUND is such case.
+ if (!AmlRdCompareDescId (
+ &RdDataType,
+ AML_RD_BUILD_SMALL_DESC_ID (ACPI_SMALL_END_TAG_DESCRIPTOR_NAME))) {
+ ASSERT (0);
+ return EFI_NOT_FOUND;
+ }
+
+ Status = AmlRdSetEndTagChecksum (LastRdNode->Buffer, CheckSum);
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
diff --git a/DynamicTablesPkg/Library/Common/AmlLib/Utils/AmlUtility.h b/DynamicTablesPkg/Library/Common/AmlLib/Utils/AmlUtility.h
index c57d780140d4..4667f57d7f08 100644
--- a/DynamicTablesPkg/Library/Common/AmlLib/Utils/AmlUtility.h
+++ b/DynamicTablesPkg/Library/Common/AmlLib/Utils/AmlUtility.h
@@ -91,5 +91,37 @@ AmlPropagateInformation (
IN UINT8 NodeCount
);

+/** Find and set the EndTag's Checksum of a list of Resource Data elements.
+
+ Lists of Resource Data elements end with an EndTag (most of the time). This
+ function finds the EndTag (if present) in a list of Resource Data elements
+ and sets the checksum.
+
+ 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] BufferOpNode Node having a list of Resource Data elements.
+ @param [in] CheckSum CheckSum to store in the EndTag.
+ To ignore/avoid computing the checksum,
+ give 0.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval EFI_NOT_FOUND No EndTag found.
+**/
+EFI_STATUS
+EFIAPI
+AmlSetRdListCheckSum (
+ IN AML_OBJECT_NODE * BufferOpNode,
+ IN UINT8 CheckSum
+ );
+
#endif // AML_UTILITY_H_

--
2.17.1


[PATCH v3 08/21] DynamicTablesPkg: Update error handling for node creation

PierreGondois
 

From: Pierre Gondois <Pierre.Gondois@...>

The node creation functions:
- AmlCreateRootNode()
- AmlCreateObjectNode()
- AmlCreateDataNode()
are now resetting the input pointer where the created node is stored.
Thus, it is not necessary to set some local variables to NULL or
check a node value before trying to delete it.

Reviewed-by: Sami Mujawar <sami.mujawar@...>
Signed-off-by: Pierre Gondois <Pierre.Gondois@...>
---
DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c | 6 +-----
DynamicTablesPkg/Library/Common/AmlLib/Tree/AmlClone.c | 2 --
2 files changed, 1 insertion(+), 7 deletions(-)

diff --git a/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c b/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c
index 4775b68cd974..cbfd9cbb68b6 100644
--- a/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c
+++ b/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c
@@ -148,7 +148,6 @@ AmlCodeGenString (
return EFI_INVALID_PARAMETER;
}

- ObjectNode = NULL;
DataNode = NULL;

Status = AmlCreateObjectNode (
@@ -187,10 +186,7 @@ AmlCodeGenString (
return Status;

error_handler:
- if (ObjectNode != NULL) {
- AmlDeleteTree ((AML_NODE_HEADER*)ObjectNode);
- }
-
+ AmlDeleteTree ((AML_NODE_HEADER*)ObjectNode);
return Status;
}

diff --git a/DynamicTablesPkg/Library/Common/AmlLib/Tree/AmlClone.c b/DynamicTablesPkg/Library/Common/AmlLib/Tree/AmlClone.c
index e09372b039f1..7aafa957a8c4 100644
--- a/DynamicTablesPkg/Library/Common/AmlLib/Tree/AmlClone.c
+++ b/DynamicTablesPkg/Library/Common/AmlLib/Tree/AmlClone.c
@@ -43,8 +43,6 @@ AmlCloneNode (
return EFI_INVALID_PARAMETER;
}

- *ClonedNode = NULL;
-
if (IS_AML_DATA_NODE (Node)) {
DataNode = (AML_DATA_NODE*)Node;
Status = AmlCreateDataNode (
--
2.17.1


[PATCH v3 04/21] DynamicTablesPkg: Add AmlRdSetEndTagChecksum()

PierreGondois
 

From: Pierre Gondois <Pierre.Gondois@...>

Add AmlRdSetEndTagChecksum(), setting the CheckSum value contained in a
Resource Data element.

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."

Reviewed-by: Sami Mujawar <sami.mujawar@...>
Signed-off-by: Pierre Gondois <Pierre.Gondois@...>
---
.../AmlLib/ResourceData/AmlResourceData.c | 33 +++++++++++++++++++
.../AmlLib/ResourceData/AmlResourceData.h | 21 ++++++++++++
2 files changed, 54 insertions(+)

diff --git a/DynamicTablesPkg/Library/Common/AmlLib/ResourceData/AmlResourceData.c b/DynamicTablesPkg/Library/Common/AmlLib/ResourceData/AmlResourceData.c
index 8b46c7232df3..41cf0bc45314 100644
--- a/DynamicTablesPkg/Library/Common/AmlLib/ResourceData/AmlResourceData.c
+++ b/DynamicTablesPkg/Library/Common/AmlLib/ResourceData/AmlResourceData.c
@@ -101,3 +101,36 @@ AmlRdGetSize (
return ((ACPI_SMALL_RESOURCE_HEADER*)Header)->Bits.Length +
sizeof (ACPI_SMALL_RESOURCE_HEADER);
}
+
+/** Set the Checksum of an EndTag resource data.
+
+ 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."
+
+ @param [in] Header Pointer to the first byte of a resource data.
+ @param [in] CheckSum Checksum value to set.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+**/
+EFI_STATUS
+EFIAPI
+AmlRdSetEndTagChecksum (
+ IN CONST AML_RD_HEADER * Header,
+ IN UINT8 CheckSum
+ )
+{
+ if ((Header == NULL) ||
+ !AmlRdCompareDescId (
+ Header,
+ AML_RD_BUILD_SMALL_DESC_ID (ACPI_SMALL_END_TAG_DESCRIPTOR_NAME))) {
+ ASSERT (0);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ ((EFI_ACPI_END_TAG_DESCRIPTOR*)Header)->Checksum = CheckSum;
+ return EFI_SUCCESS;
+}
diff --git a/DynamicTablesPkg/Library/Common/AmlLib/ResourceData/AmlResourceData.h b/DynamicTablesPkg/Library/Common/AmlLib/ResourceData/AmlResourceData.h
index 48e4e2aaddb4..e478107dffbd 100644
--- a/DynamicTablesPkg/Library/Common/AmlLib/ResourceData/AmlResourceData.h
+++ b/DynamicTablesPkg/Library/Common/AmlLib/ResourceData/AmlResourceData.h
@@ -171,4 +171,25 @@ AmlRdGetSize (
IN CONST AML_RD_HEADER * Header
);

+/** Set the Checksum of an EndTag resource data.
+
+ 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."
+
+ @param [in] Header Pointer to the first byte of a resource data.
+ @param [in] CheckSum Checksum value to set.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+**/
+EFI_STATUS
+EFIAPI
+AmlRdSetEndTagChecksum (
+ IN CONST AML_RD_HEADER * Header,
+ IN UINT8 CheckSum
+ );
+
#endif // AML_RESOURCE_DATA_H_
--
2.17.1


[PATCH v3 07/21] DynamicTablesPkg: Clear pointer in node creation fcts

PierreGondois
 

From: Pierre Gondois <Pierre.Gondois@...>

The following functions:
- AmlCreateRootNode()
- AmlCreateObjectNode()
- AmlCreateDataNode()
create a node and return it by populating a pointer. This pointer
should only be considered/used if the function returns successfully.
Otherwise, the value stored in this pointer should be ignored.

For their error handling, some other functions assume that this
pointer is reset to NULL if an error occurs during a node creation.
To make this assumption correct, explicitly clear this input pointer.

Reviewed-by: Sami Mujawar <sami.mujawar@...>
Signed-off-by: Pierre Gondois <Pierre.Gondois@...>
---
.../Library/Common/AmlLib/CodeGen/AmlCodeGen.c | 10 ++++++++--
.../AmlLib/CodeGen/AmlResourceDataCodeGen.c | 10 ++++++++--
.../Library/Common/AmlLib/Tree/AmlNode.c | 18 +++++++++++++++---
.../Library/Common/AmlLib/Tree/AmlNode.h | 12 +++++++++---
4 files changed, 40 insertions(+), 10 deletions(-)

diff --git a/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c b/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c
index 5d310f201319..4775b68cd974 100644
--- a/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c
+++ b/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c
@@ -22,7 +22,9 @@
@param [in] Node Newly created node.
@param [in] ParentNode If provided, set ParentNode as the parent
of the node created.
- @param [out] NewObjectNode If success, contains the created object node.
+ @param [out] NewObjectNode If not NULL:
+ - and Success, contains the created Node.
+ - and Error, reset to NULL.

@retval EFI_SUCCESS The function completed successfully.
@retval EFI_INVALID_PARAMETER Invalid parameter.
@@ -39,7 +41,7 @@ LinkNode (
EFI_STATUS Status;

if (NewObjectNode != NULL) {
- *NewObjectNode = Node;
+ *NewObjectNode = NULL;
}

// Add RdNode as the last element.
@@ -51,6 +53,10 @@ LinkNode (
}
}

+ if (NewObjectNode != NULL) {
+ *NewObjectNode = Node;
+ }
+
return EFI_SUCCESS;
}

diff --git a/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlResourceDataCodeGen.c b/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlResourceDataCodeGen.c
index 089597a6c906..cba942c0fd1a 100644
--- a/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlResourceDataCodeGen.c
+++ b/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlResourceDataCodeGen.c
@@ -33,7 +33,9 @@
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:
+ - and Success, contains RdNode.
+ - and Error, reset to NULL.

@retval EFI_SUCCESS The function completed successfully.
@retval EFI_INVALID_PARAMETER Invalid parameter.
@@ -52,7 +54,7 @@ LinkRdNode (
AML_OBJECT_NODE *BufferOpNode;

if (NewRdNode != NULL) {
- *NewRdNode = RdNode;
+ *NewRdNode = NULL;
}

if (ParentNode != NULL) {
@@ -85,6 +87,10 @@ LinkRdNode (
}
}

+ if (NewRdNode != NULL) {
+ *NewRdNode = RdNode;
+ }
+
return Status;

error_handler:
diff --git a/DynamicTablesPkg/Library/Common/AmlLib/Tree/AmlNode.c b/DynamicTablesPkg/Library/Common/AmlLib/Tree/AmlNode.c
index 3740c0ac7bb8..300b07a2efe4 100644
--- a/DynamicTablesPkg/Library/Common/AmlLib/Tree/AmlNode.c
+++ b/DynamicTablesPkg/Library/Common/AmlLib/Tree/AmlNode.c
@@ -79,7 +79,9 @@ AmlDeleteRootNode (

@param [in] SdtHeader Pointer to an ACPI DSDT/SSDT header to copy
the data from.
- @param [out] NewRootNodePtr The created AML_ROOT_NODE.
+ @param [out] NewRootNodePtr If success, contains the created
+ AML_ROOT_NODE.
+ Otherwise reset to NULL.

@retval EFI_SUCCESS The function completed successfully.
@retval EFI_INVALID_PARAMETER Invalid parameter.
@@ -101,6 +103,8 @@ AmlCreateRootNode (
return EFI_INVALID_PARAMETER;
}

+ *NewRootNodePtr = NULL;
+
RootNode = AllocateZeroPool (sizeof (AML_ROOT_NODE));
if (RootNode == NULL) {
ASSERT (0);
@@ -163,7 +167,9 @@ AmlDeleteObjectNode (
@param [in] PkgLength PkgLength of the node if the AmlByteEncoding
has the PkgLen attribute.
0 otherwise.
- @param [out] NewObjectNodePtr The created AML_OBJECT_NODE.
+ @param [out] NewObjectNodePtr If success, contains the created
+ AML_OBJECT_NODE.
+ Otherwise reset to NULL.

@retval EFI_SUCCESS The function completed successfully.
@retval EFI_INVALID_PARAMETER Invalid parameter.
@@ -186,6 +192,8 @@ AmlCreateObjectNode (
return EFI_INVALID_PARAMETER;
}

+ *NewObjectNodePtr = NULL;
+
ObjectNode = AllocateZeroPool (sizeof (AML_OBJECT_NODE));
if (ObjectNode == NULL) {
ASSERT (0);
@@ -252,7 +260,9 @@ AmlDeleteDataNode (
this node. Data is copied from there.
@param [in] DataSize Number of bytes to consider at the address
pointed by Data.
- @param [out] NewDataNodePtr The created AML_DATA_NODE.
+ @param [out] NewDataNodePtr If success, contains the created
+ AML_DATA_NODE.
+ Otherwise reset to NULL.

@retval EFI_SUCCESS The function completed successfully.
@retval EFI_INVALID_PARAMETER Invalid parameter.
@@ -284,6 +294,8 @@ AmlCreateDataNode (
return EFI_INVALID_PARAMETER;
}

+ *NewDataNodePtr = NULL;
+
DataNode = AllocateZeroPool (sizeof (AML_DATA_NODE));
if (DataNode == NULL) {
ASSERT (0);
diff --git a/DynamicTablesPkg/Library/Common/AmlLib/Tree/AmlNode.h b/DynamicTablesPkg/Library/Common/AmlLib/Tree/AmlNode.h
index 3584b572baae..465a0e2b4b2f 100644
--- a/DynamicTablesPkg/Library/Common/AmlLib/Tree/AmlNode.h
+++ b/DynamicTablesPkg/Library/Common/AmlLib/Tree/AmlNode.h
@@ -17,7 +17,9 @@

@param [in] SdtHeader Pointer to an ACPI DSDT/SSDT header to copy
the data from.
- @param [out] NewRootNodePtr The created AML_ROOT_NODE.
+ @param [out] NewRootNodePtr If success, contains the created
+ AML_ROOT_NODE.
+ Otherwise reset to NULL.

@retval EFI_SUCCESS The function completed successfully.
@retval EFI_INVALID_PARAMETER Invalid parameter.
@@ -36,7 +38,9 @@ AmlCreateRootNode (
@param [in] PkgLength PkgLength of the node if the AmlByteEncoding
has the PkgLen attribute.
0 otherwise.
- @param [out] NewObjectNodePtr The created AML_OBJECT_NODE.
+ @param [out] NewObjectNodePtr If success, contains the created
+ AML_OBJECT_NODE.
+ Otherwise reset to NULL.

@retval EFI_SUCCESS The function completed successfully.
@retval EFI_INVALID_PARAMETER Invalid parameter.
@@ -57,7 +61,9 @@ AmlCreateObjectNode (
this node. Data is copied from there.
@param [in] DataSize Number of bytes to consider at the address
pointed by Data.
- @param [out] NewDataNodePtr The created AML_DATA_NODE.
+ @param [out] NewDataNodePtr If success, contains the created
+ AML_DATA_NODE.
+ Otherwise reset to NULL.

@retval EFI_SUCCESS The function completed successfully.
@retval EFI_INVALID_PARAMETER Invalid parameter.
--
2.17.1


[PATCH v3 06/21] DynamicTablesPkg: Set EndTag's Checksum if RdList is modified

PierreGondois
 

From: Pierre Gondois <Pierre.Gondois@...>

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.

This patch also refactors the AmlAppendRdNode() function by getting the
last Resource Data node directly instead of iterating over all the
elements of the list of Resource Data node.

Reviewed-by: Sami Mujawar <sami.mujawar@...>
Signed-off-by: Pierre Gondois <Pierre.Gondois@...>
---
.../Common/AmlLib/Tree/AmlNodeInterface.c | 7 ++
.../Library/Common/AmlLib/Tree/AmlTree.c | 72 +++++++------------
2 files changed, 34 insertions(+), 45 deletions(-)

diff --git a/DynamicTablesPkg/Library/Common/AmlLib/Tree/AmlNodeInterface.c b/DynamicTablesPkg/Library/Common/AmlLib/Tree/AmlNodeInterface.c
index 870346c40a5d..f91bc5fd55d2 100644
--- a/DynamicTablesPkg/Library/Common/AmlLib/Tree/AmlNodeInterface.c
+++ b/DynamicTablesPkg/Library/Common/AmlLib/Tree/AmlNodeInterface.c
@@ -513,6 +513,13 @@ AmlUpdateDataNode (
ASSERT (0);
return EFI_INVALID_PARAMETER;
}
+
+ Status = AmlSetRdListCheckSum (ParentNode, 0);
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ return Status;
+ }
+
break;
}
case EAmlNodeDataTypeFieldPkgLen:
diff --git a/DynamicTablesPkg/Library/Common/AmlLib/Tree/AmlTree.c b/DynamicTablesPkg/Library/Common/AmlLib/Tree/AmlTree.c
index 0931e751709e..2772e915f468 100644
--- a/DynamicTablesPkg/Library/Common/AmlLib/Tree/AmlTree.c
+++ b/DynamicTablesPkg/Library/Common/AmlLib/Tree/AmlTree.c
@@ -566,8 +566,7 @@ AmlAppendRdNode (
)
{
EFI_STATUS Status;
- AML_DATA_NODE * CurrRdNode;
- AML_RD_HEADER RdDataType;
+ AML_DATA_NODE * LastRdNode;

if (!AmlNodeCompareOpCode (BufferOpNode, AML_BUFFER_OP, 0) ||
!IS_AML_DATA_NODE (NewRdNode) ||
@@ -576,56 +575,39 @@ AmlAppendRdNode (
return EFI_INVALID_PARAMETER;
}

- // Get the first Resource data node in the variable list of
- // argument of the BufferOp node.
- CurrRdNode = (AML_DATA_NODE*)AmlGetNextVariableArgument (
+ // 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.
+ // It is possible to have only one Resource Data in a BufferOp with
+ // no EndTag, but it should not be possible to add a new Resource Data
+ // in the list in this case.
+ Status = AmlSetRdListCheckSum (BufferOpNode, 0);
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ return Status;
+ }
+
+ // Get the last Resource data node in the variable list of argument of the
+ // BufferOp node. This must be an EndTag, otherwise setting the checksum
+ // would have failed.
+ LastRdNode = (AML_DATA_NODE*)AmlGetPreviousVariableArgument (
(AML_NODE_HEADER*)BufferOpNode,
NULL
);
- if ((CurrRdNode == NULL) ||
- !IS_AML_DATA_NODE (CurrRdNode) ||
- (CurrRdNode->DataType != EAmlNodeDataTypeResourceData)) {
+ if ((LastRdNode == NULL) ||
+ !IS_AML_DATA_NODE (LastRdNode) ||
+ (LastRdNode->DataType != EAmlNodeDataTypeResourceData)) {
ASSERT (0);
return EFI_INVALID_PARAMETER;
}

- // Iterate through the Resource Data nodes to find the End Tag.
- while (TRUE) {
- Status = AmlGetResourceDataType (CurrRdNode, &RdDataType);
- if (EFI_ERROR (Status)) {
- ASSERT (0);
- return Status;
- }
-
- // If the Resource Data is an End Tag,
- // add the new node before and return.
- if (AmlRdCompareDescId (
- &RdDataType,
- AML_RD_BUILD_SMALL_DESC_ID (ACPI_SMALL_END_TAG_DESCRIPTOR_NAME))) {
- Status = AmlVarListAddBefore (
- (AML_NODE_HEADER*)CurrRdNode,
- (AML_NODE_HEADER*)NewRdNode)
- ;
- if (EFI_ERROR (Status)) {
- ASSERT (0);
- }
- return Status;
- }
-
- // Get the next Resource Data node.
- // If this was the last node and no End Tag was found, return error.
- // It is possible to have only one Resource Data in a BufferOp,
- // but it should not be possible to add a new Resource Data in the list
- // in this case.
- CurrRdNode = (AML_DATA_NODE*)AmlGetSiblingVariableArgument (
- (AML_NODE_HEADER*)CurrRdNode
- );
- if (!IS_AML_DATA_NODE (CurrRdNode) ||
- (CurrRdNode->DataType != EAmlNodeDataTypeResourceData)) {
- ASSERT (0);
- return EFI_INVALID_PARAMETER;
- }
- } // while
+ // Add NewRdNode before the EndTag.
+ Status = AmlVarListAddBefore (
+ (AML_NODE_HEADER*)LastRdNode,
+ (AML_NODE_HEADER*)NewRdNode)
+ ;
+ ASSERT_EFI_ERROR (Status);
+ return Status;
}

/** Replace the fixed argument at the Index of the ParentNode with the NewNode.
--
2.17.1


[PATCH v3 00/21] Create a SSDT CPU topology generator

PierreGondois
 

From: Pierre Gondois <Pierre.Gondois@...>

v2:
- Update or error handling. [Sami/Pierre]
- Various comments. [Sami]
and
New patches:
DynamicTablesPkg: Remove unnecessary includes
DynamicTablesPkg: Add missing parameter check
DynamicTablesPkg: Add AddSsdtAcpiHeader()
DynamicTablesPkg: Add AmlRdSetEndTagChecksum()
DynamicTablesPkg: Add AmlSetRdListCheckSum()
DynamicTablesPkg: Set EndTag's Checksum if RdList is modified
DynamicTablesPkg: Clear pointer in node creation fcts
DynamicTablesPkg: Update error handling for node creation

v3:
-Fix typo and error handling. [Sami]

As part of the DynamicTablesPkg, add a generator creating a
SSDT table representing a CPU topology. Low Power Idle (LPI)
states can also be generated along the CPUs.
This patch-set also adds new functions to generate AML bytecode.

The changes can be seen at: https://github.com/PierreARM/edk2/tree/1449_Create_ssdt_cpu_topology_generator_v3

Pierre Gondois (21):
DynamicTablesPkg: Remove unnecessary includes
DynamicTablesPkg: Add missing parameter check
DynamicTablesPkg: Add AddSsdtAcpiHeader()
DynamicTablesPkg: Add AmlRdSetEndTagChecksum()
DynamicTablesPkg: Add AmlSetRdListCheckSum()
DynamicTablesPkg: Set EndTag's Checksum if RdList is modified
DynamicTablesPkg: Clear pointer in node creation fcts
DynamicTablesPkg: Update error handling for node creation
DynamicTablesPkg: Make AmlNodeGetIntegerValue public
DynamicTablesPkg: AML Code generation for Register()
DynamicTablesPkg: AML Code generation for Resource data EndTag
DynamicTablesPkg: AML code generation for a Package
DynamicTablesPkg: Helper function to compute package length
DynamicTablesPkg: AML code generation for a ResourceTemplate
DynamicTablesPkg: AML code generation for a Method
DynamicTablesPkg: AML code generation to Return a NameString
DynamicTablesPkg: AML code generation for a Method returning a NS
DynamicTablesPkg: AML code generation for a _LPI object
DynamicTablesPkg: AML code generation to add an _LPI state
DynamicTablesPkg: Add CM_ARM_LPI_INFO object
DynamicTablesPkg: SSDT CPU topology and LPI state generator

DynamicTablesPkg/DynamicTables.dsc.inc | 6 +
DynamicTablesPkg/Include/AcpiTableGenerator.h | 7 +-
.../Include/ArmNameSpaceObjects.h | 68 +
.../Include/Library/AmlLib/AmlLib.h | 168 ++
.../Include/Library/TableHelperLib.h | 35 +
.../SsdtCmn600Generator.c | 2 -
.../SsdtCpuTopologyGenerator.c | 1228 +++++++++++++++
.../SsdtCpuTopologyGenerator.h | 134 ++
.../SsdtCpuTopologyLibArm.inf | 33 +
.../SsdtSerialPortGenerator.c | 3 -
.../Library/Common/AmlLib/AmlEncoding/Aml.c | 87 +-
.../Library/Common/AmlLib/AmlEncoding/Aml.h | 47 +-
.../Common/AmlLib/CodeGen/AmlCodeGen.c | 1350 ++++++++++++++++-
.../AmlLib/CodeGen/AmlResourceDataCodeGen.c | 210 ++-
.../AmlLib/CodeGen/AmlResourceDataCodeGen.h | 92 ++
.../AmlLib/ResourceData/AmlResourceData.c | 33 +
.../AmlLib/ResourceData/AmlResourceData.h | 21 +
.../Library/Common/AmlLib/Tree/AmlClone.c | 2 -
.../Library/Common/AmlLib/Tree/AmlNode.c | 18 +-
.../Library/Common/AmlLib/Tree/AmlNode.h | 12 +-
.../Common/AmlLib/Tree/AmlNodeInterface.c | 7 +
.../Library/Common/AmlLib/Tree/AmlTree.c | 72 +-
.../Library/Common/AmlLib/Utils/AmlUtility.c | 79 +-
.../Library/Common/AmlLib/Utils/AmlUtility.h | 50 +-
.../SsdtSerialPortFixupLib.c | 1 -
.../ConfigurationManagerObjectParser.c | 35 +
.../Common/TableHelperLib/TableHelper.c | 89 ++
27 files changed, 3814 insertions(+), 75 deletions(-)
create mode 100644 DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyGenerator.c
create mode 100644 DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyGenerator.h
create mode 100644 DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyLibArm.inf

--
2.17.1


[PATCH v3 02/21] DynamicTablesPkg: Add missing parameter check

PierreGondois
 

From: Pierre Gondois <Pierre.Gondois@...>

Add missing check of 'AcpiTableInfo' in AddAcpiHeader().

Reviewed-by: Sami Mujawar <sami.mujawar@...>
Signed-off-by: Pierre Gondois <Pierre.Gondois@...>
---
DynamicTablesPkg/Library/Common/TableHelperLib/TableHelper.c | 2 ++
1 file changed, 2 insertions(+)

diff --git a/DynamicTablesPkg/Library/Common/TableHelperLib/TableHelper.c b/DynamicTablesPkg/Library/Common/TableHelperLib/TableHelper.c
index 9249e6b87f70..f98da7ffdd67 100644
--- a/DynamicTablesPkg/Library/Common/TableHelperLib/TableHelper.c
+++ b/DynamicTablesPkg/Library/Common/TableHelperLib/TableHelper.c
@@ -122,11 +122,13 @@ AddAcpiHeader (
ASSERT (CfgMgrProtocol != NULL);
ASSERT (Generator != NULL);
ASSERT (AcpiHeader != NULL);
+ ASSERT (AcpiTableInfo != NULL);
ASSERT (Length >= sizeof (EFI_ACPI_DESCRIPTION_HEADER));

if ((CfgMgrProtocol == NULL) ||
(Generator == NULL) ||
(AcpiHeader == NULL) ||
+ (AcpiTableInfo == NULL) ||
(Length < sizeof (EFI_ACPI_DESCRIPTION_HEADER))
) {
return EFI_INVALID_PARAMETER;
--
2.17.1


[PATCH v3 01/21] DynamicTablesPkg: Remove unnecessary includes

PierreGondois
 

From: Pierre Gondois <Pierre.Gondois@...>

Some includes are not necessary. Remove them.

Reviewed-by: Sami Mujawar <sami.mujawar@...>
Signed-off-by: Pierre Gondois <Pierre.Gondois@...>
---

Notes:
v2:
- New patch. [Pierre]

.../Acpi/Arm/AcpiSsdtCmn600LibArm/SsdtCmn600Generator.c | 2 --
.../Arm/AcpiSsdtSerialPortLibArm/SsdtSerialPortGenerator.c | 3 ---
.../Common/SsdtSerialPortFixupLib/SsdtSerialPortFixupLib.c | 1 -
3 files changed, 6 deletions(-)

diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCmn600LibArm/SsdtCmn600Generator.c b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCmn600LibArm/SsdtCmn600Generator.c
index 19b7b128a08d..b46ad25cdd26 100644
--- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCmn600LibArm/SsdtCmn600Generator.c
+++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCmn600LibArm/SsdtCmn600Generator.c
@@ -10,13 +10,11 @@
- Generic ACPI for Arm Components 1.0 Platform Design Document
**/

-#include <IndustryStandard/DebugPort2Table.h>
#include <Library/AcpiLib.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/MemoryAllocationLib.h>
-#include <Library/UefiBootServicesTableLib.h>
#include <Protocol/AcpiTable.h>

// Module specific include files.
diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtSerialPortLibArm/SsdtSerialPortGenerator.c b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtSerialPortLibArm/SsdtSerialPortGenerator.c
index 1b70fe1db1d7..d62aee1056ad 100644
--- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtSerialPortLibArm/SsdtSerialPortGenerator.c
+++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtSerialPortLibArm/SsdtSerialPortGenerator.c
@@ -6,13 +6,11 @@
SPDX-License-Identifier: BSD-2-Clause-Patent
**/

-#include <IndustryStandard/DebugPort2Table.h>
#include <Library/AcpiLib.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/MemoryAllocationLib.h>
-#include <Library/UefiBootServicesTableLib.h>
#include <Protocol/AcpiTable.h>

// Module specific include files.
@@ -20,7 +18,6 @@
#include <ConfigurationManagerObject.h>
#include <ConfigurationManagerHelper.h>
#include <Library/AcpiHelperLib.h>
-#include <Library/AmlLib/AmlLib.h>
#include <Library/SsdtSerialPortFixupLib.h>
#include <Protocol/ConfigurationManagerProtocol.h>

diff --git a/DynamicTablesPkg/Library/Common/SsdtSerialPortFixupLib/SsdtSerialPortFixupLib.c b/DynamicTablesPkg/Library/Common/SsdtSerialPortFixupLib/SsdtSerialPortFixupLib.c
index 6966410b2c34..79e1fabc9223 100644
--- a/DynamicTablesPkg/Library/Common/SsdtSerialPortFixupLib/SsdtSerialPortFixupLib.c
+++ b/DynamicTablesPkg/Library/Common/SsdtSerialPortFixupLib/SsdtSerialPortFixupLib.c
@@ -16,7 +16,6 @@
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/MemoryAllocationLib.h>
-#include <Library/UefiBootServicesTableLib.h>
#include <Protocol/AcpiTable.h>

// Module specific include files.
--
2.17.1


Re: [PATCH v2 19/21] DynamicTablesPkg: AML code generation to add an _LPI state

Sami Mujawar
 

Hi Pierre,

This patch looks good to me.

Reviewed-by: Sami Mujawar <sami.mujawar@...>

Regards,

Sami Mujawar

On 07/10/2021 04:32 PM, Pierre.Gondois@... wrote:
From: Pierre Gondois <Pierre.Gondois@...>

Add AmlAddLpiState() to generates AML code to add an _LPI state
to an _LPI object created using AmlCreateLpiNode().

AmlAddLpiState increments the count of LPI states in the LPI
node by one, and adds the following package:
Package() {
MinResidency,
WorstCaseWakeLatency,
Flags,
ArchFlags,
ResCntFreq,
EnableParentState,
(GenericRegisterDescriptor != NULL) ? // Entry method. If a
ResourceTemplate(GenericRegisterDescriptor) : // Register is given,
Integer, // use it. Use the
// Integer otherwise
ResourceTemplate() { // NULL Residency
Register (SystemMemory, 0, 0, 0, 0) // Counter
},
ResourceTemplate() { // NULL Usage Counter
Register (SystemMemory, 0, 0, 0, 0)
},
"" // NULL State Name
},

Signed-off-by: Pierre Gondois <Pierre.Gondois@...>
---
.../Include/Library/AmlLib/AmlLib.h | 71 +++
.../Common/AmlLib/CodeGen/AmlCodeGen.c | 459 ++++++++++++++++++
2 files changed, 530 insertions(+)

diff --git a/DynamicTablesPkg/Include/Library/AmlLib/AmlLib.h b/DynamicTablesPkg/Include/Library/AmlLib/AmlLib.h
index 40c45073d303..4932f6fd9c8b 100644
--- a/DynamicTablesPkg/Include/Library/AmlLib/AmlLib.h
+++ b/DynamicTablesPkg/Include/Library/AmlLib/AmlLib.h
@@ -716,6 +716,77 @@ AmlCreateLpiNode (
OUT AML_OBJECT_NODE_HANDLE * NewLpiNode OPTIONAL
);

+/** Add an _LPI state to a LPI node created using AmlCreateLpiNode ().
+
+ AmlAddLpiState () increments the Count of LPI states in the LPI node by one,
+ and adds the following package:
+ Package() {
+ MinResidency,
+ WorstCaseWakeLatency,
+ Flags,
+ ArchFlags,
+ ResCntFreq,
+ EnableParentState,
+ (GenericRegisterDescriptor != NULL) ? // Entry method. If a
+ ResourceTemplate(GenericRegisterDescriptor) : // Register is given,
+ Integer, // use it. Use the
+ // Integer otherwise.
+ ResourceTemplate() { // NULL Residency Counter
+ Register (SystemMemory, 0, 0, 0, 0)
+ },
+ ResourceTemplate() { // NULL Usage Counter
+ Register (SystemMemory, 0, 0, 0, 0)
+ },
+ "" // NULL State Name
+ },
+
+ Cf ACPI 6.3 specification, s8.4.4 "Lower Power Idle States".
+
+ @ingroup CodeGenApis
+
+ @param [in] MinResidency Minimum Residency.
+ @param [in] WorstCaseWakeLatency Worst case wake-up latency.
+ @param [in] Flags Flags.
+ @param [in] ArchFlags Architectural flags.
+ @param [in] ResCntFreq Residency Counter Frequency.
+ @param [in] EnableParentState Enabled Parent State.
+ @param [in] GenericRegisterDescriptor Entry Method.
+ If not NULL, use this Register to
+ describe the entry method address.
+ @param [in] Integer Entry Method.
+ If GenericRegisterDescriptor is NULL,
+ take this value.
+ @param [in] ResidencyCounterRegister If not NULL, use it to populate the
+ residency counter register.
+ @param [in] UsageCounterRegister If not NULL, use it to populate the
+ usage counter register.
+ @param [in] StateName If not NULL, use it to populate the
+ state name.
+ @param [in] LpiNode Lpi node created with the function
+ AmlCreateLpiNode to which the new LPI
+ state is appended.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
+**/
+EFI_STATUS
+EFIAPI
+AmlAddLpiState (
+ IN UINT32 MinResidency,
+ IN UINT32 WorstCaseWakeLatency,
+ IN UINT32 Flags,
+ IN UINT32 ArchFlags,
+ IN UINT32 ResCntFreq,
+ IN UINT32 EnableParentState,
+ IN EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE * GenericRegisterDescriptor, OPTIONAL
+ IN UINT64 Integer, OPTIONAL
+ IN EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE * ResidencyCounterRegister, OPTIONAL
+ IN EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE * UsageCounterRegister, OPTIONAL
+ IN CHAR8 * StateName, OPTIONAL
+ IN AML_OBJECT_NODE_HANDLE LpiNode
+ );
+
// DEPRECATED APIS
#ifndef DISABLE_NEW_DEPRECATED_INTERFACES

diff --git a/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c b/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c
index 2223e4bcfef9..36c908863983 100644
--- a/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c
+++ b/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c
@@ -12,6 +12,7 @@

#include <AmlCoreInterface.h>
#include <AmlEncoding/Aml.h>
+#include <Api/AmlApiHelper.h>
#include <CodeGen/AmlResourceDataCodeGen.h>
#include <Tree/AmlNode.h>
#include <Tree/AmlTree.h>
@@ -1575,3 +1576,461 @@ error_handler:
}
return Status;
}
+
+/** Add an _LPI state to a LPI node created using AmlCreateLpiNode.
+
+ AmlAddLpiState increments the Count of LPI states in the LPI node by one,
+ and adds the following package:
+ Package() {
+ MinResidency,
+ WorstCaseWakeLatency,
+ Flags,
+ ArchFlags,
+ ResCntFreq,
+ EnableParentState,
+ (GenericRegisterDescriptor != NULL) ? // Entry method. If a
+ ResourceTemplate(GenericRegisterDescriptor) : // Register is given,
+ Integer, // use it. Use the
+ // Integer otherwise.
+ ResourceTemplate() { // NULL Residency Counter
+ Register (SystemMemory, 0, 0, 0, 0)
+ },
+ ResourceTemplate() { // NULL Usage Counter
+ Register (SystemMemory, 0, 0, 0, 0)
+ },
+ "" // NULL State Name
+ },
+
+ Cf ACPI 6.3 specification, s8.4.4 "Lower Power Idle States".
+
+ @param [in] MinResidency Minimum Residency.
+ @param [in] WorstCaseWakeLatency Worst case wake-up latency.
+ @param [in] Flags Flags.
+ @param [in] ArchFlags Architectural flags.
+ @param [in] ResCntFreq Residency Counter Frequency.
+ @param [in] EnableParentState Enabled Parent State.
+ @param [in] GenericRegisterDescriptor Entry Method.
+ If not NULL, use this Register to
+ describe the entry method address.
+ @param [in] Integer Entry Method.
+ If GenericRegisterDescriptor is NULL,
+ take this value.
+ @param [in] ResidencyCounterRegister If not NULL, use it to populate the
+ residency counter register.
+ @param [in] UsageCounterRegister If not NULL, use it to populate the
+ usage counter register.
+ @param [in] StateName If not NULL, use it to populate the
+ state name.
+ @param [in] LpiNode Lpi node created with the function
+ AmlCreateLpiNode to which the new LPI
+ state is appended.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
+**/
+EFI_STATUS
+EFIAPI
+AmlAddLpiState (
+ IN UINT32 MinResidency,
+ IN UINT32 WorstCaseWakeLatency,
+ IN UINT32 Flags,
+ IN UINT32 ArchFlags,
+ IN UINT32 ResCntFreq,
+ IN UINT32 EnableParentState,
+ IN EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE * GenericRegisterDescriptor, OPTIONAL
+ IN UINT64 Integer, OPTIONAL
+ IN EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE * ResidencyCounterRegister, OPTIONAL
+ IN EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE * UsageCounterRegister, OPTIONAL
+ IN CHAR8 * StateName, OPTIONAL
+ IN AML_OBJECT_NODE_HANDLE LpiNode
+ )
+{
+ EFI_STATUS Status;
+ AML_DATA_NODE_HANDLE RdNode;
+ AML_OBJECT_NODE_HANDLE PackageNode;
+ AML_OBJECT_NODE_HANDLE IntegerNode;
+ AML_OBJECT_NODE_HANDLE StringNode;
+ AML_OBJECT_NODE_HANDLE NewLpiPackageNode;
+ AML_OBJECT_NODE_HANDLE ResourceTemplateNode;
+
+ UINT32 Index;
+ AML_OBJECT_NODE_HANDLE CountNode;
+ UINT64 Count;
+
+ if ((LpiNode == NULL) ||
+ (AmlGetNodeType ((AML_NODE_HANDLE)LpiNode) != EAmlNodeObject) ||
+ (!AmlNodeHasOpCode (LpiNode, AML_NAME_OP, 0))) {
+ ASSERT (0);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ RdNode = 0;
+ StringNode = NULL;
+ IntegerNode = NULL;
+ ResourceTemplateNode = NULL;
+
+ // AmlCreateLpiNode () created a LPI container such as:
+ // Name (_LPI, Package (
+ // 0, // Revision
+ // 1, // LevelId
+ // 0 // Count
+ // ))
+ // Get the LPI container, a PackageOp object node stored as the 2nd fixed
+ // argument (i.e. index 1) of LpiNode.
+ PackageNode = (AML_OBJECT_NODE_HANDLE)AmlGetFixedArgument (
+ LpiNode,
+ EAmlParseIndexTerm1
+ );
+ if ((PackageNode == NULL) ||
+ (AmlGetNodeType ((AML_NODE_HANDLE)PackageNode) != EAmlNodeObject) ||
+ (!AmlNodeHasOpCode (PackageNode, AML_PACKAGE_OP, 0))) {
+ ASSERT (0);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ CountNode = NULL;
+ // The third variable argument is the LPI Count node.
+ for (Index = 0; Index < 3; Index++) {
+ CountNode = (AML_OBJECT_NODE_HANDLE)AmlGetNextVariableArgument (
+ (AML_NODE_HANDLE)PackageNode,
+ (AML_NODE_HANDLE)CountNode
+ );
+ if (CountNode == NULL) {
+ ASSERT (0);
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+
+ Status = AmlNodeGetIntegerValue (CountNode, &Count);
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ return Status;
+ }
+ Status = AmlUpdateInteger (CountNode, Count + 1);
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ return Status;
+ }
+
+ Status = AmlCodeGenPackage (&NewLpiPackageNode);
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ return Status;
+ }
+
+ // MinResidency
+ Status = AmlCodeGenInteger (MinResidency, &IntegerNode);
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ IntegerNode = NULL;
+ goto error_handler;
+ }
+ Status = AmlVarListAddTail (
+ (AML_NODE_HANDLE)NewLpiPackageNode,
+ (AML_NODE_HANDLE)IntegerNode
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ goto error_handler;
+ }
+ IntegerNode = NULL;
+
+ // WorstCaseWakeLatency
+ Status = AmlCodeGenInteger (WorstCaseWakeLatency, &IntegerNode);
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ IntegerNode = NULL;
+ goto error_handler;
+ }
+ Status = AmlVarListAddTail (
+ (AML_NODE_HANDLE)NewLpiPackageNode,
+ (AML_NODE_HANDLE)IntegerNode
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ goto error_handler;
+ }
+ IntegerNode = NULL;
+
+ // Flags
+ Status = AmlCodeGenInteger (Flags, &IntegerNode);
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ IntegerNode = NULL;
+ goto error_handler;
+ }
+ Status = AmlVarListAddTail (
+ (AML_NODE_HANDLE)NewLpiPackageNode,
+ (AML_NODE_HANDLE)IntegerNode
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ goto error_handler;
+ }
+ IntegerNode = NULL;
+
+ // ArchFlags
+ Status = AmlCodeGenInteger (ArchFlags, &IntegerNode);
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ IntegerNode = NULL;
+ goto error_handler;
+ }
+ Status = AmlVarListAddTail (
+ (AML_NODE_HANDLE)NewLpiPackageNode,
+ (AML_NODE_HANDLE)IntegerNode
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ goto error_handler;
+ }
+ IntegerNode = NULL;
+
+ // ResCntFreq
+ Status = AmlCodeGenInteger (ResCntFreq, &IntegerNode);
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ IntegerNode = NULL;
+ goto error_handler;
+ }
+ Status = AmlVarListAddTail (
+ (AML_NODE_HANDLE)NewLpiPackageNode,
+ (AML_NODE_HANDLE)IntegerNode
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ goto error_handler;
+ }
+ IntegerNode = NULL;
+
+ // EnableParentState
+ Status = AmlCodeGenInteger (EnableParentState, &IntegerNode);
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ IntegerNode = NULL;
+ goto error_handler;
+ }
+ Status = AmlVarListAddTail (
+ (AML_NODE_HANDLE)NewLpiPackageNode,
+ (AML_NODE_HANDLE)IntegerNode
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ goto error_handler;
+ }
+ IntegerNode = NULL;
+
+ // Entry Method
+ if (GenericRegisterDescriptor != NULL) {
+ // Entry Method: As a Register resource data
+ Status = AmlCodeGenResourceTemplate (&ResourceTemplateNode);
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ ResourceTemplateNode = NULL;
+ goto error_handler;
+ }
+ Status = AmlCodeGenRdRegister (
+ GenericRegisterDescriptor->AddressSpaceId,
+ GenericRegisterDescriptor->RegisterBitWidth,
+ GenericRegisterDescriptor->RegisterBitOffset,
+ GenericRegisterDescriptor->Address,
+ GenericRegisterDescriptor->AccessSize,
+ NULL,
+ &RdNode
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ RdNode = NULL;
+ goto error_handler;
+ }
+
+ Status = AmlAppendRdNode (ResourceTemplateNode, RdNode);
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ goto error_handler;
+ }
+ RdNode = NULL;
+
+ Status = AmlVarListAddTail (
+ (AML_NODE_HANDLE)NewLpiPackageNode,
+ (AML_NODE_HANDLE)ResourceTemplateNode
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ goto error_handler;
+ }
+ ResourceTemplateNode = NULL;
+ } else {
+ // Entry Method: As an integer
+ Status = AmlCodeGenInteger (Integer, &IntegerNode);
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ IntegerNode = NULL;
+ goto error_handler;
+ }
+ Status = AmlVarListAddTail (
+ (AML_NODE_HANDLE)NewLpiPackageNode,
+ (AML_NODE_HANDLE)IntegerNode
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ goto error_handler;
+ }
+ IntegerNode = NULL;
+ }
+
+ // Residency Counter Register.
+ Status = AmlCodeGenResourceTemplate (&ResourceTemplateNode);
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ ResourceTemplateNode = NULL;
+ goto error_handler;
+ }
+ if (ResidencyCounterRegister != NULL) {
+ Status = AmlCodeGenRdRegister (
+ ResidencyCounterRegister->AddressSpaceId,
+ ResidencyCounterRegister->RegisterBitWidth,
+ ResidencyCounterRegister->RegisterBitOffset,
+ ResidencyCounterRegister->Address,
+ ResidencyCounterRegister->AccessSize,
+ NULL,
+ &RdNode
+ );
+ } else {
+ Status = AmlCodeGenRdRegister (
+ EFI_ACPI_6_4_SYSTEM_MEMORY,
+ 0,
+ 0,
+ 0,
+ 0,
+ NULL,
+ &RdNode
+ );
+ }
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ RdNode = NULL;
+ goto error_handler;
+ }
+
+ Status = AmlAppendRdNode (ResourceTemplateNode, RdNode);
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ goto error_handler;
+ }
+ RdNode = NULL;
+
+ Status = AmlVarListAddTail (
+ (AML_NODE_HANDLE)NewLpiPackageNode,
+ (AML_NODE_HANDLE)ResourceTemplateNode
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ goto error_handler;
+ }
+ ResourceTemplateNode = NULL;
+
+ // Usage Counter Register.
+ Status = AmlCodeGenResourceTemplate (&ResourceTemplateNode);
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ ResourceTemplateNode = NULL;
+ goto error_handler;
+ }
+ if (UsageCounterRegister != NULL) {
+ Status = AmlCodeGenRdRegister (
+ UsageCounterRegister->AddressSpaceId,
+ UsageCounterRegister->RegisterBitWidth,
+ UsageCounterRegister->RegisterBitOffset,
+ UsageCounterRegister->Address,
+ UsageCounterRegister->AccessSize,
+ NULL,
+ &RdNode
+ );
+ } else {
+ Status = AmlCodeGenRdRegister (
+ EFI_ACPI_6_4_SYSTEM_MEMORY,
+ 0,
+ 0,
+ 0,
+ 0,
+ NULL,
+ &RdNode
+ );
+ }
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ RdNode = NULL;
+ goto error_handler;
+ }
+
+ Status = AmlAppendRdNode (ResourceTemplateNode, RdNode);
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ goto error_handler;
+ }
+ RdNode = NULL;
+
+ Status = AmlVarListAddTail (
+ (AML_NODE_HANDLE)NewLpiPackageNode,
+ (AML_NODE_HANDLE)ResourceTemplateNode
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ goto error_handler;
+ }
+ ResourceTemplateNode = NULL;
+
+ // State name.
+ if (UsageCounterRegister != NULL) {
+ Status = AmlCodeGenString (StateName, &StringNode);
+ } else {
+ Status = AmlCodeGenString ("", &StringNode);
+ }
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ StringNode = NULL;
+ goto error_handler;
+ }
+ Status = AmlVarListAddTail (
+ (AML_NODE_HANDLE)NewLpiPackageNode,
+ (AML_NODE_HANDLE)StringNode
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ goto error_handler;
+ }
+ StringNode = NULL;
+
+ // Add the new LPI state to the LpiNode.
+ Status = AmlVarListAddTail (
+ (AML_NODE_HANDLE)PackageNode,
+ (AML_NODE_HANDLE)NewLpiPackageNode
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ goto error_handler;
+ }
+
+ return Status;
+
+error_handler:
+ if (RdNode != NULL) {
+ AmlDeleteTree ((AML_NODE_HANDLE)RdNode);
+ }
+ if (NewLpiPackageNode != NULL) {
+ AmlDeleteTree ((AML_NODE_HANDLE)NewLpiPackageNode);
+ }
+ if (StringNode != NULL) {
+ AmlDeleteTree ((AML_NODE_HANDLE)StringNode);
+ }
+ if (IntegerNode != NULL) {
+ AmlDeleteTree ((AML_NODE_HANDLE)IntegerNode);
+ }
+ if (ResourceTemplateNode != NULL) {
+ AmlDeleteTree ((AML_NODE_HANDLE)ResourceTemplateNode);
+ }
+
+ return Status;
+}
IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.


Re: [PATCH v2 18/21] DynamicTablesPkg: AML code generation for a _LPI object

Sami Mujawar
 

Hi Pierre,

Thank you for this patch.

Reviewed-by: Sami Mujawar <sami.mujawar@...>

Regards,

Sami Mujawar

On 07/10/2021 04:32 PM, Pierre.Gondois@... wrote:
From: Pierre Gondois <Pierre.Gondois@...>

_LPI object provides a method to describe Low Power Idle
states that define the local power states for each node
in a hierarchical processor topology.

Therefore, add AmlCreateLpiNode() to generate code for a
_LPI object.

AmlCreateLpiNode ("_LPI", 0, 1, ParentNode, &LpiNode) is
equivalent of the following ASL code:
Name (_LPI, Package (
0, // Revision
1, // LevelId
0 // Count
))

Signed-off-by: Pierre Gondois <Pierre.Gondois@...>
---
.../Include/Library/AmlLib/AmlLib.h | 44 ++++++
.../Common/AmlLib/CodeGen/AmlCodeGen.c | 133 ++++++++++++++++++
2 files changed, 177 insertions(+)

diff --git a/DynamicTablesPkg/Include/Library/AmlLib/AmlLib.h b/DynamicTablesPkg/Include/Library/AmlLib/AmlLib.h
index 7740aac24470..40c45073d303 100644
--- a/DynamicTablesPkg/Include/Library/AmlLib/AmlLib.h
+++ b/DynamicTablesPkg/Include/Library/AmlLib/AmlLib.h
@@ -672,6 +672,50 @@ AmlCodeGenMethodRetNameString (
OUT AML_OBJECT_NODE_HANDLE * NewObjectNode OPTIONAL
);

+/** Create a _LPI name.
+
+ AmlCreateLpiNode ("_LPI", 0, 1, ParentNode, &LpiNode) is
+ equivalent of the following ASL code:
+ Name (_LPI, Package (
+ 0, // Revision
+ 1, // LevelId
+ 0 // Count
+ ))
+
+ This function doesn't define any LPI state. As shown above, the count
+ of _LPI state is set to 0.
+ The AmlAddLpiState () function must be used to add LPI states.
+
+ Cf ACPI 6.3 specification, s8.4.4 "Lower Power Idle States".
+
+ @ingroup CodeGenApis
+
+ @param [in] LpiNameString The new LPI 's object name.
+ Must be a NULL-terminated ASL NameString
+ e.g.: "_LPI", "DEV0.PLPI", etc.
+ The input string is copied.
+ @param [in] Revision Revision number of the _LPI states.
+ @param [in] LevelId A platform defined number that identifies the
+ level of hierarchy of the processor node to
+ which the LPI states apply.
+ @param [in] ParentNode If provided, set ParentNode as the parent
+ of the node created.
+ @param [out] NewLpiNode If success, contains the created node.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
+**/
+EFI_STATUS
+EFIAPI
+AmlCreateLpiNode (
+ IN CONST CHAR8 * LpiNameString,
+ IN UINT16 Revision,
+ IN UINT64 LevelId,
+ IN AML_NODE_HANDLE ParentNode, OPTIONAL
+ OUT AML_OBJECT_NODE_HANDLE * NewLpiNode OPTIONAL
+ );
+
// DEPRECATED APIS
#ifndef DISABLE_NEW_DEPRECATED_INTERFACES

diff --git a/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c b/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c
index 67474094b975..2223e4bcfef9 100644
--- a/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c
+++ b/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c
@@ -1442,3 +1442,136 @@ error_handler:
}
return Status;
}
+
+/** Create a _LPI name.
+
+ AmlCreateLpiNode ("_LPI", 0, 1, ParentNode, &LpiNode) is
+ equivalent of the following ASL code:
+ Name (_LPI, Package (
+ 0, // Revision
+ 1, // LevelId
+ 0 // Count
+ ))
+
+ This function doesn't define any LPI state. As shown above, the count
+ of _LPI state is set to 0.
+ The AmlAddLpiState () function allows to add LPI states.
+
+ Cf ACPI 6.3 specification, s8.4.4 "Lower Power Idle States".
+
+ @param [in] LpiNameString The new LPI 's object name.
+ Must be a NULL-terminated ASL NameString
+ e.g.: "_LPI", "DEV0.PLPI", etc.
+ The input string is copied.
+ @param [in] Revision Revision number of the _LPI states.
+ @param [in] LevelId A platform defined number that identifies the
+ level of hierarchy of the processor node to
+ which the LPI states apply.
+ @param [in] ParentNode If provided, set ParentNode as the parent
+ of the node created.
+ @param [out] NewLpiNode If success, contains the created node.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
+**/
+EFI_STATUS
+EFIAPI
+AmlCreateLpiNode (
+ IN CONST CHAR8 * LpiNameString,
+ IN UINT16 Revision,
+ IN UINT64 LevelId,
+ IN AML_NODE_HANDLE ParentNode, OPTIONAL
+ OUT AML_OBJECT_NODE_HANDLE * NewLpiNode OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+ AML_OBJECT_NODE_HANDLE PackageNode;
+ AML_OBJECT_NODE_HANDLE IntegerNode;
+
+ if ((LpiNameString == NULL) ||
+ ((ParentNode == NULL) && (NewLpiNode == NULL))) {
+ ASSERT (0);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ IntegerNode = NULL;
+
+ Status = AmlCodeGenPackage (&PackageNode);
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ return Status;
+ }
+
+ // Create and attach Revision
+ Status = AmlCodeGenInteger (Revision, &IntegerNode);
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ IntegerNode = NULL;
+ goto error_handler;
+ }
+
+ Status = AmlVarListAddTail (
+ (AML_NODE_HANDLE)PackageNode,
+ (AML_NODE_HANDLE)IntegerNode
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ goto error_handler;
+ }
+
+ IntegerNode = NULL;
+
+ // Create and attach LevelId
+ Status = AmlCodeGenInteger (LevelId, &IntegerNode);
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ IntegerNode = NULL;
+ goto error_handler;
+ }
+
+ Status = AmlVarListAddTail (
+ (AML_NODE_HANDLE)PackageNode,
+ (AML_NODE_HANDLE)IntegerNode
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ goto error_handler;
+ }
+
+ IntegerNode = NULL;
+
+ // Create and attach Count. No LPI state is added, so 0.
+ Status = AmlCodeGenInteger (0, &IntegerNode);
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ IntegerNode = NULL;
+ goto error_handler;
+ }
+
+ Status = AmlVarListAddTail (
+ (AML_NODE_HANDLE)PackageNode,
+ (AML_NODE_HANDLE)IntegerNode
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ goto error_handler;
+ }
+
+ IntegerNode = NULL;
+
+ Status = AmlCodeGenName (LpiNameString, PackageNode, ParentNode, NewLpiNode);
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ goto error_handler;
+ }
+
+ return Status;
+
+error_handler:
+ AmlDeleteTree ((AML_NODE_HANDLE)PackageNode);
+ if (IntegerNode != NULL) {
+ AmlDeleteTree ((AML_NODE_HANDLE)IntegerNode);
+ }
+ return Status;
+}
IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.


Re: [PATCH edk2-platforms 1/1] Silicon/Qemu: don't advertise GICC legacy mmio interface in SbsaQamu MADT

Ard Biesheuvel
 

On Fri, 8 Oct 2021 at 12:34, Leif Lindholm <leif@...> wrote:

The MADT GICC structure contains the field PhysicalBaseAddress, which
is needed for a GICv1/v2 implementation, or to indicate legacy
compatibility in modern GICs.

Linux commit 9739f6ef053f1, included in v5.12, adds a warning message
when this field is populated but invalid:
[Firmware Bug]: CPU interface incapable of MMIO access

As it happens, we currently initialize this to PcdGicDistributorBase
instead of PcdGicInterruptInterfaceBase, and as a result we now trigger
this warning.

Since this is an SBSA reference implementation, and legacy GIC support
has never worked for this port, set the field to 0.

Signed-off-by: Leif Lindholm <leif@...>
Cc: Ard Biesheuvel <ardb+tianocore@...>
Cc: Graeme Gregory <graeme@...>
Cc: Radoslaw Biernacki <rad@...>
Acked-by: Ard Biesheuvel <ardb@...>

---
Silicon/Qemu/SbsaQemu/Drivers/SbsaQemuAcpiDxe/SbsaQemuAcpiDxe.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Silicon/Qemu/SbsaQemu/Drivers/SbsaQemuAcpiDxe/SbsaQemuAcpiDxe.c b/Silicon/Qemu/SbsaQemu/Drivers/SbsaQemuAcpiDxe/SbsaQemuAcpiDxe.c
index b8901030ecd0..dbc5e9475358 100644
--- a/Silicon/Qemu/SbsaQemu/Drivers/SbsaQemuAcpiDxe/SbsaQemuAcpiDxe.c
+++ b/Silicon/Qemu/SbsaQemu/Drivers/SbsaQemuAcpiDxe/SbsaQemuAcpiDxe.c
@@ -71,7 +71,7 @@ AddMadtTable (
0, /* Mpidr */
EFI_ACPI_6_0_GIC_ENABLED, /* Flags */
SBSAQEMU_MADT_GIC_PMU_IRQ, /* PMU Irq */
- FixedPcdGet32 (PcdGicDistributorBase), /* PhysicalBaseAddress */
+ 0, /* PhysicalBaseAddress */
SBSAQEMU_MADT_GIC_VBASE, /* GicVBase */
SBSAQEMU_MADT_GIC_HBASE, /* GicHBase */
25, /* GsivId */
--
2.30.2


Re: [PATCH v2 17/21] DynamicTablesPkg: AML code generation for a Method returning a NS

Sami Mujawar
 

Hi Pierre,

I think this v2 patch has introduced an issue (which was not there in
v1), see my comment marked inline as [SAMI].

With that fixed,

Reviewed-by: Sami Mujawar <sami.mujawar@...>

Regards,

Sami Mujawar


On 07/10/2021 04:32 PM, Pierre.Gondois@... wrote:
From: Pierre Gondois <Pierre.Gondois@...>

Add AmlCodeGenMethodRetNameString() to generate AML code to create
a Method returning a NameString (NS).

AmlCodeGenMethodRetNameString (
"MET0", "_CRS", 1, TRUE, 3, ParentNode, NewObjectNode
);
is equivalent of the following ASL code:
Method(MET0, 1, Serialized, 3) {
Return (_CRS)
}

Signed-off-by: Pierre Gondois <Pierre.Gondois@...>
---
.../Include/Library/AmlLib/AmlLib.h | 53 +++++++++
.../Common/AmlLib/CodeGen/AmlCodeGen.c | 107 ++++++++++++++++++
2 files changed, 160 insertions(+)

diff --git a/DynamicTablesPkg/Include/Library/AmlLib/AmlLib.h b/DynamicTablesPkg/Include/Library/AmlLib/AmlLib.h
index 6824cf3a6c82..7740aac24470 100644
--- a/DynamicTablesPkg/Include/Library/AmlLib/AmlLib.h
+++ b/DynamicTablesPkg/Include/Library/AmlLib/AmlLib.h
@@ -619,6 +619,59 @@ AmlCodeGenScope (
OUT AML_OBJECT_NODE_HANDLE * NewObjectNode OPTIONAL
);

+/** AML code generation for a method returning a NameString.
+
+ AmlCodeGenMethodRetNameString (
+ "MET0", "_CRS", 1, TRUE, 3, ParentNode, NewObjectNode
+ );
+ is equivalent of the following ASL code:
+ Method(MET0, 1, Serialized, 3) {
+ Return (_CRS)
+ }
+
+ The ASL parameters "ReturnType" and "ParameterTypes" are not asked
+ in this function. They are optional parameters in ASL.
+
+ @ingroup CodeGenApis
+
+ @param [in] MethodNameString The new Method's name.
+ Must be a NULL-terminated ASL NameString
+ e.g.: "MET0", "_SB.MET0", etc.
+ The input string is copied.
+ @param [in] ReturnedNameString The name of the object returned by the
+ method. Optional parameter, can be:
+ - NULL (ignored).
+ - A NULL-terminated ASL NameString.
+ e.g.: "MET0", "_SB.MET0", etc.
+ The input string is copied.
+ @param [in] NumArgs Number of arguments.
+ Must be 0 <= NumArgs <= 6.
+ @param [in] IsSerialized TRUE is equivalent to Serialized.
+ FALSE is equivalent to NotSerialized.
+ Default is NotSerialized in ASL spec.
+ @param [in] SyncLevel Synchronization level for the method.
+ Must be 0 <= SyncLevel <= 15.
+ Default is 0 in ASL.
+ @param [in] ParentNode If provided, set ParentNode as the parent
+ of the node created.
+ @param [out] NewObjectNode If success, contains the created node.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
+**/
+EFI_STATUS
+EFIAPI
+AmlCodeGenMethodRetNameString (
+ IN CONST CHAR8 * MethodNameString,
+ IN CONST CHAR8 * ReturnedNameString, OPTIONAL
+ IN UINT8 NumArgs,
+ IN BOOLEAN IsSerialized,
+ IN UINT8 SyncLevel,
+ IN AML_NODE_HANDLE ParentNode, OPTIONAL
+ OUT AML_OBJECT_NODE_HANDLE * NewObjectNode OPTIONAL
+ );
+
// DEPRECATED APIS
#ifndef DISABLE_NEW_DEPRECATED_INTERFACES

diff --git a/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c b/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c
index 93d4ba79e937..67474094b975 100644
--- a/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c
+++ b/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c
@@ -1335,3 +1335,110 @@ exit_handler:
}
return Status;
}
+
+/** AML code generation for a method returning a NameString.
+
+ AmlCodeGenMethodRetNameString (
+ "MET0", "_CRS", 1, TRUE, 3, ParentNode, NewObjectNode
+ );
+ is equivalent of the following ASL code:
+ Method(MET0, 1, Serialized, 3) {
+ Return (_CRS)
+ }
+
+ The ASL parameters "ReturnType" and "ParameterTypes" are not asked
+ in this function. They are optional parameters in ASL.
+
+ @param [in] MethodNameString The new Method's name.
+ Must be a NULL-terminated ASL NameString
+ e.g.: "MET0", "_SB.MET0", etc.
+ The input string is copied.
+ @param [in] ReturnedNameString The name of the object returned by the
+ method. Optional parameter, can be:
+ - NULL (ignored).
+ - A NULL-terminated ASL NameString.
+ e.g.: "MET0", "_SB.MET0", etc.
+ The input string is copied.
+ @param [in] NumArgs Number of arguments.
+ Must be 0 <= NumArgs <= 6.
+ @param [in] IsSerialized TRUE is equivalent to Serialized.
+ FALSE is equivalent to NotSerialized.
+ Default is NotSerialized in ASL spec.
+ @param [in] SyncLevel Synchronization level for the method.
+ Must be 0 <= SyncLevel <= 15.
+ Default is 0 in ASL.
+ @param [in] ParentNode If provided, set ParentNode as the parent
+ of the node created.
+ @param [out] NewObjectNode If success, contains the created node.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
+**/
+EFI_STATUS
+EFIAPI
+AmlCodeGenMethodRetNameString (
+ IN CONST CHAR8 * MethodNameString,
+ IN CONST CHAR8 * ReturnedNameString, OPTIONAL
+ IN UINT8 NumArgs,
+ IN BOOLEAN IsSerialized,
+ IN UINT8 SyncLevel,
+ IN AML_NODE_HANDLE ParentNode, OPTIONAL
+ OUT AML_OBJECT_NODE_HANDLE * NewObjectNode OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+ AML_OBJECT_NODE_HANDLE MethodNode;
+
+ if ((MethodNameString == NULL) ||
+ ((ParentNode == NULL) && (NewObjectNode == NULL))) {
+ ASSERT (0);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // Create a Method named MethodNameString.
+ Status = AmlCodeGenMethod (
+ MethodNameString,
+ NumArgs,
+ IsSerialized,
+ SyncLevel,
+ NULL,
+ &MethodNode
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ return Status;
+ }
+
+ // Return ReturnedNameString if provided.
+ if (ReturnedNameString != NULL) {
+ Status = AmlCodeGenReturnNameString (
+ ReturnedNameString,
+ (AML_NODE_HANDLE)MethodNode,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ MethodNode = NULL;
[SAMI] Setting MethodNode to NULL will result in the MethodNode not
being deleted in case of an error.
+ goto error_handler;
+ }
+ }
+
+ Status = LinkNode (
+ MethodNode,
+ ParentNode,
+ NewObjectNode
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ goto error_handler;
+ }
+
+ return Status;
+
+error_handler:
+ if (MethodNode != NULL) {
+ AmlDeleteTree ((AML_NODE_HANDLE)MethodNode);
+ }
+ return Status;
+}
IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.


Re: [PATCH v2 15/21] DynamicTablesPkg: AML code generation for a Method

Sami Mujawar
 

Hi Pierre,

Thank you for adding documentation for the steps for generating a Method.

Reviewed-by: Sami Mujawar <sami.mujawar@...>

Regards,

Sami Mujawar

On 07/10/2021 04:32 PM, Pierre.Gondois@... wrote:
From: Pierre Gondois <Pierre.Gondois@...>

Add AmlCodeGenMethod() to generate code for a control method.

AmlCodeGenMethod ("MET0", 1, TRUE, 3, ParentNode, NewObjectNode)
is equivalent of the following ASL code:
Method(MET0, 1, Serialized, 3) {}

Signed-off-by: Pierre Gondois <Pierre.Gondois@...>
---
.../Common/AmlLib/CodeGen/AmlCodeGen.c | 184 ++++++++++++++++++
1 file changed, 184 insertions(+)

diff --git a/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c b/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c
index da80e9d77cc2..dd519bc67007 100644
--- a/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c
+++ b/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c
@@ -970,3 +970,187 @@ error_handler1:

return Status;
}
+
+/** AML code generation for a Method object node.
+
+ AmlCodeGenMethod ("MET0", 1, TRUE, 3, ParentNode, NewObjectNode) is
+ equivalent of the following ASL code:
+ Method(MET0, 1, Serialized, 3) {}
+
+ ACPI 6.4, s20.2.5.2 "Named Objects Encoding":
+ DefMethod := MethodOp PkgLength NameString MethodFlags TermList
+ MethodOp := 0x14
+
+ The ASL parameters "ReturnType" and "ParameterTypes" are not asked
+ in this function. They are optional parameters in ASL.
+
+ @param [in] NameString The new Method's name.
+ Must be a NULL-terminated ASL NameString
+ e.g.: "MET0", "_SB.MET0", etc.
+ The input string is copied.
+ @param [in] NumArgs Number of arguments.
+ Must be 0 <= NumArgs <= 6.
+ @param [in] IsSerialized TRUE is equivalent to Serialized.
+ FALSE is equivalent to NotSerialized.
+ Default is NotSerialized in ASL spec.
+ @param [in] SyncLevel Synchronization level for the method.
+ Must be 0 <= SyncLevel <= 15.
+ Default is 0 in ASL.
+ @param [in] ParentNode If provided, set ParentNode as the parent
+ of the node created.
+ @param [out] NewObjectNode If success, contains the created node.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+AmlCodeGenMethod (
+ IN CONST CHAR8 * NameString,
+ IN UINT8 NumArgs,
+ IN BOOLEAN IsSerialized,
+ IN UINT8 SyncLevel,
+ IN AML_NODE_HEADER * ParentNode, OPTIONAL
+ OUT AML_OBJECT_NODE ** NewObjectNode OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+ UINT32 PkgLen;
+ UINT8 Flags;
+ AML_OBJECT_NODE * ObjectNode;
+ AML_DATA_NODE * DataNode;
+ CHAR8 * AmlNameString;
+ UINT32 AmlNameStringSize;
+
+ if ((NameString == NULL) ||
+ (NumArgs > 6) ||
+ (SyncLevel > 15) ||
+ ((ParentNode == NULL) && (NewObjectNode == NULL))) {
+ ASSERT (0);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ ObjectNode = NULL;
+ DataNode = NULL;
+
+ // ACPI 6.4, s20.2.5.2 "Named Objects Encoding":
+ // DefMethod := MethodOp PkgLength NameString MethodFlags TermList
+ // MethodOp := 0x14
+ // So:
+ // 1- Create the NameString
+ // 2- Compute the size to write in the PkgLen
+ // 3- Create nodes for the NameString and Method object node
+ // 4- Set the NameString DataNode as a fixed argument
+ // 5- Create and link the MethodFlags node
+
+ // 1- Create the NameString
+ Status = ConvertAslNameToAmlName (NameString, &AmlNameString);
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ return Status;
+ }
+
+ Status = AmlGetNameStringSize (AmlNameString, &AmlNameStringSize);
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ goto error_handler1;
+ }
+
+ // 2- Compute the size to write in the PkgLen
+ // Add 1 byte (ByteData) for MethodFlags.
+ Status = AmlComputePkgLength (AmlNameStringSize + 1, &PkgLen);
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ goto error_handler1;
+ }
+
+ // 3- Create nodes for the NameString and Method object node
+ Status = AmlCreateObjectNode (
+ AmlGetByteEncodingByOpCode (AML_METHOD_OP, 0),
+ PkgLen,
+ &ObjectNode
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ goto error_handler1;
+ }
+
+ Status = AmlCreateDataNode (
+ EAmlNodeDataTypeNameString,
+ (UINT8*)AmlNameString,
+ AmlNameStringSize,
+ &DataNode
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ goto error_handler2;
+ }
+
+ // 4- Set the NameString DataNode as a fixed argument
+ Status = AmlSetFixedArgument (
+ ObjectNode,
+ EAmlParseIndexTerm0,
+ (AML_NODE_HEADER*)DataNode
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ goto error_handler2;
+ }
+
+ DataNode = NULL;
+
+ // 5- Create and link the MethodFlags node
+ Flags = NumArgs |
+ (IsSerialized ? BIT3 : 0) |
+ (SyncLevel << 4);
+
+ Status = AmlCreateDataNode (EAmlNodeDataTypeUInt, &Flags, 1, &DataNode);
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ goto error_handler2;
+ }
+
+ Status = AmlSetFixedArgument (
+ ObjectNode,
+ EAmlParseIndexTerm1,
+ (AML_NODE_HEADER*)DataNode
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ goto error_handler2;
+ }
+
+ // Data node is attached so set the pointer to
+ // NULL to ensure correct error handling.
+ DataNode = NULL;
+
+ Status = LinkNode (
+ ObjectNode,
+ ParentNode,
+ NewObjectNode
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ goto error_handler2;
+ }
+
+ // Free AmlNameString before returning as it is copied
+ // in the call to AmlCreateDataNode().
+ goto error_handler1;
+
+error_handler2:
+ if (ObjectNode != NULL) {
+ AmlDeleteTree ((AML_NODE_HEADER*)ObjectNode);
+ }
+ if (DataNode != NULL) {
+ AmlDeleteTree ((AML_NODE_HEADER*)DataNode);
+ }
+
+error_handler1:
+ if (AmlNameString != NULL) {
+ FreePool (AmlNameString);
+ }
+ return Status;
+}
IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.


Re: [PATCH v2 14/21] DynamicTablesPkg: AML code generation for a ResourceTemplate

Sami Mujawar
 

Hi Pierre,

Thank you for this patch.

Reviewed-by: Sami Mujawar <sami.mujawar@...>

Regards,

Sami Mujawar

On 07/10/2021 04:32 PM, Pierre.Gondois@... wrote:
From: Pierre Gondois <Pierre.Gondois@...>

ASL provides a ResourceTemplate macro that creates a Buffer in which
resource descriptor macros can be listed. The ResourceTemplate macro
automatically generates an End descriptor and calculates the checksum
for the resource template.

Therefore, add AmlCodeGenResourceTemplate() to generate AML code for
the ResourceTemplate() macro. This function generates a Buffer node
with an EndTag resource data descriptor, which is similar to the ASL
ResourceTemplate() macro.

Signed-off-by: Pierre Gondois <Pierre.Gondois@...>
---
.../Common/AmlLib/CodeGen/AmlCodeGen.c | 190 ++++++++++++++++++
1 file changed, 190 insertions(+)

diff --git a/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c b/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c
index a4cd2502dc56..da80e9d77cc2 100644
--- a/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c
+++ b/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c
@@ -12,6 +12,7 @@

#include <AmlCoreInterface.h>
#include <AmlEncoding/Aml.h>
+#include <CodeGen/AmlResourceDataCodeGen.h>
#include <Tree/AmlNode.h>
#include <Tree/AmlTree.h>
#include <String/AmlString.h>
@@ -316,6 +317,195 @@ error_handler:
return Status;
}

+/** AML code generation for a Buffer object node.
+
+ To create a Buffer object node with an empty buffer,
+ call the function with (Buffer=NULL, BufferSize=0).
+
+ @param [in] Buffer Buffer to set for the created Buffer
+ object node. The Buffer's content is copied.
+ NULL if there is no buffer to set for
+ the Buffer node.
+ @param [in] BufferSize Size of the Buffer.
+ 0 if there is no buffer to set for
+ the Buffer node.
+ @param [out] NewObjectNode If success, contains the created
+ Buffer object node.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+AmlCodeGenBuffer (
+ IN CONST UINT8 * Buffer, OPTIONAL
+ IN UINT32 BufferSize, OPTIONAL
+ OUT AML_OBJECT_NODE ** NewObjectNode
+ )
+{
+ EFI_STATUS Status;
+ AML_OBJECT_NODE * BufferNode;
+ AML_OBJECT_NODE * BufferSizeNode;
+ UINT32 BufferSizeNodeSize;
+ AML_DATA_NODE * DataNode;
+ UINT32 PkgLen;
+
+ // Buffer and BufferSize must be either both set, or both clear.
+ if ((NewObjectNode == NULL) ||
+ ((Buffer == NULL) != (BufferSize == 0))) {
+ ASSERT (0);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ BufferNode = NULL;
+ DataNode = NULL;
+
+ // Cf ACPI 6.3 specification, s20.2.5.4 "Type 2 Opcodes Encoding"
+ // DefBuffer := BufferOp PkgLength BufferSize ByteList
+ // BufferOp := 0x11
+ // BufferSize := TermArg => Integer
+
+ Status = AmlCodeGenInteger (BufferSize, &BufferSizeNode);
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ return Status;
+ }
+
+ // Get the number of bytes required to encode the BufferSizeNode.
+ Status = AmlComputeSize (
+ (AML_NODE_HEADER*)BufferSizeNode,
+ &BufferSizeNodeSize
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ goto error_handler;
+ }
+
+ // Compute the size to write in the PkgLen.
+ Status = AmlComputePkgLength (BufferSizeNodeSize + BufferSize, &PkgLen);
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ goto error_handler;
+ }
+
+ // Create an object node for the buffer.
+ Status = AmlCreateObjectNode (
+ AmlGetByteEncodingByOpCode (AML_BUFFER_OP, 0),
+ PkgLen,
+ &BufferNode
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ goto error_handler;
+ }
+
+ // Set the BufferSizeNode as a fixed argument of the BufferNode.
+ Status = AmlSetFixedArgument (
+ BufferNode,
+ EAmlParseIndexTerm0,
+ (AML_NODE_HEADER*)BufferSizeNode
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ goto error_handler;
+ }
+
+ // BufferSizeNode is now attached.
+ BufferSizeNode = NULL;
+
+ // If there is a buffer, create a DataNode and attach it to the BufferNode.
+ if (Buffer != NULL) {
+ Status = AmlCreateDataNode (
+ EAmlNodeDataTypeRaw,
+ Buffer,
+ BufferSize,
+ &DataNode
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ goto error_handler;
+ }
+
+ Status = AmlVarListAddTail (
+ (AML_NODE_HEADER*)BufferNode,
+ (AML_NODE_HEADER*)DataNode
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ goto error_handler;
+ }
+ }
+
+ *NewObjectNode = BufferNode;
+ return Status;
+
+error_handler:
+ if (BufferSizeNode != NULL) {
+ AmlDeleteTree ((AML_NODE_HEADER*)BufferSizeNode);
+ }
+ if (BufferNode != NULL) {
+ AmlDeleteTree ((AML_NODE_HEADER*)BufferNode);
+ }
+ if (DataNode != NULL) {
+ AmlDeleteTree ((AML_NODE_HEADER*)DataNode);
+ }
+ return Status;
+}
+
+/** AML code generation for a ResourceTemplate.
+
+ "ResourceTemplate" is a macro defined in ACPI 6.3, s19.3.3
+ "ASL Resource Templates". It allows to store resource data elements.
+
+ In AML, a ResourceTemplate is implemented as a Buffer storing resource
+ data elements. An EndTag resource data descriptor must be at the end
+ of the list of resource data elements.
+ This function generates a Buffer node with an EndTag resource data
+ descriptor. It can be seen as an empty list of resource data elements.
+
+ @param [out] NewObjectNode If success, contains the created
+ ResourceTemplate object node.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+AmlCodeGenResourceTemplate (
+ OUT AML_OBJECT_NODE ** NewObjectNode
+ )
+{
+ EFI_STATUS Status;
+ AML_OBJECT_NODE * BufferNode;
+
+ if (NewObjectNode == NULL) {
+ ASSERT (0);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // Create a BufferNode with an empty buffer.
+ Status = AmlCodeGenBuffer (NULL, 0, &BufferNode);
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ return Status;
+ }
+
+ // Create an EndTag resource data element and attach it to the Buffer.
+ Status = AmlCodeGenEndTag (0, BufferNode, NULL);
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ AmlDeleteTree ((AML_NODE_HEADER*)BufferNode);
+ return Status;
+ }
+
+ *NewObjectNode = BufferNode;
+ return Status;
+}
+
/** AML code generation for a Name object node.

@param [in] NameString The new variable name.
IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.


Re: [PATCH v2 11/21] DynamicTablesPkg: AML Code generation for Resource data EndTag

Sami Mujawar
 

Hi Pierre,

This patch looks good to me.

Reviewed-by: Sami Mujawar <sami.mujawar@...>

Regards,

Sami Mujawar

On 07/10/2021 04:32 PM, Pierre.Gondois@... wrote:
From: Pierre Gondois <Pierre.Gondois@...>

Add a helper function AmlCodeGenEndTag() to generate AML Resource Data
EndTag. The EndTag resource data is automatically generated by the ASL
compiler at the end of a list of resource data elements. Therefore, an
equivalent function is not present in ASL.

However, AmlCodeGenEndTag() is useful when generating AML code for the
ResourceTemplate() macro.

Signed-off-by: Pierre Gondois <Pierre.Gondois@...>
---
.../AmlLib/CodeGen/AmlResourceDataCodeGen.c | 113 ++++++++++++++++++
.../AmlLib/CodeGen/AmlResourceDataCodeGen.h | 43 +++++++
2 files changed, 156 insertions(+)

diff --git a/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlResourceDataCodeGen.c b/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlResourceDataCodeGen.c
index 20b745f27a2b..0bdb6c24c5bb 100644
--- a/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlResourceDataCodeGen.c
+++ b/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlResourceDataCodeGen.c
@@ -280,6 +280,119 @@ AmlCodeGenRdRegister (
return LinkRdNode (RdNode, 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;
+}
+
// DEPRECATED APIS
#ifndef DISABLE_NEW_DEPRECATED_INTERFACES

diff --git a/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlResourceDataCodeGen.h b/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlResourceDataCodeGen.h
index 831d6a7462ae..102340495933 100644
--- a/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlResourceDataCodeGen.h
+++ b/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlResourceDataCodeGen.h
@@ -104,4 +104,47 @@ AmlCodeGenRdRegister (
OUT AML_DATA_NODE_HANDLE *NewRdNode OPTIONAL
);

+/** 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
+ );
+
#endif // AML_RESOURCE_DATA_CODE_GEN_H_
IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.


Re: [PATCH v2 12/21] DynamicTablesPkg: AML code generation for a Package

Sami Mujawar
 

Hi Pierre,

Thank you for this patch.

Reviewed-by: Sami Mujawar <sami.mujawar@...>

Regards,

Sami Mujawar

On 07/10/2021 04:32 PM, Pierre.Gondois@... wrote:
From: Pierre Gondois <Pierre.Gondois@...>

Add AmlCodeGenPackage() to generate AML code for declaring
a Package() object. This function generates an empty package
node. New elements can then be added to the package's variable
argument list.

Signed-off-by: Pierre Gondois <Pierre.Gondois@...>
---
.../Common/AmlLib/CodeGen/AmlCodeGen.c | 81 ++++++++++++++++++-
1 file changed, 80 insertions(+), 1 deletion(-)

diff --git a/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c b/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c
index cbfd9cbb68b6..a4cd2502dc56 100644
--- a/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c
+++ b/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c
@@ -1,7 +1,7 @@
/** @file
AML Code Generation.

- Copyright (c) 2020, Arm Limited. All rights reserved.<BR>
+ Copyright (c) 2020 - 2021, Arm Limited. All rights reserved.<BR>

SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -237,6 +237,85 @@ AmlCodeGenInteger (
return Status;
}

+/** AML code generation for a Package object node.
+
+ The package generated is empty. New elements can be added via its
+ list of variable arguments.
+
+ @param [out] NewObjectNode If success, contains the created
+ Package object node.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+AmlCodeGenPackage (
+ OUT AML_OBJECT_NODE ** NewObjectNode
+ )
+{
+ EFI_STATUS Status;
+ AML_DATA_NODE * DataNode;
+ UINT8 NodeCount;
+
+ if (NewObjectNode == NULL) {
+ ASSERT (0);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ NodeCount = 0;
+
+ // Create an object node.
+ // PkgLen is 2:
+ // - one byte to store the PkgLength
+ // - one byte for the NumElements.
+ // Cf ACPI6.3, s20.2.5 "Term Objects Encoding"
+ // DefPackage := PackageOp PkgLength NumElements PackageElementList
+ // NumElements := ByteData
+ Status = AmlCreateObjectNode (
+ AmlGetByteEncodingByOpCode (AML_PACKAGE_OP, 0),
+ 2,
+ NewObjectNode
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ return Status;
+ }
+
+ // NumElements is a ByteData.
+ Status = AmlCreateDataNode (
+ EAmlNodeDataTypeUInt,
+ &NodeCount,
+ sizeof (NodeCount),
+ &DataNode
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ goto error_handler;
+ }
+
+ Status = AmlSetFixedArgument (
+ *NewObjectNode,
+ EAmlParseIndexTerm0,
+ (AML_NODE_HEADER*)DataNode
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ goto error_handler;
+ }
+
+ return Status;
+
+error_handler:
+ AmlDeleteTree ((AML_NODE_HEADER*)*NewObjectNode);
+ if (DataNode != NULL) {
+ AmlDeleteTree ((AML_NODE_HEADER*)DataNode);
+ }
+ return Status;
+}
+
/** AML code generation for a Name object node.

@param [in] NameString The new variable name.
IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.


Re: [PATCH v2 08/21] DynamicTablesPkg: Update error handling for node creation

Sami Mujawar
 

Hi Pierre,

Thank you for this patch.

Reviewed-by: Sami Mujawar <sami.mujawar@...>

Regards,

Sami Mujawar

On 07/10/2021 04:31 PM, Pierre.Gondois@... wrote:
From: Pierre Gondois <Pierre.Gondois@...>

The node creation functions:
- AmlCreateRootNode()
- AmlCreateObjectNode()
- AmlCreateDataNode()
are now resetting the input pointer where the created node is stored.
Thus, it is not necessary to set some local variables to NULL or
check a node value before trying to delete it.

Signed-off-by: Pierre Gondois <Pierre.Gondois@...>
---
DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c | 6 +-----
DynamicTablesPkg/Library/Common/AmlLib/Tree/AmlClone.c | 2 --
2 files changed, 1 insertion(+), 7 deletions(-)

diff --git a/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c b/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c
index 4775b68cd974..cbfd9cbb68b6 100644
--- a/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c
+++ b/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c
@@ -148,7 +148,6 @@ AmlCodeGenString (
return EFI_INVALID_PARAMETER;
}

- ObjectNode = NULL;
DataNode = NULL;

Status = AmlCreateObjectNode (
@@ -187,10 +186,7 @@ AmlCodeGenString (
return Status;

error_handler:
- if (ObjectNode != NULL) {
- AmlDeleteTree ((AML_NODE_HEADER*)ObjectNode);
- }
-
+ AmlDeleteTree ((AML_NODE_HEADER*)ObjectNode);
return Status;
}

diff --git a/DynamicTablesPkg/Library/Common/AmlLib/Tree/AmlClone.c b/DynamicTablesPkg/Library/Common/AmlLib/Tree/AmlClone.c
index e09372b039f1..7aafa957a8c4 100644
--- a/DynamicTablesPkg/Library/Common/AmlLib/Tree/AmlClone.c
+++ b/DynamicTablesPkg/Library/Common/AmlLib/Tree/AmlClone.c
@@ -43,8 +43,6 @@ AmlCloneNode (
return EFI_INVALID_PARAMETER;
}

- *ClonedNode = NULL;
-
if (IS_AML_DATA_NODE (Node)) {
DataNode = (AML_DATA_NODE*)Node;
Status = AmlCreateDataNode (
IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.


Re: [PATCH v2 07/21] DynamicTablesPkg: Clear pointer in node creation fcts

Sami Mujawar
 

Hi Pierre,

There is a minor typo in the commit message that I will fix when pushing
the patch.

Otherwise, this patch looks good to me.

Reviewed-by: Sami Mujawar <sami.mujawar@...>

Regards,

Sami Mujawar

On 07/10/2021 04:31 PM, Pierre.Gondois@... wrote:
From: Pierre Gondois <Pierre.Gondois@...>

The following functions:
- AmlCreateRootNode()
- AmlCreateObjectNode()
- AmlCreateDataNode()
create a node and return it by populating a pointer. This pointer
should only be considered/used if the function returns successfully.
Otherwise, the value stored in this pointer should be ignored.

For their error handling, some other functions assume that this
pointer is reset to NULL if an error occurs during a node creation.
To make this assumption correct, exlpicitely clear this input pointer.

Signed-off-by: Pierre Gondois <Pierre.Gondois@...>
---
.../Library/Common/AmlLib/CodeGen/AmlCodeGen.c | 10 ++++++++--
.../AmlLib/CodeGen/AmlResourceDataCodeGen.c | 10 ++++++++--
.../Library/Common/AmlLib/Tree/AmlNode.c | 18 +++++++++++++++---
.../Library/Common/AmlLib/Tree/AmlNode.h | 12 +++++++++---
4 files changed, 40 insertions(+), 10 deletions(-)

diff --git a/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c b/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c
index 5d310f201319..4775b68cd974 100644
--- a/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c
+++ b/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c
@@ -22,7 +22,9 @@
@param [in] Node Newly created node.
@param [in] ParentNode If provided, set ParentNode as the parent
of the node created.
- @param [out] NewObjectNode If success, contains the created object node.
+ @param [out] NewObjectNode If not NULL:
+ - and Success, contains the created Node.
+ - and Error, reset to NULL.

@retval EFI_SUCCESS The function completed successfully.
@retval EFI_INVALID_PARAMETER Invalid parameter.
@@ -39,7 +41,7 @@ LinkNode (
EFI_STATUS Status;

if (NewObjectNode != NULL) {
- *NewObjectNode = Node;
+ *NewObjectNode = NULL;
}

// Add RdNode as the last element.
@@ -51,6 +53,10 @@ LinkNode (
}
}

+ if (NewObjectNode != NULL) {
+ *NewObjectNode = Node;
+ }
+
return EFI_SUCCESS;
}

diff --git a/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlResourceDataCodeGen.c b/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlResourceDataCodeGen.c
index 089597a6c906..cba942c0fd1a 100644
--- a/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlResourceDataCodeGen.c
+++ b/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlResourceDataCodeGen.c
@@ -33,7 +33,9 @@
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:
+ - and Success, contains RdNode.
+ - and Error, reset to NULL.

@retval EFI_SUCCESS The function completed successfully.
@retval EFI_INVALID_PARAMETER Invalid parameter.
@@ -52,7 +54,7 @@ LinkRdNode (
AML_OBJECT_NODE *BufferOpNode;

if (NewRdNode != NULL) {
- *NewRdNode = RdNode;
+ *NewRdNode = NULL;
}

if (ParentNode != NULL) {
@@ -85,6 +87,10 @@ LinkRdNode (
}
}

+ if (NewRdNode != NULL) {
+ *NewRdNode = RdNode;
+ }
+
return Status;

error_handler:
diff --git a/DynamicTablesPkg/Library/Common/AmlLib/Tree/AmlNode.c b/DynamicTablesPkg/Library/Common/AmlLib/Tree/AmlNode.c
index 3740c0ac7bb8..300b07a2efe4 100644
--- a/DynamicTablesPkg/Library/Common/AmlLib/Tree/AmlNode.c
+++ b/DynamicTablesPkg/Library/Common/AmlLib/Tree/AmlNode.c
@@ -79,7 +79,9 @@ AmlDeleteRootNode (

@param [in] SdtHeader Pointer to an ACPI DSDT/SSDT header to copy
the data from.
- @param [out] NewRootNodePtr The created AML_ROOT_NODE.
+ @param [out] NewRootNodePtr If success, contains the created
+ AML_ROOT_NODE.
+ Otherwise reset to NULL.

@retval EFI_SUCCESS The function completed successfully.
@retval EFI_INVALID_PARAMETER Invalid parameter.
@@ -101,6 +103,8 @@ AmlCreateRootNode (
return EFI_INVALID_PARAMETER;
}

+ *NewRootNodePtr = NULL;
+
RootNode = AllocateZeroPool (sizeof (AML_ROOT_NODE));
if (RootNode == NULL) {
ASSERT (0);
@@ -163,7 +167,9 @@ AmlDeleteObjectNode (
@param [in] PkgLength PkgLength of the node if the AmlByteEncoding
has the PkgLen attribute.
0 otherwise.
- @param [out] NewObjectNodePtr The created AML_OBJECT_NODE.
+ @param [out] NewObjectNodePtr If success, contains the created
+ AML_OBJECT_NODE.
+ Otherwise reset to NULL.

@retval EFI_SUCCESS The function completed successfully.
@retval EFI_INVALID_PARAMETER Invalid parameter.
@@ -186,6 +192,8 @@ AmlCreateObjectNode (
return EFI_INVALID_PARAMETER;
}

+ *NewObjectNodePtr = NULL;
+
ObjectNode = AllocateZeroPool (sizeof (AML_OBJECT_NODE));
if (ObjectNode == NULL) {
ASSERT (0);
@@ -252,7 +260,9 @@ AmlDeleteDataNode (
this node. Data is copied from there.
@param [in] DataSize Number of bytes to consider at the address
pointed by Data.
- @param [out] NewDataNodePtr The created AML_DATA_NODE.
+ @param [out] NewDataNodePtr If success, contains the created
+ AML_DATA_NODE.
+ Otherwise reset to NULL.

@retval EFI_SUCCESS The function completed successfully.
@retval EFI_INVALID_PARAMETER Invalid parameter.
@@ -284,6 +294,8 @@ AmlCreateDataNode (
return EFI_INVALID_PARAMETER;
}

+ *NewDataNodePtr = NULL;
+
DataNode = AllocateZeroPool (sizeof (AML_DATA_NODE));
if (DataNode == NULL) {
ASSERT (0);
diff --git a/DynamicTablesPkg/Library/Common/AmlLib/Tree/AmlNode.h b/DynamicTablesPkg/Library/Common/AmlLib/Tree/AmlNode.h
index 3584b572baae..465a0e2b4b2f 100644
--- a/DynamicTablesPkg/Library/Common/AmlLib/Tree/AmlNode.h
+++ b/DynamicTablesPkg/Library/Common/AmlLib/Tree/AmlNode.h
@@ -17,7 +17,9 @@

@param [in] SdtHeader Pointer to an ACPI DSDT/SSDT header to copy
the data from.
- @param [out] NewRootNodePtr The created AML_ROOT_NODE.
+ @param [out] NewRootNodePtr If success, contains the created
+ AML_ROOT_NODE.
+ Otherwise reset to NULL.

@retval EFI_SUCCESS The function completed successfully.
@retval EFI_INVALID_PARAMETER Invalid parameter.
@@ -36,7 +38,9 @@ AmlCreateRootNode (
@param [in] PkgLength PkgLength of the node if the AmlByteEncoding
has the PkgLen attribute.
0 otherwise.
- @param [out] NewObjectNodePtr The created AML_OBJECT_NODE.
+ @param [out] NewObjectNodePtr If success, contains the created
+ AML_OBJECT_NODE.
+ Otherwise reset to NULL.

@retval EFI_SUCCESS The function completed successfully.
@retval EFI_INVALID_PARAMETER Invalid parameter.
@@ -57,7 +61,9 @@ AmlCreateObjectNode (
this node. Data is copied from there.
@param [in] DataSize Number of bytes to consider at the address
pointed by Data.
- @param [out] NewDataNodePtr The created AML_DATA_NODE.
+ @param [out] NewDataNodePtr If success, contains the created
+ AML_DATA_NODE.
+ Otherwise reset to NULL.

@retval EFI_SUCCESS The function completed successfully.
@retval EFI_INVALID_PARAMETER Invalid parameter.
IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.


Re: [PATCH v2 05/21] DynamicTablesPkg: Add AmlSetRdListCheckSum()

Sami Mujawar
 

Hi Pierre,

Thank you for this patch.

Reviewed-by: Sami Mujawar <sami.mujawar@...>

Regards,

Sami Mujawar

On 07/10/2021 04:31 PM, Pierre.Gondois@... wrote:
From: Pierre Gondois <Pierre.Gondois@...>

Lists of Resource Data elements end with an EndTag (most of the time).
This function finds the EndTag (if present) in a list of Resource Data
elements and sets the checksum.

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."

Signed-off-by: Pierre Gondois <Pierre.Gondois@...>
---
.../Library/Common/AmlLib/Utils/AmlUtility.c | 76 +++++++++++++++++++
.../Library/Common/AmlLib/Utils/AmlUtility.h | 32 ++++++++
2 files changed, 108 insertions(+)

diff --git a/DynamicTablesPkg/Library/Common/AmlLib/Utils/AmlUtility.c b/DynamicTablesPkg/Library/Common/AmlLib/Utils/AmlUtility.c
index 7ebd08f945c0..ef159e3b831e 100644
--- a/DynamicTablesPkg/Library/Common/AmlLib/Utils/AmlUtility.c
+++ b/DynamicTablesPkg/Library/Common/AmlLib/Utils/AmlUtility.c
@@ -904,3 +904,79 @@ AmlPropagateInformation (

return EFI_SUCCESS;
}
+
+/** Find and set the EndTag's Checksum of a list of Resource Data elements.
+
+ Lists of Resource Data elements end with an EndTag (most of the time). This
+ function finds the EndTag (if present) in a list of Resource Data elements
+ and sets the checksum.
+
+ 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] BufferOpNode Node having a list of Resource Data elements.
+ @param [in] CheckSum CheckSum to store in the EndTag.
+ To ignore/avoid computing the checksum,
+ give 0.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval EFI_NOT_FOUND No EndTag found.
+**/
+EFI_STATUS
+EFIAPI
+AmlSetRdListCheckSum (
+ IN AML_OBJECT_NODE * BufferOpNode,
+ IN UINT8 CheckSum
+ )
+{
+ EFI_STATUS Status;
+ AML_DATA_NODE * LastRdNode;
+ AML_RD_HEADER RdDataType;
+
+ if (!AmlNodeCompareOpCode (BufferOpNode, AML_BUFFER_OP, 0)) {
+ ASSERT (0);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // Get the last Resource data node in the variable list of
+ // argument of the BufferOp node.
+ LastRdNode = (AML_DATA_NODE*)AmlGetPreviousVariableArgument (
+ (AML_NODE_HEADER*)BufferOpNode,
+ NULL
+ );
+ if ((LastRdNode == NULL) ||
+ !IS_AML_DATA_NODE (LastRdNode) ||
+ (LastRdNode->DataType != EAmlNodeDataTypeResourceData)) {
+ ASSERT (0);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = AmlGetResourceDataType (LastRdNode, &RdDataType);
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ return Status;
+ }
+
+ // Check the LastRdNode is an EndTag.
+ // It is possible to have only one Resource Data in a BufferOp with
+ // no EndTag. Return EFI_NOT_FOUND is such case.
+ if (!AmlRdCompareDescId (
+ &RdDataType,
+ AML_RD_BUILD_SMALL_DESC_ID (ACPI_SMALL_END_TAG_DESCRIPTOR_NAME))) {
+ ASSERT (0);
+ return EFI_NOT_FOUND;
+ }
+
+ Status = AmlRdSetEndTagChecksum (LastRdNode->Buffer, CheckSum);
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
diff --git a/DynamicTablesPkg/Library/Common/AmlLib/Utils/AmlUtility.h b/DynamicTablesPkg/Library/Common/AmlLib/Utils/AmlUtility.h
index c57d780140d4..4667f57d7f08 100644
--- a/DynamicTablesPkg/Library/Common/AmlLib/Utils/AmlUtility.h
+++ b/DynamicTablesPkg/Library/Common/AmlLib/Utils/AmlUtility.h
@@ -91,5 +91,37 @@ AmlPropagateInformation (
IN UINT8 NodeCount
);

+/** Find and set the EndTag's Checksum of a list of Resource Data elements.
+
+ Lists of Resource Data elements end with an EndTag (most of the time). This
+ function finds the EndTag (if present) in a list of Resource Data elements
+ and sets the checksum.
+
+ 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] BufferOpNode Node having a list of Resource Data elements.
+ @param [in] CheckSum CheckSum to store in the EndTag.
+ To ignore/avoid computing the checksum,
+ give 0.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval EFI_NOT_FOUND No EndTag found.
+**/
+EFI_STATUS
+EFIAPI
+AmlSetRdListCheckSum (
+ IN AML_OBJECT_NODE * BufferOpNode,
+ IN UINT8 CheckSum
+ );
+
#endif // AML_UTILITY_H_
IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.

9041 - 9060 of 90661