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