3 Copyright (c) 2006, 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 "BdsPlatform.h"
27 // BDS Platform Functions
30 PlatformBdsShowProgress (
31 IN EFI_UGA_PIXEL TitleForeground
,
32 IN EFI_UGA_PIXEL TitleBackground
,
34 IN EFI_UGA_PIXEL ProgressColor
,
36 IN UINTN PreviousValue
42 Show progress bar with title above it. It only works in UGA mode.
46 TitleForeground - Foreground color for Title.
47 TitleBackground - Background color for Title.
48 Title - Title above progress bar.
49 ProgressColor - Progress bar color.
50 Progress - Progress (0-100)
54 EFI_STATUS - Success update the progress bar
59 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
73 return EFI_INVALID_PARAMETER
;
76 Status
= gBS
->HandleProtocol (
77 gST
->ConsoleOutHandle
,
78 &gEfiUgaDrawProtocolGuid
,
81 if (EFI_ERROR (Status
)) {
82 return EFI_UNSUPPORTED
;
85 Status
= UgaDraw
->GetMode (
92 if (EFI_ERROR (Status
)) {
93 return EFI_UNSUPPORTED
;
96 BlockWidth
= SizeOfX
/ 100;
97 BlockHeight
= SizeOfY
/ 50;
102 PosY
= SizeOfY
* 48 / 50;
106 // Clear progress area
108 SetMem (&Color
, sizeof (EFI_UGA_PIXEL
), 0x0);
110 Status
= UgaDraw
->Blt (
117 PosY
- GLYPH_HEIGHT
- 1,
119 SizeOfY
- (PosY
- GLYPH_HEIGHT
- 1),
120 SizeOfX
* sizeof (EFI_UGA_PIXEL
)
124 // Show progress by drawing blocks
126 for (Index
= PreviousValue
; Index
< BlockNum
; Index
++) {
127 PosX
= Index
* BlockWidth
;
128 Status
= UgaDraw
->Blt (
138 (BlockWidth
) * sizeof (EFI_UGA_PIXEL
)
143 (SizeOfX
- StrLen (Title
) * GLYPH_WIDTH
) / 2,
144 PosY
- GLYPH_HEIGHT
- 1,
155 IN EXTENDMEM_COVERAGE_LEVEL Level
161 Perform the memory test base on the memory test intensive level,
162 and update the memory resource.
166 Level - The memory test intensive level.
170 EFI_STATUS - Success test all the system memory and update
176 EFI_STATUS InitStatus
;
177 EFI_STATUS KeyStatus
;
178 EFI_STATUS ReturnStatus
;
179 BOOLEAN RequireSoftECCInit
;
180 EFI_GENERIC_MEMORY_TEST_PROTOCOL
*GenMemoryTest
;
181 UINT64 TestedMemorySize
;
182 UINT64 TotalMemorySize
;
184 UINT64 PreviousValue
;
188 CHAR16 StrPercent
[16];
189 CHAR16
*StrTotalMemory
;
192 EFI_UGA_PIXEL Foreground
;
193 EFI_UGA_PIXEL Background
;
199 ReturnStatus
= EFI_SUCCESS
;
200 ZeroMem (&Key
, sizeof (EFI_INPUT_KEY
));
202 Pos
= AllocatePool (128);
208 StrTotalMemory
= Pos
;
210 TestedMemorySize
= 0;
216 SetMem (&Foreground
, sizeof (EFI_UGA_PIXEL
), 0xff);
217 SetMem (&Background
, sizeof (EFI_UGA_PIXEL
), 0x0);
218 SetMem (&Color
, sizeof (EFI_UGA_PIXEL
), 0xff);
220 RequireSoftECCInit
= FALSE
;
222 gST
->ConOut
->ClearScreen (gST
->ConOut
);
223 gST
->ConOut
->SetAttribute (gST
->ConOut
, EFI_YELLOW
| EFI_BRIGHT
);
224 gST
->ConOut
->EnableCursor (gST
->ConOut
, FALSE
);
226 Status
= gBS
->LocateProtocol (
227 &gEfiGenericMemTestProtocolGuid
,
231 if (EFI_ERROR (Status
)) {
236 InitStatus
= GenMemoryTest
->MemoryTestInit (
241 if (InitStatus
== EFI_NO_MEDIA
) {
243 // The PEI codes also have the relevant memory test code to check the memory,
244 // it can select to test some range of the memory or all of them. If PEI code
245 // checks all the memory, this BDS memory test will has no not-test memory to
246 // do the test, and then the status of EFI_NO_MEDIA will be returned by
247 // "MemoryTestInit". So it does not need to test memory again, just return.
253 gST
->ConOut
->SetCursorPosition (gST
->ConOut
, 0, 2);
254 TmpStr
= GetStringById (STRING_TOKEN (STR_ESC_TO_SKIP_MEM_TEST
));
256 if (TmpStr
!= NULL
) {
257 gST
->ConOut
->OutputString (gST
->ConOut
, TmpStr
);
258 gBS
->FreePool (TmpStr
);
262 Status
= GenMemoryTest
->PerformMemoryTest (
269 if (ErrorOut
&& (Status
== EFI_DEVICE_ERROR
)) {
270 TmpStr
= GetStringById (STRING_TOKEN (STR_SYSTEM_MEM_ERROR
));
271 if (TmpStr
!= NULL
) {
272 PrintXY (10, 10, NULL
, NULL
, TmpStr
);
273 gST
->ConOut
->SetCursorPosition (gST
->ConOut
, 0, 4);
274 gST
->ConOut
->OutputString (gST
->ConOut
, TmpStr
);
275 gBS
->FreePool (TmpStr
);
281 TestPercent
= (UINTN
) DivU64x32 (
282 DivU64x32 (MultU64x32 (TestedMemorySize
, 100), 16),
283 (UINTN
)DivU64x32 (TotalMemorySize
, 16)
285 if (TestPercent
!= PreviousValue
) {
286 UnicodeValueToString (StrPercent
, 0, TestPercent
, 0);
287 gST
->ConOut
->SetCursorPosition (gST
->ConOut
, 0, 0);
288 TmpStr
= GetStringById (STRING_TOKEN (STR_MEMORY_TEST_PERCENT
));
289 if (TmpStr
!= NULL
) {
290 BdsLibOutputStrings (gST
->ConOut
, StrPercent
, TmpStr
, NULL
);
291 gBS
->FreePool (TmpStr
);
294 TmpStr
= GetStringById (STRING_TOKEN (STR_PERFORM_MEM_TEST
));
295 if (TmpStr
!= NULL
) {
296 PlatformBdsShowProgress (
302 (UINTN
) PreviousValue
304 gBS
->FreePool (TmpStr
);
308 PreviousValue
= TestPercent
;
310 KeyStatus
= gST
->ConIn
->ReadKeyStroke (gST
->ConIn
, &Key
);
311 if (Key
.ScanCode
== SCAN_ESC
) {
312 if (!RequireSoftECCInit
) {
313 TmpStr
= GetStringById (STRING_TOKEN (STR_PERFORM_MEM_TEST
));
314 if (TmpStr
!= NULL
) {
315 PlatformBdsShowProgress (
321 (UINTN
) PreviousValue
323 gBS
->FreePool (TmpStr
);
326 gST
->ConOut
->SetCursorPosition (gST
->ConOut
, 0, 0);
327 gST
->ConOut
->OutputString (gST
->ConOut
, L
"100");
328 Status
= GenMemoryTest
->Finished (GenMemoryTest
);
334 } while (Status
!= EFI_NOT_FOUND
);
336 Status
= GenMemoryTest
->Finished (GenMemoryTest
);
339 UnicodeValueToString (StrTotalMemory
, COMMA_TYPE
, (UINTN
) TotalMemorySize
, 0);
340 if (StrTotalMemory
[0] == L
',') {
344 TmpStr
= GetStringById (STRING_TOKEN (STR_MEM_TEST_COMPLETED
));
345 if (TmpStr
!= NULL
) {
346 StrCat (StrTotalMemory
, TmpStr
);
347 gBS
->FreePool (TmpStr
);
350 gST
->ConOut
->ClearScreen (gST
->ConOut
);
351 gST
->ConOut
->SetAttribute (gST
->ConOut
, EFI_YELLOW
| EFI_BRIGHT
);
352 gST
->ConOut
->EnableCursor (gST
->ConOut
, FALSE
);
353 gST
->ConOut
->OutputString (gST
->ConOut
, StrTotalMemory
);
354 PlatformBdsShowProgress (
360 (UINTN
) PreviousValue
365 DataSize
= sizeof (Value
);
366 Status
= gRT
->GetVariable (
374 if (EFI_ERROR (Status
)) {
379 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,