]> git.proxmox.com Git - mirror_edk2.git/blame - IntelFrameworkModulePkg/Universal/BdsDxe/MemoryTest.c
Change 'WatchDog' to 'Watchdog' in FDF file.
[mirror_edk2.git] / IntelFrameworkModulePkg / Universal / BdsDxe / MemoryTest.c
CommitLineData
5c08e117 1/** @file\r
2 Perform the platform memory test\r
3\r
4Copyright (c) 2004 - 2008, Intel Corporation. <BR>\r
5All rights reserved. This program and the accompanying materials\r
6are licensed and made available under the terms and conditions of the BSD License\r
7which accompanies this distribution. The full text of the license may be found at\r
8http://opensource.org/licenses/bsd-license.php\r
9\r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15#include "Bds.h"\r
16#include "String.h"\r
17\r
18//\r
19// BDS Platform Functions\r
20//\r
21/**\r
22\r
23 Show progress bar with title above it. It only works in Graphics mode.\r
24\r
25\r
26 @param TitleForeground Foreground color for Title.\r
27 @param TitleBackground Background color for Title.\r
28 @param Title Title above progress bar.\r
29 @param ProgressColor Progress bar color.\r
30 @param Progress Progress (0-100)\r
31 @param PreviousValue The previous value of the progress.\r
32\r
33 @retval EFI_STATUS Success update the progress bar\r
34\r
35**/\r
36EFI_STATUS\r
37PlatformBdsShowProgress (\r
38 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL TitleForeground,\r
39 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL TitleBackground,\r
40 IN CHAR16 *Title,\r
41 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL ProgressColor,\r
42 IN UINTN Progress,\r
43 IN UINTN PreviousValue\r
44 )\r
45{\r
46 EFI_STATUS Status;\r
47 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
48 EFI_UGA_DRAW_PROTOCOL *UgaDraw;\r
49 UINT32 SizeOfX;\r
50 UINT32 SizeOfY;\r
51 UINT32 ColorDepth;\r
52 UINT32 RefreshRate;\r
53 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color;\r
54 UINTN BlockHeight;\r
55 UINTN BlockWidth;\r
56 UINTN BlockNum;\r
57 UINTN PosX;\r
58 UINTN PosY;\r
59 UINTN Index;\r
60\r
61 if (Progress > 100) {\r
62 return EFI_INVALID_PARAMETER;\r
63 }\r
64\r
65 UgaDraw = NULL;\r
66 Status = gBS->HandleProtocol (\r
67 gST->ConsoleOutHandle,\r
68 &gEfiGraphicsOutputProtocolGuid,\r
69 (VOID **) &GraphicsOutput\r
70 );\r
71 if (EFI_ERROR (Status) && FeaturePcdGet (PcdUgaConsumeSupport)) {\r
72 GraphicsOutput = NULL;\r
73\r
74 Status = gBS->HandleProtocol (\r
75 gST->ConsoleOutHandle,\r
76 &gEfiUgaDrawProtocolGuid,\r
77 (VOID **) &UgaDraw\r
78 );\r
79 }\r
80 if (EFI_ERROR (Status)) {\r
81 return EFI_UNSUPPORTED;\r
82 }\r
83\r
84 SizeOfX = 0;\r
85 SizeOfY = 0;\r
86 if (GraphicsOutput != NULL) {\r
87 SizeOfX = GraphicsOutput->Mode->Info->HorizontalResolution;\r
88 SizeOfY = GraphicsOutput->Mode->Info->VerticalResolution;\r
89 } else if (UgaDraw != NULL) {\r
90 Status = UgaDraw->GetMode (\r
91 UgaDraw,\r
92 &SizeOfX,\r
93 &SizeOfY,\r
94 &ColorDepth,\r
95 &RefreshRate\r
96 );\r
97 if (EFI_ERROR (Status)) {\r
98 return EFI_UNSUPPORTED;\r
99 }\r
100 } else {\r
101 return EFI_UNSUPPORTED;\r
102 }\r
103\r
104 BlockWidth = SizeOfX / 100;\r
105 BlockHeight = SizeOfY / 50;\r
106\r
107 BlockNum = Progress;\r
108\r
109 PosX = 0;\r
110 PosY = SizeOfY * 48 / 50;\r
111\r
112 if (BlockNum == 0) {\r
113 //\r
114 // Clear progress area\r
115 //\r
116 SetMem (&Color, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0x0);\r
117\r
118 if (GraphicsOutput != NULL) {\r
119 Status = GraphicsOutput->Blt (\r
120 GraphicsOutput,\r
121 &Color,\r
122 EfiBltVideoFill,\r
123 0,\r
124 0,\r
125 0,\r
126 PosY - EFI_GLYPH_HEIGHT - 1,\r
127 SizeOfX,\r
128 SizeOfY - (PosY - EFI_GLYPH_HEIGHT - 1),\r
129 SizeOfX * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
130 );\r
131 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {\r
132 Status = UgaDraw->Blt (\r
133 UgaDraw,\r
134 (EFI_UGA_PIXEL *) &Color,\r
135 EfiUgaVideoFill,\r
136 0,\r
137 0,\r
138 0,\r
139 PosY - EFI_GLYPH_HEIGHT - 1,\r
140 SizeOfX,\r
141 SizeOfY - (PosY - EFI_GLYPH_HEIGHT - 1),\r
142 SizeOfX * sizeof (EFI_UGA_PIXEL)\r
143 );\r
144 } else {\r
145 return EFI_UNSUPPORTED;\r
146 }\r
147 }\r
148 //\r
149 // Show progress by drawing blocks\r
150 //\r
151 for (Index = PreviousValue; Index < BlockNum; Index++) {\r
152 PosX = Index * BlockWidth;\r
153 if (GraphicsOutput != NULL) {\r
154 Status = GraphicsOutput->Blt (\r
155 GraphicsOutput,\r
156 &ProgressColor,\r
157 EfiBltVideoFill,\r
158 0,\r
159 0,\r
160 PosX,\r
161 PosY,\r
162 BlockWidth - 1,\r
163 BlockHeight,\r
164 (BlockWidth) * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
165 );\r
166 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {\r
167 Status = UgaDraw->Blt (\r
168 UgaDraw,\r
169 (EFI_UGA_PIXEL *) &ProgressColor,\r
170 EfiUgaVideoFill,\r
171 0,\r
172 0,\r
173 PosX,\r
174 PosY,\r
175 BlockWidth - 1,\r
176 BlockHeight,\r
177 (BlockWidth) * sizeof (EFI_UGA_PIXEL)\r
178 );\r
179 } else {\r
180 return EFI_UNSUPPORTED;\r
181 }\r
182 }\r
183\r
184 PrintXY (\r
185 (SizeOfX - StrLen (Title) * EFI_GLYPH_WIDTH) / 2,\r
186 PosY - EFI_GLYPH_HEIGHT - 1,\r
187 &TitleForeground,\r
188 &TitleBackground,\r
189 Title\r
190 );\r
191\r
192 return EFI_SUCCESS;\r
193}\r
194\r
195/**\r
196\r
197 Perform the memory test base on the memory test intensive level,\r
198 and update the memory resource.\r
199\r
200\r
201 @param Level The memory test intensive level.\r
202\r
203 @retval EFI_STATUS Success test all the system memory and update\r
204 the memory resource\r
205\r
206**/\r
207EFI_STATUS\r
208BdsMemoryTest (\r
209 IN EXTENDMEM_COVERAGE_LEVEL Level\r
210 )\r
211{\r
212 EFI_STATUS Status;\r
213 EFI_STATUS KeyStatus;\r
214 EFI_STATUS InitStatus;\r
215 EFI_STATUS ReturnStatus;\r
216 BOOLEAN RequireSoftECCInit;\r
217 EFI_GENERIC_MEMORY_TEST_PROTOCOL *GenMemoryTest;\r
218 UINT64 TestedMemorySize;\r
219 UINT64 TotalMemorySize;\r
220 UINTN TestPercent;\r
221 UINT64 PreviousValue;\r
222 BOOLEAN ErrorOut;\r
223 BOOLEAN TestAbort;\r
224 EFI_INPUT_KEY Key;\r
225 CHAR16 StrPercent[16];\r
226 CHAR16 *StrTotalMemory;\r
227 CHAR16 *Pos;\r
228 CHAR16 *TmpStr;\r
229 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground;\r
230 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background;\r
231 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color;\r
08c4ca5b 232 BOOLEAN IsFirstBoot;\r
5c08e117 233 UINT32 TempData;\r
234\r
235 ReturnStatus = EFI_SUCCESS;\r
236 ZeroMem (&Key, sizeof (EFI_INPUT_KEY));\r
237\r
238 Pos = AllocatePool (128);\r
239\r
240 if (Pos == NULL) {\r
241 return ReturnStatus;\r
242 }\r
243\r
244 StrTotalMemory = Pos;\r
245\r
246 TestedMemorySize = 0;\r
247 TotalMemorySize = 0;\r
248 PreviousValue = 0;\r
249 ErrorOut = FALSE;\r
250 TestAbort = FALSE;\r
251\r
252 SetMem (&Foreground, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff);\r
253 SetMem (&Background, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0x0);\r
254 SetMem (&Color, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff);\r
255\r
256 RequireSoftECCInit = FALSE;\r
257\r
258 gST->ConOut->ClearScreen (gST->ConOut);\r
259 gST->ConOut->SetAttribute (gST->ConOut, EFI_YELLOW | EFI_BRIGHT);\r
260 gST->ConOut->EnableCursor (gST->ConOut, FALSE);\r
261\r
262 Status = gBS->LocateProtocol (\r
263 &gEfiGenericMemTestProtocolGuid,\r
264 NULL,\r
265 (VOID **) &GenMemoryTest\r
266 );\r
267 if (EFI_ERROR (Status)) {\r
268 FreePool (Pos);\r
269 return EFI_SUCCESS;\r
270 }\r
271\r
272 InitStatus = GenMemoryTest->MemoryTestInit (\r
273 GenMemoryTest,\r
274 Level,\r
275 &RequireSoftECCInit\r
276 );\r
277 if (InitStatus == EFI_NO_MEDIA) {\r
278 //\r
279 // The PEI codes also have the relevant memory test code to check the memory,\r
280 // it can select to test some range of the memory or all of them. If PEI code\r
281 // checks all the memory, this BDS memory test will has no not-test memory to\r
282 // do the test, and then the status of EFI_NO_MEDIA will be returned by\r
283 // "MemoryTestInit". So it does not need to test memory again, just return.\r
284 //\r
285 FreePool (Pos);\r
286 return EFI_SUCCESS;\r
287 }\r
288\r
289 gST->ConOut->SetCursorPosition (gST->ConOut, 0, 2);\r
290 TmpStr = GetStringById (STRING_TOKEN (STR_ESC_TO_SKIP_MEM_TEST));\r
291\r
292 if (TmpStr != NULL) {\r
293 gST->ConOut->OutputString (gST->ConOut, TmpStr);\r
294 FreePool (TmpStr);\r
295 }\r
296\r
297 do {\r
298 Status = GenMemoryTest->PerformMemoryTest (\r
299 GenMemoryTest,\r
300 &TestedMemorySize,\r
301 &TotalMemorySize,\r
302 &ErrorOut,\r
303 TestAbort\r
304 );\r
305 if (ErrorOut && (Status == EFI_DEVICE_ERROR)) {\r
306 TmpStr = GetStringById (STRING_TOKEN (STR_SYSTEM_MEM_ERROR));\r
307 if (TmpStr != NULL) {\r
308 PrintXY (10, 10, NULL, NULL, TmpStr);\r
309 gST->ConOut->SetCursorPosition (gST->ConOut, 0, 4);\r
310 gST->ConOut->OutputString (gST->ConOut, TmpStr);\r
311 FreePool (TmpStr);\r
312 }\r
313\r
314 ASSERT (0);\r
315 }\r
316\r
317 TempData = (UINT32) DivU64x32 (TotalMemorySize, 16);\r
318 TestPercent = (UINTN) DivU64x32 (\r
319 DivU64x32 (MultU64x32 (TestedMemorySize, 100), 16),\r
320 TempData\r
321 );\r
322 if (TestPercent != PreviousValue) {\r
323 UnicodeValueToString (StrPercent, 0, TestPercent, 0);\r
324 gST->ConOut->SetCursorPosition (gST->ConOut, 0, 0);\r
325 TmpStr = GetStringById (STRING_TOKEN (STR_MEMORY_TEST_PERCENT));\r
326 if (TmpStr != NULL) {\r
327 BdsLibOutputStrings (gST->ConOut, StrPercent, TmpStr, NULL);\r
328 FreePool (TmpStr);\r
329 }\r
330\r
331 TmpStr = GetStringById (STRING_TOKEN (STR_PERFORM_MEM_TEST));\r
332 if (TmpStr != NULL) {\r
333 PlatformBdsShowProgress (\r
334 Foreground,\r
335 Background,\r
336 TmpStr,\r
337 Color,\r
338 TestPercent,\r
339 (UINTN) PreviousValue\r
340 );\r
341 FreePool (TmpStr);\r
342 }\r
343 }\r
344\r
345 PreviousValue = TestPercent;\r
346\r
347 KeyStatus = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);\r
348 if (!EFI_ERROR (KeyStatus) && (Key.ScanCode == SCAN_ESC)) {\r
349 if (!RequireSoftECCInit) {\r
350 TmpStr = GetStringById (STRING_TOKEN (STR_PERFORM_MEM_TEST));\r
351 if (TmpStr != NULL) {\r
352 PlatformBdsShowProgress (\r
353 Foreground,\r
354 Background,\r
355 TmpStr,\r
356 Color,\r
357 100,\r
358 (UINTN) PreviousValue\r
359 );\r
360 FreePool (TmpStr);\r
361 }\r
362\r
363 gST->ConOut->SetCursorPosition (gST->ConOut, 0, 0);\r
364 gST->ConOut->OutputString (gST->ConOut, L"100");\r
365 Status = GenMemoryTest->Finished (GenMemoryTest);\r
366 goto Done;\r
367 }\r
368\r
369 TestAbort = TRUE;\r
370 }\r
371 } while (Status != EFI_NOT_FOUND);\r
372\r
373 Status = GenMemoryTest->Finished (GenMemoryTest);\r
374\r
375Done:\r
376 UnicodeValueToString (StrTotalMemory, COMMA_TYPE, TotalMemorySize, 0);\r
377 if (StrTotalMemory[0] == L',') {\r
378 StrTotalMemory++;\r
379 }\r
380\r
381 TmpStr = GetStringById (STRING_TOKEN (STR_MEM_TEST_COMPLETED));\r
382 if (TmpStr != NULL) {\r
383 StrCat (StrTotalMemory, TmpStr);\r
384 FreePool (TmpStr);\r
385 }\r
386\r
387 gST->ConOut->ClearScreen (gST->ConOut);\r
388 gST->ConOut->SetAttribute (gST->ConOut, EFI_YELLOW | EFI_BRIGHT);\r
389 gST->ConOut->EnableCursor (gST->ConOut, FALSE);\r
390 gST->ConOut->OutputString (gST->ConOut, StrTotalMemory);\r
391 PlatformBdsShowProgress (\r
392 Foreground,\r
393 Background,\r
394 StrTotalMemory,\r
395 Color,\r
396 100,\r
397 (UINTN) PreviousValue\r
398 );\r
399\r
400 FreePool (Pos);\r
401\r
08c4ca5b 402 //\r
403 // Use a DynamicHii type pcd to save the boot status, which is used to\r
404 // control configuration mode, such as FULL/MINIMAL/NO_CHANGES configuration.\r
405 //\r
406 IsFirstBoot = PcdGetBool(PcdBootState);\r
407 if (IsFirstBoot) {\r
408 PcdSetBool(PcdBootState, FALSE);\r
5c08e117 409 }\r
410\r
411 return ReturnStatus;\r
412}\r