+++ /dev/null
-/*++\r
-\r
-Copyright (c) 2006, Intel Corporation \r
-All rights reserved. This program and the accompanying materials \r
-are licensed and made available under the terms and conditions of the BSD License \r
-which accompanies this distribution. The full text of the license may be found at \r
-http://opensource.org/licenses/bsd-license.php \r
- \r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
-\r
-Module Name:\r
-\r
- MemoryTest.c\r
-\r
-Abstract:\r
-\r
- Perform the platform memory test\r
-\r
---*/\r
-\r
-#include "Bds.h"\r
-#include "String.h"\r
-\r
-//\r
-// BDS Platform Functions\r
-//\r
-EFI_STATUS\r
-PlatformBdsShowProgress (\r
- IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL TitleForeground,\r
- IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL TitleBackground,\r
- IN CHAR16 *Title,\r
- IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL ProgressColor,\r
- IN UINTN Progress,\r
- IN UINTN PreviousValue\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- \r
- Show progress bar with title above it. It only works in UGA mode.\r
-\r
-Arguments:\r
- \r
- TitleForeground - Foreground color for Title.\r
- TitleBackground - Background color for Title.\r
- Title - Title above progress bar.\r
- ProgressColor - Progress bar color.\r
- Progress - Progress (0-100)\r
-\r
-Returns: \r
- \r
- EFI_STATUS - Success update the progress bar\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
- EFI_UGA_DRAW_PROTOCOL *UgaDraw;\r
- UINT32 SizeOfX;\r
- UINT32 SizeOfY;\r
- UINT32 ColorDepth;\r
- UINT32 RefreshRate;\r
- EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color;\r
- UINTN BlockHeight;\r
- UINTN BlockWidth;\r
- UINTN BlockNum;\r
- UINTN PosX;\r
- UINTN PosY;\r
- UINTN Index;\r
-\r
- if (Progress > 100) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- UgaDraw = NULL;\r
- Status = gBS->HandleProtocol (\r
- gST->ConsoleOutHandle,\r
- &gEfiGraphicsOutputProtocolGuid,\r
- (VOID**)&GraphicsOutput\r
- );\r
- if (EFI_ERROR (Status)) {\r
- GraphicsOutput = NULL;\r
-\r
- Status = gBS->HandleProtocol (\r
- gST->ConsoleOutHandle,\r
- &gEfiUgaDrawProtocolGuid,\r
- (VOID**)&UgaDraw\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return EFI_UNSUPPORTED;\r
- }\r
- }\r
-\r
- if (GraphicsOutput != NULL) {\r
- SizeOfX = GraphicsOutput->Mode->Info->HorizontalResolution;\r
- SizeOfY = GraphicsOutput->Mode->Info->VerticalResolution;\r
- } else {\r
- Status = UgaDraw->GetMode (\r
- UgaDraw,\r
- &SizeOfX,\r
- &SizeOfY,\r
- &ColorDepth,\r
- &RefreshRate\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return EFI_UNSUPPORTED;\r
- }\r
- }\r
-\r
- BlockWidth = SizeOfX / 100;\r
- BlockHeight = SizeOfY / 50;\r
-\r
- BlockNum = Progress;\r
-\r
- PosX = 0;\r
- PosY = SizeOfY * 48 / 50;\r
-\r
- if (BlockNum == 0) {\r
- //\r
- // Clear progress area\r
- //\r
- SetMem (&Color, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0x0);\r
-\r
- if (GraphicsOutput != NULL) {\r
- Status = GraphicsOutput->Blt (\r
- GraphicsOutput,\r
- &Color,\r
- EfiBltVideoFill,\r
- 0,\r
- 0,\r
- 0,\r
- PosY - GLYPH_HEIGHT - 1,\r
- SizeOfX,\r
- SizeOfY - (PosY - GLYPH_HEIGHT - 1),\r
- SizeOfX * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
- );\r
- } else {\r
- Status = UgaDraw->Blt (\r
- UgaDraw,\r
- (EFI_UGA_PIXEL *) &Color,\r
- EfiUgaVideoFill,\r
- 0,\r
- 0,\r
- 0,\r
- PosY - GLYPH_HEIGHT - 1,\r
- SizeOfX,\r
- SizeOfY - (PosY - GLYPH_HEIGHT - 1),\r
- SizeOfX * sizeof (EFI_UGA_PIXEL)\r
- );\r
- }\r
- }\r
- //\r
- // Show progress by drawing blocks\r
- //\r
- for (Index = PreviousValue; Index < BlockNum; Index++) {\r
- PosX = Index * BlockWidth;\r
- if (GraphicsOutput != NULL) {\r
- Status = GraphicsOutput->Blt (\r
- GraphicsOutput,\r
- &ProgressColor,\r
- EfiBltVideoFill,\r
- 0,\r
- 0,\r
- PosX,\r
- PosY,\r
- BlockWidth - 1,\r
- BlockHeight,\r
- (BlockWidth) * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
- );\r
- } else {\r
- Status = UgaDraw->Blt (\r
- UgaDraw,\r
- (EFI_UGA_PIXEL *) &ProgressColor,\r
- EfiUgaVideoFill,\r
- 0,\r
- 0,\r
- PosX,\r
- PosY,\r
- BlockWidth - 1,\r
- BlockHeight,\r
- (BlockWidth) * sizeof (EFI_UGA_PIXEL)\r
- );\r
- }\r
- }\r
-\r
- PrintXY (\r
- (SizeOfX - StrLen (Title) * GLYPH_WIDTH) / 2,\r
- PosY - GLYPH_HEIGHT - 1,\r
- &TitleForeground,\r
- &TitleBackground,\r
- Title\r
- );\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-BdsMemoryTest (\r
- IN EXTENDMEM_COVERAGE_LEVEL Level\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- \r
- Perform the memory test base on the memory test intensive level, \r
- and update the memory resource.\r
-\r
-Arguments:\r
- \r
- Level - The memory test intensive level.\r
-\r
-Returns: \r
- \r
- EFI_STATUS - Success test all the system memory and update\r
- the memory resource\r
- \r
---*/\r
-{\r
- EFI_STATUS Status;\r
- EFI_STATUS InitStatus;\r
- EFI_STATUS KeyStatus;\r
- EFI_STATUS ReturnStatus;\r
- BOOLEAN RequireSoftECCInit;\r
- EFI_GENERIC_MEMORY_TEST_PROTOCOL *GenMemoryTest;\r
- UINT64 TestedMemorySize;\r
- UINT64 TotalMemorySize;\r
- UINTN TestPercent;\r
- UINT64 PreviousValue;\r
- BOOLEAN ErrorOut;\r
- BOOLEAN TestAbort;\r
- EFI_INPUT_KEY Key;\r
- CHAR16 StrPercent[16];\r
- CHAR16 *StrTotalMemory;\r
- CHAR16 *Pos;\r
- CHAR16 *TmpStr;\r
- EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground;\r
- EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background;\r
- EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color;\r
- UINT8 Value;\r
- UINTN DataSize;\r
-\r
- ReturnStatus = EFI_SUCCESS;\r
- ZeroMem (&Key, sizeof (EFI_INPUT_KEY));\r
-\r
- Pos = AllocatePool (128);\r
-\r
- if (Pos == NULL) {\r
- return ReturnStatus;\r
- }\r
-\r
- StrTotalMemory = Pos;\r
-\r
- TestedMemorySize = 0;\r
- TotalMemorySize = 0;\r
- PreviousValue = 0;\r
- ErrorOut = FALSE;\r
- TestAbort = FALSE;\r
-\r
- SetMem (&Foreground, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff);\r
- SetMem (&Background, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0x0);\r
- SetMem (&Color, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff);\r
-\r
- RequireSoftECCInit = FALSE;\r
-\r
- gST->ConOut->ClearScreen (gST->ConOut);\r
- gST->ConOut->SetAttribute (gST->ConOut, EFI_YELLOW | EFI_BRIGHT);\r
- gST->ConOut->EnableCursor (gST->ConOut, FALSE);\r
-\r
- Status = gBS->LocateProtocol (\r
- &gEfiGenericMemTestProtocolGuid,\r
- NULL,\r
- (VOID**)&GenMemoryTest\r
- );\r
- if (EFI_ERROR (Status)) {\r
- gBS->FreePool (Pos);\r
- return EFI_SUCCESS;\r
- }\r
-\r
- InitStatus = GenMemoryTest->MemoryTestInit (\r
- GenMemoryTest,\r
- Level,\r
- &RequireSoftECCInit\r
- );\r
- if (InitStatus == EFI_NO_MEDIA) {\r
- //\r
- // The PEI codes also have the relevant memory test code to check the memory,\r
- // it can select to test some range of the memory or all of them. If PEI code\r
- // checks all the memory, this BDS memory test will has no not-test memory to\r
- // do the test, and then the status of EFI_NO_MEDIA will be returned by\r
- // "MemoryTestInit". So it does not need to test memory again, just return.\r
- //\r
- gBS->FreePool (Pos);\r
- return EFI_SUCCESS;\r
- }\r
-\r
- gST->ConOut->SetCursorPosition (gST->ConOut, 0, 2);\r
- TmpStr = GetStringById (STRING_TOKEN (STR_ESC_TO_SKIP_MEM_TEST));\r
-\r
- if (TmpStr != NULL) {\r
- gST->ConOut->OutputString (gST->ConOut, TmpStr);\r
- gBS->FreePool (TmpStr);\r
- }\r
-\r
- do {\r
- Status = GenMemoryTest->PerformMemoryTest (\r
- GenMemoryTest,\r
- &TestedMemorySize,\r
- &TotalMemorySize,\r
- &ErrorOut,\r
- TestAbort\r
- );\r
- if (ErrorOut && (Status == EFI_DEVICE_ERROR)) {\r
- TmpStr = GetStringById (STRING_TOKEN (STR_SYSTEM_MEM_ERROR));\r
- if (TmpStr != NULL) {\r
- PrintXY (10, 10, NULL, NULL, TmpStr);\r
- gST->ConOut->SetCursorPosition (gST->ConOut, 0, 4);\r
- gST->ConOut->OutputString (gST->ConOut, TmpStr);\r
- gBS->FreePool (TmpStr);\r
- }\r
-\r
- ASSERT (0);\r
- }\r
-\r
- TestPercent = (UINTN) DivU64x32 (\r
- DivU64x32 (MultU64x32 (TestedMemorySize, 100), 16),\r
- (UINTN)DivU64x32 (TotalMemorySize, 16)\r
- );\r
- if (TestPercent != PreviousValue) {\r
- UnicodeValueToString (StrPercent, 0, TestPercent, 0);\r
- gST->ConOut->SetCursorPosition (gST->ConOut, 0, 0);\r
- TmpStr = GetStringById (STRING_TOKEN (STR_MEMORY_TEST_PERCENT));\r
- if (TmpStr != NULL) {\r
- BdsLibOutputStrings (gST->ConOut, StrPercent, TmpStr, NULL);\r
- gBS->FreePool (TmpStr);\r
- }\r
-\r
- TmpStr = GetStringById (STRING_TOKEN (STR_PERFORM_MEM_TEST));\r
- if (TmpStr != NULL) {\r
- PlatformBdsShowProgress (\r
- Foreground,\r
- Background,\r
- TmpStr,\r
- Color,\r
- TestPercent,\r
- (UINTN) PreviousValue\r
- );\r
- gBS->FreePool (TmpStr);\r
- }\r
- }\r
-\r
- PreviousValue = TestPercent;\r
-\r
- KeyStatus = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);\r
- if (Key.ScanCode == SCAN_ESC) {\r
- if (!RequireSoftECCInit) {\r
- TmpStr = GetStringById (STRING_TOKEN (STR_PERFORM_MEM_TEST));\r
- if (TmpStr != NULL) {\r
- PlatformBdsShowProgress (\r
- Foreground,\r
- Background,\r
- TmpStr,\r
- Color,\r
- 100,\r
- (UINTN) PreviousValue\r
- );\r
- gBS->FreePool (TmpStr);\r
- }\r
-\r
- gST->ConOut->SetCursorPosition (gST->ConOut, 0, 0);\r
- gST->ConOut->OutputString (gST->ConOut, L"100");\r
- Status = GenMemoryTest->Finished (GenMemoryTest);\r
- goto Done;\r
- }\r
-\r
- TestAbort = TRUE;\r
- }\r
- } while (Status != EFI_NOT_FOUND);\r
-\r
- Status = GenMemoryTest->Finished (GenMemoryTest);\r
-\r
-Done:\r
- UnicodeValueToString (StrTotalMemory, COMMA_TYPE, (UINTN) TotalMemorySize, 0);\r
- if (StrTotalMemory[0] == L',') {\r
- StrTotalMemory++;\r
- }\r
-\r
- TmpStr = GetStringById (STRING_TOKEN (STR_MEM_TEST_COMPLETED));\r
- if (TmpStr != NULL) {\r
- StrCat (StrTotalMemory, TmpStr);\r
- gBS->FreePool (TmpStr);\r
- }\r
-\r
- gST->ConOut->ClearScreen (gST->ConOut);\r
- gST->ConOut->SetAttribute (gST->ConOut, EFI_YELLOW | EFI_BRIGHT);\r
- gST->ConOut->EnableCursor (gST->ConOut, FALSE);\r
- gST->ConOut->OutputString (gST->ConOut, StrTotalMemory);\r
- PlatformBdsShowProgress (\r
- Foreground,\r
- Background,\r
- StrTotalMemory,\r
- Color,\r
- 100,\r
- (UINTN) PreviousValue\r
- );\r
-\r
- gBS->FreePool (Pos);\r
-\r
- DataSize = sizeof (Value);\r
- Status = gRT->GetVariable (\r
- L"BootState",\r
- &gEfiBootStateGuid,\r
- NULL,\r
- &DataSize,\r
- &Value\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- Value = 1;\r
- gRT->SetVariable (\r
- L"BootState",\r
- &gEfiBootStateGuid,\r
- EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
- sizeof (Value),\r
- &Value\r
- );\r
- }\r
-\r
- return ReturnStatus;\r
-}\r