From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: mx.groups.io; dkim=missing; spf=pass (domain: hpe.com, ip: 148.163.147.86, mailfrom: prvs=016589022d=gilbert.chen@hpe.com) Received: from mx0a-002e3701.pphosted.com (mx0a-002e3701.pphosted.com [148.163.147.86]) by groups.io with SMTP; Wed, 18 Sep 2019 20:51:47 -0700 Received: from pps.filterd (m0150242.ppops.net [127.0.0.1]) by mx0a-002e3701.pphosted.com (8.16.0.42/8.16.0.42) with SMTP id x8J3pdLt030784 for ; Thu, 19 Sep 2019 03:51:46 GMT Received: from g9t5009.houston.hpe.com (g9t5009.houston.hpe.com [15.241.48.73]) by mx0a-002e3701.pphosted.com with ESMTP id 2v3vapnb9d-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT) for ; Thu, 19 Sep 2019 03:51:46 +0000 Received: from g4t3433.houston.hpecorp.net (g4t3433.houston.hpecorp.net [16.208.49.245]) by g9t5009.houston.hpe.com (Postfix) with ESMTP id 9066A51 for ; Thu, 19 Sep 2019 03:51:45 +0000 (UTC) Received: from ARBDN0VRAE.asiapacific.hpqcorp.net (arbdn0vrae.asiapacific.hpqcorp.net [10.43.41.0]) by g4t3433.houston.hpecorp.net (Postfix) with ESMTP id C10DF45 for ; Thu, 19 Sep 2019 03:51:44 +0000 (UTC) From: "Gilbert Chen" To: devel@edk2.groups.io Subject: [plaforms/devel-riscv-v2 PATCHv2 09/14] U500Pkg/Library: Initial version of PlatformBootManagerLib Date: Thu, 19 Sep 2019 11:51:26 +0800 Message-Id: <20190919035131.4700-10-gilbert.chen@hpe.com> X-Mailer: git-send-email 2.12.0.windows.1 In-Reply-To: <20190919035131.4700-1-gilbert.chen@hpe.com> References: <20190919035131.4700-1-gilbert.chen@hpe.com> MIME-Version: 1.0 X-HPE-SCL: -1 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.70,1.0.8 definitions=2019-09-19_01:2019-09-18,2019-09-19 signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 priorityscore=1501 impostorscore=0 malwarescore=0 suspectscore=15 adultscore=0 mlxlogscore=999 mlxscore=0 lowpriorityscore=0 spamscore=0 phishscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-1908290000 definitions=main-1909190033 X-MIME-Autoconverted: from 8bit to quoted-printable by mx0a-002e3701.pphosted.com id x8J3pdLt030784 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable SiFive RISC-V U500 Platform Boot Manager library. Signed-off-by: Gilbert Chen --- .../Library/PlatformBootManagerLib/MemoryTest.c | 682 +++++++++++++++= ++++++ .../PlatformBootManagerLib/PlatformBootManager.c | 274 +++++++++ .../PlatformBootManagerLib/PlatformBootManager.h | 135 ++++ .../PlatformBootManagerLib.inf | 63 ++ .../Library/PlatformBootManagerLib/PlatformData.c | 49 ++ .../Library/PlatformBootManagerLib/Strings.uni | 28 + 6 files changed, 1231 insertions(+) create mode 100644 Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootMan= agerLib/MemoryTest.c create mode 100644 Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootMan= agerLib/PlatformBootManager.c create mode 100644 Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootMan= agerLib/PlatformBootManager.h create mode 100644 Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootMan= agerLib/PlatformBootManagerLib.inf create mode 100644 Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootMan= agerLib/PlatformData.c create mode 100644 Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootMan= agerLib/Strings.uni diff --git a/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib= /MemoryTest.c b/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManager= Lib/MemoryTest.c new file mode 100644 index 00000000..8c6d89e9 --- /dev/null +++ b/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/Memory= Test.c @@ -0,0 +1,682 @@ +/** @file + Perform the RISC-V platform memory test + +Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All right= s reserved.
+Copyright (c) 2004 - 2015, Intel Corporation. All rights reserved.
+ +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "PlatformBootManager.h" + +EFI_HII_HANDLE gStringPackHandle =3D NULL; +EFI_GUID mPlatformBootManagerStringPackGuid =3D { + 0x154dd51, 0x9079, 0x4a10, { 0x89, 0x5c, 0x9c, 0x7, 0x72, 0x81, 0x57, = 0x88 } + }; +// extern UINT8 BdsDxeStrings[]; + +// +// BDS Platform Functions +// +/** + + Show progress bar with title above it. It only works in Graphics mode. + + @param TitleForeground Foreground color for Title. + @param TitleBackground Background color for Title. + @param Title Title above progress bar. + @param ProgressColor Progress bar color. + @param Progress Progress (0-100) + @param PreviousValue The previous value of the progress. + + @retval EFI_STATUS Success update the progress bar + +**/ +EFI_STATUS +PlatformBootManagerShowProgress ( + IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL TitleForeground, + IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL TitleBackground, + IN CHAR16 *Title, + IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL ProgressColor, + IN UINTN Progress, + IN UINTN PreviousValue + ) +{ + EFI_STATUS Status; + EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput; + EFI_UGA_DRAW_PROTOCOL *UgaDraw; + UINT32 SizeOfX; + UINT32 SizeOfY; + UINT32 ColorDepth; + UINT32 RefreshRate; + EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color; + UINTN BlockHeight; + UINTN BlockWidth; + UINTN BlockNum; + UINTN PosX; + UINTN PosY; + UINTN Index; + + if (Progress > 100) { + return EFI_INVALID_PARAMETER; + } + + UgaDraw =3D NULL; + Status =3D gBS->HandleProtocol ( + gST->ConsoleOutHandle, + &gEfiGraphicsOutputProtocolGuid, + (VOID **) &GraphicsOutput + ); + if (EFI_ERROR (Status) && FeaturePcdGet (PcdUgaConsumeSupport)) { + GraphicsOutput =3D NULL; + + Status =3D gBS->HandleProtocol ( + gST->ConsoleOutHandle, + &gEfiUgaDrawProtocolGuid, + (VOID **) &UgaDraw + ); + } + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + + SizeOfX =3D 0; + SizeOfY =3D 0; + if (GraphicsOutput !=3D NULL) { + SizeOfX =3D GraphicsOutput->Mode->Info->HorizontalResolution; + SizeOfY =3D GraphicsOutput->Mode->Info->VerticalResolution; + } else if (UgaDraw !=3D NULL) { + Status =3D UgaDraw->GetMode ( + UgaDraw, + &SizeOfX, + &SizeOfY, + &ColorDepth, + &RefreshRate + ); + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + } else { + return EFI_UNSUPPORTED; + } + + BlockWidth =3D SizeOfX / 100; + BlockHeight =3D SizeOfY / 50; + + BlockNum =3D Progress; + + PosX =3D 0; + PosY =3D SizeOfY * 48 / 50; + + if (BlockNum =3D=3D 0) { + // + // Clear progress area + // + SetMem (&Color, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0x0); + + if (GraphicsOutput !=3D NULL) { + Status =3D GraphicsOutput->Blt ( + GraphicsOutput, + &Color, + EfiBltVideoFill, + 0, + 0, + 0, + PosY - EFI_GLYPH_HEIGHT - 1, + SizeOfX, + SizeOfY - (PosY - EFI_GLYPH_HEIGHT - 1), + SizeOfX * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXE= L) + ); + } else if (FeaturePcdGet (PcdUgaConsumeSupport)) { + Status =3D UgaDraw->Blt ( + UgaDraw, + (EFI_UGA_PIXEL *) &Color, + EfiUgaVideoFill, + 0, + 0, + 0, + PosY - EFI_GLYPH_HEIGHT - 1, + SizeOfX, + SizeOfY - (PosY - EFI_GLYPH_HEIGHT - 1), + SizeOfX * sizeof (EFI_UGA_PIXEL) + ); + } else { + return EFI_UNSUPPORTED; + } + } + // + // Show progress by drawing blocks + // + for (Index =3D PreviousValue; Index < BlockNum; Index++) { + PosX =3D Index * BlockWidth; + if (GraphicsOutput !=3D NULL) { + Status =3D GraphicsOutput->Blt ( + GraphicsOutput, + &ProgressColor, + EfiBltVideoFill, + 0, + 0, + PosX, + PosY, + BlockWidth - 1, + BlockHeight, + (BlockWidth) * sizeof (EFI_GRAPHICS_OUTPUT_BLT= _PIXEL) + ); + } else if (FeaturePcdGet (PcdUgaConsumeSupport)) { + Status =3D UgaDraw->Blt ( + UgaDraw, + (EFI_UGA_PIXEL *) &ProgressColor, + EfiUgaVideoFill, + 0, + 0, + PosX, + PosY, + BlockWidth - 1, + BlockHeight, + (BlockWidth) * sizeof (EFI_UGA_PIXEL) + ); + } else { + return EFI_UNSUPPORTED; + } + } + + PrintXY ( + (SizeOfX - StrLen (Title) * EFI_GLYPH_WIDTH) / 2, + PosY - EFI_GLYPH_HEIGHT - 1, + &TitleForeground, + &TitleBackground, + Title + ); + + return EFI_SUCCESS; +} + +/** + Perform the memory test base on the memory test intensive level, + and update the memory resource. + + @param Level The memory test intensive level. + + @retval EFI_STATUS Success test all the system memory and update + the memory resource + +**/ +EFI_STATUS +PlatformBootManagerMemoryTest ( + IN EXTENDMEM_COVERAGE_LEVEL Level + ) +{ + EFI_STATUS Status; + EFI_STATUS KeyStatus; + EFI_STATUS InitStatus; + 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[80]; + CHAR16 *StrTotalMemory; + CHAR16 *Pos; + CHAR16 *TmpStr; + EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground; + EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background; + EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color; + UINT32 TempData; + UINTN StrTotalMemorySize; + + ReturnStatus =3D EFI_SUCCESS; + ZeroMem (&Key, sizeof (EFI_INPUT_KEY)); + + StrTotalMemorySize =3D 128; + Pos =3D AllocateZeroPool (StrTotalMemorySize); + ASSERT (Pos !=3D NULL); + + if (gStringPackHandle =3D=3D NULL) { + gStringPackHandle =3D HiiAddPackages ( + &mPlatformBootManagerStringPackGuid, + gImageHandle, + PlatformBootManagerLibStrings, + NULL + ); + ASSERT (gStringPackHandle !=3D NULL); + } + + StrTotalMemory =3D Pos; + + TestedMemorySize =3D 0; + TotalMemorySize =3D 0; + PreviousValue =3D 0; + ErrorOut =3D FALSE; + TestAbort =3D FALSE; + + SetMem (&Foreground, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff); + SetMem (&Background, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0x0); + SetMem (&Color, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff); + + RequireSoftECCInit =3D FALSE; + + Status =3D gBS->LocateProtocol ( + &gEfiGenericMemTestProtocolGuid, + NULL, + (VOID **) &GenMemoryTest + ); + if (EFI_ERROR (Status)) { + FreePool (Pos); + return EFI_SUCCESS; + } + + InitStatus =3D GenMemoryTest->MemoryTestInit ( + GenMemoryTest, + Level, + &RequireSoftECCInit + ); + if (InitStatus =3D=3D EFI_NO_MEDIA) { + // + // The PEI codes also have the relevant memory test code to check th= e 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. + // + FreePool (Pos); + return EFI_SUCCESS; + } + + if (!FeaturePcdGet(PcdBootlogoOnlyEnable)) { + TmpStr =3D HiiGetString (gStringPackHandle, STRING_TOKEN (STR_ESC_TO= _SKIP_MEM_TEST), NULL); + + if (TmpStr !=3D NULL) { + PrintXY (10, 10, NULL, NULL, TmpStr); + FreePool (TmpStr); + } + } else { + DEBUG ((DEBUG_INFO, "Enter memory test.\n")); + } + do { + Status =3D GenMemoryTest->PerformMemoryTest ( + GenMemoryTest, + &TestedMemorySize, + &TotalMemorySize, + &ErrorOut, + TestAbort + ); + if (ErrorOut && (Status =3D=3D EFI_DEVICE_ERROR)) { + TmpStr =3D HiiGetString (gStringPackHandle, STRING_TOKEN (STR_SYST= EM_MEM_ERROR), NULL); + if (TmpStr !=3D NULL) { + PrintXY (10, 10, NULL, NULL, TmpStr); + FreePool (TmpStr); + } + + ASSERT (0); + } + + if (!FeaturePcdGet(PcdBootlogoOnlyEnable)) { + TempData =3D (UINT32) DivU64x32 (TotalMemorySize, 16); + TestPercent =3D (UINTN) DivU64x32 ( + DivU64x32 (MultU64x32 (TestedMemorySize, 1= 00), 16), + TempData + ); + if (TestPercent !=3D PreviousValue) { + UnicodeValueToString (StrPercent, 0, TestPercent, 0); + TmpStr =3D HiiGetString (gStringPackHandle, STRING_TOKEN (STR_ME= MORY_TEST_PERCENT), NULL); + if (TmpStr !=3D NULL) { + // + // TmpStr size is 64, StrPercent is reserved to 16. + // + StrnCatS ( + StrPercent, + sizeof (StrPercent) / sizeof (CHAR16), + TmpStr, + sizeof (StrPercent) / sizeof (CHAR16) - StrLen (StrPercent) = - 1 + ); + PrintXY (10, 10, NULL, NULL, StrPercent); + FreePool (TmpStr); + } + + TmpStr =3D HiiGetString (gStringPackHandle, STRING_TOKEN (STR_PE= RFORM_MEM_TEST), NULL); + if (TmpStr !=3D NULL) { + PlatformBootManagerShowProgress ( + Foreground, + Background, + TmpStr, + Color, + TestPercent, + (UINTN) PreviousValue + ); + FreePool (TmpStr); + } + } + + PreviousValue =3D TestPercent; + } else { + DEBUG ((DEBUG_INFO, "Perform memory test (ESC to skip).\n")); + } + + if (!PcdGetBool (PcdConInConnectOnDemand)) { + KeyStatus =3D gST->ConIn->ReadKeyStroke (gST->ConIn, &Key); + if (!EFI_ERROR (KeyStatus) && (Key.ScanCode =3D=3D SCAN_ESC)) { + if (!RequireSoftECCInit) { + if (!FeaturePcdGet(PcdBootlogoOnlyEnable)) { + TmpStr =3D HiiGetString (gStringPackHandle, STRING_TOKEN (ST= R_PERFORM_MEM_TEST), NULL); + if (TmpStr !=3D NULL) { + PlatformBootManagerShowProgress ( + Foreground, + Background, + TmpStr, + Color, + 100, + (UINTN) PreviousValue + ); + FreePool (TmpStr); + } + + PrintXY (10, 10, NULL, NULL, L"100"); + } + Status =3D GenMemoryTest->Finished (GenMemoryTest); + goto Done; + } + + TestAbort =3D TRUE; + } + } + } while (Status !=3D EFI_NOT_FOUND); + + Status =3D GenMemoryTest->Finished (GenMemoryTest); + +Done: + if (!FeaturePcdGet(PcdBootlogoOnlyEnable)) { + UnicodeValueToString (StrTotalMemory, COMMA_TYPE, TotalMemorySize, 0= ); + if (StrTotalMemory[0] =3D=3D L',') { + StrTotalMemory++; + StrTotalMemorySize -=3D sizeof (CHAR16); + } + + TmpStr =3D HiiGetString (gStringPackHandle, STRING_TOKEN (STR_MEM_TE= ST_COMPLETED), NULL); + if (TmpStr !=3D NULL) { + StrnCatS ( + StrTotalMemory, + StrTotalMemorySize / sizeof (CHAR16), + TmpStr, + StrTotalMemorySize / sizeof (CHAR16) - StrLen (StrTotalMemory) -= 1 + ); + FreePool (TmpStr); + } + + PrintXY (10, 10, NULL, NULL, StrTotalMemory); + PlatformBootManagerShowProgress ( + Foreground, + Background, + StrTotalMemory, + Color, + 100, + (UINTN) PreviousValue + ); + + } else { + DEBUG ((DEBUG_INFO, "%d bytes of system memory tested OK\r\n", Total= MemorySize)); + } + + FreePool (Pos); + return ReturnStatus; +} + +/** + Convert a *.BMP graphics image to a GOP blt buffer. If a NULL Blt buff= er + is passed in a GopBlt buffer will be allocated by this routine. If a G= opBlt + buffer is passed in it will be used if it is big enough. + + @param BmpImage Pointer to BMP file + @param BmpImageSize Number of bytes in BmpImage + @param GopBlt Buffer containing GOP version of BmpImage. + @param GopBltSize Size of GopBlt in bytes. + @param PixelHeight Height of GopBlt/BmpImage in pixels + @param PixelWidth Width of GopBlt/BmpImage in pixels + + @retval EFI_SUCCESS GopBlt and GopBltSize are returned. + @retval EFI_UNSUPPORTED BmpImage is not a valid *.BMP image + @retval EFI_BUFFER_TOO_SMALL The passed in GopBlt buffer is not big e= nough. + GopBltSize will contain the required siz= e. + @retval EFI_OUT_OF_RESOURCES No enough buffer to allocate. + +**/ +EFI_STATUS +PlatformBootManagerConvertBmpToGopBlt ( + IN VOID *BmpImage, + IN UINTN BmpImageSize, + IN OUT VOID **GopBlt, + IN OUT UINTN *GopBltSize, + OUT UINTN *PixelHeight, + OUT UINTN *PixelWidth + ) +{ + UINT8 *Image; + UINT8 *ImageHeader; + BMP_IMAGE_HEADER *BmpHeader; + BMP_COLOR_MAP *BmpColorMap; + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer; + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt; + UINT64 BltBufferSize; + UINTN Index; + UINTN Height; + UINTN Width; + UINTN ImageIndex; + UINT32 DataSizePerLine; + BOOLEAN IsAllocated; + UINT32 ColorMapNum; + + if (sizeof (BMP_IMAGE_HEADER) > BmpImageSize) { + DEBUG ((DEBUG_INFO, "BMP_IMAGE_HEADER) > BmpImageSize.\n")); + return EFI_INVALID_PARAMETER; + } + + BmpHeader =3D (BMP_IMAGE_HEADER *) BmpImage; + + if (BmpHeader->CharB !=3D 'B' || BmpHeader->CharM !=3D 'M') { + DEBUG ((DEBUG_INFO, "(BmpHeader->CharB !=3D 'B' || BmpHeader->CharM = !=3D 'M').\n")); + return EFI_UNSUPPORTED; + } + + // + // Doesn't support compress. + // + if (BmpHeader->CompressionType !=3D 0) { + DEBUG ((DEBUG_INFO, "It's compressed! We dont support.\n")); + return EFI_UNSUPPORTED; + } + + // + // Only support BITMAPINFOHEADER format. + // BITMAPFILEHEADER + BITMAPINFOHEADER =3D BMP_IMAGE_HEADER + // + if (BmpHeader->HeaderSize !=3D sizeof (BMP_IMAGE_HEADER) - OFFSET_OF(B= MP_IMAGE_HEADER, HeaderSize)) { + DEBUG ((DEBUG_INFO, "Only support BITMAPINFOHEADER.\n")); + return EFI_UNSUPPORTED; + } + + // + // The data size in each line must be 4 byte alignment. + // + DataSizePerLine =3D ((BmpHeader->PixelWidth * BmpHeader->BitPerPixel += 31) >> 3) & (~0x3); + BltBufferSize =3D MultU64x32 (DataSizePerLine, BmpHeader->PixelHeight)= ; + if (BltBufferSize > (UINT32) ~0) { + DEBUG ((DEBUG_INFO, "The data size in each line must be 4 byte align= ment.\n")); + return EFI_INVALID_PARAMETER; + } + + if ((BmpHeader->Size !=3D BmpImageSize) || + (BmpHeader->Size < BmpHeader->ImageOffset) || + (BmpHeader->Size - BmpHeader->ImageOffset !=3D BmpHeader->PixelHe= ight * DataSizePerLine)) { + DEBUG ((DEBUG_INFO, "BmpHeader->Size problem.\n")); + return EFI_INVALID_PARAMETER; + } + + // + // Calculate Color Map offset in the image. + // + Image =3D BmpImage; + BmpColorMap =3D (BMP_COLOR_MAP *) (Image + sizeof (BMP_IMAGE_HEADER)); + if (BmpHeader->ImageOffset < sizeof (BMP_IMAGE_HEADER)) { + DEBUG ((DEBUG_INFO, "BmpHeader->ImageOffset < sizeof (BMP_IMAGE_HEAD= ER)\n")); + return EFI_INVALID_PARAMETER; + } + + if (BmpHeader->ImageOffset > sizeof (BMP_IMAGE_HEADER)) { + switch (BmpHeader->BitPerPixel) { + case 1: + ColorMapNum =3D 2; + break; + case 4: + ColorMapNum =3D 16; + break; + case 8: + ColorMapNum =3D 256; + break; + default: + ColorMapNum =3D 0; + break; + } + // + // BMP file may has padding data between the bmp header section and = the bmp data section. + // + if (BmpHeader->ImageOffset - sizeof (BMP_IMAGE_HEADER) < sizeof (BMP= _COLOR_MAP) * ColorMapNum) { + DEBUG ((DEBUG_INFO, "(BmpHeader->ImageOffset - sizeof (BMP_IMAGE_H= EADER) < sizeof (BMP_COLOR_MAP) * ColorMapNum)\n")); + return EFI_INVALID_PARAMETER; + } + } + + // + // Calculate graphics image data address in the image + // + Image =3D ((UINT8 *) BmpImage) + BmpHeader->ImageOffset; + ImageHeader =3D Image; + + // + // Calculate the BltBuffer needed size. + // + BltBufferSize =3D MultU64x32 ((UINT64) BmpHeader->PixelWidth, BmpHeade= r->PixelHeight); + // + // Ensure the BltBufferSize * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) d= oesn't overflow + // + if (BltBufferSize > DivU64x32 ((UINTN) ~0, sizeof (EFI_GRAPHICS_OUTPUT= _BLT_PIXEL))) { + return EFI_UNSUPPORTED; + } + BltBufferSize =3D MultU64x32 (BltBufferSize, sizeof (EFI_GRAPHICS_OUTP= UT_BLT_PIXEL)); + + IsAllocated =3D FALSE; + if (*GopBlt =3D=3D NULL) { + // + // GopBlt is not allocated by caller. + // + *GopBltSize =3D (UINTN) BltBufferSize; + *GopBlt =3D AllocatePool (*GopBltSize); + IsAllocated =3D TRUE; + if (*GopBlt =3D=3D NULL) { + DEBUG ((DEBUG_INFO, "EFI_OUT_OF_RESOURCES\n")); + return EFI_OUT_OF_RESOURCES; + } + } else { + // + // GopBlt has been allocated by caller. + // + if (*GopBltSize < (UINTN) BltBufferSize) { + *GopBltSize =3D (UINTN) BltBufferSize; + DEBUG ((DEBUG_INFO, "EEFI_BUFFER_TOO_SMALL\n")); + return EFI_BUFFER_TOO_SMALL; + } + } + + *PixelWidth =3D BmpHeader->PixelWidth; + *PixelHeight =3D BmpHeader->PixelHeight; + + // + // Convert image from BMP to Blt buffer format + // + BltBuffer =3D *GopBlt; + for (Height =3D 0; Height < BmpHeader->PixelHeight; Height++) { + Blt =3D &BltBuffer[(BmpHeader->PixelHeight - Height - 1) * BmpHeader= ->PixelWidth]; + for (Width =3D 0; Width < BmpHeader->PixelWidth; Width++, Image++, B= lt++) { + switch (BmpHeader->BitPerPixel) { + case 1: + // + // Convert 1-bit (2 colors) BMP to 24-bit color + // + for (Index =3D 0; Index < 8 && Width < BmpHeader->PixelWidth; In= dex++) { + Blt->Red =3D BmpColorMap[((*Image) >> (7 - Index)) & 0x1].R= ed; + Blt->Green =3D BmpColorMap[((*Image) >> (7 - Index)) & 0x1].G= reen; + Blt->Blue =3D BmpColorMap[((*Image) >> (7 - Index)) & 0x1].B= lue; + Blt++; + Width++; + } + + Blt--; + Width--; + break; + + case 4: + // + // Convert 4-bit (16 colors) BMP Palette to 24-bit color + // + Index =3D (*Image) >> 4; + Blt->Red =3D BmpColorMap[Index].Red; + Blt->Green =3D BmpColorMap[Index].Green; + Blt->Blue =3D BmpColorMap[Index].Blue; + if (Width < (BmpHeader->PixelWidth - 1)) { + Blt++; + Width++; + Index =3D (*Image) & 0x0f; + Blt->Red =3D BmpColorMap[Index].Red; + Blt->Green =3D BmpColorMap[Index].Green; + Blt->Blue =3D BmpColorMap[Index].Blue; + } + break; + + case 8: + // + // Convert 8-bit (256 colors) BMP Palette to 24-bit color + // + Blt->Red =3D BmpColorMap[*Image].Red; + Blt->Green =3D BmpColorMap[*Image].Green; + Blt->Blue =3D BmpColorMap[*Image].Blue; + break; + + case 24: + // + // It is 24-bit BMP. + // + Blt->Blue =3D *Image++; + Blt->Green =3D *Image++; + Blt->Red =3D *Image; + break; + + default: + // + // Other bit format BMP is not supported. + // + if (IsAllocated) { + FreePool (*GopBlt); + *GopBlt =3D NULL; + } + DEBUG ((DEBUG_INFO, "Other bit format BMP is not supported.\n"))= ; + return EFI_UNSUPPORTED; + break; + }; + + } + + ImageIndex =3D (UINTN) (Image - ImageHeader); + if ((ImageIndex % 4) !=3D 0) { + // + // Bmp Image starts each row on a 32-bit boundary! + // + Image =3D Image + (4 - (ImageIndex % 4)); + } + } + + return EFI_SUCCESS; +} diff --git a/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib= /PlatformBootManager.c b/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBo= otManagerLib/PlatformBootManager.c new file mode 100644 index 00000000..9ef85089 --- /dev/null +++ b/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/Platfo= rmBootManager.c @@ -0,0 +1,274 @@ +/** @file + This file include all platform action which can be customized + by IBV/OEM. + +Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All right= s reserved.
+Copyright (c) 2015, Intel Corporation. All rights reserved.
+ +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "PlatformBootManager.h" + + +EFI_GUID mUefiShellFileGuid =3D { 0x7C04A583, 0x9E3E, 0x4f1c, {0xAD, 0x6= 5, 0xE0, 0x52, 0x68, 0xD0, 0xB4, 0xD1}}; + +/** + Perform the platform diagnostic, such like test memory. OEM/IBV also + can customize this function to support specific platform diagnostic. + + @param MemoryTestLevel The memory test intensive level + @param QuietBoot Indicate if need to enable the quiet boot + +**/ +VOID +PlatformBootManagerDiagnostics ( + IN EXTENDMEM_COVERAGE_LEVEL MemoryTestLevel, + IN BOOLEAN QuietBoot + ) +{ + EFI_STATUS Status; + + // + // Here we can decide if we need to show + // the diagnostics screen + // Notes: this quiet boot code should be remove + // from the graphic lib + // + if (QuietBoot) { + + // + // Perform system diagnostic + // + Status =3D PlatformBootManagerMemoryTest (MemoryTestLevel); + return; + } + + // + // Perform system diagnostic + // + Status =3D PlatformBootManagerMemoryTest (MemoryTestLevel); +} + +/** + Return the index of the load option in the load option array. + + The function consider two load options are equal when the + OptionType, Attributes, Description, FilePath and OptionalData are equ= al. + + @param Key Pointer to the load option to be found. + @param Array Pointer to the array of load options to be found. + @param Count Number of entries in the Array. + + @retval -1 Key wasn't found in the Array. + @retval 0 ~ Count-1 The index of the Key in the Array. +**/ +INTN +PlatformFindLoadOption ( + IN CONST EFI_BOOT_MANAGER_LOAD_OPTION *Key, + IN CONST EFI_BOOT_MANAGER_LOAD_OPTION *Array, + IN UINTN Count + ) +{ + UINTN Index; + + for (Index =3D 0; Index < Count; Index++) { + if ((Key->OptionType =3D=3D Array[Index].OptionType) && + (Key->Attributes =3D=3D Array[Index].Attributes) && + (StrCmp (Key->Description, Array[Index].Description) =3D=3D 0) &= & + (CompareMem (Key->FilePath, Array[Index].FilePath, GetDevicePath= Size (Key->FilePath)) =3D=3D 0) && + (Key->OptionalDataSize =3D=3D Array[Index].OptionalDataSize) && + (CompareMem (Key->OptionalData, Array[Index].OptionalData, Key->= OptionalDataSize) =3D=3D 0)) { + return (INTN) Index; + } + } + + return -1; +} + +VOID +PlatformRegisterFvBootOption ( + EFI_GUID *FileGuid, + CHAR16 *Description, + UINT32 Attributes + ) +{ + EFI_STATUS Status; + UINTN OptionIndex; + EFI_BOOT_MANAGER_LOAD_OPTION NewOption; + EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions; + UINTN BootOptionCount; + MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FileNode; + EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + + Status =3D gBS->HandleProtocol (gImageHandle, &gEfiLoadedImageProtocol= Guid, (VOID **) &LoadedImage); + ASSERT_EFI_ERROR (Status); + + EfiInitializeFwVolDevicepathNode (&FileNode, FileGuid); + DevicePath =3D AppendDevicePathNode ( + DevicePathFromHandle (LoadedImage->DeviceHandle), + (EFI_DEVICE_PATH_PROTOCOL *) &FileNode + ); + + Status =3D EfiBootManagerInitializeLoadOption ( + &NewOption, + LoadOptionNumberUnassigned, + LoadOptionTypeBoot, + Attributes, + Description, + DevicePath, + NULL, + 0 + ); + if (!EFI_ERROR (Status)) { + BootOptions =3D EfiBootManagerGetLoadOptions (&BootOptionCount, Load= OptionTypeBoot); + + OptionIndex =3D PlatformFindLoadOption (&NewOption, BootOptions, Boo= tOptionCount); + + if (OptionIndex =3D=3D -1) { + Status =3D EfiBootManagerAddLoadOptionVariable (&NewOption, (UINTN= ) -1); + ASSERT_EFI_ERROR (Status); + } + EfiBootManagerFreeLoadOption (&NewOption); + EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount); + } +} + +/** + Do the platform specific action before the console is connected. + + Such as: + Update console variable; + Register new Driver#### or Boot####; + Signal ReadyToLock event. +**/ +VOID +EFIAPI +PlatformBootManagerBeforeConsole ( + VOID + ) +{ + UINTN Index; + EFI_STATUS Status; + EFI_INPUT_KEY Enter; + EFI_INPUT_KEY F2; + EFI_BOOT_MANAGER_LOAD_OPTION BootOption; + + // + // Update the console variables. + // + for (Index =3D 0; gPlatformConsole[Index].DevicePath !=3D NULL; Index+= +) { + DEBUG ((DEBUG_INFO, "Check gPlatformConsole %d\n", Index)); + if ((gPlatformConsole[Index].ConnectType & CONSOLE_IN) =3D=3D CONSOL= E_IN) { + Status =3D EfiBootManagerUpdateConsoleVariable (ConIn, gPlatformCo= nsole[Index].DevicePath, NULL); + DEBUG ((DEBUG_INFO, "CONSOLE_IN variable set %s : %r\n", ConvertDe= vicePathToText (gPlatformConsole[Index].DevicePath, FALSE, FALSE), Status= )); + } + + if ((gPlatformConsole[Index].ConnectType & CONSOLE_OUT) =3D=3D CONSO= LE_OUT) { + Status =3D EfiBootManagerUpdateConsoleVariable (ConOut, gPlatformC= onsole[Index].DevicePath, NULL); + DEBUG ((DEBUG_INFO, "CONSOLE_OUT variable set %s : %r\n", ConvertD= evicePathToText (gPlatformConsole[Index].DevicePath, FALSE, FALSE), Statu= s)); + } + + if ((gPlatformConsole[Index].ConnectType & STD_ERROR) =3D=3D STD_ERR= OR) { + Status =3D EfiBootManagerUpdateConsoleVariable (ErrOut, gPlatformC= onsole[Index].DevicePath, NULL); + DEBUG ((DEBUG_INFO, "STD_ERROR variable set %r", Status)); + } + } + + // + // Register ENTER as CONTINUE key + // + Enter.ScanCode =3D SCAN_NULL; + Enter.UnicodeChar =3D CHAR_CARRIAGE_RETURN; + EfiBootManagerRegisterContinueKeyOption (0, &Enter, NULL); + // + // Map F2 to Boot Manager Menu + // + F2.ScanCode =3D SCAN_F2; + F2.UnicodeChar =3D CHAR_NULL; + EfiBootManagerGetBootManagerMenu (&BootOption); + EfiBootManagerAddKeyOptionVariable (NULL, (UINT16) BootOption.OptionNu= mber, 0, &F2, NULL); + // + // Register UEFI Shell + // + PlatformRegisterFvBootOption (&mUefiShellFileGuid, L"UEFI Shell", LOAD= _OPTION_ACTIVE); +} + +/** + Do the platform specific action after the console is connected. + + Such as: + Dynamically switch output mode; + Signal console ready platform customized event; + Run diagnostics like memory testing; + Connect certain devices; + Dispatch aditional option roms. +**/ +VOID +EFIAPI +PlatformBootManagerAfterConsole ( + VOID + ) +{ + EFI_GRAPHICS_OUTPUT_BLT_PIXEL Black; + EFI_GRAPHICS_OUTPUT_BLT_PIXEL White; + + Black.Blue =3D Black.Green =3D Black.Red =3D Black.Reserved =3D 0; + White.Blue =3D White.Green =3D White.Red =3D White.Reserved =3D 0xFF; + + EfiBootManagerConnectAll (); + EfiBootManagerRefreshAllBootOption (); + + PlatformBootManagerDiagnostics (QUICK, TRUE); + + PrintXY (10, 10, &White, &Black, L"F2 to enter Boot Manager Menu. = "); + PrintXY (10, 30, &White, &Black, L"Enter to boot directly."); +} + +/** + This function is called each second during the boot manager waits the = timeout. + + @param TimeoutRemain The remaining timeout. +**/ +VOID +EFIAPI +PlatformBootManagerWaitCallback ( + UINT16 TimeoutRemain + ) +{ + EFI_GRAPHICS_OUTPUT_BLT_PIXEL Black; + EFI_GRAPHICS_OUTPUT_BLT_PIXEL White; + UINT16 Timeout; + + Timeout =3D PcdGet16 (PcdPlatformBootTimeOut); + + Black.Blue =3D Black.Green =3D Black.Red =3D Black.Reserved =3D 0; + White.Blue =3D White.Green =3D White.Red =3D White.Reserved =3D 0xFF; + + PlatformBootManagerShowProgress ( + White, + Black, + L"Start boot option", + White, + (Timeout - TimeoutRemain) * 100 / Timeout, + 0 + ); +} + +/** + The function is called when no boot option could be launched, + including platform recovery options and options pointing to applicatio= ns + built into firmware volumes. + + If this function returns, BDS attempts to enter an infinite loop. +**/ +VOID +EFIAPI +PlatformBootManagerUnableToBoot ( + VOID + ) +{ + return; +} diff --git a/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib= /PlatformBootManager.h b/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBo= otManagerLib/PlatformBootManager.h new file mode 100644 index 00000000..20d66758 --- /dev/null +++ b/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/Platfo= rmBootManager.h @@ -0,0 +1,135 @@ +/**@file + Head file for BDS Platform specific code + +Copyright (c) 2016, Hewlett Packard Enterprise Development LP. All right= s reserved.
+Copyright (c) 2015, Intel Corporation. All rights reserved.
+ +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _PLATFORM_BOOT_MANAGER_H_ +#define _PLATFORM_BOOT_MANAGER_H_ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +typedef struct { + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + UINTN ConnectType; +} PLATFORM_CONSOLE_CONNECT_ENTRY; + +extern PLATFORM_CONSOLE_CONNECT_ENTRY gPlatformConsole[]; + +#define gEndEntire \ + { \ + END_DEVICE_PATH_TYPE,\ + END_ENTIRE_DEVICE_PATH_SUBTYPE,\ + END_DEVICE_PATH_LENGTH,\ + 0\ + } + +#define CONSOLE_OUT BIT0 +#define CONSOLE_IN BIT1 +#define STD_ERROR BIT2 + +//D3987D4B-971A-435F-8CAF-4967EB627241 +#define EFI_SERIAL_DXE_GUID \ + { 0xD3987D4B, 0x971A, 0x435F, { 0x8C, 0xAF, 0x49, 0x67, 0xEB, 0x62, 0x= 72, 0x41 } } + +typedef struct { + VENDOR_DEVICE_PATH Guid; + UART_DEVICE_PATH Uart; + VENDOR_DEVICE_PATH TerminalType; + EFI_DEVICE_PATH_PROTOCOL End; +} SERIAL_CONSOLE_DEVICE_PATH; + +/** + Use SystemTable Conout to stop video based Simple Text Out consoles fr= om going + to the video device. Put up LogoFile on every video device that is a c= onsole. + + @param[in] LogoFile File name of logo to display on the center of t= he screen. + + @retval EFI_SUCCESS ConsoleControl has been flipped to graphics an= d logo displayed. + @retval EFI_UNSUPPORTED Logo not found + +**/ +EFI_STATUS +PlatformBootManagerEnableQuietBoot ( + IN EFI_GUID *LogoFile + ); + +/** + Use SystemTable Conout to turn on video based Simple Text Out consoles= . The + Simple Text Out screens will now be synced up with all non video outpu= t devices + + @retval EFI_SUCCESS UGA devices are back in text mode and synced u= p. + +**/ +EFI_STATUS +PlatformBootManagerDisableQuietBoot ( + VOID + ); + +/** + Perform the memory test base on the memory test intensive level, + and update the memory resource. + + @param Level The memory test intensive level. + + @retval EFI_STATUS Success test all the system memory and update + the memory resource + +**/ +EFI_STATUS +PlatformBootManagerMemoryTest ( + IN EXTENDMEM_COVERAGE_LEVEL Level + ); + +/** + + Show progress bar with title above it. It only works in Graphics mode. + + + @param TitleForeground Foreground color for Title. + @param TitleBackground Background color for Title. + @param Title Title above progress bar. + @param ProgressColor Progress bar color. + @param Progress Progress (0-100) + @param PreviousValue The previous value of the progress. + + @retval EFI_STATUS Success update the progress bar + +**/ +EFI_STATUS +PlatformBootManagerShowProgress ( + IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL TitleForeground, + IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL TitleBackground, + IN CHAR16 *Title, + IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL ProgressColor, + IN UINTN Progress, + IN UINTN PreviousValue + ); + +#endif // _PLATFORM_BOOT_MANAGER_H diff --git a/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib= /PlatformBootManagerLib.inf b/Platform/RiscV/SiFive/U500Pkg/Library/Platf= ormBootManagerLib/PlatformBootManagerLib.inf new file mode 100644 index 00000000..92c31db4 --- /dev/null +++ b/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/Platfo= rmBootManagerLib.inf @@ -0,0 +1,63 @@ +## @file +# Include all platform action which can be customized by IBV/OEM. +# +# Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All ri= ghts reserved.
+# Copyright (c) 2012 - 2015, Intel Corporation. All rights reserved. +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D PlatformBootManagerLib + FILE_GUID =3D 7DDA7916-6139-4D46-A415-30E854AF3BC= 7 + MODULE_TYPE =3D DXE_DRIVER + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D PlatformBootManagerLib|DXE_DRIVER + +# +# The following information is for reference only and not required by th= e build tools. +# +# VALID_ARCHITECTURES =3D RISCV +# + +[Sources] + PlatformData.c + PlatformBootManager.c + PlatformBootManager.h + MemoryTest.c + Strings.uni + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + Platform/RiscV/RiscVPlatformPkg.dec + +[LibraryClasses] + BaseLib + UefiBootServicesTableLib + UefiRuntimeServicesTableLib + UefiLib + UefiBootManagerLib + PcdLib + DxeServicesLib + MemoryAllocationLib + DevicePathLib + HiiLib + PrintLib + +[Guids] + +[Protocols] + gEfiGenericMemTestProtocolGuid ## CONSUMES + gEfiGraphicsOutputProtocolGuid ## CONSUMES + gEfiUgaDrawProtocolGuid ## CONSUMES + +[Pcd] + gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut + gEfiMdeModulePkgTokenSpaceGuid.PcdConOutRow + gEfiMdeModulePkgTokenSpaceGuid.PcdConOutColumn + gEfiMdePkgTokenSpaceGuid.PcdUgaConsumeSupport + gEfiMdeModulePkgTokenSpaceGuid.PcdConInConnectOnDemand + gUefiRiscVPlatformPkgTokenSpaceGuid.PcdBootlogoOnlyEnable diff --git a/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib= /PlatformData.c b/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManag= erLib/PlatformData.c new file mode 100644 index 00000000..3208051e --- /dev/null +++ b/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/Platfo= rmData.c @@ -0,0 +1,49 @@ +/**@file + Defined the platform specific device path which will be filled to + ConIn/ConOut variables. + +Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All right= s reserved.
+Copyright (c) 2015, Intel Corporation. All rights reserved.
+ +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "PlatformBootManager.h" + +// +// Platform specific serial device path +// +SERIAL_CONSOLE_DEVICE_PATH gSerialConsoleDevicePath0 =3D { + { + { HARDWARE_DEVICE_PATH, HW_VENDOR_DP, { sizeof (VENDOR_DEVICE_PATH),= 0} }, + EFI_SERIAL_DXE_GUID // Use the driver's GUID + }, + { + { MESSAGING_DEVICE_PATH, MSG_UART_DP, { sizeof (UART_DEVICE_PATH), 0= } }, + 0, // Reserved + 115200, // BaudRate + 8, // DataBits + 1, // Parity + 1 // StopBits + }, + { + { MESSAGING_DEVICE_PATH, MSG_VENDOR_DP, { sizeof (VENDOR_DEVICE_PATH= ), 0} }, + DEVICE_PATH_MESSAGING_PC_ANSI + }, + { END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE, { sizeof (EFI_= DEVICE_PATH_PROTOCOL), 0 } } +}; + +// +// Predefined platform default console device path +// +PLATFORM_CONSOLE_CONNECT_ENTRY gPlatformConsole[] =3D { + { + (EFI_DEVICE_PATH_PROTOCOL *) &gSerialConsoleDevicePath0, + CONSOLE_OUT | CONSOLE_IN + }, + { + NULL, + 0 + } +}; diff --git a/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib= /Strings.uni b/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerL= ib/Strings.uni new file mode 100644 index 00000000..73bf5d51 --- /dev/null +++ b/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/String= s.uni @@ -0,0 +1,28 @@ +///** @file +// +// String definitions for PlatformBootManagerLib. +// +// Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All r= ights reserved.
+// Copyright (c) 2004 - 2015, Intel Corporation. All rights reserved. +// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +//**/ + +/=3D# + +#langdef en-US "English" +#langdef fr-FR "Fran=C3=A7ais" + +#string STR_PERFORM_MEM_TEST #language en-US "Perform memory = test (ESC to skip)" + #language fr-FR "Ex=C3=A9cute l'= examen de m=C3=A9moire (ESC pour sauter)" +#string STR_MEMORY_TEST_PERCENT #language en-US "% of the system= memory tested OK" + #language fr-FR "% de la m=C3=A9= moire de syst=C3=A8me essay=C3=A9e D'ACCORD" +#string STR_ESC_TO_SKIP_MEM_TEST #language en-US "Press ESC key t= o skip memory test" + #language fr-FR "Appuie sur ESC = sauter examen de m=C3=A9moire" +#string STR_MEM_TEST_COMPLETED #language en-US " bytes of syste= m memory tested OK\r\n" + #language fr-FR "octets dela m=C3= =A9moire de syst=C3=A8me essay=C3=A9e D'ACCORD\r\n" +#string STR_SYSTEM_MEM_ERROR #language en-US "System encounte= rs memory errors" + #language fr-FR "le Syst=C3=A8me= rencontre les erreurs de m=C3=A9moire" +#string STR_START_BOOT_OPTION #language en-US "Start boot opti= on" + #language fr-FR "l'option de bot= te de D=C3=A9but" --=20 2.12.0.windows.1