Home | History | Annotate | Download | only in PlatformBootManagerLib
      1 /** @file
      2   Perform the platform memory test
      3 
      4 Copyright (c) 2004 - 2015, Intel Corporation. All rights reserved.<BR>
      5 This program and the accompanying materials
      6 are licensed and made available under the terms and conditions of the BSD License
      7 which accompanies this distribution.  The full text of the license may be found at
      8 http://opensource.org/licenses/bsd-license.php
      9 
     10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     12 
     13 **/
     14 
     15 #include "PlatformBootManager.h"
     16 
     17 EFI_HII_HANDLE gStringPackHandle                  = NULL;
     18 EFI_GUID       mPlatformBootManagerStringPackGuid = {
     19   0x154dd51, 0x9079, 0x4a10, { 0x89, 0x5c, 0x9c, 0x7, 0x72, 0x81, 0x57, 0x88 }
     20   };
     21 // extern UINT8  BdsDxeStrings[];
     22 
     23 //
     24 // BDS Platform Functions
     25 //
     26 
     27 /**
     28   Perform the memory test base on the memory test intensive level,
     29   and update the memory resource.
     30 
     31   @param  Level         The memory test intensive level.
     32 
     33   @retval EFI_STATUS    Success test all the system memory and update
     34                         the memory resource
     35 
     36 **/
     37 EFI_STATUS
     38 PlatformBootManagerMemoryTest (
     39   IN EXTENDMEM_COVERAGE_LEVEL Level
     40   )
     41 {
     42   EFI_STATUS                        Status;
     43   EFI_STATUS                        KeyStatus;
     44   EFI_STATUS                        InitStatus;
     45   EFI_STATUS                        ReturnStatus;
     46   BOOLEAN                           RequireSoftECCInit;
     47   EFI_GENERIC_MEMORY_TEST_PROTOCOL  *GenMemoryTest;
     48   UINT64                            TestedMemorySize;
     49   UINT64                            TotalMemorySize;
     50   UINTN                             TestPercent;
     51   UINT64                            PreviousValue;
     52   BOOLEAN                           ErrorOut;
     53   BOOLEAN                           TestAbort;
     54   EFI_INPUT_KEY                     Key;
     55   CHAR16                            StrPercent[80];
     56   CHAR16                            *StrTotalMemory;
     57   CHAR16                            *Pos;
     58   CHAR16                            *TmpStr;
     59   EFI_GRAPHICS_OUTPUT_BLT_PIXEL     Foreground;
     60   EFI_GRAPHICS_OUTPUT_BLT_PIXEL     Background;
     61   EFI_GRAPHICS_OUTPUT_BLT_PIXEL     Color;
     62   UINT32                            TempData;
     63   UINTN                             StrTotalMemorySize;
     64 
     65   ReturnStatus = EFI_SUCCESS;
     66   ZeroMem (&Key, sizeof (EFI_INPUT_KEY));
     67 
     68   StrTotalMemorySize = 128;
     69   Pos = AllocateZeroPool (StrTotalMemorySize);
     70   ASSERT (Pos != NULL);
     71 
     72   if (gStringPackHandle == NULL) {
     73     gStringPackHandle = HiiAddPackages (
     74                            &mPlatformBootManagerStringPackGuid,
     75                            gImageHandle,
     76                            PlatformBootManagerLibStrings,
     77                            NULL
     78                            );
     79     ASSERT (gStringPackHandle != NULL);
     80   }
     81 
     82   StrTotalMemory    = Pos;
     83 
     84   TestedMemorySize  = 0;
     85   TotalMemorySize   = 0;
     86   PreviousValue     = 0;
     87   ErrorOut          = FALSE;
     88   TestAbort         = FALSE;
     89 
     90   SetMem (&Foreground, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff);
     91   SetMem (&Background, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0x0);
     92   SetMem (&Color, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff);
     93 
     94   RequireSoftECCInit = FALSE;
     95 
     96   Status = gBS->LocateProtocol (
     97                   &gEfiGenericMemTestProtocolGuid,
     98                   NULL,
     99                   (VOID **) &GenMemoryTest
    100                   );
    101   if (EFI_ERROR (Status)) {
    102     FreePool (Pos);
    103     return EFI_SUCCESS;
    104   }
    105 
    106   InitStatus = GenMemoryTest->MemoryTestInit (
    107                                 GenMemoryTest,
    108                                 Level,
    109                                 &RequireSoftECCInit
    110                                 );
    111   if (InitStatus == EFI_NO_MEDIA) {
    112     //
    113     // The PEI codes also have the relevant memory test code to check the memory,
    114     // it can select to test some range of the memory or all of them. If PEI code
    115     // checks all the memory, this BDS memory test will has no not-test memory to
    116     // do the test, and then the status of EFI_NO_MEDIA will be returned by
    117     // "MemoryTestInit". So it does not need to test memory again, just return.
    118     //
    119     FreePool (Pos);
    120     return EFI_SUCCESS;
    121   }
    122 
    123   if (!FeaturePcdGet(PcdBootlogoOnlyEnable)) {
    124     TmpStr = HiiGetString (gStringPackHandle, STRING_TOKEN (STR_ESC_TO_SKIP_MEM_TEST), NULL);
    125 
    126     if (TmpStr != NULL) {
    127       PrintXY (10, 10, NULL, NULL, TmpStr);
    128       FreePool (TmpStr);
    129     }
    130   } else {
    131     DEBUG ((EFI_D_INFO, "Enter memory test.\n"));
    132   }
    133   do {
    134     Status = GenMemoryTest->PerformMemoryTest (
    135                               GenMemoryTest,
    136                               &TestedMemorySize,
    137                               &TotalMemorySize,
    138                               &ErrorOut,
    139                               TestAbort
    140                               );
    141     if (ErrorOut && (Status == EFI_DEVICE_ERROR)) {
    142       TmpStr = HiiGetString (gStringPackHandle, STRING_TOKEN (STR_SYSTEM_MEM_ERROR), NULL);
    143       if (TmpStr != NULL) {
    144         PrintXY (10, 10, NULL, NULL, TmpStr);
    145         FreePool (TmpStr);
    146       }
    147 
    148       ASSERT (0);
    149     }
    150 
    151     if (!FeaturePcdGet(PcdBootlogoOnlyEnable)) {
    152       TempData = (UINT32) DivU64x32 (TotalMemorySize, 16);
    153       TestPercent = (UINTN) DivU64x32 (
    154                               DivU64x32 (MultU64x32 (TestedMemorySize, 100), 16),
    155                               TempData
    156                               );
    157       if (TestPercent != PreviousValue) {
    158         UnicodeValueToString (StrPercent, 0, TestPercent, 0);
    159         TmpStr = HiiGetString (gStringPackHandle, STRING_TOKEN (STR_MEMORY_TEST_PERCENT), NULL);
    160         if (TmpStr != NULL) {
    161           //
    162           // TmpStr size is 64, StrPercent is reserved to 16.
    163           //
    164           StrnCatS (
    165             StrPercent,
    166             sizeof (StrPercent) / sizeof (CHAR16),
    167             TmpStr,
    168             sizeof (StrPercent) / sizeof (CHAR16) - StrLen (StrPercent) - 1
    169             );
    170           PrintXY (10, 10, NULL, NULL, StrPercent);
    171           FreePool (TmpStr);
    172         }
    173 
    174         TmpStr = HiiGetString (gStringPackHandle, STRING_TOKEN (STR_PERFORM_MEM_TEST), NULL);
    175         if (TmpStr != NULL) {
    176           BootLogoUpdateProgress (
    177             Foreground,
    178             Background,
    179             TmpStr,
    180             Color,
    181             TestPercent,
    182             (UINTN) PreviousValue
    183             );
    184           FreePool (TmpStr);
    185         }
    186       }
    187 
    188       PreviousValue = TestPercent;
    189     } else {
    190       DEBUG ((EFI_D_INFO, "Perform memory test (ESC to skip).\n"));
    191     }
    192 
    193     if (!PcdGetBool (PcdConInConnectOnDemand)) {
    194       KeyStatus     = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
    195       if (!EFI_ERROR (KeyStatus) && (Key.ScanCode == SCAN_ESC)) {
    196         if (!RequireSoftECCInit) {
    197           if (!FeaturePcdGet(PcdBootlogoOnlyEnable)) {
    198             TmpStr = HiiGetString (gStringPackHandle, STRING_TOKEN (STR_PERFORM_MEM_TEST), NULL);
    199             if (TmpStr != NULL) {
    200               BootLogoUpdateProgress (
    201                 Foreground,
    202                 Background,
    203                 TmpStr,
    204                 Color,
    205                 100,
    206                 (UINTN) PreviousValue
    207                 );
    208               FreePool (TmpStr);
    209             }
    210 
    211             PrintXY (10, 10, NULL, NULL, L"100");
    212           }
    213           Status = GenMemoryTest->Finished (GenMemoryTest);
    214           goto Done;
    215         }
    216 
    217         TestAbort = TRUE;
    218       }
    219     }
    220   } while (Status != EFI_NOT_FOUND);
    221 
    222   Status = GenMemoryTest->Finished (GenMemoryTest);
    223 
    224 Done:
    225   if (!FeaturePcdGet(PcdBootlogoOnlyEnable)) {
    226     UnicodeValueToString (StrTotalMemory, COMMA_TYPE, TotalMemorySize, 0);
    227     if (StrTotalMemory[0] == L',') {
    228       StrTotalMemory++;
    229       StrTotalMemorySize -= sizeof (CHAR16);
    230     }
    231 
    232     TmpStr = HiiGetString (gStringPackHandle, STRING_TOKEN (STR_MEM_TEST_COMPLETED), NULL);
    233     if (TmpStr != NULL) {
    234       StrnCatS (
    235         StrTotalMemory,
    236         StrTotalMemorySize / sizeof (CHAR16),
    237         TmpStr,
    238         StrTotalMemorySize / sizeof (CHAR16) - StrLen (StrTotalMemory) - 1
    239         );
    240       FreePool (TmpStr);
    241     }
    242 
    243     PrintXY (10, 10, NULL, NULL, StrTotalMemory);
    244     BootLogoUpdateProgress (
    245       Foreground,
    246       Background,
    247       StrTotalMemory,
    248       Color,
    249       100,
    250       (UINTN) PreviousValue
    251       );
    252 
    253   } else {
    254     DEBUG ((EFI_D_INFO, "%d bytes of system memory tested OK\r\n", TotalMemorySize));
    255   }
    256 
    257   FreePool (Pos);
    258   return ReturnStatus;
    259 }
    260