+++ /dev/null
-/** @file\r
- Perform the platform memory test\r
-\r
-Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>\r
-SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\r
-\r
-#include "Bds.h"\r
-#include "String.h"\r
-\r
-//\r
-// BDS Platform Functions\r
-//\r
-/**\r
-\r
- Show progress bar with title above it. It only works in Graphics mode.\r
-\r
-\r
- @param TitleForeground Foreground color for Title.\r
- @param TitleBackground Background color for Title.\r
- @param Title Title above progress bar.\r
- @param ProgressColor Progress bar color.\r
- @param Progress Progress (0-100)\r
- @param PreviousValue The previous value of the progress.\r
-\r
- @retval EFI_STATUS Success update the progress bar\r
-\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
- 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) && FeaturePcdGet (PcdUgaConsumeSupport)) {\r
- GraphicsOutput = NULL;\r
-\r
- Status = gBS->HandleProtocol (\r
- gST->ConsoleOutHandle,\r
- &gEfiUgaDrawProtocolGuid,\r
- (VOID **) &UgaDraw\r
- );\r
- }\r
- if (EFI_ERROR (Status)) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- SizeOfX = 0;\r
- SizeOfY = 0;\r
- if (GraphicsOutput != NULL) {\r
- SizeOfX = GraphicsOutput->Mode->Info->HorizontalResolution;\r
- SizeOfY = GraphicsOutput->Mode->Info->VerticalResolution;\r
- } else if (UgaDraw != NULL) {\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
- } else {\r
- return EFI_UNSUPPORTED;\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 - EFI_GLYPH_HEIGHT - 1,\r
- SizeOfX,\r
- SizeOfY - (PosY - EFI_GLYPH_HEIGHT - 1),\r
- SizeOfX * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
- );\r
- } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {\r
- Status = UgaDraw->Blt (\r
- UgaDraw,\r
- (EFI_UGA_PIXEL *) &Color,\r
- EfiUgaVideoFill,\r
- 0,\r
- 0,\r
- 0,\r
- PosY - EFI_GLYPH_HEIGHT - 1,\r
- SizeOfX,\r
- SizeOfY - (PosY - EFI_GLYPH_HEIGHT - 1),\r
- SizeOfX * sizeof (EFI_UGA_PIXEL)\r
- );\r
- } else {\r
- return EFI_UNSUPPORTED;\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 if (FeaturePcdGet (PcdUgaConsumeSupport)) {\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
- } else {\r
- return EFI_UNSUPPORTED;\r
- }\r
- }\r
-\r
- PrintXY (\r
- (SizeOfX - StrLen (Title) * EFI_GLYPH_WIDTH) / 2,\r
- PosY - EFI_GLYPH_HEIGHT - 1,\r
- &TitleForeground,\r
- &TitleBackground,\r
- Title\r
- );\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Perform the memory test base on the memory test intensive level,\r
- and update the memory resource.\r
-\r
- @param Level The memory test intensive level.\r
-\r
- @retval EFI_STATUS Success test all the system memory and update\r
- the memory resource\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-BdsMemoryTest (\r
- IN EXTENDMEM_COVERAGE_LEVEL Level\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_STATUS KeyStatus;\r
- EFI_STATUS InitStatus;\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[80];\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
- BOOLEAN IsFirstBoot;\r
- UINT32 TempData;\r
- UINTN StrTotalMemorySize;\r
-\r
- ReturnStatus = EFI_SUCCESS;\r
- ZeroMem (&Key, sizeof (EFI_INPUT_KEY));\r
-\r
- StrTotalMemorySize = 128;\r
- Pos = AllocateZeroPool (StrTotalMemorySize);\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
- Status = gBS->LocateProtocol (\r
- &gEfiGenericMemTestProtocolGuid,\r
- NULL,\r
- (VOID **) &GenMemoryTest\r
- );\r
- if (EFI_ERROR (Status)) {\r
- 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
- FreePool (Pos);\r
- return EFI_SUCCESS;\r
- }\r
-\r
- if (!FeaturePcdGet(PcdBootlogoOnlyEnable)) {\r
- TmpStr = GetStringById (STRING_TOKEN (STR_ESC_TO_SKIP_MEM_TEST));\r
-\r
- if (TmpStr != NULL) {\r
- PrintXY (10, 10, NULL, NULL, TmpStr);\r
- FreePool (TmpStr);\r
- }\r
- } else {\r
- DEBUG ((EFI_D_INFO, "Enter memory test.\n"));\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
- FreePool (TmpStr);\r
- }\r
-\r
- ASSERT (0);\r
- }\r
-\r
- if (!FeaturePcdGet(PcdBootlogoOnlyEnable)) {\r
- TempData = (UINT32) DivU64x32 (TotalMemorySize, 16);\r
- TestPercent = (UINTN) DivU64x32 (\r
- DivU64x32 (MultU64x32 (TestedMemorySize, 100), 16),\r
- TempData\r
- );\r
- if (TestPercent != PreviousValue) {\r
- UnicodeValueToStringS (StrPercent, sizeof (StrPercent), 0, TestPercent, 0);\r
- TmpStr = GetStringById (STRING_TOKEN (STR_MEMORY_TEST_PERCENT));\r
- if (TmpStr != NULL) {\r
- //\r
- // TmpStr size is 64, StrPercent is reserved to 16.\r
- //\r
- StrnCatS (\r
- StrPercent,\r
- sizeof (StrPercent) / sizeof (CHAR16),\r
- TmpStr,\r
- sizeof (StrPercent) / sizeof (CHAR16) - StrLen (StrPercent) - 1\r
- );\r
- PrintXY (10, 10, NULL, NULL, StrPercent);\r
- 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
- FreePool (TmpStr);\r
- }\r
- }\r
-\r
- PreviousValue = TestPercent;\r
- } else {\r
- DEBUG ((EFI_D_INFO, "Perform memory test (ESC to skip).\n"));\r
- }\r
-\r
- if (!PcdGetBool (PcdConInConnectOnDemand)) {\r
- KeyStatus = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);\r
- if (!EFI_ERROR (KeyStatus) && (Key.ScanCode == SCAN_ESC)) {\r
- if (!RequireSoftECCInit) {\r
- if (!FeaturePcdGet(PcdBootlogoOnlyEnable)) {\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
- FreePool (TmpStr);\r
- }\r
-\r
- PrintXY (10, 10, NULL, NULL, L"100");\r
- }\r
- Status = GenMemoryTest->Finished (GenMemoryTest);\r
- goto Done;\r
- }\r
-\r
- TestAbort = TRUE;\r
- }\r
- }\r
- } while (Status != EFI_NOT_FOUND);\r
-\r
- Status = GenMemoryTest->Finished (GenMemoryTest);\r
-\r
-Done:\r
- if (!FeaturePcdGet(PcdBootlogoOnlyEnable)) {\r
- UnicodeValueToStringS (StrTotalMemory, StrTotalMemorySize, COMMA_TYPE, TotalMemorySize, 0);\r
- if (StrTotalMemory[0] == L',') {\r
- StrTotalMemory++;\r
- StrTotalMemorySize -= sizeof (CHAR16);\r
- }\r
-\r
- TmpStr = GetStringById (STRING_TOKEN (STR_MEM_TEST_COMPLETED));\r
- if (TmpStr != NULL) {\r
- StrnCatS (\r
- StrTotalMemory,\r
- StrTotalMemorySize / sizeof (CHAR16),\r
- TmpStr,\r
- StrTotalMemorySize / sizeof (CHAR16) - StrLen (StrTotalMemory) - 1\r
- );\r
- FreePool (TmpStr);\r
- }\r
-\r
- PrintXY (10, 10, NULL, NULL, StrTotalMemory);\r
- PlatformBdsShowProgress (\r
- Foreground,\r
- Background,\r
- StrTotalMemory,\r
- Color,\r
- 100,\r
- (UINTN) PreviousValue\r
- );\r
-\r
- } else {\r
- DEBUG ((EFI_D_INFO, "%d bytes of system memory tested OK\r\n", TotalMemorySize));\r
- }\r
-\r
- FreePool (Pos);\r
-\r
-\r
- //\r
- // Use a DynamicHii type pcd to save the boot status, which is used to\r
- // control configuration mode, such as FULL/MINIMAL/NO_CHANGES configuration.\r
- //\r
- IsFirstBoot = PcdGetBool(PcdBootState);\r
- if (IsFirstBoot) {\r
- Status = PcdSetBoolS(PcdBootState, FALSE);\r
- if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_ERROR, "Set PcdBootState to FALSE failed.\n"));\r
- }\r
- }\r
-\r
- return ReturnStatus;\r
-}\r