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