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