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