1 /** @file 2 Perform the platform memory test 3 4 Copyright (c) 2004 - 2015, Intel Corporation. All rights reserved.<BR> 5 This program and the accompanying materials 6 are licensed and made available under the terms and conditions of the BSD License 7 which accompanies this distribution. The full text of the license may be found at 8 http://opensource.org/licenses/bsd-license.php 9 10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 12 13 **/ 14 15 #include "PlatformBootManager.h" 16 17 EFI_HII_HANDLE gStringPackHandle = NULL; 18 EFI_GUID mPlatformBootManagerStringPackGuid = { 19 0x154dd51, 0x9079, 0x4a10, { 0x89, 0x5c, 0x9c, 0x7, 0x72, 0x81, 0x57, 0x88 } 20 }; 21 // extern UINT8 BdsDxeStrings[]; 22 23 // 24 // BDS Platform Functions 25 // 26 27 /** 28 Perform the memory test base on the memory test intensive level, 29 and update the memory resource. 30 31 @param Level The memory test intensive level. 32 33 @retval EFI_STATUS Success test all the system memory and update 34 the memory resource 35 36 **/ 37 EFI_STATUS 38 PlatformBootManagerMemoryTest ( 39 IN EXTENDMEM_COVERAGE_LEVEL Level 40 ) 41 { 42 EFI_STATUS Status; 43 EFI_STATUS KeyStatus; 44 EFI_STATUS InitStatus; 45 EFI_STATUS ReturnStatus; 46 BOOLEAN RequireSoftECCInit; 47 EFI_GENERIC_MEMORY_TEST_PROTOCOL *GenMemoryTest; 48 UINT64 TestedMemorySize; 49 UINT64 TotalMemorySize; 50 UINTN TestPercent; 51 UINT64 PreviousValue; 52 BOOLEAN ErrorOut; 53 BOOLEAN TestAbort; 54 EFI_INPUT_KEY Key; 55 CHAR16 StrPercent[80]; 56 CHAR16 *StrTotalMemory; 57 CHAR16 *Pos; 58 CHAR16 *TmpStr; 59 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground; 60 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background; 61 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color; 62 UINT32 TempData; 63 UINTN StrTotalMemorySize; 64 65 ReturnStatus = EFI_SUCCESS; 66 ZeroMem (&Key, sizeof (EFI_INPUT_KEY)); 67 68 StrTotalMemorySize = 128; 69 Pos = AllocateZeroPool (StrTotalMemorySize); 70 ASSERT (Pos != NULL); 71 72 if (gStringPackHandle == NULL) { 73 gStringPackHandle = HiiAddPackages ( 74 &mPlatformBootManagerStringPackGuid, 75 gImageHandle, 76 PlatformBootManagerLibStrings, 77 NULL 78 ); 79 ASSERT (gStringPackHandle != NULL); 80 } 81 82 StrTotalMemory = Pos; 83 84 TestedMemorySize = 0; 85 TotalMemorySize = 0; 86 PreviousValue = 0; 87 ErrorOut = FALSE; 88 TestAbort = FALSE; 89 90 SetMem (&Foreground, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff); 91 SetMem (&Background, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0x0); 92 SetMem (&Color, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff); 93 94 RequireSoftECCInit = FALSE; 95 96 Status = gBS->LocateProtocol ( 97 &gEfiGenericMemTestProtocolGuid, 98 NULL, 99 (VOID **) &GenMemoryTest 100 ); 101 if (EFI_ERROR (Status)) { 102 FreePool (Pos); 103 return EFI_SUCCESS; 104 } 105 106 InitStatus = GenMemoryTest->MemoryTestInit ( 107 GenMemoryTest, 108 Level, 109 &RequireSoftECCInit 110 ); 111 if (InitStatus == EFI_NO_MEDIA) { 112 // 113 // The PEI codes also have the relevant memory test code to check the memory, 114 // it can select to test some range of the memory or all of them. If PEI code 115 // checks all the memory, this BDS memory test will has no not-test memory to 116 // do the test, and then the status of EFI_NO_MEDIA will be returned by 117 // "MemoryTestInit". So it does not need to test memory again, just return. 118 // 119 FreePool (Pos); 120 return EFI_SUCCESS; 121 } 122 123 if (!FeaturePcdGet(PcdBootlogoOnlyEnable)) { 124 TmpStr = HiiGetString (gStringPackHandle, STRING_TOKEN (STR_ESC_TO_SKIP_MEM_TEST), NULL); 125 126 if (TmpStr != NULL) { 127 PrintXY (10, 10, NULL, NULL, TmpStr); 128 FreePool (TmpStr); 129 } 130 } else { 131 DEBUG ((EFI_D_INFO, "Enter memory test.\n")); 132 } 133 do { 134 Status = GenMemoryTest->PerformMemoryTest ( 135 GenMemoryTest, 136 &TestedMemorySize, 137 &TotalMemorySize, 138 &ErrorOut, 139 TestAbort 140 ); 141 if (ErrorOut && (Status == EFI_DEVICE_ERROR)) { 142 TmpStr = HiiGetString (gStringPackHandle, STRING_TOKEN (STR_SYSTEM_MEM_ERROR), NULL); 143 if (TmpStr != NULL) { 144 PrintXY (10, 10, NULL, NULL, TmpStr); 145 FreePool (TmpStr); 146 } 147 148 ASSERT (0); 149 } 150 151 if (!FeaturePcdGet(PcdBootlogoOnlyEnable)) { 152 TempData = (UINT32) DivU64x32 (TotalMemorySize, 16); 153 TestPercent = (UINTN) DivU64x32 ( 154 DivU64x32 (MultU64x32 (TestedMemorySize, 100), 16), 155 TempData 156 ); 157 if (TestPercent != PreviousValue) { 158 UnicodeValueToString (StrPercent, 0, TestPercent, 0); 159 TmpStr = HiiGetString (gStringPackHandle, STRING_TOKEN (STR_MEMORY_TEST_PERCENT), NULL); 160 if (TmpStr != NULL) { 161 // 162 // TmpStr size is 64, StrPercent is reserved to 16. 163 // 164 StrnCatS ( 165 StrPercent, 166 sizeof (StrPercent) / sizeof (CHAR16), 167 TmpStr, 168 sizeof (StrPercent) / sizeof (CHAR16) - StrLen (StrPercent) - 1 169 ); 170 PrintXY (10, 10, NULL, NULL, StrPercent); 171 FreePool (TmpStr); 172 } 173 174 TmpStr = HiiGetString (gStringPackHandle, STRING_TOKEN (STR_PERFORM_MEM_TEST), NULL); 175 if (TmpStr != NULL) { 176 BootLogoUpdateProgress ( 177 Foreground, 178 Background, 179 TmpStr, 180 Color, 181 TestPercent, 182 (UINTN) PreviousValue 183 ); 184 FreePool (TmpStr); 185 } 186 } 187 188 PreviousValue = TestPercent; 189 } else { 190 DEBUG ((EFI_D_INFO, "Perform memory test (ESC to skip).\n")); 191 } 192 193 if (!PcdGetBool (PcdConInConnectOnDemand)) { 194 KeyStatus = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key); 195 if (!EFI_ERROR (KeyStatus) && (Key.ScanCode == SCAN_ESC)) { 196 if (!RequireSoftECCInit) { 197 if (!FeaturePcdGet(PcdBootlogoOnlyEnable)) { 198 TmpStr = HiiGetString (gStringPackHandle, STRING_TOKEN (STR_PERFORM_MEM_TEST), NULL); 199 if (TmpStr != NULL) { 200 BootLogoUpdateProgress ( 201 Foreground, 202 Background, 203 TmpStr, 204 Color, 205 100, 206 (UINTN) PreviousValue 207 ); 208 FreePool (TmpStr); 209 } 210 211 PrintXY (10, 10, NULL, NULL, L"100"); 212 } 213 Status = GenMemoryTest->Finished (GenMemoryTest); 214 goto Done; 215 } 216 217 TestAbort = TRUE; 218 } 219 } 220 } while (Status != EFI_NOT_FOUND); 221 222 Status = GenMemoryTest->Finished (GenMemoryTest); 223 224 Done: 225 if (!FeaturePcdGet(PcdBootlogoOnlyEnable)) { 226 UnicodeValueToString (StrTotalMemory, COMMA_TYPE, TotalMemorySize, 0); 227 if (StrTotalMemory[0] == L',') { 228 StrTotalMemory++; 229 StrTotalMemorySize -= sizeof (CHAR16); 230 } 231 232 TmpStr = HiiGetString (gStringPackHandle, STRING_TOKEN (STR_MEM_TEST_COMPLETED), NULL); 233 if (TmpStr != NULL) { 234 StrnCatS ( 235 StrTotalMemory, 236 StrTotalMemorySize / sizeof (CHAR16), 237 TmpStr, 238 StrTotalMemorySize / sizeof (CHAR16) - StrLen (StrTotalMemory) - 1 239 ); 240 FreePool (TmpStr); 241 } 242 243 PrintXY (10, 10, NULL, NULL, StrTotalMemory); 244 BootLogoUpdateProgress ( 245 Foreground, 246 Background, 247 StrTotalMemory, 248 Color, 249 100, 250 (UINTN) PreviousValue 251 ); 252 253 } else { 254 DEBUG ((EFI_D_INFO, "%d bytes of system memory tested OK\r\n", TotalMemorySize)); 255 } 256 257 FreePool (Pos); 258 return ReturnStatus; 259 } 260