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