mirror of
https://github.com/Dasharo/edk2.git
synced 2026-06-13 10:16:24 -07:00
DynamicTablesPkg: Adds API to create method with Notify support
Adds APIs to create AML methods with Notify support in the AmlLib library. New API takes additional parameters for Notify type and Notify value. Notify type can be one of NameString, Local or Arg. Notification value is an integer representing the Notify value. Ref: ACPI spec 6.5 section 19.6.94 Notify (Notify Object of Event) Signed-off-by: Abdul Lateef Attar <AbdulLateef.Attar@amd.com>
This commit is contained in:
committed by
mergify[bot]
parent
f840501d1f
commit
c204f5402e
@@ -2,7 +2,7 @@
|
||||
AML Lib.
|
||||
|
||||
Copyright (c) 2019 - 2023, Arm Limited. All rights reserved.<BR>
|
||||
Copyright (C) 2023 - 2025, Advanced Micro Devices, Inc. All rights reserved.<BR>
|
||||
Copyright (C) 2023 - 2026, Advanced Micro Devices, Inc. All rights reserved.<BR>
|
||||
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
**/
|
||||
@@ -151,6 +151,17 @@ typedef struct {
|
||||
UINTN DataSize;
|
||||
} AML_METHOD_PARAM;
|
||||
|
||||
/** structure to hold Notify method parameter types.
|
||||
NotifyObject - Notify Object parameter.
|
||||
Only NameString, Local and Arg types are supported.
|
||||
NotifyValue - Notify Value parameter.
|
||||
Must be an integer value.
|
||||
**/
|
||||
typedef struct {
|
||||
AML_METHOD_PARAM NotifyObject;
|
||||
UINT8 NotifyValue;
|
||||
} AML_NOTIFY_PARAM;
|
||||
|
||||
/** Parse the definition block.
|
||||
|
||||
The function parses the whole AML blob. It starts with the ACPI DSDT/SSDT
|
||||
@@ -2224,4 +2235,73 @@ AmlCodeGenRdUartSerialBusV2 (
|
||||
OUT AML_DATA_NODE_HANDLE *NewRdNode OPTIONAL
|
||||
);
|
||||
|
||||
/** AML code generation to create a method with Notify call.
|
||||
|
||||
Example 1:
|
||||
AmlCodeGenMethodNotifyList ("_L01", FALSE, 0, 0, NULL, ParentNode, NewObjectNode);
|
||||
is equivalent to the following ASL code:
|
||||
Method (_L01, 0, NotSerialize)
|
||||
{
|
||||
}
|
||||
|
||||
Example 2:
|
||||
AML_METHOD_PARAM Notify[2];
|
||||
Notify[0].NotifyObject.Type = AmlMethodParamTypeString;
|
||||
Notify[0].NotifyObject.Data.Buffer = (VOID*)"XCD0";
|
||||
Notify[0].NotifyObject.DataSize = 4;
|
||||
Notify[0].NotifyValue = 2;
|
||||
Notify[1].NotifyObject.Type = AmlMethodParamTypeString;
|
||||
Notify[1].NotifyObject.Data.Buffer = (VOID*)"XCD1";
|
||||
Notify[1].NotifyObject.DataSize = 4;
|
||||
Notify[1].NotifyValue = 2;
|
||||
AmlCodeGenMethodNotifyList ("_L02", FALSE, 0, 2, Notify, ParentNode, NewObjectNode);
|
||||
|
||||
is equivalent to the following ASL code:
|
||||
Method (_L02, 0, NotSerialize)
|
||||
{
|
||||
Notify ("XCD0", 2)
|
||||
Notify ("XCD1", 2)
|
||||
}
|
||||
|
||||
Ref : ACPI 6.6, s19.6.95 Notify (Notify Object of Event):
|
||||
Object must be a reference to a device, processor, or thermal zone object.
|
||||
|
||||
Note:
|
||||
This code cannot validate whether the referenced object is a valid device,
|
||||
processor, or thermal zone object.
|
||||
It assumes that NameString, Local, and Arg objects reference valid device,
|
||||
processor, or thermal zone objects.
|
||||
|
||||
@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] 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] NotifyParamCount Number of Notify parameters
|
||||
@param [in] NotifyParameters Array of Notify parameters
|
||||
@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
|
||||
AmlCodeGenMethodNotifyList (
|
||||
IN CONST CHAR8 *MethodNameString,
|
||||
IN BOOLEAN IsSerialized,
|
||||
IN UINT8 SyncLevel,
|
||||
IN UINT32 NotifyParamCount,
|
||||
IN AML_NOTIFY_PARAM *NotifyParameters OPTIONAL,
|
||||
IN AML_NODE_HANDLE ParentNode OPTIONAL,
|
||||
OUT AML_OBJECT_NODE_HANDLE *NewObjectNode OPTIONAL
|
||||
);
|
||||
|
||||
#endif // AML_LIB_H_
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
AML Code Generation.
|
||||
|
||||
Copyright (c) 2020 - 2023, Arm Limited. All rights reserved.<BR>
|
||||
Copyright (C) 2023 - 2025, Advanced Micro Devices, Inc. All rights reserved.<BR>
|
||||
Copyright (C) 2023 - 2026, Advanced Micro Devices, Inc. All rights reserved.<BR>
|
||||
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
**/
|
||||
@@ -5088,3 +5088,402 @@ error_handler:
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Create a Notify object node.
|
||||
|
||||
Creates and optionally adds the following node:
|
||||
Notify (NameString, Value)
|
||||
Notify (Local, Value)
|
||||
Notify (Arg, Value)
|
||||
|
||||
Ref : ACPI 6.6, s19.6.95 Notify (Notify Object of Event):
|
||||
Object must be a reference to a device, processor, or thermal zone object.
|
||||
|
||||
Note:
|
||||
This code cannot validate whether the referenced object is a valid device,
|
||||
processor, or thermal zone object.
|
||||
It assumes that NameString, Local, and Arg objects reference valid device,
|
||||
processor, or thermal zone objects.
|
||||
|
||||
@param [in] NotifyObjectNode Object node be notified
|
||||
@param [in] ValueObjectNode Notify value object.
|
||||
@param [in] ParentNode If provided, set ParentNode as the parent
|
||||
of the node created.
|
||||
@param [out] NewObjectNode If success and provided, 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.
|
||||
**/
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
AmlCodeGenNotifyNode (
|
||||
IN AML_NODE_HEADER *NotifyObjectNode,
|
||||
IN AML_NODE_HEADER *ValueObjectNode,
|
||||
IN AML_NODE_HEADER *ParentNode OPTIONAL,
|
||||
OUT AML_OBJECT_NODE **NewObjectNode OPTIONAL
|
||||
)
|
||||
{
|
||||
AML_OBJECT_NODE *ObjectNode;
|
||||
EFI_STATUS Status;
|
||||
|
||||
if ((NotifyObjectNode == NULL) || (ValueObjectNode == NULL) ||
|
||||
((ParentNode == NULL) && (NewObjectNode == NULL)))
|
||||
{
|
||||
ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if ((ParentNode != NULL) &&
|
||||
!AmlNodeCompareOpCode (
|
||||
(AML_OBJECT_NODE *)ParentNode,
|
||||
AML_METHOD_OP,
|
||||
0
|
||||
))
|
||||
{
|
||||
ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
ObjectNode = NULL;
|
||||
Status = AmlCreateObjectNode (
|
||||
AmlGetByteEncodingByOpCode (AML_NOTIFY_OP, 0),
|
||||
0,
|
||||
&ObjectNode
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
Status = AmlSetFixedArgument (
|
||||
ObjectNode,
|
||||
EAmlParseIndexTerm0,
|
||||
NotifyObjectNode
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
goto error_handler;
|
||||
}
|
||||
|
||||
Status = AmlSetFixedArgument (
|
||||
ObjectNode,
|
||||
EAmlParseIndexTerm1,
|
||||
ValueObjectNode
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
goto error_handler;
|
||||
}
|
||||
|
||||
Status = LinkNode (
|
||||
(AML_OBJECT_NODE_HANDLE)ObjectNode,
|
||||
ParentNode,
|
||||
(AML_OBJECT_NODE_HANDLE *)NewObjectNode
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
goto error_handler;
|
||||
}
|
||||
|
||||
return Status;
|
||||
|
||||
error_handler:
|
||||
if (ObjectNode != NULL) {
|
||||
AmlDeleteTree ((AML_NODE_HEADER *)ObjectNode);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Create a Notify object node from Notify parameters.
|
||||
|
||||
Creates and optionally adds the following node:
|
||||
Notify (NameString, Value)
|
||||
Notify (Local, Value)
|
||||
Notify (Arg, Value)
|
||||
|
||||
Ref : ACPI 6.6, s19.6.95 Notify (Notify Object of Event):
|
||||
Object must be a reference to a device, processor, or thermal zone object.
|
||||
|
||||
Note:
|
||||
This code cannot validate whether the referenced object is a valid device,
|
||||
processor, or thermal zone object.
|
||||
It assumes that NameString, Local, and Arg objects reference valid device,
|
||||
processor, or thermal zone objects.
|
||||
|
||||
@param [in] NotifyObject Object to be notified.
|
||||
@param [in] NotifyValue Notification value.
|
||||
@param [in] ParentNode If provided, set ParentNode as the parent
|
||||
of the node created.
|
||||
@param [out] NewObjectNode If success and provided, 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.
|
||||
**/
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
AmlCodeGenNotify (
|
||||
IN AML_METHOD_PARAM NotifyObject,
|
||||
IN UINT8 NotifyValue,
|
||||
IN AML_NODE_HEADER *ParentNode OPTIONAL,
|
||||
OUT AML_OBJECT_NODE **NewObjectNode OPTIONAL
|
||||
)
|
||||
{
|
||||
AML_OBJECT_NODE *NotifyObjectNode;
|
||||
AML_OBJECT_NODE *ValueObjectNode;
|
||||
EFI_STATUS Status;
|
||||
|
||||
if ((ParentNode == NULL) && (NewObjectNode == NULL)) {
|
||||
ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if ((NotifyObject.Type != AmlMethodParamTypeString) &&
|
||||
(NotifyObject.Type != AmlMethodParamTypeArg) &&
|
||||
(NotifyObject.Type != AmlMethodParamTypeLocal))
|
||||
{
|
||||
ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
ValueObjectNode = NULL;
|
||||
NotifyObjectNode = NULL;
|
||||
|
||||
switch (NotifyObject.Type) {
|
||||
case AmlMethodParamTypeString:
|
||||
if (NotifyObject.Data.Buffer == NULL) {
|
||||
ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
|
||||
Status = EFI_INVALID_PARAMETER;
|
||||
goto exit_handler;
|
||||
}
|
||||
|
||||
Status = AmlCodeGenString (
|
||||
NotifyObject.Data.Buffer,
|
||||
&NotifyObjectNode
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
goto exit_handler;
|
||||
}
|
||||
|
||||
break;
|
||||
case AmlMethodParamTypeArg:
|
||||
if (NotifyObject.Data.Arg > (UINT8)(AML_ARG6 - AML_ARG0)) {
|
||||
ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
|
||||
Status = EFI_INVALID_PARAMETER;
|
||||
goto exit_handler;
|
||||
}
|
||||
|
||||
Status = AmlCreateObjectNode (
|
||||
AmlGetByteEncodingByOpCode (
|
||||
AML_ARG0 + NotifyObject.Data.Arg,
|
||||
0
|
||||
),
|
||||
0,
|
||||
&NotifyObjectNode
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
goto exit_handler;
|
||||
}
|
||||
|
||||
break;
|
||||
case AmlMethodParamTypeLocal:
|
||||
if (NotifyObject.Data.Local > (UINT8)(AML_LOCAL7 - AML_LOCAL0)) {
|
||||
ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
|
||||
Status = EFI_INVALID_PARAMETER;
|
||||
goto exit_handler;
|
||||
}
|
||||
|
||||
Status = AmlCreateObjectNode (
|
||||
AmlGetByteEncodingByOpCode (
|
||||
AML_LOCAL0 + NotifyObject.Data.Local,
|
||||
0
|
||||
),
|
||||
0,
|
||||
&NotifyObjectNode
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
goto exit_handler;
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
|
||||
Status = EFI_INVALID_PARAMETER;
|
||||
goto exit_handler;
|
||||
} // switch
|
||||
|
||||
Status = AmlCodeGenInteger (
|
||||
NotifyValue,
|
||||
&ValueObjectNode
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
goto exit_handler;
|
||||
}
|
||||
|
||||
Status = AmlCodeGenNotifyNode (
|
||||
(AML_NODE_HEADER *)NotifyObjectNode,
|
||||
(AML_NODE_HEADER *)ValueObjectNode,
|
||||
ParentNode,
|
||||
NewObjectNode
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
goto exit_handler;
|
||||
}
|
||||
|
||||
NotifyObjectNode = NULL;
|
||||
ValueObjectNode = NULL;
|
||||
|
||||
exit_handler:
|
||||
|
||||
if (NotifyObjectNode != NULL) {
|
||||
AmlDeleteTree ((AML_NODE_HEADER *)NotifyObjectNode);
|
||||
}
|
||||
|
||||
if (ValueObjectNode != NULL) {
|
||||
AmlDeleteTree ((AML_NODE_HEADER *)ValueObjectNode);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/** AML code generation to create a method with Notify call.
|
||||
|
||||
Example 1:
|
||||
AmlCodeGenMethodNotifyList ("_L01", FALSE, 0, 0, NULL, ParentNode, NewObjectNode);
|
||||
is equivalent to the following ASL code:
|
||||
Method (_L01, 0, NotSerialize)
|
||||
{
|
||||
}
|
||||
|
||||
Example 2:
|
||||
AML_METHOD_PARAM Notify[2];
|
||||
Notify[0].NotifyObject.Type = AmlMethodParamTypeString;
|
||||
Notify[0].NotifyObject.Data.Buffer = (VOID*)"XCD0";
|
||||
Notify[0].NotifyObject.DataSize = 4;
|
||||
Notify[0].NotifyValue = 2;
|
||||
Notify[1].NotifyObject.Type = AmlMethodParamTypeString;
|
||||
Notify[1].NotifyObject.Data.Buffer = (VOID*)"XCD1";
|
||||
Notify[1].NotifyObject.DataSize = 4;
|
||||
Notify[1].NotifyValue = 2;
|
||||
AmlCodeGenMethodNotifyList ("_L02", FALSE, 0, 2, Notify, ParentNode, NewObjectNode);
|
||||
|
||||
is equivalent to the following ASL code:
|
||||
Method (_L02, 0, NotSerialize)
|
||||
{
|
||||
Notify ("XCD0", 2)
|
||||
Notify ("XCD1", 2)
|
||||
}
|
||||
|
||||
Ref : ACPI 6.6, s19.6.95 Notify (Notify Object of Event):
|
||||
Object must be a reference to a device, processor, or thermal zone object.
|
||||
|
||||
Note:
|
||||
This code cannot validate whether the referenced object is a valid device,
|
||||
processor, or thermal zone object.
|
||||
It assumes that NameString, Local, and Arg objects reference valid device,
|
||||
processor, or thermal zone objects.
|
||||
|
||||
@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] 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] NotifyParamCount Number of Notify parameters
|
||||
@param [in] NotifyParameters Array of Notify parameters
|
||||
@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
|
||||
AmlCodeGenMethodNotifyList (
|
||||
IN CONST CHAR8 *MethodNameString,
|
||||
IN BOOLEAN IsSerialized,
|
||||
IN UINT8 SyncLevel,
|
||||
IN UINT32 NotifyParamCount,
|
||||
IN AML_NOTIFY_PARAM *NotifyParameters OPTIONAL,
|
||||
IN AML_NODE_HANDLE ParentNode OPTIONAL,
|
||||
OUT AML_OBJECT_NODE_HANDLE *NewObjectNode OPTIONAL
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINT32 Index;
|
||||
AML_OBJECT_NODE_HANDLE MethodNode;
|
||||
|
||||
if ((MethodNameString == NULL) ||
|
||||
((ParentNode == NULL) && (NewObjectNode == NULL)))
|
||||
{
|
||||
ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Status = AmlCodeGenMethod (
|
||||
MethodNameString,
|
||||
0, // NumArgs
|
||||
IsSerialized,
|
||||
SyncLevel,
|
||||
NULL,
|
||||
&MethodNode
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
if ((NotifyParameters == NULL) || (NotifyParamCount == 0)) {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
for (Index = 0; Index < NotifyParamCount; Index++) {
|
||||
Status = AmlCodeGenNotify (
|
||||
NotifyParameters[Index].NotifyObject,
|
||||
NotifyParameters[Index].NotifyValue,
|
||||
(AML_NODE_HEADER *)MethodNode,
|
||||
NULL
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
goto error_handler;
|
||||
}
|
||||
}
|
||||
|
||||
Status = LinkNode (
|
||||
MethodNode,
|
||||
ParentNode,
|
||||
NewObjectNode
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
goto error_handler;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
error_handler:
|
||||
if (MethodNode != NULL) {
|
||||
AmlDeleteTree ((AML_NODE_HANDLE)MethodNode);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user