Nt32Pkg: Platform BDS should test the untested memory
[mirror_edk2.git] / Nt32Pkg / Library / PlatformBootManagerLib / PlatformBootManager.c
index a527a42..7964b2b 100644 (file)
@@ -18,6 +18,93 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \r
 EFI_GUID mUefiShellFileGuid = { 0x7C04A583, 0x9E3E, 0x4f1c, 0xAD, 0x65, 0xE0, 0x52, 0x68, 0xD0, 0xB4, 0xD1 };\r
 \r
+/**\r
+  Perform the memory test base on the memory test intensive level,\r
+  and update the memory resource.\r
+\r
+  @param  Level         The memory test intensive level.\r
+\r
+  @retval EFI_STATUS    Success test all the system memory and update\r
+                        the memory resource\r
+\r
+**/\r
+EFI_STATUS\r
+PlatformBootManagerMemoryTest (\r
+  IN EXTENDMEM_COVERAGE_LEVEL Level\r
+  )\r
+{\r
+  EFI_STATUS                        Status;\r
+  BOOLEAN                           RequireSoftECCInit;\r
+  EFI_GENERIC_MEMORY_TEST_PROTOCOL  *GenMemoryTest;\r
+  UINT64                            TestedMemorySize;\r
+  UINT64                            TotalMemorySize;\r
+  UINTN                             TestPercent;\r
+  UINT64                            PreviousValue;\r
+  BOOLEAN                           ErrorOut;\r
+  UINT32                            TempData;\r
+\r
+  TestedMemorySize  = 0;\r
+  TotalMemorySize   = 0;\r
+  PreviousValue     = 0;\r
+\r
+  RequireSoftECCInit = FALSE;\r
+\r
+  Status = gBS->LocateProtocol (\r
+                  &gEfiGenericMemTestProtocolGuid,\r
+                  NULL,\r
+                  (VOID **) &GenMemoryTest\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  Status = GenMemoryTest->MemoryTestInit (\r
+                            GenMemoryTest,\r
+                            Level,\r
+                            &RequireSoftECCInit\r
+                            );\r
+  if (Status == EFI_NO_MEDIA) {\r
+    //\r
+    // The PEI codes also have the relevant memory test code to check the memory,\r
+    // it can select to test some range of the memory or all of them. If PEI code\r
+    // checks all the memory, this BDS memory test will has no not-test memory to\r
+    // do the test, and then the status of EFI_NO_MEDIA will be returned by\r
+    // "MemoryTestInit". So it does not need to test memory again, just return.\r
+    //\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  do {\r
+    Status = GenMemoryTest->PerformMemoryTest (\r
+                              GenMemoryTest,\r
+                              &TestedMemorySize,\r
+                              &TotalMemorySize,\r
+                              &ErrorOut,\r
+                              FALSE\r
+                              );\r
+    if (ErrorOut && (Status == EFI_DEVICE_ERROR)) {\r
+      Print (L"System encounters memory errors!");\r
+      CpuDeadLoop ();\r
+    }\r
+    \r
+    TempData = (UINT32) DivU64x32 (TotalMemorySize, 16);\r
+    TestPercent = (UINTN) DivU64x32 (\r
+                            DivU64x32 (MultU64x32 (TestedMemorySize, 100), 16),\r
+                            TempData\r
+                            );\r
+    if (TestPercent != PreviousValue) {\r
+      Print (L"Perform memory test: %d/100", TestPercent);\r
+      PreviousValue = TestPercent;\r
+    }\r
+  } while (Status != EFI_NOT_FOUND);\r
+\r
+  Status = GenMemoryTest->Finished (GenMemoryTest);\r
+\r
+  Print (L"\r%dM bytes of system memory tested OK\n", (UINT32) DivU64x32 (TotalMemorySize, 1024 * 1024));\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
 /**\r
   Return the index of the load option in the load option array.\r
 \r
@@ -197,6 +284,7 @@ PlatformBootManagerAfterConsole (
   VOID\r
   )\r
 {\r
+  PlatformBootManagerMemoryTest (QUICK);\r
   EfiBootManagerConnectAll ();\r
   EfiBootManagerRefreshAllBootOption ();\r
   Print (\r