DynamicTablesPkg: AmlLib: AmlAddPrtEntry() to handle GSI

In ACPI 6.4, s6.2.13, _PRT objects describing PCI legacy interrupts
can be defined following 2 models.
In the first model, _PRT entries reference link devices. Link devices
then describe interrupts. This allows to dynamically modify
interrupts through _SRS and _PRS objects and to choose exactly the
interrupt type (level/edge triggered, active high/low).
In the second model, interrupt numbers are described in the _PRT entry.
The interrupt type is then assumed by the OS.

AmlAddPrtEntry() currently only handles the first model. Make
changes to also handle the second model.

Signed-off-by: Pierre Gondois <Pierre.Gondois@arm.com>
Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
This commit is contained in:
Pierre Gondois 2022-02-01 16:30:13 +01:00 committed by mergify[bot]
parent 13136cc311
commit 5751d60821
1 changed files with 59 additions and 38 deletions

View File

@ -1,7 +1,7 @@
/** @file
AML Code Generation.
Copyright (c) 2020 - 2021, Arm Limited. All rights reserved.<BR>
Copyright (c) 2020 - 2022, Arm Limited. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@ -881,6 +881,9 @@ AmlCodeGenNameResourceTemplate (
// interrupt, so let it to index 0.
}
The 2 models described in ACPI 6.4, s6.2.13 "_PRT (PCI Routing Table)" can
be generated by this function. The example above matches the first model.
The package is added at the tail of the list of the input _PRT node
name:
Name (_PRT, Package () {
@ -901,8 +904,10 @@ AmlCodeGenNameResourceTemplate (
@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.
describing the interrupt used. The input string
is copied.
If NULL, generate 0 in the 'Source' field (cf.
second model, using GSIV).
@param [in] SourceIndex Source index or GSIV.
@param [in] PrtNameNode Prt Named node to add the object to ....
@ -930,7 +935,6 @@ AmlAddPrtEntry (
AML_DATA_NODE *DataNode;
if ((Pin > 3) ||
(LinkName == NULL) ||
(PrtNameNode == NULL) ||
(AmlGetNodeType ((AML_NODE_HANDLE)PrtNameNode) != EAmlNodeObject) ||
(!AmlNodeHasOpCode (PrtNameNode, AML_NAME_OP, 0)) ||
@ -999,42 +1003,59 @@ AmlAddPrtEntry (
NewElementNode = NULL;
Status = ConvertAslNameToAmlName (LinkName, &AmlNameString);
if (EFI_ERROR (Status)) {
ASSERT (0);
goto error_handler;
if (LinkName != NULL) {
Status = ConvertAslNameToAmlName (LinkName, &AmlNameString);
if (EFI_ERROR (Status)) {
ASSERT_EFI_ERROR (Status);
goto error_handler;
}
Status = AmlGetNameStringSize (AmlNameString, &AmlNameStringSize);
if (EFI_ERROR (Status)) {
ASSERT_EFI_ERROR (Status);
goto error_handler;
}
Status = AmlCreateDataNode (
EAmlNodeDataTypeNameString,
(UINT8 *)AmlNameString,
AmlNameStringSize,
&DataNode
);
if (EFI_ERROR (Status)) {
ASSERT_EFI_ERROR (Status);
goto error_handler;
}
// AmlNameString will be freed be fore returning.
Status = AmlVarListAddTail (
(AML_NODE_HANDLE)PackageNode,
(AML_NODE_HANDLE)DataNode
);
if (EFI_ERROR (Status)) {
ASSERT_EFI_ERROR (Status);
goto error_handler;
}
DataNode = NULL;
} else {
Status = AmlCodeGenInteger (0, &NewElementNode);
if (EFI_ERROR (Status)) {
ASSERT_EFI_ERROR (Status);
goto error_handler;
}
Status = AmlVarListAddTail (
(AML_NODE_HANDLE)PackageNode,
(AML_NODE_HANDLE)NewElementNode
);
if (EFI_ERROR (Status)) {
ASSERT_EFI_ERROR (Status);
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);