2 Perform the platform memory test
4 Copyright (c) 2004 - 2009, 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,
196 Perform the memory test base on the memory test intensive level,
197 and update the memory resource.
199 @param Level The memory test intensive level.
201 @retval EFI_STATUS Success test all the system memory and update
208 IN EXTENDMEM_COVERAGE_LEVEL Level
212 EFI_STATUS KeyStatus
;
213 EFI_STATUS InitStatus
;
214 EFI_STATUS ReturnStatus
;
215 BOOLEAN RequireSoftECCInit
;
216 EFI_GENERIC_MEMORY_TEST_PROTOCOL
*GenMemoryTest
;
217 UINT64 TestedMemorySize
;
218 UINT64 TotalMemorySize
;
220 UINT64 PreviousValue
;
224 CHAR16 StrPercent
[80];
225 CHAR16
*StrTotalMemory
;
228 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground
;
229 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background
;
230 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color
;
234 ReturnStatus
= EFI_SUCCESS
;
235 ZeroMem (&Key
, sizeof (EFI_INPUT_KEY
));
237 Pos
= AllocatePool (128);
243 StrTotalMemory
= Pos
;
245 TestedMemorySize
= 0;
251 SetMem (&Foreground
, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
), 0xff);
252 SetMem (&Background
, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
), 0x0);
253 SetMem (&Color
, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
), 0xff);
255 RequireSoftECCInit
= FALSE
;
257 Status
= gBS
->LocateProtocol (
258 &gEfiGenericMemTestProtocolGuid
,
260 (VOID
**) &GenMemoryTest
262 if (EFI_ERROR (Status
)) {
267 InitStatus
= GenMemoryTest
->MemoryTestInit (
272 if (InitStatus
== EFI_NO_MEDIA
) {
274 // The PEI codes also have the relevant memory test code to check the memory,
275 // it can select to test some range of the memory or all of them. If PEI code
276 // checks all the memory, this BDS memory test will has no not-test memory to
277 // do the test, and then the status of EFI_NO_MEDIA will be returned by
278 // "MemoryTestInit". So it does not need to test memory again, just return.
284 TmpStr
= GetStringById (STRING_TOKEN (STR_ESC_TO_SKIP_MEM_TEST
));
286 if (TmpStr
!= NULL
) {
287 PrintXY (10, 10, NULL
, NULL
, TmpStr
);
292 Status
= GenMemoryTest
->PerformMemoryTest (
299 if (ErrorOut
&& (Status
== EFI_DEVICE_ERROR
)) {
300 TmpStr
= GetStringById (STRING_TOKEN (STR_SYSTEM_MEM_ERROR
));
301 if (TmpStr
!= NULL
) {
302 PrintXY (10, 10, NULL
, NULL
, TmpStr
);
309 TempData
= (UINT32
) DivU64x32 (TotalMemorySize
, 16);
310 TestPercent
= (UINTN
) DivU64x32 (
311 DivU64x32 (MultU64x32 (TestedMemorySize
, 100), 16),
314 if (TestPercent
!= PreviousValue
) {
315 UnicodeValueToString (StrPercent
, 0, TestPercent
, 0);
316 TmpStr
= GetStringById (STRING_TOKEN (STR_MEMORY_TEST_PERCENT
));
317 if (TmpStr
!= NULL
) {
319 // TmpStr size is 64, StrPercent is reserved to 16.
321 StrCat (StrPercent
, TmpStr
);
322 PrintXY (10, 10, NULL
, NULL
, StrPercent
);
326 TmpStr
= GetStringById (STRING_TOKEN (STR_PERFORM_MEM_TEST
));
327 if (TmpStr
!= NULL
) {
328 PlatformBdsShowProgress (
334 (UINTN
) PreviousValue
340 PreviousValue
= TestPercent
;
342 KeyStatus
= gST
->ConIn
->ReadKeyStroke (gST
->ConIn
, &Key
);
343 if (!EFI_ERROR (KeyStatus
) && (Key
.ScanCode
== SCAN_ESC
)) {
344 if (!RequireSoftECCInit
) {
345 TmpStr
= GetStringById (STRING_TOKEN (STR_PERFORM_MEM_TEST
));
346 if (TmpStr
!= NULL
) {
347 PlatformBdsShowProgress (
353 (UINTN
) PreviousValue
358 PrintXY (10, 10, NULL
, NULL
, L
"100");
359 Status
= GenMemoryTest
->Finished (GenMemoryTest
);
365 } while (Status
!= EFI_NOT_FOUND
);
367 Status
= GenMemoryTest
->Finished (GenMemoryTest
);
370 UnicodeValueToString (StrTotalMemory
, COMMA_TYPE
, TotalMemorySize
, 0);
371 if (StrTotalMemory
[0] == L
',') {
375 TmpStr
= GetStringById (STRING_TOKEN (STR_MEM_TEST_COMPLETED
));
376 if (TmpStr
!= NULL
) {
377 StrCat (StrTotalMemory
, TmpStr
);
381 PrintXY (10, 10, NULL
, NULL
, StrTotalMemory
);
382 PlatformBdsShowProgress (
388 (UINTN
) PreviousValue
394 // Use a DynamicHii type pcd to save the boot status, which is used to
395 // control configuration mode, such as FULL/MINIMAL/NO_CHANGES configuration.
397 IsFirstBoot
= PcdGetBool(PcdBootState
);
399 PcdSetBool(PcdBootState
, FALSE
);