3 Copyright (c) 2006 - 2007, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 Perform the platform memory test
23 // Include common header file for this module.
25 #include "CommonHeader.h"
28 #include "BdsPlatform.h"
32 // BDS Platform Functions
35 PlatformBdsShowProgress (
36 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL TitleForeground
,
37 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL TitleBackground
,
39 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL ProgressColor
,
41 IN UINTN PreviousValue
47 Show progress bar with title above it. It only works in UGA mode.
51 TitleForeground - Foreground color for Title.
52 TitleBackground - Background color for Title.
53 Title - Title above progress bar.
54 ProgressColor - Progress bar color.
55 Progress - Progress (0-100)
59 EFI_STATUS - Success update the progress bar
64 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
65 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
70 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color
;
79 return EFI_INVALID_PARAMETER
;
83 Status
= gBS
->HandleProtocol (
84 gST
->ConsoleOutHandle
,
85 &gEfiGraphicsOutputProtocolGuid
,
88 if (EFI_ERROR (Status
)) {
89 GraphicsOutput
= NULL
;
91 Status
= gBS
->HandleProtocol (
92 gST
->ConsoleOutHandle
,
93 &gEfiUgaDrawProtocolGuid
,
96 if (EFI_ERROR (Status
)) {
97 return EFI_UNSUPPORTED
;
101 if (GraphicsOutput
!= NULL
) {
102 SizeOfX
= GraphicsOutput
->Mode
->Info
->HorizontalResolution
;
103 SizeOfY
= GraphicsOutput
->Mode
->Info
->VerticalResolution
;
105 Status
= UgaDraw
->GetMode (
112 if (EFI_ERROR (Status
)) {
113 return EFI_UNSUPPORTED
;
117 BlockWidth
= SizeOfX
/ 100;
118 BlockHeight
= SizeOfY
/ 50;
123 PosY
= SizeOfY
* 48 / 50;
127 // Clear progress area
129 SetMem (&Color
, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
), 0x0);
131 if (GraphicsOutput
!= NULL
) {
132 Status
= GraphicsOutput
->Blt (
139 PosY
- GLYPH_HEIGHT
- 1,
141 SizeOfY
- (PosY
- GLYPH_HEIGHT
- 1),
142 SizeOfX
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
145 Status
= UgaDraw
->Blt (
147 (EFI_UGA_PIXEL
*) &Color
,
152 PosY
- GLYPH_HEIGHT
- 1,
154 SizeOfY
- (PosY
- GLYPH_HEIGHT
- 1),
155 SizeOfX
* sizeof (EFI_UGA_PIXEL
)
160 // Show progress by drawing blocks
162 for (Index
= PreviousValue
; Index
< BlockNum
; Index
++) {
163 PosX
= Index
* BlockWidth
;
164 if (GraphicsOutput
!= NULL
) {
165 Status
= GraphicsOutput
->Blt (
175 (BlockWidth
) * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
178 Status
= UgaDraw
->Blt (
180 (EFI_UGA_PIXEL
*) &ProgressColor
,
188 (BlockWidth
) * sizeof (EFI_UGA_PIXEL
)
194 (SizeOfX
- StrLen (Title
) * GLYPH_WIDTH
) / 2,
195 PosY
- GLYPH_HEIGHT
- 1,
206 IN EXTENDMEM_COVERAGE_LEVEL Level
212 Perform the memory test base on the memory test intensive level,
213 and update the memory resource.
217 Level - The memory test intensive level.
221 EFI_STATUS - Success test all the system memory and update
227 EFI_STATUS InitStatus
;
228 EFI_STATUS KeyStatus
;
229 EFI_STATUS ReturnStatus
;
230 BOOLEAN RequireSoftECCInit
;
231 EFI_GENERIC_MEMORY_TEST_PROTOCOL
*GenMemoryTest
;
232 UINT64 TestedMemorySize
;
233 UINT64 TotalMemorySize
;
235 UINT64 PreviousValue
;
239 CHAR16 StrPercent
[16];
240 CHAR16
*StrTotalMemory
;
243 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground
;
244 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background
;
245 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color
;
249 ReturnStatus
= EFI_SUCCESS
;
250 ZeroMem (&Key
, sizeof (EFI_INPUT_KEY
));
252 Pos
= AllocatePool (128);
258 StrTotalMemory
= Pos
;
260 TestedMemorySize
= 0;
266 SetMem (&Foreground
, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
), 0xff);
267 SetMem (&Background
, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
), 0x0);
268 SetMem (&Color
, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
), 0xff);
270 RequireSoftECCInit
= FALSE
;
272 gST
->ConOut
->ClearScreen (gST
->ConOut
);
273 gST
->ConOut
->SetAttribute (gST
->ConOut
, EFI_YELLOW
| EFI_BRIGHT
);
274 gST
->ConOut
->EnableCursor (gST
->ConOut
, FALSE
);
276 Status
= gBS
->LocateProtocol (
277 &gEfiGenericMemTestProtocolGuid
,
281 if (EFI_ERROR (Status
)) {
286 InitStatus
= GenMemoryTest
->MemoryTestInit (
291 if (InitStatus
== EFI_NO_MEDIA
) {
293 // The PEI codes also have the relevant memory test code to check the memory,
294 // it can select to test some range of the memory or all of them. If PEI code
295 // checks all the memory, this BDS memory test will has no not-test memory to
296 // do the test, and then the status of EFI_NO_MEDIA will be returned by
297 // "MemoryTestInit". So it does not need to test memory again, just return.
303 gST
->ConOut
->SetCursorPosition (gST
->ConOut
, 0, 2);
304 TmpStr
= GetStringById (STRING_TOKEN (STR_ESC_TO_SKIP_MEM_TEST
));
306 if (TmpStr
!= NULL
) {
307 gST
->ConOut
->OutputString (gST
->ConOut
, TmpStr
);
312 Status
= GenMemoryTest
->PerformMemoryTest (
319 if (ErrorOut
&& (Status
== EFI_DEVICE_ERROR
)) {
320 TmpStr
= GetStringById (STRING_TOKEN (STR_SYSTEM_MEM_ERROR
));
321 if (TmpStr
!= NULL
) {
322 PrintXY (10, 10, NULL
, NULL
, TmpStr
);
323 gST
->ConOut
->SetCursorPosition (gST
->ConOut
, 0, 4);
324 gST
->ConOut
->OutputString (gST
->ConOut
, TmpStr
);
331 TestPercent
= (UINTN
) DivU64x32 (
332 DivU64x32 (MultU64x32 (TestedMemorySize
, 100), 16),
333 (UINTN
)DivU64x32 (TotalMemorySize
, 16)
335 if (TestPercent
!= PreviousValue
) {
336 UnicodeValueToString (StrPercent
, 0, TestPercent
, 0);
337 gST
->ConOut
->SetCursorPosition (gST
->ConOut
, 0, 0);
338 TmpStr
= GetStringById (STRING_TOKEN (STR_MEMORY_TEST_PERCENT
));
339 if (TmpStr
!= NULL
) {
340 BdsLibOutputStrings (gST
->ConOut
, StrPercent
, TmpStr
, NULL
);
344 TmpStr
= GetStringById (STRING_TOKEN (STR_PERFORM_MEM_TEST
));
345 if (TmpStr
!= NULL
) {
346 PlatformBdsShowProgress (
352 (UINTN
) PreviousValue
358 PreviousValue
= TestPercent
;
360 KeyStatus
= gST
->ConIn
->ReadKeyStroke (gST
->ConIn
, &Key
);
361 if (Key
.ScanCode
== SCAN_ESC
) {
362 if (!RequireSoftECCInit
) {
363 TmpStr
= GetStringById (STRING_TOKEN (STR_PERFORM_MEM_TEST
));
364 if (TmpStr
!= NULL
) {
365 PlatformBdsShowProgress (
371 (UINTN
) PreviousValue
376 gST
->ConOut
->SetCursorPosition (gST
->ConOut
, 0, 0);
377 gST
->ConOut
->OutputString (gST
->ConOut
, L
"100");
378 Status
= GenMemoryTest
->Finished (GenMemoryTest
);
384 } while (Status
!= EFI_NOT_FOUND
);
386 Status
= GenMemoryTest
->Finished (GenMemoryTest
);
389 UnicodeValueToString (StrTotalMemory
, COMMA_TYPE
, (UINTN
) TotalMemorySize
, 0);
390 if (StrTotalMemory
[0] == L
',') {
394 TmpStr
= GetStringById (STRING_TOKEN (STR_MEM_TEST_COMPLETED
));
395 if (TmpStr
!= NULL
) {
396 StrCat (StrTotalMemory
, TmpStr
);
400 gST
->ConOut
->ClearScreen (gST
->ConOut
);
401 gST
->ConOut
->SetAttribute (gST
->ConOut
, EFI_YELLOW
| EFI_BRIGHT
);
402 gST
->ConOut
->EnableCursor (gST
->ConOut
, FALSE
);
403 gST
->ConOut
->OutputString (gST
->ConOut
, StrTotalMemory
);
404 PlatformBdsShowProgress (
410 (UINTN
) PreviousValue
415 DataSize
= sizeof (Value
);
416 Status
= gRT
->GetVariable (
424 if (EFI_ERROR (Status
)) {
429 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,