mirror of https://github.com/acidanthera/audk.git
DynamicTablesPkg: AML Code generation to add _PRT entries
_PRT entries can describe interrupt mapping for Pci devices. The object is described in ACPI 6.4 s6.2.13 "_PRT (PCI Routing Table)". Add AmlCodeGenPrtEntry() helper function to add _PRT entries to an existing _PRT object. To: Sami Mujawar <sami.mujawar@arm.com> To: Alexei Fedorov <Alexei.Fedorov@arm.com> Signed-off-by: Pierre Gondois <Pierre.Gondois@arm.com> Reviewed-by: Sami Mujawar <sami.mujawar@arm.com>
This commit is contained in:
parent
fd5fc4bbb7
commit
b2b8def4e3
|
@ -891,6 +891,58 @@ AmlCodeGenNameResourceTemplate (
|
||||||
OUT AML_OBJECT_NODE_HANDLE *NewObjectNode OPTIONAL
|
OUT AML_OBJECT_NODE_HANDLE *NewObjectNode OPTIONAL
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/** Add a _PRT entry.
|
||||||
|
|
||||||
|
AmlCodeGenPrtEntry (0x0FFFF, 0, "LNKA", 0, PrtNameNode) is
|
||||||
|
equivalent of the following ASL code:
|
||||||
|
Package (4) {
|
||||||
|
0x0FFFF, // Address: Device address (([Device Id] << 16) | 0xFFFF).
|
||||||
|
0, // Pin: PCI pin number of the device (0-INTA, ...).
|
||||||
|
LNKA // Source: Name of the device that allocates the interrupt
|
||||||
|
// to which the above pin is connected.
|
||||||
|
0 // Source Index: Source is assumed to only describe one
|
||||||
|
// interrupt, so let it to index 0.
|
||||||
|
}
|
||||||
|
|
||||||
|
The package is added at the tail of the list of the input _PRT node
|
||||||
|
name:
|
||||||
|
Name (_PRT, Package () {
|
||||||
|
[Pre-existing _PRT entries],
|
||||||
|
[Newly created _PRT entry]
|
||||||
|
})
|
||||||
|
|
||||||
|
Cf. ACPI 6.4, s6.2.13 "_PRT (PCI Routing Table)"
|
||||||
|
|
||||||
|
@ingroup CodeGenApis
|
||||||
|
|
||||||
|
@param [in] Address Address. Cf ACPI 6.4 specification, Table 6.2:
|
||||||
|
"ADR Object Address Encodings":
|
||||||
|
High word-Device #, Low word-Function #. (for
|
||||||
|
example, device 3, function 2 is 0x00030002).
|
||||||
|
To refer to all the functions on a device #,
|
||||||
|
use a function number of FFFF).
|
||||||
|
@param [in] Pin PCI pin number of the device (0-INTA ... 3-INTD).
|
||||||
|
Must be between 0-3.
|
||||||
|
@param [in] LinkName Link Name, i.e. device in the AML NameSpace
|
||||||
|
describing the interrupt used.
|
||||||
|
The input string is copied.
|
||||||
|
@param [in] SourceIndex Source index or GSIV.
|
||||||
|
@param [in] PrtNameNode Prt Named node to add the object to ....
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS Success.
|
||||||
|
@retval EFI_INVALID_PARAMETER Invalid parameter.
|
||||||
|
@retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
AmlAddPrtEntry (
|
||||||
|
IN UINT32 Address,
|
||||||
|
IN UINT8 Pin,
|
||||||
|
IN CONST CHAR8 *LinkName,
|
||||||
|
IN UINT32 SourceIndex,
|
||||||
|
IN AML_OBJECT_NODE_HANDLE PrtNameNode
|
||||||
|
);
|
||||||
|
|
||||||
/** AML code generation for a Device object node.
|
/** AML code generation for a Device object node.
|
||||||
|
|
||||||
AmlCodeGenDevice ("COM0", ParentNode, NewObjectNode) is
|
AmlCodeGenDevice ("COM0", ParentNode, NewObjectNode) is
|
||||||
|
|
|
@ -868,6 +868,220 @@ AmlCodeGenNameResourceTemplate (
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Add a _PRT entry.
|
||||||
|
|
||||||
|
AmlCodeGenPrtEntry (0x0FFFF, 0, "LNKA", 0, PrtNameNode) is
|
||||||
|
equivalent of the following ASL code:
|
||||||
|
Package (4) {
|
||||||
|
0x0FFFF, // Address: Device address (([Device Id] << 16) | 0xFFFF).
|
||||||
|
0, // Pin: PCI pin number of the device (0-INTA, ...).
|
||||||
|
LNKA // Source: Name of the device that allocates the interrupt
|
||||||
|
// to which the above pin is connected.
|
||||||
|
0 // Source Index: Source is assumed to only describe one
|
||||||
|
// interrupt, so let it to index 0.
|
||||||
|
}
|
||||||
|
|
||||||
|
The package is added at the tail of the list of the input _PRT node
|
||||||
|
name:
|
||||||
|
Name (_PRT, Package () {
|
||||||
|
[Pre-existing _PRT entries],
|
||||||
|
[Newly created _PRT entry]
|
||||||
|
})
|
||||||
|
|
||||||
|
Cf. ACPI 6.4 specification:
|
||||||
|
- s6.2.13 "_PRT (PCI Routing Table)"
|
||||||
|
- s6.1.1 "_ADR (Address)"
|
||||||
|
|
||||||
|
@param [in] Address Address. Cf ACPI 6.4 specification, Table 6.2:
|
||||||
|
"ADR Object Address Encodings":
|
||||||
|
High word-Device #, Low word-Function #. (for
|
||||||
|
example, device 3, function 2 is 0x00030002).
|
||||||
|
To refer to all the functions on a device #,
|
||||||
|
use a function number of FFFF).
|
||||||
|
@param [in] Pin PCI pin number of the device (0-INTA ... 3-INTD).
|
||||||
|
Must be between 0-3.
|
||||||
|
@param [in] LinkName Link Name, i.e. device in the AML NameSpace
|
||||||
|
describing the interrupt used.
|
||||||
|
The input string is copied.
|
||||||
|
@param [in] SourceIndex Source index or GSIV.
|
||||||
|
@param [in] PrtNameNode Prt Named node to add the object to ....
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS Success.
|
||||||
|
@retval EFI_INVALID_PARAMETER Invalid parameter.
|
||||||
|
@retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
AmlAddPrtEntry (
|
||||||
|
IN UINT32 Address,
|
||||||
|
IN UINT8 Pin,
|
||||||
|
IN CONST CHAR8 *LinkName,
|
||||||
|
IN UINT32 SourceIndex,
|
||||||
|
IN AML_OBJECT_NODE_HANDLE PrtNameNode
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
AML_OBJECT_NODE *PrtEntryList;
|
||||||
|
AML_OBJECT_NODE *PackageNode;
|
||||||
|
AML_OBJECT_NODE *NewElementNode;
|
||||||
|
|
||||||
|
CHAR8 *AmlNameString;
|
||||||
|
UINT32 AmlNameStringSize;
|
||||||
|
AML_DATA_NODE *DataNode;
|
||||||
|
|
||||||
|
if ((Pin > 3) ||
|
||||||
|
(LinkName == NULL) ||
|
||||||
|
(PrtNameNode == NULL) ||
|
||||||
|
(AmlGetNodeType ((AML_NODE_HANDLE)PrtNameNode) != EAmlNodeObject) ||
|
||||||
|
(!AmlNodeHasOpCode (PrtNameNode, AML_NAME_OP, 0)) ||
|
||||||
|
!AmlNameOpCompareName (PrtNameNode, "_PRT"))
|
||||||
|
{
|
||||||
|
ASSERT (0);
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
NewElementNode = NULL;
|
||||||
|
AmlNameString = NULL;
|
||||||
|
DataNode = NULL;
|
||||||
|
|
||||||
|
// Get the Package object node of the _PRT node,
|
||||||
|
// which is the 2nd fixed argument (i.e. index 1).
|
||||||
|
PrtEntryList = (AML_OBJECT_NODE_HANDLE)AmlGetFixedArgument (
|
||||||
|
PrtNameNode,
|
||||||
|
EAmlParseIndexTerm1
|
||||||
|
);
|
||||||
|
if ((PrtEntryList == NULL) ||
|
||||||
|
(AmlGetNodeType ((AML_NODE_HANDLE)PrtEntryList) != EAmlNodeObject) ||
|
||||||
|
(!AmlNodeHasOpCode (PrtEntryList, AML_PACKAGE_OP, 0)))
|
||||||
|
{
|
||||||
|
ASSERT (0);
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The new _PRT entry.
|
||||||
|
Status = AmlCodeGenPackage (&PackageNode);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
ASSERT (0);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = AmlCodeGenInteger (Address, &NewElementNode);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
ASSERT (0);
|
||||||
|
goto error_handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = AmlVarListAddTail (
|
||||||
|
(AML_NODE_HANDLE)PackageNode,
|
||||||
|
(AML_NODE_HANDLE)NewElementNode
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
ASSERT (0);
|
||||||
|
goto error_handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
NewElementNode = NULL;
|
||||||
|
|
||||||
|
Status = AmlCodeGenInteger (Pin, &NewElementNode);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
ASSERT (0);
|
||||||
|
goto error_handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = AmlVarListAddTail (
|
||||||
|
(AML_NODE_HANDLE)PackageNode,
|
||||||
|
(AML_NODE_HANDLE)NewElementNode
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
ASSERT (0);
|
||||||
|
goto error_handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
NewElementNode = NULL;
|
||||||
|
|
||||||
|
Status = ConvertAslNameToAmlName (LinkName, &AmlNameString);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
ASSERT (0);
|
||||||
|
goto error_handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = AmlGetNameStringSize (AmlNameString, &AmlNameStringSize);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
ASSERT (0);
|
||||||
|
goto error_handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = AmlCreateDataNode (
|
||||||
|
EAmlNodeDataTypeNameString,
|
||||||
|
(UINT8 *)AmlNameString,
|
||||||
|
AmlNameStringSize,
|
||||||
|
&DataNode
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
ASSERT (0);
|
||||||
|
goto error_handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
// AmlNameString will be freed before returning.
|
||||||
|
|
||||||
|
Status = AmlVarListAddTail (
|
||||||
|
(AML_NODE_HANDLE)PackageNode,
|
||||||
|
(AML_NODE_HANDLE)DataNode
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
ASSERT (0);
|
||||||
|
goto error_handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
DataNode = NULL;
|
||||||
|
|
||||||
|
Status = AmlCodeGenInteger (SourceIndex, &NewElementNode);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
ASSERT (0);
|
||||||
|
goto error_handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = AmlVarListAddTail (
|
||||||
|
(AML_NODE_HANDLE)PackageNode,
|
||||||
|
(AML_NODE_HANDLE)NewElementNode
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
ASSERT (0);
|
||||||
|
goto error_handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Append to the the list of _PRT entries.
|
||||||
|
Status = AmlVarListAddTail (
|
||||||
|
(AML_NODE_HANDLE)PrtEntryList,
|
||||||
|
(AML_NODE_HANDLE)PackageNode
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
ASSERT (0);
|
||||||
|
goto error_handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Free AmlNameString before returning as it is copied
|
||||||
|
// in the call to AmlCreateDataNode().
|
||||||
|
goto exit_handler;
|
||||||
|
|
||||||
|
error_handler:
|
||||||
|
AmlDeleteTree ((AML_NODE_HANDLE)PackageNode);
|
||||||
|
if (NewElementNode != NULL) {
|
||||||
|
AmlDeleteTree ((AML_NODE_HANDLE)NewElementNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DataNode != NULL) {
|
||||||
|
AmlDeleteTree ((AML_NODE_HANDLE)DataNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
exit_handler:
|
||||||
|
if (AmlNameString != NULL) {
|
||||||
|
FreePool (AmlNameString);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
/** AML code generation for a Device object node.
|
/** AML code generation for a Device object node.
|
||||||
|
|
||||||
AmlCodeGenDevice ("COM0", ParentNode, NewObjectNode) is
|
AmlCodeGenDevice ("COM0", ParentNode, NewObjectNode) is
|
||||||
|
|
Loading…
Reference in New Issue