DynamicTablesPkg: Test for duplicate GT Block frame numbers
authorKrzysztof Koch <krzysztof.koch@arm.com>
Tue, 9 Apr 2019 13:44:37 +0000 (14:44 +0100)
committerSami Mujawar <sami.mujawar@arm.com>
Mon, 10 Jun 2019 19:44:31 +0000 (20:44 +0100)
Check for duplicate frame numbers when populating the GT Block Timer
Frames inside the GTDT table generator.

Signed-off-by: Krzysztof Koch <krzysztof.koch@arm.com>
Reviewed-by: Alexei Fedorov <Alexei.Fedorov@arm.com>
Reviewed-by: Sami Mujawar <sami.mujawar@arm.com>
DynamicTablesPkg/Library/Acpi/Arm/AcpiGtdtLibArm/GtdtGenerator.c

index 543e6f4..10cf16c 100644 (file)
@@ -179,6 +179,55 @@ AddGenericWatchdogList (
   } // for\r
 }\r
 \r
+/**\r
+  Function to test if two Generic Timer Block Frame Info structures have the\r
+  same frame number.\r
+\r
+  @param [in]  Frame1           Pointer to the first GT Block Frame Info\r
+                                structure.\r
+  @param [in]  Frame2           Pointer to the second GT Block Frame Info\r
+                                structure.\r
+  @param [in]  Index1           Index of Frame1 in the shared GT Block Frame\r
+                                Information List.\r
+  @param [in]  Index2           Index of Frame2 in the shared GT Block Frame\r
+                                Information List.\r
+\r
+  @retval TRUE                  Frame1 and Frame2 have the same frame number.\r
+  @return FALSE                 Frame1 and Frame2 have different frame numbers.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+IsGtFrameNumberEqual (\r
+  IN  CONST VOID          * Frame1,\r
+  IN  CONST VOID          * Frame2,\r
+  IN        UINTN           Index1,\r
+  IN        UINTN           Index2\r
+  )\r
+{\r
+  UINT8     FrameNumber1;\r
+  UINT8     FrameNumber2;\r
+\r
+  ASSERT ((Frame1 != NULL) && (Frame2 != NULL));\r
+\r
+  FrameNumber1 = ((CM_ARM_GTBLOCK_TIMER_FRAME_INFO*)Frame1)->FrameNumber;\r
+  FrameNumber2 = ((CM_ARM_GTBLOCK_TIMER_FRAME_INFO*)Frame2)->FrameNumber;\r
+\r
+  if (FrameNumber1 == FrameNumber2) {\r
+    DEBUG ((\r
+      DEBUG_ERROR,\r
+      "ERROR: GTDT: GT Block Frame Info Structures %d and %d have the same " \\r
+      "frame number: 0x%x.\n",\r
+      Index1,\r
+      Index2,\r
+      FrameNumber1\r
+      ));\r
+    return TRUE;\r
+  }\r
+\r
+  return FALSE;\r
+}\r
+\r
 /** Update the GT Block Timer Frame lists in the GTDT Table.\r
 \r
   @param [in]  GtBlockFrame           Pointer to the GT Block Frames\r
@@ -187,8 +236,8 @@ AddGenericWatchdogList (
                                       Information List.\r
   @param [in]  GTBlockFrameCount      Number of GT Block Frames.\r
 \r
-  @retval EFI_SUCCESS           Table generated successfully.\r
-  @retval EFI_INVALID_PARAMETER A parameter is invalid.\r
+  @retval EFI_SUCCESS                 Table generated successfully.\r
+  @retval EFI_INVALID_PARAMETER       A parameter is invalid.\r
 **/\r
 STATIC\r
 EFI_STATUS\r
@@ -198,6 +247,8 @@ AddGTBlockTimerFrames (
   IN       UINT32                                             GTBlockFrameCount\r
 )\r
 {\r
+  BOOLEAN    IsFrameNumberDuplicated;\r
+\r
   ASSERT (GtBlockFrame != NULL);\r
   ASSERT (GTBlockTimerFrameList != NULL);\r
 \r
@@ -211,6 +262,17 @@ AddGTBlockTimerFrames (
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
+  IsFrameNumberDuplicated = FindDuplicateValue (\r
+                              GTBlockTimerFrameList,\r
+                              GTBlockFrameCount,\r
+                              sizeof (CM_ARM_GTBLOCK_TIMER_FRAME_INFO),\r
+                              IsGtFrameNumberEqual\r
+                              );\r
+  // Duplicate entry was found so timer frame numbers provided are invalid\r
+  if (IsFrameNumberDuplicated) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
   while (GTBlockFrameCount-- != 0) {\r
     DEBUG ((\r
       DEBUG_INFO,\r