summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--DynamicTablesPkg/Library/Common/AmlLib/Utils/AmlUtility.c76
-rw-r--r--DynamicTablesPkg/Library/Common/AmlLib/Utils/AmlUtility.h32
2 files changed, 108 insertions, 0 deletions
diff --git a/DynamicTablesPkg/Library/Common/AmlLib/Utils/AmlUtility.c b/DynamicTablesPkg/Library/Common/AmlLib/Utils/AmlUtility.c
index 7ebd08f945..ef159e3b83 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 c57d780140..4667f57d7f 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_