]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/MemoryTest/NullMemoryTestDxe/NullMemoryTest.c
MdeModulePkg/NullMemoryTest: Fix bug in CompatibleRangeTest
[mirror_edk2.git] / MdeModulePkg / Universal / MemoryTest / NullMemoryTestDxe / NullMemoryTest.c
index 11af8ea77fd00f155eb7252acb0b3d652701d206..a9bd1015013104d99e63d9f609452f6fe67e4bba 100644 (file)
@@ -59,37 +59,40 @@ GenericMemoryTestEntryPoint (
 }\r
 \r
 /**\r
-  Convert the memory descriptor to tested.\r
+  Convert the memory range to tested.\r
 \r
-  @param Descriptor  Pointer to EFI_GCD_MEMORY_SPACE_DESCRIPTOR\r
+  @param BaseAddress  Base address of the memory range.\r
+  @param Length       Length of the memory range.\r
+  @param Capabilities Capabilities of the memory range.\r
 \r
-  @retval EFI_SUCCESS The memory descriptor is converted to tested.\r
+  @retval EFI_SUCCESS The memory range is converted to tested.\r
   @retval others      Error happens.\r
 **/\r
 EFI_STATUS\r
 ConvertToTestedMemory (\r
-  IN CONST EFI_GCD_MEMORY_SPACE_DESCRIPTOR *Descriptor\r
+  IN UINT64           BaseAddress,\r
+  IN UINT64           Length,\r
+  IN UINT64           Capabilities\r
   )\r
 {\r
   EFI_STATUS Status;\r
   Status = gDS->RemoveMemorySpace (\r
-                  Descriptor->BaseAddress,\r
-                  Descriptor->Length\r
+                  BaseAddress,\r
+                  Length\r
                   );\r
   if (!EFI_ERROR (Status)) {\r
     Status = gDS->AddMemorySpace (\r
-                    ((Descriptor->Capabilities & EFI_MEMORY_MORE_RELIABLE) == EFI_MEMORY_MORE_RELIABLE) ?\r
+                    ((Capabilities & EFI_MEMORY_MORE_RELIABLE) == EFI_MEMORY_MORE_RELIABLE) ?\r
                     EfiGcdMemoryTypeMoreReliable : EfiGcdMemoryTypeSystemMemory,\r
-                    Descriptor->BaseAddress,\r
-                    Descriptor->Length,\r
-                    Descriptor->Capabilities &~\r
+                    BaseAddress,\r
+                    Length,\r
+                    Capabilities &~\r
                     (EFI_MEMORY_PRESENT | EFI_MEMORY_INITIALIZED | EFI_MEMORY_TESTED | EFI_MEMORY_RUNTIME)\r
                     );\r
   }\r
   return Status;\r
 }\r
 \r
-\r
 /**\r
   Initialize the generic memory test.\r
 \r
@@ -129,7 +132,11 @@ InitializeMemoryTest (
       //\r
       // For those reserved memory that have not been tested, simply promote to system memory.\r
       //\r
-      Status = ConvertToTestedMemory (&MemorySpaceMap[Index]);\r
+      Status = ConvertToTestedMemory (\r
+                 MemorySpaceMap[Index].BaseAddress,\r
+                 MemorySpaceMap[Index].Length,\r
+                 MemorySpaceMap[Index].Capabilities\r
+                 );\r
       ASSERT_EFI_ERROR (Status);\r
       mTestedSystemMemory += MemorySpaceMap[Index].Length;\r
       mTotalSystemMemory += MemorySpaceMap[Index].Length;\r
@@ -233,10 +240,51 @@ GenCompatibleRangeTest (
 {\r
   EFI_STATUS                      Status;\r
   EFI_GCD_MEMORY_SPACE_DESCRIPTOR Descriptor;\r
-\r
-  Status = gDS->GetMemorySpaceDescriptor (StartAddress, &Descriptor);\r
-  if (!EFI_ERROR (Status)) {\r
-    Status = ConvertToTestedMemory (&Descriptor);\r
+  EFI_PHYSICAL_ADDRESS            CurrentBase;\r
+  UINT64                          CurrentLength;\r
+\r
+  //\r
+  // Check if the parameter is below 16MB\r
+  //\r
+  if (StartAddress + Length > SIZE_16MB) {\r
+    return EFI_INVALID_PARAMETER;\r
   }\r
-  return Status;\r
+  CurrentBase = StartAddress;\r
+  do {\r
+    //\r
+    // Check the required memory range status; if the required memory range span\r
+    // the different GCD memory descriptor, it may be cause different action.\r
+    //\r
+    Status = gDS->GetMemorySpaceDescriptor (\r
+                    CurrentBase,\r
+                    &Descriptor\r
+                    );\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
+\r
+    if (Descriptor.GcdMemoryType == EfiGcdMemoryTypeReserved &&\r
+        (Descriptor.Capabilities & (EFI_MEMORY_PRESENT | EFI_MEMORY_INITIALIZED | EFI_MEMORY_TESTED)) ==\r
+          (EFI_MEMORY_PRESENT | EFI_MEMORY_INITIALIZED)\r
+          ) {\r
+      CurrentLength = Descriptor.BaseAddress + Descriptor.Length - CurrentBase;\r
+      if (CurrentBase + CurrentLength > StartAddress + Length) {\r
+        CurrentLength = StartAddress + Length - CurrentBase;\r
+      }\r
+      Status = ConvertToTestedMemory (\r
+                 CurrentBase,\r
+                 CurrentLength,\r
+                 Descriptor.Capabilities\r
+                 );\r
+      if (EFI_ERROR (Status)) {\r
+        return Status;\r
+      }\r
+    }\r
+    CurrentBase = Descriptor.BaseAddress + Descriptor.Length;\r
+  } while (CurrentBase < StartAddress + Length);\r
+  //\r
+  // Here means the required range already be tested, so just return success.\r
+  //\r
+  return EFI_SUCCESS;\r
 }\r
+\r