2 Perform the platform memory test
4 Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
13 // BDS Platform Functions
17 Show progress bar with title above it. It only works in Graphics mode.
20 @param TitleForeground Foreground color for Title.
21 @param TitleBackground Background color for Title.
22 @param Title Title above progress bar.
23 @param ProgressColor Progress bar color.
24 @param Progress Progress (0-100)
25 @param PreviousValue The previous value of the progress.
27 @retval EFI_STATUS Success update the progress bar
31 PlatformBdsShowProgress (
32 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL TitleForeground
,
33 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL TitleBackground
,
35 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL ProgressColor
,
37 IN UINTN PreviousValue
41 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
42 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
47 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color
;
56 return EFI_INVALID_PARAMETER
;
60 Status
= gBS
->HandleProtocol (
61 gST
->ConsoleOutHandle
,
62 &gEfiGraphicsOutputProtocolGuid
,
63 (VOID
**) &GraphicsOutput
65 if (EFI_ERROR (Status
) && FeaturePcdGet (PcdUgaConsumeSupport
)) {
66 GraphicsOutput
= NULL
;
68 Status
= gBS
->HandleProtocol (
69 gST
->ConsoleOutHandle
,
70 &gEfiUgaDrawProtocolGuid
,
74 if (EFI_ERROR (Status
)) {
75 return EFI_UNSUPPORTED
;
80 if (GraphicsOutput
!= NULL
) {
81 SizeOfX
= GraphicsOutput
->Mode
->Info
->HorizontalResolution
;
82 SizeOfY
= GraphicsOutput
->Mode
->Info
->VerticalResolution
;
83 } else if (UgaDraw
!= NULL
) {
84 Status
= UgaDraw
->GetMode (
91 if (EFI_ERROR (Status
)) {
92 return EFI_UNSUPPORTED
;
95 return EFI_UNSUPPORTED
;
98 BlockWidth
= SizeOfX
/ 100;
99 BlockHeight
= SizeOfY
/ 50;
104 PosY
= SizeOfY
* 48 / 50;
108 // Clear progress area
110 SetMem (&Color
, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
), 0x0);
112 if (GraphicsOutput
!= NULL
) {
113 Status
= GraphicsOutput
->Blt (
120 PosY
- EFI_GLYPH_HEIGHT
- 1,
122 SizeOfY
- (PosY
- EFI_GLYPH_HEIGHT
- 1),
123 SizeOfX
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
125 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
126 Status
= UgaDraw
->Blt (
128 (EFI_UGA_PIXEL
*) &Color
,
133 PosY
- EFI_GLYPH_HEIGHT
- 1,
135 SizeOfY
- (PosY
- EFI_GLYPH_HEIGHT
- 1),
136 SizeOfX
* sizeof (EFI_UGA_PIXEL
)
139 return EFI_UNSUPPORTED
;
143 // Show progress by drawing blocks
145 for (Index
= PreviousValue
; Index
< BlockNum
; Index
++) {
146 PosX
= Index
* BlockWidth
;
147 if (GraphicsOutput
!= NULL
) {
148 Status
= GraphicsOutput
->Blt (
158 (BlockWidth
) * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
160 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
161 Status
= UgaDraw
->Blt (
163 (EFI_UGA_PIXEL
*) &ProgressColor
,
171 (BlockWidth
) * sizeof (EFI_UGA_PIXEL
)
174 return EFI_UNSUPPORTED
;
179 (SizeOfX
- StrLen (Title
) * EFI_GLYPH_WIDTH
) / 2,
180 PosY
- EFI_GLYPH_HEIGHT
- 1,
190 Perform the memory test base on the memory test intensive level,
191 and update the memory resource.
193 @param Level The memory test intensive level.
195 @retval EFI_STATUS Success test all the system memory and update
202 IN EXTENDMEM_COVERAGE_LEVEL Level
206 EFI_STATUS KeyStatus
;
207 EFI_STATUS InitStatus
;
208 EFI_STATUS ReturnStatus
;
209 BOOLEAN RequireSoftECCInit
;
210 EFI_GENERIC_MEMORY_TEST_PROTOCOL
*GenMemoryTest
;
211 UINT64 TestedMemorySize
;
212 UINT64 TotalMemorySize
;
214 UINT64 PreviousValue
;
218 CHAR16 StrPercent
[80];
219 CHAR16
*StrTotalMemory
;
222 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground
;
223 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background
;
224 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color
;
227 UINTN StrTotalMemorySize
;
229 ReturnStatus
= EFI_SUCCESS
;
230 ZeroMem (&Key
, sizeof (EFI_INPUT_KEY
));
232 StrTotalMemorySize
= 128;
233 Pos
= AllocateZeroPool (StrTotalMemorySize
);
239 StrTotalMemory
= Pos
;
241 TestedMemorySize
= 0;
247 SetMem (&Foreground
, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
), 0xff);
248 SetMem (&Background
, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
), 0x0);
249 SetMem (&Color
, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
), 0xff);
251 RequireSoftECCInit
= FALSE
;
253 Status
= gBS
->LocateProtocol (
254 &gEfiGenericMemTestProtocolGuid
,
256 (VOID
**) &GenMemoryTest
258 if (EFI_ERROR (Status
)) {
263 InitStatus
= GenMemoryTest
->MemoryTestInit (
268 if (InitStatus
== EFI_NO_MEDIA
) {
270 // The PEI codes also have the relevant memory test code to check the memory,
271 // it can select to test some range of the memory or all of them. If PEI code
272 // checks all the memory, this BDS memory test will has no not-test memory to
273 // do the test, and then the status of EFI_NO_MEDIA will be returned by
274 // "MemoryTestInit". So it does not need to test memory again, just return.
280 if (!FeaturePcdGet(PcdBootlogoOnlyEnable
)) {
281 TmpStr
= GetStringById (STRING_TOKEN (STR_ESC_TO_SKIP_MEM_TEST
));
283 if (TmpStr
!= NULL
) {
284 PrintXY (10, 10, NULL
, NULL
, TmpStr
);
288 DEBUG ((EFI_D_INFO
, "Enter memory test.\n"));
291 Status
= GenMemoryTest
->PerformMemoryTest (
298 if (ErrorOut
&& (Status
== EFI_DEVICE_ERROR
)) {
299 TmpStr
= GetStringById (STRING_TOKEN (STR_SYSTEM_MEM_ERROR
));
300 if (TmpStr
!= NULL
) {
301 PrintXY (10, 10, NULL
, NULL
, TmpStr
);
308 if (!FeaturePcdGet(PcdBootlogoOnlyEnable
)) {
309 TempData
= (UINT32
) DivU64x32 (TotalMemorySize
, 16);
310 TestPercent
= (UINTN
) DivU64x32 (
311 DivU64x32 (MultU64x32 (TestedMemorySize
, 100), 16),
314 if (TestPercent
!= PreviousValue
) {
315 UnicodeValueToStringS (StrPercent
, sizeof (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.
323 sizeof (StrPercent
) / sizeof (CHAR16
),
325 sizeof (StrPercent
) / sizeof (CHAR16
) - StrLen (StrPercent
) - 1
327 PrintXY (10, 10, NULL
, NULL
, StrPercent
);
331 TmpStr
= GetStringById (STRING_TOKEN (STR_PERFORM_MEM_TEST
));
332 if (TmpStr
!= NULL
) {
333 PlatformBdsShowProgress (
339 (UINTN
) PreviousValue
345 PreviousValue
= TestPercent
;
347 DEBUG ((EFI_D_INFO
, "Perform memory test (ESC to skip).\n"));
350 if (!PcdGetBool (PcdConInConnectOnDemand
)) {
351 KeyStatus
= gST
->ConIn
->ReadKeyStroke (gST
->ConIn
, &Key
);
352 if (!EFI_ERROR (KeyStatus
) && (Key
.ScanCode
== SCAN_ESC
)) {
353 if (!RequireSoftECCInit
) {
354 if (!FeaturePcdGet(PcdBootlogoOnlyEnable
)) {
355 TmpStr
= GetStringById (STRING_TOKEN (STR_PERFORM_MEM_TEST
));
356 if (TmpStr
!= NULL
) {
357 PlatformBdsShowProgress (
363 (UINTN
) PreviousValue
368 PrintXY (10, 10, NULL
, NULL
, L
"100");
370 Status
= GenMemoryTest
->Finished (GenMemoryTest
);
377 } while (Status
!= EFI_NOT_FOUND
);
379 Status
= GenMemoryTest
->Finished (GenMemoryTest
);
382 if (!FeaturePcdGet(PcdBootlogoOnlyEnable
)) {
383 UnicodeValueToStringS (StrTotalMemory
, StrTotalMemorySize
, COMMA_TYPE
, TotalMemorySize
, 0);
384 if (StrTotalMemory
[0] == L
',') {
386 StrTotalMemorySize
-= sizeof (CHAR16
);
389 TmpStr
= GetStringById (STRING_TOKEN (STR_MEM_TEST_COMPLETED
));
390 if (TmpStr
!= NULL
) {
393 StrTotalMemorySize
/ sizeof (CHAR16
),
395 StrTotalMemorySize
/ sizeof (CHAR16
) - StrLen (StrTotalMemory
) - 1
400 PrintXY (10, 10, NULL
, NULL
, StrTotalMemory
);
401 PlatformBdsShowProgress (
407 (UINTN
) PreviousValue
411 DEBUG ((EFI_D_INFO
, "%d bytes of system memory tested OK\r\n", TotalMemorySize
));
418 // Use a DynamicHii type pcd to save the boot status, which is used to
419 // control configuration mode, such as FULL/MINIMAL/NO_CHANGES configuration.
421 IsFirstBoot
= PcdGetBool(PcdBootState
);
423 Status
= PcdSetBoolS(PcdBootState
, FALSE
);
424 if (EFI_ERROR (Status
)) {
425 DEBUG ((EFI_D_ERROR
, "Set PcdBootState to FALSE failed.\n"));