Gicc->Reserved2[2] = EFI_ACPI_RESERVED_BYTE;\r
}\r
\r
+/**\r
+ Function to test if two GIC CPU Interface information structures have the\r
+ same ACPI Processor UID.\r
+\r
+ @param [in] GicCInfo1 Pointer to the first GICC info structure.\r
+ @param [in] GicCInfo2 Pointer to the second GICC info structure.\r
+ @param [in] Index1 Index of GicCInfo1 in the shared list of GIC\r
+ CPU Interface Info structures.\r
+ @param [in] Index2 Index of GicCInfo2 in the shared list of GIC\r
+ CPU Interface Info structures.\r
+\r
+ @retval TRUE GicCInfo1 and GicCInfo2 have the same UID.\r
+ @retval FALSE GicCInfo1 and GicCInfo2 have different UIDs.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+IsAcpiUidEqual (\r
+ IN CONST VOID * GicCInfo1,\r
+ IN CONST VOID * GicCInfo2,\r
+ IN UINTN Index1,\r
+ IN UINTN Index2\r
+ )\r
+{\r
+ UINT32 Uid1;\r
+ UINT32 Uid2;\r
+\r
+ ASSERT ((GicCInfo1 != NULL) && (GicCInfo2 != NULL));\r
+\r
+ Uid1 = ((CM_ARM_GICC_INFO*)GicCInfo1)->AcpiProcessorUid;\r
+ Uid2 = ((CM_ARM_GICC_INFO*)GicCInfo2)->AcpiProcessorUid;\r
+\r
+ if (Uid1 == Uid2) {\r
+ DEBUG ((\r
+ DEBUG_ERROR,\r
+ "ERROR: MADT: GICC Info Structures %d and %d have the same ACPI " \\r
+ "Processor UID: 0x%x.\n",\r
+ Index1,\r
+ Index2,\r
+ Uid1\r
+ ));\r
+ return TRUE;\r
+ }\r
+\r
+ return FALSE;\r
+}\r
+\r
/** Add the GIC CPU Interface Information to the MADT Table.\r
\r
- @param [in] Gicc Pointer to GIC CPU Interface\r
- structure list.\r
- @param [in] GicCInfo Pointer to the GIC CPU\r
- Information list.\r
- @param [in] GicCCount Count of GIC CPU Interfaces.\r
+ This function also checks for duplicate ACPI Processor UIDs.\r
+\r
+ @param [in] Gicc Pointer to GIC CPU Interface structure list.\r
+ @param [in] GicCInfo Pointer to the GIC CPU Information list.\r
+ @param [in] GicCCount Count of GIC CPU Interfaces.\r
+\r
+ @retval EFI_SUCCESS GIC CPU Interface Information was added\r
+ successfully.\r
+ @retval EFI_INVALID_PARAMETER One or more invalid GIC CPU Info values were\r
+ provided and the generator failed to add the\r
+ information to the table.\r
**/\r
STATIC\r
-VOID\r
+EFI_STATUS\r
AddGICCList (\r
IN EFI_ACPI_6_2_GIC_STRUCTURE * Gicc,\r
IN CONST CM_ARM_GICC_INFO * GicCInfo,\r
IN UINT32 GicCCount\r
)\r
{\r
+ BOOLEAN IsAcpiProcUidDuplicated;\r
+\r
ASSERT (Gicc != NULL);\r
ASSERT (GicCInfo != NULL);\r
\r
+ IsAcpiProcUidDuplicated = FindDuplicateValue (\r
+ GicCInfo,\r
+ GicCCount,\r
+ sizeof (CM_ARM_GICC_INFO),\r
+ IsAcpiUidEqual\r
+ );\r
+ // Duplicate ACPI Processor UID was found so the GICC info provided\r
+ // is invalid\r
+ if (IsAcpiProcUidDuplicated) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
while (GicCCount-- != 0) {\r
AddGICC (Gicc++, GicCInfo++);\r
}\r
+\r
+ return EFI_SUCCESS;\r
}\r
\r
/** Update the GIC Distributor Information in the MADT Table.\r
goto error_handler;\r
}\r
\r
- AddGICCList (\r
+ Status = AddGICCList (\r
(EFI_ACPI_6_2_GIC_STRUCTURE*)((UINT8*)Madt + GicCOffset),\r
GicCInfo,\r
GicCCount\r
);\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((\r
+ DEBUG_ERROR,\r
+ "ERROR: MADT: Failed to add GICC structures. Status = %r\n",\r
+ Status\r
+ ));\r
+ goto error_handler;\r
+ }\r
\r
AddGICD (\r
(EFI_ACPI_6_2_GIC_DISTRIBUTOR_STRUCTURE*)((UINT8*)Madt + GicDOffset),\r