]> git.proxmox.com Git - mirror_edk2.git/blame - IntelFrameworkModulePkg/Universal/BdsDxe/MemoryTest.c
1. Update Fat binaries for IA32, x64, IPF and EBC to base on MdePkg 1.01 release...
[mirror_edk2.git] / IntelFrameworkModulePkg / Universal / BdsDxe / MemoryTest.c
CommitLineData
5c08e117 1/** @file\r
2 Perform the platform memory test\r
3\r
5d7c1609 4Copyright (c) 2004 - 2009, Intel Corporation. <BR>\r
5c08e117 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
5c08e117 196 Perform the memory test base on the memory test intensive level,\r
197 and update the memory resource.\r
198\r
a798a789 199 @param Level The memory test intensive level.\r
5c08e117 200\r
a798a789 201 @retval EFI_STATUS Success test all the system memory and update\r
202 the memory resource\r
5c08e117 203\r
204**/\r
205EFI_STATUS\r
206BdsMemoryTest (\r
207 IN EXTENDMEM_COVERAGE_LEVEL Level\r
208 )\r
209{\r
210 EFI_STATUS Status;\r
211 EFI_STATUS KeyStatus;\r
212 EFI_STATUS InitStatus;\r
213 EFI_STATUS ReturnStatus;\r
214 BOOLEAN RequireSoftECCInit;\r
215 EFI_GENERIC_MEMORY_TEST_PROTOCOL *GenMemoryTest;\r
216 UINT64 TestedMemorySize;\r
217 UINT64 TotalMemorySize;\r
218 UINTN TestPercent;\r
219 UINT64 PreviousValue;\r
220 BOOLEAN ErrorOut;\r
221 BOOLEAN TestAbort;\r
222 EFI_INPUT_KEY Key;\r
5d7c1609 223 CHAR16 StrPercent[80];\r
5c08e117 224 CHAR16 *StrTotalMemory;\r
225 CHAR16 *Pos;\r
226 CHAR16 *TmpStr;\r
227 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground;\r
228 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background;\r
229 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color;\r
08c4ca5b 230 BOOLEAN IsFirstBoot;\r
5c08e117 231 UINT32 TempData;\r
232\r
233 ReturnStatus = EFI_SUCCESS;\r
234 ZeroMem (&Key, sizeof (EFI_INPUT_KEY));\r
235\r
236 Pos = AllocatePool (128);\r
237\r
238 if (Pos == NULL) {\r
239 return ReturnStatus;\r
240 }\r
241\r
242 StrTotalMemory = Pos;\r
243\r
244 TestedMemorySize = 0;\r
245 TotalMemorySize = 0;\r
246 PreviousValue = 0;\r
247 ErrorOut = FALSE;\r
248 TestAbort = FALSE;\r
249\r
250 SetMem (&Foreground, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff);\r
251 SetMem (&Background, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0x0);\r
252 SetMem (&Color, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff);\r
253\r
254 RequireSoftECCInit = FALSE;\r
255\r
5c08e117 256 Status = gBS->LocateProtocol (\r
257 &gEfiGenericMemTestProtocolGuid,\r
258 NULL,\r
259 (VOID **) &GenMemoryTest\r
260 );\r
261 if (EFI_ERROR (Status)) {\r
262 FreePool (Pos);\r
263 return EFI_SUCCESS;\r
264 }\r
265\r
266 InitStatus = GenMemoryTest->MemoryTestInit (\r
267 GenMemoryTest,\r
268 Level,\r
269 &RequireSoftECCInit\r
270 );\r
271 if (InitStatus == EFI_NO_MEDIA) {\r
272 //\r
273 // The PEI codes also have the relevant memory test code to check the memory,\r
274 // it can select to test some range of the memory or all of them. If PEI code\r
275 // checks all the memory, this BDS memory test will has no not-test memory to\r
276 // do the test, and then the status of EFI_NO_MEDIA will be returned by\r
277 // "MemoryTestInit". So it does not need to test memory again, just return.\r
278 //\r
279 FreePool (Pos);\r
280 return EFI_SUCCESS;\r
281 }\r
282\r
5c08e117 283 TmpStr = GetStringById (STRING_TOKEN (STR_ESC_TO_SKIP_MEM_TEST));\r
284\r
285 if (TmpStr != NULL) {\r
5d7c1609 286 PrintXY (10, 10, NULL, NULL, TmpStr);\r
5c08e117 287 FreePool (TmpStr);\r
288 }\r
289\r
290 do {\r
291 Status = GenMemoryTest->PerformMemoryTest (\r
292 GenMemoryTest,\r
293 &TestedMemorySize,\r
294 &TotalMemorySize,\r
295 &ErrorOut,\r
296 TestAbort\r
297 );\r
298 if (ErrorOut && (Status == EFI_DEVICE_ERROR)) {\r
299 TmpStr = GetStringById (STRING_TOKEN (STR_SYSTEM_MEM_ERROR));\r
300 if (TmpStr != NULL) {\r
301 PrintXY (10, 10, NULL, NULL, TmpStr);\r
5c08e117 302 FreePool (TmpStr);\r
303 }\r
304\r
305 ASSERT (0);\r
306 }\r
307\r
308 TempData = (UINT32) DivU64x32 (TotalMemorySize, 16);\r
309 TestPercent = (UINTN) DivU64x32 (\r
310 DivU64x32 (MultU64x32 (TestedMemorySize, 100), 16),\r
311 TempData\r
312 );\r
313 if (TestPercent != PreviousValue) {\r
314 UnicodeValueToString (StrPercent, 0, TestPercent, 0);\r
5c08e117 315 TmpStr = GetStringById (STRING_TOKEN (STR_MEMORY_TEST_PERCENT));\r
316 if (TmpStr != NULL) {\r
5d7c1609 317 //\r
318 // TmpStr size is 64, StrPercent is reserved to 16.\r
319 //\r
320 StrCat (StrPercent, TmpStr);\r
321 PrintXY (10, 10, NULL, NULL, StrPercent);\r
5c08e117 322 FreePool (TmpStr);\r
323 }\r
324\r
325 TmpStr = GetStringById (STRING_TOKEN (STR_PERFORM_MEM_TEST));\r
326 if (TmpStr != NULL) {\r
327 PlatformBdsShowProgress (\r
328 Foreground,\r
329 Background,\r
330 TmpStr,\r
331 Color,\r
332 TestPercent,\r
333 (UINTN) PreviousValue\r
334 );\r
335 FreePool (TmpStr);\r
336 }\r
337 }\r
338\r
339 PreviousValue = TestPercent;\r
340\r
341 KeyStatus = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);\r
342 if (!EFI_ERROR (KeyStatus) && (Key.ScanCode == SCAN_ESC)) {\r
343 if (!RequireSoftECCInit) {\r
344 TmpStr = GetStringById (STRING_TOKEN (STR_PERFORM_MEM_TEST));\r
345 if (TmpStr != NULL) {\r
346 PlatformBdsShowProgress (\r
347 Foreground,\r
348 Background,\r
349 TmpStr,\r
350 Color,\r
351 100,\r
352 (UINTN) PreviousValue\r
353 );\r
354 FreePool (TmpStr);\r
355 }\r
356\r
5d7c1609 357 PrintXY (10, 10, NULL, NULL, L"100");\r
5c08e117 358 Status = GenMemoryTest->Finished (GenMemoryTest);\r
359 goto Done;\r
360 }\r
361\r
362 TestAbort = TRUE;\r
363 }\r
364 } while (Status != EFI_NOT_FOUND);\r
365\r
366 Status = GenMemoryTest->Finished (GenMemoryTest);\r
367\r
368Done:\r
369 UnicodeValueToString (StrTotalMemory, COMMA_TYPE, TotalMemorySize, 0);\r
370 if (StrTotalMemory[0] == L',') {\r
371 StrTotalMemory++;\r
372 }\r
373\r
374 TmpStr = GetStringById (STRING_TOKEN (STR_MEM_TEST_COMPLETED));\r
375 if (TmpStr != NULL) {\r
376 StrCat (StrTotalMemory, TmpStr);\r
377 FreePool (TmpStr);\r
378 }\r
379\r
5d7c1609 380 PrintXY (10, 10, NULL, NULL, StrTotalMemory);\r
5c08e117 381 PlatformBdsShowProgress (\r
382 Foreground,\r
383 Background,\r
384 StrTotalMemory,\r
385 Color,\r
386 100,\r
387 (UINTN) PreviousValue\r
388 );\r
389\r
390 FreePool (Pos);\r
391\r
08c4ca5b 392 //\r
393 // Use a DynamicHii type pcd to save the boot status, which is used to\r
394 // control configuration mode, such as FULL/MINIMAL/NO_CHANGES configuration.\r
395 //\r
396 IsFirstBoot = PcdGetBool(PcdBootState);\r
397 if (IsFirstBoot) {\r
398 PcdSetBool(PcdBootState, FALSE);\r
5c08e117 399 }\r
400\r
401 return ReturnStatus;\r
402}\r