mirror of
https://github.com/tianocore/edk2
synced 2026-08-27 00:23:19 -04:00
DynamicTablesPkg: handle missing 'iommu-map' in root complex parser
Some guests (e.g. kvmtool) do not provide a SMMU, so the PCI node in the DTB lacks an 'iommu-map'. The current code ASSERTs during boot with: "ASSERT [ConfigurationManagerDxe] RootComplexParser.c(244): (Data != ((void *) 0)) && ((DataSize % (4 * sizeof (UINT32))) == 0)" Instead, return EFI_NOT_FOUND when 'iommu-map' is absent so firmware boot can proceed. Cc: Ard Biesheuvel <ardb+tianocore@kernel.org> Cc: Leif Lindholm <leif.lindholm@oss.qualcomm.com> Cc: Gerd Hoffmann <kraxel@redhat.com> Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
This commit is contained in:
parent
ebe7fab41e
commit
18d0c3596e
1 changed files with 52 additions and 42 deletions
|
|
@ -239,49 +239,56 @@ RootComplexNodeParser (
|
|||
RootComplexInfo->Identifier = GetNextIortIdentifier ();
|
||||
|
||||
Data = FdtGetProp (Fdt, RootComplexNode, "iommu-map", &DataSize);
|
||||
if ((Data == NULL) || ((DataSize % (IOMMU_MAP_CELL_COUNT * sizeof (UINT32))) != 0)) {
|
||||
// If error or invalid number of cells (not multiple of IOMMU_MAP_CELL_COUNT).
|
||||
ASSERT ((Data != NULL) && ((DataSize % (IOMMU_MAP_CELL_COUNT * sizeof (UINT32))) == 0));
|
||||
return EFI_ABORTED;
|
||||
if (Data == NULL) {
|
||||
// Some guests (e.g. kvmtool) do not provide a SMMU, so the PCI node
|
||||
// in the DTB lacks an 'iommu-map'. In such cases set the Number of
|
||||
// ID mappings to 0.
|
||||
RootComplexInfo->IdMappingCount = 0;
|
||||
} else {
|
||||
if (((DataSize % (IOMMU_MAP_CELL_COUNT * sizeof (UINT32))) != 0)) {
|
||||
// If error or invalid number of cells (not multiple of IOMMU_MAP_CELL_COUNT).
|
||||
ASSERT ((DataSize % (IOMMU_MAP_CELL_COUNT * sizeof (UINT32))) == 0);
|
||||
return EFI_ABORTED;
|
||||
}
|
||||
|
||||
DataSize /= IOMMU_MAP_CELL_COUNT * sizeof (UINT32);
|
||||
|
||||
IdMappings = AllocateZeroPool (DataSize * sizeof (CM_ARM_ID_MAPPING));
|
||||
if (IdMappings == NULL) {
|
||||
ASSERT (IdMappings != NULL);
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
for (MapIndex = 0; MapIndex < DataSize; MapIndex++) {
|
||||
IdMappings[MapIndex].InputBase = Fdt32ToCpu (((UINT32 *)Data)[MapIndex * IOMMU_MAP_CELL_COUNT]);
|
||||
IdMappings[MapIndex].NumIds = Fdt32ToCpu (((UINT32 *)Data)[MapIndex * IOMMU_MAP_CELL_COUNT + 3]);
|
||||
IdMappings[MapIndex].OutputBase = Fdt32ToCpu (((UINT32 *)Data)[MapIndex * IOMMU_MAP_CELL_COUNT + 2]);
|
||||
IdMappings[MapIndex].OutputReferenceToken = CM_ABSTRACT_TOKEN_MAKE (
|
||||
ETokenNameSpaceFdtHwInfo,
|
||||
EFdtHwInfoIortObject,
|
||||
Fdt32ToCpu (((UINT32 *)Data)[MapIndex * IOMMU_MAP_CELL_COUNT + 1])
|
||||
);
|
||||
}
|
||||
|
||||
// Add the CmObj to the Configuration Manager.
|
||||
Status = AddSingleCmObjArray (
|
||||
FdtParserHandle,
|
||||
CREATE_CM_ARM_OBJECT_ID (EArmObjIdMappingArray),
|
||||
IdMappings,
|
||||
sizeof (CM_ARM_ID_MAPPING) * DataSize,
|
||||
DataSize,
|
||||
&RootComplexInfo->IdMappingToken
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
FreePool (IdMappings);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/// Number of ID mappings
|
||||
RootComplexInfo->IdMappingCount = DataSize;
|
||||
}
|
||||
|
||||
DataSize /= IOMMU_MAP_CELL_COUNT * sizeof (UINT32);
|
||||
|
||||
IdMappings = AllocateZeroPool (DataSize * sizeof (CM_ARM_ID_MAPPING));
|
||||
if (IdMappings == NULL) {
|
||||
ASSERT (IdMappings != NULL);
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
for (MapIndex = 0; MapIndex < DataSize; MapIndex++) {
|
||||
IdMappings[MapIndex].InputBase = Fdt32ToCpu (((UINT32 *)Data)[MapIndex * IOMMU_MAP_CELL_COUNT]);
|
||||
IdMappings[MapIndex].NumIds = Fdt32ToCpu (((UINT32 *)Data)[MapIndex * IOMMU_MAP_CELL_COUNT + 3]);
|
||||
IdMappings[MapIndex].OutputBase = Fdt32ToCpu (((UINT32 *)Data)[MapIndex * IOMMU_MAP_CELL_COUNT + 2]);
|
||||
IdMappings[MapIndex].OutputReferenceToken = CM_ABSTRACT_TOKEN_MAKE (
|
||||
ETokenNameSpaceFdtHwInfo,
|
||||
EFdtHwInfoIortObject,
|
||||
Fdt32ToCpu (((UINT32 *)Data)[MapIndex * IOMMU_MAP_CELL_COUNT + 1])
|
||||
);
|
||||
}
|
||||
|
||||
// Add the CmObj to the Configuration Manager.
|
||||
Status = AddSingleCmObjArray (
|
||||
FdtParserHandle,
|
||||
CREATE_CM_ARM_OBJECT_ID (EArmObjIdMappingArray),
|
||||
IdMappings,
|
||||
sizeof (CM_ARM_ID_MAPPING) * DataSize,
|
||||
DataSize,
|
||||
&RootComplexInfo->IdMappingToken
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
FreePool (IdMappings);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/// Number of ID mappings
|
||||
RootComplexInfo->IdMappingCount = DataSize;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
@ -378,7 +385,10 @@ ArmPciRootComplexParser (
|
|||
|
||||
Status = RootComplexNodeParser (FdtParserHandle, Fdt, RootComplexNode, &RootComplexInfo);
|
||||
if (EFI_ERROR (Status)) {
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
if (Status != EFI_NOT_FOUND) {
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue