2 Perform the platform memory test
4 Copyright (c) 2004 - 2008, Intel Corporation. <BR>
5 All rights reserved. This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
19 // BDS Platform Functions
23 Show progress bar with title above it. It only works in Graphics mode.
26 @param TitleForeground Foreground color for Title.
27 @param TitleBackground Background color for Title.
28 @param Title Title above progress bar.
29 @param ProgressColor Progress bar color.
30 @param Progress Progress (0-100)
31 @param PreviousValue The previous value of the progress.
33 @retval EFI_STATUS Success update the progress bar
37 PlatformBdsShowProgress (
38 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL TitleForeground
,
39 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL TitleBackground
,
41 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL ProgressColor
,
43 IN UINTN PreviousValue
47 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
48 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
53 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color
;
62 return EFI_INVALID_PARAMETER
;
66 Status
= gBS
->HandleProtocol (
67 gST
->ConsoleOutHandle
,
68 &gEfiGraphicsOutputProtocolGuid
,
69 (VOID
**) &GraphicsOutput
71 if (EFI_ERROR (Status
) && FeaturePcdGet (PcdUgaConsumeSupport
)) {
72 GraphicsOutput
= NULL
;
74 Status
= gBS
->HandleProtocol (
75 gST
->ConsoleOutHandle
,
76 &gEfiUgaDrawProtocolGuid
,
80 if (EFI_ERROR (Status
)) {
81 return EFI_UNSUPPORTED
;
86 if (GraphicsOutput
!= NULL
) {
87 SizeOfX
= GraphicsOutput
->Mode
->Info
->HorizontalResolution
;
88 SizeOfY
= GraphicsOutput
->Mode
->Info
->VerticalResolution
;
89 } else if (UgaDraw
!= NULL
) {
90 Status
= UgaDraw
->GetMode (
97 if (EFI_ERROR (Status
)) {
98 return EFI_UNSUPPORTED
;
101 return EFI_UNSUPPORTED
;
104 BlockWidth
= SizeOfX
/ 100;
105 BlockHeight
= SizeOfY
/ 50;
110 PosY
= SizeOfY
* 48 / 50;
114 // Clear progress area
116 SetMem (&Color
, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
), 0x0);
118 if (GraphicsOutput
!= NULL
) {
119 Status
= GraphicsOutput
->Blt (
126 PosY
- EFI_GLYPH_HEIGHT
- 1,
128 SizeOfY
- (PosY
- EFI_GLYPH_HEIGHT
- 1),
129 SizeOfX
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
131 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
132 Status
= UgaDraw
->Blt (
134 (EFI_UGA_PIXEL
*) &Color
,
139 PosY
- EFI_GLYPH_HEIGHT
- 1,
141 SizeOfY
- (PosY
- EFI_GLYPH_HEIGHT
- 1),
142 SizeOfX
* sizeof (EFI_UGA_PIXEL
)
145 return EFI_UNSUPPORTED
;
149 // Show progress by drawing blocks
151 for (Index
= PreviousValue
; Index
< BlockNum
; Index
++) {
152 PosX
= Index
* BlockWidth
;
153 if (GraphicsOutput
!= NULL
) {
154 Status
= GraphicsOutput
->Blt (
164 (BlockWidth
) * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
166 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
167 Status
= UgaDraw
->Blt (
169 (EFI_UGA_PIXEL
*) &ProgressColor
,
177 (BlockWidth
) * sizeof (EFI_UGA_PIXEL
)
180 return EFI_UNSUPPORTED
;
185 (SizeOfX
- StrLen (Title
) * EFI_GLYPH_WIDTH
) / 2,
186 PosY
- EFI_GLYPH_HEIGHT
- 1,
197 Perform the memory test base on the memory test intensive level,
198 and update the memory resource.
201 @param Level The memory test intensive level.
203 @retval EFI_STATUS Success test all the system memory and update
209 IN EXTENDMEM_COVERAGE_LEVEL Level
213 EFI_STATUS KeyStatus
;
214 EFI_STATUS InitStatus
;
215 EFI_STATUS ReturnStatus
;
216 BOOLEAN RequireSoftECCInit
;
217 EFI_GENERIC_MEMORY_TEST_PROTOCOL
*GenMemoryTest
;
218 UINT64 TestedMemorySize
;
219 UINT64 TotalMemorySize
;
221 UINT64 PreviousValue
;
225 CHAR16 StrPercent
[16];
226 CHAR16
*StrTotalMemory
;
229 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground
;
230 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background
;
231 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color
;
235 ReturnStatus
= EFI_SUCCESS
;
236 ZeroMem (&Key
, sizeof (EFI_INPUT_KEY
));
238 Pos
= AllocatePool (128);
244 StrTotalMemory
= Pos
;
246 TestedMemorySize
= 0;
252 SetMem (&Foreground
, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
), 0xff);
253 SetMem (&Background
, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
), 0x0);
254 SetMem (&Color
, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
), 0xff);
256 RequireSoftECCInit
= FALSE
;
258 gST
->ConOut
->ClearScreen (gST
->ConOut
);
259 gST
->ConOut
->SetAttribute (gST
->ConOut
, EFI_YELLOW
| EFI_BRIGHT
);
260 gST
->ConOut
->EnableCursor (gST
->ConOut
, FALSE
);
262 Status
= gBS
->LocateProtocol (
263 &gEfiGenericMemTestProtocolGuid
,
265 (VOID
**) &GenMemoryTest
267 if (EFI_ERROR (Status
)) {
272 InitStatus
= GenMemoryTest
->MemoryTestInit (
277 if (InitStatus
== EFI_NO_MEDIA
) {
279 // The PEI codes also have the relevant memory test code to check the memory,
280 // it can select to test some range of the memory or all of them. If PEI code
281 // checks all the memory, this BDS memory test will has no not-test memory to
282 // do the test, and then the status of EFI_NO_MEDIA will be returned by
283 // "MemoryTestInit". So it does not need to test memory again, just return.
289 gST
->ConOut
->SetCursorPosition (gST
->ConOut
, 0, 2);
290 TmpStr
= GetStringById (STRING_TOKEN (STR_ESC_TO_SKIP_MEM_TEST
));
292 if (TmpStr
!= NULL
) {
293 gST
->ConOut
->OutputString (gST
->ConOut
, TmpStr
);
298 Status
= GenMemoryTest
->PerformMemoryTest (
305 if (ErrorOut
&& (Status
== EFI_DEVICE_ERROR
)) {
306 TmpStr
= GetStringById (STRING_TOKEN (STR_SYSTEM_MEM_ERROR
));
307 if (TmpStr
!= NULL
) {
308 PrintXY (10, 10, NULL
, NULL
, TmpStr
);
309 gST
->ConOut
->SetCursorPosition (gST
->ConOut
, 0, 4);
310 gST
->ConOut
->OutputString (gST
->ConOut
, TmpStr
);
317 TempData
= (UINT32
) DivU64x32 (TotalMemorySize
, 16);
318 TestPercent
= (UINTN
) DivU64x32 (
319 DivU64x32 (MultU64x32 (TestedMemorySize
, 100), 16),
322 if (TestPercent
!= PreviousValue
) {
323 UnicodeValueToString (StrPercent
, 0, TestPercent
, 0);
324 gST
->ConOut
->SetCursorPosition (gST
->ConOut
, 0, 0);
325 TmpStr
= GetStringById (STRING_TOKEN (STR_MEMORY_TEST_PERCENT
));
326 if (TmpStr
!= NULL
) {
327 BdsLibOutputStrings (gST
->ConOut
, StrPercent
, TmpStr
, NULL
);
331 TmpStr
= GetStringById (STRING_TOKEN (STR_PERFORM_MEM_TEST
));
332 if (TmpStr
!= NULL
) {
333 PlatformBdsShowProgress (
339 (UINTN
) PreviousValue
345 PreviousValue
= TestPercent
;
347 KeyStatus
= gST
->ConIn
->ReadKeyStroke (gST
->ConIn
, &Key
);
348 if (!EFI_ERROR (KeyStatus
) && (Key
.ScanCode
== SCAN_ESC
)) {
349 if (!RequireSoftECCInit
) {
350 TmpStr
= GetStringById (STRING_TOKEN (STR_PERFORM_MEM_TEST
));
351 if (TmpStr
!= NULL
) {
352 PlatformBdsShowProgress (
358 (UINTN
) PreviousValue
363 gST
->ConOut
->SetCursorPosition (gST
->ConOut
, 0, 0);
364 gST
->ConOut
->OutputString (gST
->ConOut
, L
"100");
365 Status
= GenMemoryTest
->Finished (GenMemoryTest
);
371 } while (Status
!= EFI_NOT_FOUND
);
373 Status
= GenMemoryTest
->Finished (GenMemoryTest
);
376 UnicodeValueToString (StrTotalMemory
, COMMA_TYPE
, TotalMemorySize
, 0);
377 if (StrTotalMemory
[0] == L
',') {
381 TmpStr
= GetStringById (STRING_TOKEN (STR_MEM_TEST_COMPLETED
));
382 if (TmpStr
!= NULL
) {
383 StrCat (StrTotalMemory
, TmpStr
);
387 gST
->ConOut
->ClearScreen (gST
->ConOut
);
388 gST
->ConOut
->SetAttribute (gST
->ConOut
, EFI_YELLOW
| EFI_BRIGHT
);
389 gST
->ConOut
->EnableCursor (gST
->ConOut
, FALSE
);
390 gST
->ConOut
->OutputString (gST
->ConOut
, StrTotalMemory
);
391 PlatformBdsShowProgress (
397 (UINTN
) PreviousValue
403 // Use a DynamicHii type pcd to save the boot status, which is used to
404 // control configuration mode, such as FULL/MINIMAL/NO_CHANGES configuration.
406 IsFirstBoot
= PcdGetBool(PcdBootState
);
408 PcdSetBool(PcdBootState
, FALSE
);