[edk2-devel] [plaforms/devel-riscv-v2 PATCHv2 09/14] U500Pkg/Library: Initial version of PlatformBootManagerLib

Gilbert Chen posted 14 patches 6 years, 4 months ago
[edk2-devel] [plaforms/devel-riscv-v2 PATCHv2 09/14] U500Pkg/Library: Initial version of PlatformBootManagerLib
Posted by Gilbert Chen 6 years, 4 months ago
SiFive RISC-V U500 Platform Boot Manager library.

Signed-off-by: Gilbert Chen <gilbert.chen@hpe.com>
---
 .../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/PlatformBootManagerLib/MemoryTest.c
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/PlatformBootManager.c
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/PlatformBootManager.h
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/PlatformData.c
 create mode 100644 Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/Strings.uni

diff --git a/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/MemoryTest.c b/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/MemoryTest.c
new file mode 100644
index 00000000..8c6d89e9
--- /dev/null
+++ b/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/MemoryTest.c
@@ -0,0 +1,682 @@
+/** @file
+  Perform the RISC-V platform memory test
+
+Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+Copyright (c) 2004 - 2015, Intel Corporation. All rights reserved.<BR>
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "PlatformBootManager.h"
+
+EFI_HII_HANDLE gStringPackHandle = NULL;
+EFI_GUID       mPlatformBootManagerStringPackGuid = {
+  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 = NULL;
+  Status = gBS->HandleProtocol (
+                  gST->ConsoleOutHandle,
+                  &gEfiGraphicsOutputProtocolGuid,
+                  (VOID **) &GraphicsOutput
+                  );
+  if (EFI_ERROR (Status) && FeaturePcdGet (PcdUgaConsumeSupport)) {
+    GraphicsOutput = NULL;
+
+    Status = gBS->HandleProtocol (
+                    gST->ConsoleOutHandle,
+                    &gEfiUgaDrawProtocolGuid,
+                    (VOID **) &UgaDraw
+                    );
+  }
+  if (EFI_ERROR (Status)) {
+    return EFI_UNSUPPORTED;
+  }
+
+  SizeOfX = 0;
+  SizeOfY = 0;
+  if (GraphicsOutput != NULL) {
+    SizeOfX = GraphicsOutput->Mode->Info->HorizontalResolution;
+    SizeOfY = GraphicsOutput->Mode->Info->VerticalResolution;
+  } else if (UgaDraw != NULL) {
+    Status = UgaDraw->GetMode (
+                        UgaDraw,
+                        &SizeOfX,
+                        &SizeOfY,
+                        &ColorDepth,
+                        &RefreshRate
+                        );
+    if (EFI_ERROR (Status)) {
+      return EFI_UNSUPPORTED;
+    }
+  } else {
+    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_GRAPHICS_OUTPUT_BLT_PIXEL), 0x0);
+
+    if (GraphicsOutput != NULL) {
+      Status = 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_PIXEL)
+                          );
+    } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {
+      Status = 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 = PreviousValue; Index < BlockNum; Index++) {
+    PosX = Index * BlockWidth;
+    if (GraphicsOutput != NULL) {
+      Status = GraphicsOutput->Blt (
+                          GraphicsOutput,
+                          &ProgressColor,
+                          EfiBltVideoFill,
+                          0,
+                          0,
+                          PosX,
+                          PosY,
+                          BlockWidth - 1,
+                          BlockHeight,
+                          (BlockWidth) * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
+                          );
+    } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {
+      Status = 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 = EFI_SUCCESS;
+  ZeroMem (&Key, sizeof (EFI_INPUT_KEY));
+
+  StrTotalMemorySize = 128;
+  Pos = AllocateZeroPool (StrTotalMemorySize);
+  ASSERT (Pos != NULL);
+
+  if (gStringPackHandle == NULL) {
+    gStringPackHandle = HiiAddPackages (
+                           &mPlatformBootManagerStringPackGuid,
+                           gImageHandle,
+                           PlatformBootManagerLibStrings,
+                           NULL
+                           );
+    ASSERT (gStringPackHandle != NULL);
+  }
+
+  StrTotalMemory    = Pos;
+
+  TestedMemorySize  = 0;
+  TotalMemorySize   = 0;
+  PreviousValue     = 0;
+  ErrorOut          = FALSE;
+  TestAbort         = 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 = FALSE;
+
+  Status = gBS->LocateProtocol (
+                  &gEfiGenericMemTestProtocolGuid,
+                  NULL,
+                  (VOID **) &GenMemoryTest
+                  );
+  if (EFI_ERROR (Status)) {
+    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.
+    //
+    FreePool (Pos);
+    return EFI_SUCCESS;
+  }
+
+  if (!FeaturePcdGet(PcdBootlogoOnlyEnable)) {
+    TmpStr = HiiGetString (gStringPackHandle, STRING_TOKEN (STR_ESC_TO_SKIP_MEM_TEST), NULL);
+
+    if (TmpStr != NULL) {
+      PrintXY (10, 10, NULL, NULL, TmpStr);
+      FreePool (TmpStr);
+    }
+  } else {
+    DEBUG ((DEBUG_INFO, "Enter memory test.\n"));
+  }
+  do {
+    Status = GenMemoryTest->PerformMemoryTest (
+                              GenMemoryTest,
+                              &TestedMemorySize,
+                              &TotalMemorySize,
+                              &ErrorOut,
+                              TestAbort
+                              );
+    if (ErrorOut && (Status == EFI_DEVICE_ERROR)) {
+      TmpStr = HiiGetString (gStringPackHandle, STRING_TOKEN (STR_SYSTEM_MEM_ERROR), NULL);
+      if (TmpStr != NULL) {
+        PrintXY (10, 10, NULL, NULL, TmpStr);
+        FreePool (TmpStr);
+      }
+
+      ASSERT (0);
+    }
+
+    if (!FeaturePcdGet(PcdBootlogoOnlyEnable)) {
+      TempData = (UINT32) DivU64x32 (TotalMemorySize, 16);
+      TestPercent = (UINTN) DivU64x32 (
+                              DivU64x32 (MultU64x32 (TestedMemorySize, 100), 16),
+                              TempData
+                              );
+      if (TestPercent != PreviousValue) {
+        UnicodeValueToString (StrPercent, 0, TestPercent, 0);
+        TmpStr = HiiGetString (gStringPackHandle, STRING_TOKEN (STR_MEMORY_TEST_PERCENT), NULL);
+        if (TmpStr != 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 = HiiGetString (gStringPackHandle, STRING_TOKEN (STR_PERFORM_MEM_TEST), NULL);
+        if (TmpStr != NULL) {
+          PlatformBootManagerShowProgress (
+            Foreground,
+            Background,
+            TmpStr,
+            Color,
+            TestPercent,
+            (UINTN) PreviousValue
+            );
+          FreePool (TmpStr);
+        }
+      }
+
+      PreviousValue = TestPercent;
+    } else {
+      DEBUG ((DEBUG_INFO, "Perform memory test (ESC to skip).\n"));
+    }
+
+    if (!PcdGetBool (PcdConInConnectOnDemand)) {
+      KeyStatus     = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
+      if (!EFI_ERROR (KeyStatus) && (Key.ScanCode == SCAN_ESC)) {
+        if (!RequireSoftECCInit) {
+          if (!FeaturePcdGet(PcdBootlogoOnlyEnable)) {
+            TmpStr = HiiGetString (gStringPackHandle, STRING_TOKEN (STR_PERFORM_MEM_TEST), NULL);
+            if (TmpStr != NULL) {
+              PlatformBootManagerShowProgress (
+                Foreground,
+                Background,
+                TmpStr,
+                Color,
+                100,
+                (UINTN) PreviousValue
+                );
+              FreePool (TmpStr);
+            }
+
+            PrintXY (10, 10, NULL, NULL, L"100");
+          }
+          Status = GenMemoryTest->Finished (GenMemoryTest);
+          goto Done;
+        }
+
+        TestAbort = TRUE;
+      }
+    }
+  } while (Status != EFI_NOT_FOUND);
+
+  Status = GenMemoryTest->Finished (GenMemoryTest);
+
+Done:
+  if (!FeaturePcdGet(PcdBootlogoOnlyEnable)) {
+    UnicodeValueToString (StrTotalMemory, COMMA_TYPE, TotalMemorySize, 0);
+    if (StrTotalMemory[0] == L',') {
+      StrTotalMemory++;
+      StrTotalMemorySize -= sizeof (CHAR16);
+    }
+
+    TmpStr = HiiGetString (gStringPackHandle, STRING_TOKEN (STR_MEM_TEST_COMPLETED), NULL);
+    if (TmpStr != 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", TotalMemorySize));
+  }
+
+  FreePool (Pos);
+  return ReturnStatus;
+}
+
+/**
+  Convert a *.BMP graphics image to a GOP blt buffer. If a NULL Blt buffer
+  is passed in a GopBlt buffer will be allocated by this routine. If a GopBlt
+  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 enough.
+                                GopBltSize will contain the required size.
+  @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 = (BMP_IMAGE_HEADER *) BmpImage;
+
+  if (BmpHeader->CharB != 'B' || BmpHeader->CharM != 'M') {
+    DEBUG ((DEBUG_INFO, "(BmpHeader->CharB != 'B' || BmpHeader->CharM != 'M').\n"));
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // Doesn't support compress.
+  //
+  if (BmpHeader->CompressionType != 0) {
+    DEBUG ((DEBUG_INFO, "It's compressed! We dont support.\n"));
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // Only support BITMAPINFOHEADER format.
+  // BITMAPFILEHEADER + BITMAPINFOHEADER = BMP_IMAGE_HEADER
+  //
+  if (BmpHeader->HeaderSize != sizeof (BMP_IMAGE_HEADER) - OFFSET_OF(BMP_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 = ((BmpHeader->PixelWidth * BmpHeader->BitPerPixel + 31) >> 3) & (~0x3);
+  BltBufferSize = MultU64x32 (DataSizePerLine, BmpHeader->PixelHeight);
+  if (BltBufferSize > (UINT32) ~0) {
+    DEBUG ((DEBUG_INFO, "The data size in each line must be 4 byte alignment.\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if ((BmpHeader->Size != BmpImageSize) ||
+      (BmpHeader->Size < BmpHeader->ImageOffset) ||
+      (BmpHeader->Size - BmpHeader->ImageOffset !=  BmpHeader->PixelHeight * DataSizePerLine)) {
+    DEBUG ((DEBUG_INFO, "BmpHeader->Size problem.\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Calculate Color Map offset in the image.
+  //
+  Image       = BmpImage;
+  BmpColorMap = (BMP_COLOR_MAP *) (Image + sizeof (BMP_IMAGE_HEADER));
+  if (BmpHeader->ImageOffset < sizeof (BMP_IMAGE_HEADER)) {
+    DEBUG ((DEBUG_INFO, "BmpHeader->ImageOffset < sizeof (BMP_IMAGE_HEADER)\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (BmpHeader->ImageOffset > sizeof (BMP_IMAGE_HEADER)) {
+    switch (BmpHeader->BitPerPixel) {
+      case 1:
+        ColorMapNum = 2;
+        break;
+      case 4:
+        ColorMapNum = 16;
+        break;
+      case 8:
+        ColorMapNum = 256;
+        break;
+      default:
+        ColorMapNum = 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_HEADER) < sizeof (BMP_COLOR_MAP) * ColorMapNum)\n"));
+      return EFI_INVALID_PARAMETER;
+    }
+  }
+
+  //
+  // Calculate graphics image data address in the image
+  //
+  Image         = ((UINT8 *) BmpImage) + BmpHeader->ImageOffset;
+  ImageHeader   = Image;
+
+  //
+  // Calculate the BltBuffer needed size.
+  //
+  BltBufferSize = MultU64x32 ((UINT64) BmpHeader->PixelWidth, BmpHeader->PixelHeight);
+  //
+  // Ensure the BltBufferSize * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) doesn't overflow
+  //
+  if (BltBufferSize > DivU64x32 ((UINTN) ~0, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL))) {
+    return EFI_UNSUPPORTED;
+  }
+  BltBufferSize = MultU64x32 (BltBufferSize, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
+
+  IsAllocated   = FALSE;
+  if (*GopBlt == NULL) {
+    //
+    // GopBlt is not allocated by caller.
+    //
+    *GopBltSize = (UINTN) BltBufferSize;
+    *GopBlt     = AllocatePool (*GopBltSize);
+    IsAllocated = TRUE;
+    if (*GopBlt == 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 = (UINTN) BltBufferSize;
+      DEBUG ((DEBUG_INFO, "EEFI_BUFFER_TOO_SMALL\n"));
+      return EFI_BUFFER_TOO_SMALL;
+    }
+  }
+
+  *PixelWidth   = BmpHeader->PixelWidth;
+  *PixelHeight  = BmpHeader->PixelHeight;
+
+  //
+  // Convert image from BMP to Blt buffer format
+  //
+  BltBuffer = *GopBlt;
+  for (Height = 0; Height < BmpHeader->PixelHeight; Height++) {
+    Blt = &BltBuffer[(BmpHeader->PixelHeight - Height - 1) * BmpHeader->PixelWidth];
+    for (Width = 0; Width < BmpHeader->PixelWidth; Width++, Image++, Blt++) {
+      switch (BmpHeader->BitPerPixel) {
+      case 1:
+        //
+        // Convert 1-bit (2 colors) BMP to 24-bit color
+        //
+        for (Index = 0; Index < 8 && Width < BmpHeader->PixelWidth; Index++) {
+          Blt->Red    = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Red;
+          Blt->Green  = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Green;
+          Blt->Blue   = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Blue;
+          Blt++;
+          Width++;
+        }
+
+        Blt--;
+        Width--;
+        break;
+
+      case 4:
+        //
+        // Convert 4-bit (16 colors) BMP Palette to 24-bit color
+        //
+        Index       = (*Image) >> 4;
+        Blt->Red    = BmpColorMap[Index].Red;
+        Blt->Green  = BmpColorMap[Index].Green;
+        Blt->Blue   = BmpColorMap[Index].Blue;
+        if (Width < (BmpHeader->PixelWidth - 1)) {
+          Blt++;
+          Width++;
+          Index       = (*Image) & 0x0f;
+          Blt->Red    = BmpColorMap[Index].Red;
+          Blt->Green  = BmpColorMap[Index].Green;
+          Blt->Blue   = BmpColorMap[Index].Blue;
+        }
+        break;
+
+      case 8:
+        //
+        // Convert 8-bit (256 colors) BMP Palette to 24-bit color
+        //
+        Blt->Red    = BmpColorMap[*Image].Red;
+        Blt->Green  = BmpColorMap[*Image].Green;
+        Blt->Blue   = BmpColorMap[*Image].Blue;
+        break;
+
+      case 24:
+        //
+        // It is 24-bit BMP.
+        //
+        Blt->Blue   = *Image++;
+        Blt->Green  = *Image++;
+        Blt->Red    = *Image;
+        break;
+
+      default:
+        //
+        // Other bit format BMP is not supported.
+        //
+        if (IsAllocated) {
+          FreePool (*GopBlt);
+          *GopBlt = NULL;
+        }
+        DEBUG ((DEBUG_INFO, "Other bit format BMP is not supported.\n"));
+        return EFI_UNSUPPORTED;
+        break;
+      };
+
+    }
+
+    ImageIndex = (UINTN) (Image - ImageHeader);
+    if ((ImageIndex % 4) != 0) {
+      //
+      // Bmp Image starts each row on a 32-bit boundary!
+      //
+      Image = Image + (4 - (ImageIndex % 4));
+    }
+  }
+
+  return EFI_SUCCESS;
+}
diff --git a/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/PlatformBootManager.c b/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/PlatformBootManager.c
new file mode 100644
index 00000000..9ef85089
--- /dev/null
+++ b/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/PlatformBootManager.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 rights reserved.<BR>
+Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "PlatformBootManager.h"
+
+
+EFI_GUID mUefiShellFileGuid = { 0x7C04A583, 0x9E3E, 0x4f1c, {0xAD, 0x65, 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 = PlatformBootManagerMemoryTest (MemoryTestLevel);
+    return;
+  }
+
+  //
+  // Perform system diagnostic
+  //
+  Status = 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 equal.
+
+  @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 = 0; Index < Count; Index++) {
+    if ((Key->OptionType == Array[Index].OptionType) &&
+        (Key->Attributes == Array[Index].Attributes) &&
+        (StrCmp (Key->Description, Array[Index].Description) == 0) &&
+        (CompareMem (Key->FilePath, Array[Index].FilePath, GetDevicePathSize (Key->FilePath)) == 0) &&
+        (Key->OptionalDataSize == Array[Index].OptionalDataSize) &&
+        (CompareMem (Key->OptionalData, Array[Index].OptionalData, Key->OptionalDataSize) == 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 = gBS->HandleProtocol (gImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **) &LoadedImage);
+  ASSERT_EFI_ERROR (Status);
+
+  EfiInitializeFwVolDevicepathNode (&FileNode, FileGuid);
+  DevicePath = AppendDevicePathNode (
+                 DevicePathFromHandle (LoadedImage->DeviceHandle),
+                 (EFI_DEVICE_PATH_PROTOCOL *) &FileNode
+                 );
+
+  Status = EfiBootManagerInitializeLoadOption (
+             &NewOption,
+             LoadOptionNumberUnassigned,
+             LoadOptionTypeBoot,
+             Attributes,
+             Description,
+             DevicePath,
+             NULL,
+             0
+             );
+  if (!EFI_ERROR (Status)) {
+    BootOptions = EfiBootManagerGetLoadOptions (&BootOptionCount, LoadOptionTypeBoot);
+
+    OptionIndex = PlatformFindLoadOption (&NewOption, BootOptions, BootOptionCount);
+
+    if (OptionIndex == -1) {
+      Status = 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 = 0; gPlatformConsole[Index].DevicePath != NULL; Index++) {
+    DEBUG ((DEBUG_INFO, "Check gPlatformConsole %d\n", Index));
+    if ((gPlatformConsole[Index].ConnectType & CONSOLE_IN) == CONSOLE_IN) {
+      Status = EfiBootManagerUpdateConsoleVariable (ConIn, gPlatformConsole[Index].DevicePath, NULL);
+      DEBUG ((DEBUG_INFO, "CONSOLE_IN variable set %s : %r\n", ConvertDevicePathToText (gPlatformConsole[Index].DevicePath, FALSE, FALSE), Status));
+    }
+
+    if ((gPlatformConsole[Index].ConnectType & CONSOLE_OUT) == CONSOLE_OUT) {
+      Status = EfiBootManagerUpdateConsoleVariable (ConOut, gPlatformConsole[Index].DevicePath, NULL);
+      DEBUG ((DEBUG_INFO, "CONSOLE_OUT variable set %s : %r\n", ConvertDevicePathToText (gPlatformConsole[Index].DevicePath, FALSE, FALSE), Status));
+    }
+
+    if ((gPlatformConsole[Index].ConnectType & STD_ERROR) == STD_ERROR) {
+      Status = EfiBootManagerUpdateConsoleVariable (ErrOut, gPlatformConsole[Index].DevicePath, NULL);
+      DEBUG ((DEBUG_INFO, "STD_ERROR variable set %r", Status));
+    }
+  }
+
+  //
+  // Register ENTER as CONTINUE key
+  //
+  Enter.ScanCode    = SCAN_NULL;
+  Enter.UnicodeChar = CHAR_CARRIAGE_RETURN;
+  EfiBootManagerRegisterContinueKeyOption (0, &Enter, NULL);
+  //
+  // Map F2 to Boot Manager Menu
+  //
+  F2.ScanCode    = SCAN_F2;
+  F2.UnicodeChar = CHAR_NULL;
+  EfiBootManagerGetBootManagerMenu (&BootOption);
+  EfiBootManagerAddKeyOptionVariable (NULL, (UINT16) BootOption.OptionNumber, 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 = Black.Green = Black.Red = Black.Reserved = 0;
+  White.Blue = White.Green = White.Red = White.Reserved = 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 = PcdGet16 (PcdPlatformBootTimeOut);
+
+  Black.Blue = Black.Green = Black.Red = Black.Reserved = 0;
+  White.Blue = White.Green = White.Red = White.Reserved = 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 applications
+  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/PlatformBootManagerLib/PlatformBootManager.h
new file mode 100644
index 00000000..20d66758
--- /dev/null
+++ b/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/PlatformBootManager.h
@@ -0,0 +1,135 @@
+/**@file
+   Head file for BDS Platform specific code
+
+Copyright (c) 2016, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _PLATFORM_BOOT_MANAGER_H_
+#define _PLATFORM_BOOT_MANAGER_H_
+
+#include <PiDxe.h>
+#include <IndustryStandard/Bmp.h>
+#include <Protocol/GenericMemoryTest.h>
+#include <Protocol/LoadedImage.h>
+#include <Protocol/UgaDraw.h>
+#include <Protocol/GraphicsOutput.h>
+#include <Protocol/BootLogo.h>
+#include <Protocol/DevicePath.h>
+
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/BaseLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiBootManagerLib.h>
+#include <Library/PcdLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/HiiLib.h>
+#include <Library/PrintLib.h>
+#include <Library/DxeServicesLib.h>
+
+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, 0x72, 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 from going
+  to the video device. Put up LogoFile on every video device that is a console.
+
+  @param[in]  LogoFile   File name of logo to display on the center of the screen.
+
+  @retval EFI_SUCCESS     ConsoleControl has been flipped to graphics and 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 output devices
+
+  @retval EFI_SUCCESS     UGA devices are back in text mode and synced up.
+
+**/
+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/PlatformBootManagerLib/PlatformBootManagerLib.inf
new file mode 100644
index 00000000..92c31db4
--- /dev/null
+++ b/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.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 rights reserved.<BR>
+#  Copyright (c) 2012 - 2015, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = PlatformBootManagerLib
+  FILE_GUID                      = 7DDA7916-6139-4D46-A415-30E854AF3BC7
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = PlatformBootManagerLib|DXE_DRIVER
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = 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/PlatformBootManagerLib/PlatformData.c
new file mode 100644
index 00000000..3208051e
--- /dev/null
+++ b/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/PlatformData.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 rights reserved.<BR>
+Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "PlatformBootManager.h"
+
+//
+// Platform specific serial device path
+//
+SERIAL_CONSOLE_DEVICE_PATH gSerialConsoleDevicePath0 = {
+  {
+    { 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[] = {
+  {
+    (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/PlatformBootManagerLib/Strings.uni
new file mode 100644
index 00000000..73bf5d51
--- /dev/null
+++ b/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/Strings.uni
@@ -0,0 +1,28 @@
+///** @file
+//
+//    String definitions for PlatformBootManagerLib.
+//
+//  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+//  Copyright (c) 2004 - 2015, Intel Corporation. All rights reserved.<BR>
+//
+//  SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+//**/
+
+/=#
+
+#langdef   en-US "English"
+#langdef   fr-FR "Français"
+
+#string STR_PERFORM_MEM_TEST           #language en-US  "Perform memory test (ESC to skip)"
+                                       #language fr-FR  "Exécute l'examen de mémoire (ESC pour sauter)"
+#string STR_MEMORY_TEST_PERCENT        #language en-US  "% of the system memory tested OK"
+                                       #language fr-FR  "% de la mémoire de système essayée D'ACCORD"
+#string STR_ESC_TO_SKIP_MEM_TEST       #language en-US  "Press ESC key to skip memory test"
+                                       #language fr-FR  "Appuie sur ESC sauter examen de mémoire"
+#string STR_MEM_TEST_COMPLETED         #language en-US  " bytes of system memory tested OK\r\n"
+                                       #language fr-FR  "octets dela mémoire de système essayée D'ACCORD\r\n"
+#string STR_SYSTEM_MEM_ERROR           #language en-US  "System encounters memory errors"
+                                       #language fr-FR  "le Système rencontre les erreurs de mémoire"
+#string STR_START_BOOT_OPTION          #language en-US  "Start boot option"
+                                       #language fr-FR  "l'option de botte de Début"
-- 
2.12.0.windows.1


-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.

View/Reply Online (#47542): https://edk2.groups.io/g/devel/message/47542
Mute This Topic: https://groups.io/mt/34196357/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub  [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-

Re: [edk2-devel] [plaforms/devel-riscv-v2 PATCHv2 09/14] U500Pkg/Library: Initial version of PlatformBootManagerLib
Posted by Leif Lindholm 6 years, 4 months ago
On Thu, Sep 19, 2019 at 11:51:26AM +0800, Gilbert Chen wrote:
> SiFive RISC-V U500 Platform Boot Manager library.

First of all, let me say that I think before upstreaming to master,
you ought to look into merging PlatformBootManagerLibs for all Risc-V
platforms. Like we have for *most* ARM/AARCH64 platforms with
ArmPkg/Library/PlatformBootManagerLib/.

(Longer-term we should merge them all together into a single one.)

> Signed-off-by: Gilbert Chen <gilbert.chen@hpe.com>
> ---
>  .../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/PlatformBootManagerLib/MemoryTest.c
>  create mode 100644 Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/PlatformBootManager.c
>  create mode 100644 Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/PlatformBootManager.h
>  create mode 100644 Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
>  create mode 100644 Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/PlatformData.c
>  create mode 100644 Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/Strings.uni
> 
> diff --git a/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/MemoryTest.c b/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/MemoryTest.c
> new file mode 100644
> index 00000000..8c6d89e9
> --- /dev/null
> +++ b/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/MemoryTest.c

Why build a MemoryTest into the PlatformBootManagerLib?

> @@ -0,0 +1,682 @@
> +/** @file
> +  Perform the RISC-V platform memory test
> +
> +Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
> +Copyright (c) 2004 - 2015, Intel Corporation. All rights reserved.<BR>
> +
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "PlatformBootManager.h"
> +
> +EFI_HII_HANDLE gStringPackHandle = NULL;
> +EFI_GUID       mPlatformBootManagerStringPackGuid = {
> +  0x154dd51, 0x9079, 0x4a10, { 0x89, 0x5c, 0x9c, 0x7, 0x72, 0x81, 0x57, 0x88 }
> +  };
> +// extern UINT8  BdsDxeStrings[];

No need to keep commented-out code in.

> +
> +//
> +// 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 (

I'm not a super fan of how this file integrates a custom memory test
with a direct (copy) graphical progress indicator. There are both
common memory test and common progress indicators - please use those
instead. And improve them if they are currently insufficient for your
needs.

> diff --git a/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/PlatformBootManager.c b/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/PlatformBootManager.c
> new file mode 100644
> index 00000000..9ef85089
> --- /dev/null
> +++ b/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/PlatformBootManager.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 rights reserved.<BR>
> +Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
> +
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "PlatformBootManager.h"
> +
> +
> +EFI_GUID mUefiShellFileGuid = { 0x7C04A583, 0x9E3E, 0x4f1c, {0xAD, 0x65, 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 = PlatformBootManagerMemoryTest (MemoryTestLevel);
> +    return;
> +  }
> +
> +  //
> +  // Perform system diagnostic
> +  //
> +  Status = 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 equal.
> +
> +  @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 = 0; Index < Count; Index++) {
> +    if ((Key->OptionType == Array[Index].OptionType) &&
> +        (Key->Attributes == Array[Index].Attributes) &&
> +        (StrCmp (Key->Description, Array[Index].Description) == 0) &&
> +        (CompareMem (Key->FilePath, Array[Index].FilePath, GetDevicePathSize (Key->FilePath)) == 0) &&
> +        (Key->OptionalDataSize == Array[Index].OptionalDataSize) &&
> +        (CompareMem (Key->OptionalData, Array[Index].OptionalData, Key->OptionalDataSize) == 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 = gBS->HandleProtocol (gImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **) &LoadedImage);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  EfiInitializeFwVolDevicepathNode (&FileNode, FileGuid);
> +  DevicePath = AppendDevicePathNode (
> +                 DevicePathFromHandle (LoadedImage->DeviceHandle),
> +                 (EFI_DEVICE_PATH_PROTOCOL *) &FileNode
> +                 );
> +
> +  Status = EfiBootManagerInitializeLoadOption (
> +             &NewOption,
> +             LoadOptionNumberUnassigned,
> +             LoadOptionTypeBoot,
> +             Attributes,
> +             Description,
> +             DevicePath,
> +             NULL,
> +             0
> +             );
> +  if (!EFI_ERROR (Status)) {
> +    BootOptions = EfiBootManagerGetLoadOptions (&BootOptionCount, LoadOptionTypeBoot);
> +
> +    OptionIndex = PlatformFindLoadOption (&NewOption, BootOptions, BootOptionCount);
> +
> +    if (OptionIndex == -1) {
> +      Status = 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 = 0; gPlatformConsole[Index].DevicePath != NULL; Index++) {
> +    DEBUG ((DEBUG_INFO, "Check gPlatformConsole %d\n", Index));
> +    if ((gPlatformConsole[Index].ConnectType & CONSOLE_IN) == CONSOLE_IN) {
> +      Status = EfiBootManagerUpdateConsoleVariable (ConIn, gPlatformConsole[Index].DevicePath, NULL);
> +      DEBUG ((DEBUG_INFO, "CONSOLE_IN variable set %s : %r\n", ConvertDevicePathToText (gPlatformConsole[Index].DevicePath, FALSE, FALSE), Status));

Some really long lines here, can we wrap them?

> +    }
> +
> +    if ((gPlatformConsole[Index].ConnectType & CONSOLE_OUT) == CONSOLE_OUT) {
> +      Status = EfiBootManagerUpdateConsoleVariable (ConOut, gPlatformConsole[Index].DevicePath, NULL);
> +      DEBUG ((DEBUG_INFO, "CONSOLE_OUT variable set %s : %r\n", ConvertDevicePathToText (gPlatformConsole[Index].DevicePath, FALSE, FALSE), Status));
> +    }
> +
> +    if ((gPlatformConsole[Index].ConnectType & STD_ERROR) == STD_ERROR) {
> +      Status = EfiBootManagerUpdateConsoleVariable (ErrOut, gPlatformConsole[Index].DevicePath, NULL);
> +      DEBUG ((DEBUG_INFO, "STD_ERROR variable set %r", Status));
> +    }
> +  }
> +
> +  //
> +  // Register ENTER as CONTINUE key
> +  //
> +  Enter.ScanCode    = SCAN_NULL;
> +  Enter.UnicodeChar = CHAR_CARRIAGE_RETURN;
> +  EfiBootManagerRegisterContinueKeyOption (0, &Enter, NULL);
> +  //
> +  // Map F2 to Boot Manager Menu
> +  //
> +  F2.ScanCode    = SCAN_F2;
> +  F2.UnicodeChar = CHAR_NULL;
> +  EfiBootManagerGetBootManagerMenu (&BootOption);
> +  EfiBootManagerAddKeyOptionVariable (NULL, (UINT16) BootOption.OptionNumber, 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 = Black.Green = Black.Red = Black.Reserved = 0;
> +  White.Blue = White.Green = White.Red = White.Reserved = 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 = PcdGet16 (PcdPlatformBootTimeOut);
> +
> +  Black.Blue = Black.Green = Black.Red = Black.Reserved = 0;
> +  White.Blue = White.Green = White.Red = White.Reserved = 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 applications
> +  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/PlatformBootManagerLib/PlatformBootManager.h
> new file mode 100644
> index 00000000..20d66758
> --- /dev/null
> +++ b/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/PlatformBootManager.h
> @@ -0,0 +1,135 @@
> +/**@file
> +   Head file for BDS Platform specific code
> +
> +Copyright (c) 2016, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
> +Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
> +
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef _PLATFORM_BOOT_MANAGER_H_
> +#define _PLATFORM_BOOT_MANAGER_H_

Please drop leading _.

> +
> +#include <PiDxe.h>
> +#include <IndustryStandard/Bmp.h>
> +#include <Protocol/GenericMemoryTest.h>
> +#include <Protocol/LoadedImage.h>
> +#include <Protocol/UgaDraw.h>
> +#include <Protocol/GraphicsOutput.h>
> +#include <Protocol/BootLogo.h>
> +#include <Protocol/DevicePath.h>
> +
> +#include <Library/DebugLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiRuntimeServicesTableLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/UefiRuntimeServicesTableLib.h>
> +#include <Library/UefiLib.h>
> +#include <Library/UefiBootManagerLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/DevicePathLib.h>
> +#include <Library/HiiLib.h>
> +#include <Library/PrintLib.h>
> +#include <Library/DxeServicesLib.h>

Please remove any includes not needed by this file, and add them to
the files that actually use them.

> +
> +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, 0x72, 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 from going
> +  to the video device. Put up LogoFile on every video device that is a console.
> +
> +  @param[in]  LogoFile   File name of logo to display on the center of the screen.
> +
> +  @retval EFI_SUCCESS     ConsoleControl has been flipped to graphics and 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 output devices
> +
> +  @retval EFI_SUCCESS     UGA devices are back in text mode and synced up.
> +
> +**/
> +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/PlatformBootManagerLib/PlatformBootManagerLib.inf
> new file mode 100644
> index 00000000..92c31db4
> --- /dev/null
> +++ b/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.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 rights reserved.<BR>
> +#  Copyright (c) 2012 - 2015, Intel Corporation. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005

Please bump specification version.

> +  BASE_NAME                      = PlatformBootManagerLib
> +  FILE_GUID                      = 7DDA7916-6139-4D46-A415-30E854AF3BC7
> +  MODULE_TYPE                    = DXE_DRIVER
> +  VERSION_STRING                 = 1.0
> +  LIBRARY_CLASS                  = PlatformBootManagerLib|DXE_DRIVER
> +
> +#
> +# The following information is for reference only and not required by the build tools.
> +#
> +#  VALID_ARCHITECTURES           = 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

Please sort Sources, Packages and LibraryClasses alphabetically.

> +
> +[Guids]
> +
> +[Protocols]
> +  gEfiGenericMemTestProtocolGuid  ## CONSUMES
> +  gEfiGraphicsOutputProtocolGuid  ## CONSUMES
> +  gEfiUgaDrawProtocolGuid         ## CONSUMES

You're hopefully not really using UGA, so please drop that.

> +
> +[Pcd]
> +  gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutRow
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutColumn
> +  gEfiMdePkgTokenSpaceGuid.PcdUgaConsumeSupport
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdConInConnectOnDemand
> +  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdBootlogoOnlyEnable

Please sort Pcds alphabetically.

> diff --git a/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/PlatformData.c b/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/PlatformData.c
> new file mode 100644
> index 00000000..3208051e
> --- /dev/null
> +++ b/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/PlatformData.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 rights reserved.<BR>
> +Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
> +
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "PlatformBootManager.h"
> +
> +//
> +// Platform specific serial device path
> +//
> +SERIAL_CONSOLE_DEVICE_PATH gSerialConsoleDevicePath0 = {
> +  {
> +    { 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[] = {
> +  {
> +    (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/PlatformBootManagerLib/Strings.uni
> new file mode 100644
> index 00000000..73bf5d51
> --- /dev/null
> +++ b/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/Strings.uni
> @@ -0,0 +1,28 @@
> +///** @file
> +//
> +//    String definitions for PlatformBootManagerLib.
> +//
> +//  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
> +//  Copyright (c) 2004 - 2015, Intel Corporation. All rights reserved.<BR>
> +//
> +//  SPDX-License-Identifier: BSD-2-Clause-Patent
> +//
> +//**/
> +
> +/=#
> +
> +#langdef   en-US "English"
> +#langdef   fr-FR "Français"
> +
> +#string STR_PERFORM_MEM_TEST           #language en-US  "Perform memory test (ESC to skip)"
> +                                       #language fr-FR  "Exécute l'examen de mémoire (ESC pour sauter)"
> +#string STR_MEMORY_TEST_PERCENT        #language en-US  "% of the system memory tested OK"
> +                                       #language fr-FR  "% de la mémoire de système essayée D'ACCORD"
> +#string STR_ESC_TO_SKIP_MEM_TEST       #language en-US  "Press ESC key to skip memory test"
> +                                       #language fr-FR  "Appuie sur ESC sauter examen de mémoire"
> +#string STR_MEM_TEST_COMPLETED         #language en-US  " bytes of system memory tested OK\r\n"
> +                                       #language fr-FR  "octets dela mémoire de système essayée D'ACCORD\r\n"

if there's a space before 'bytes' you probably want one before
'octets'.

/
    Leif

> +#string STR_SYSTEM_MEM_ERROR           #language en-US  "System encounters memory errors"
> +                                       #language fr-FR  "le Système rencontre les erreurs de mémoire"
> +#string STR_START_BOOT_OPTION          #language en-US  "Start boot option"
> +                                       #language fr-FR  "l'option de botte de Début"
> -- 
> 2.12.0.windows.1
> 
> 
> 
> 

-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.

View/Reply Online (#48403): https://edk2.groups.io/g/devel/message/48403
Mute This Topic: https://groups.io/mt/34196357/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub  [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-

Re: [edk2-devel] [plaforms/devel-riscv-v2 PATCHv2 09/14] U500Pkg/Library: Initial version of PlatformBootManagerLib
Posted by Abner Chang 6 years, 3 months ago

> -----Original Message-----
> From: devel@edk2.groups.io [mailto:devel@edk2.groups.io] On Behalf Of
> Leif Lindholm
> Sent: Thursday, October 3, 2019 6:03 AM
> To: devel@edk2.groups.io; Chen, Gilbert <gilbert.chen@hpe.com>
> Cc: Palmer Dabbelt <palmer@sifive.com>
> Subject: Re: [edk2-devel] [plaforms/devel-riscv-v2 PATCHv2 09/14]
> U500Pkg/Library: Initial version of PlatformBootManagerLib
> 
> On Thu, Sep 19, 2019 at 11:51:26AM +0800, Gilbert Chen wrote:
> > SiFive RISC-V U500 Platform Boot Manager library.
> 
> First of all, let me say that I think before upstreaming to master, you ought to
> look into merging PlatformBootManagerLibs for all Risc-V platforms. Like we
> have for *most* ARM/AARCH64 platforms with
> ArmPkg/Library/PlatformBootManagerLib/.
> 
> (Longer-term we should merge them all together into a single one.)
> 
> > Signed-off-by: Gilbert Chen <gilbert.chen@hpe.com>
> > ---
> >  .../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/PlatformBootManagerLib/MemoryT
> es
> > t.c  create mode 100644
> >
> Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/PlatformB
> > ootManager.c  create mode 100644
> >
> Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/PlatformB
> > ootManager.h  create mode 100644
> >
> Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/PlatformB
> > ootManagerLib.inf  create mode 100644
> >
> Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/PlatformD
> > ata.c  create mode 100644
> > Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/Strings.u
> > ni
> >
> > diff --git
> >
> a/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/Memory
> T
> > est.c
> >
> b/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/Memor
> yT
> > est.c
> > new file mode 100644
> > index 00000000..8c6d89e9
> > --- /dev/null
> > +++
> b/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/Mem
> > +++ oryTest.c
> 
> Why build a MemoryTest into the PlatformBootManagerLib?
Why not to do memory if platform provides memory test protocol?
> 
> > @@ -0,0 +1,682 @@
> > +/** @file
> > +  Perform the RISC-V platform memory test
> > +
> > +Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All
> > +rights reserved.<BR> Copyright (c) 2004 - 2015, Intel Corporation.
> > +All rights reserved.<BR>
> > +
> > +SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#include "PlatformBootManager.h"
> > +
> > +EFI_HII_HANDLE gStringPackHandle = NULL;
> > +EFI_GUID       mPlatformBootManagerStringPackGuid = {
> > +  0x154dd51, 0x9079, 0x4a10, { 0x89, 0x5c, 0x9c, 0x7, 0x72, 0x81,
> > +0x57, 0x88 }
> > +  };
> > +// extern UINT8  BdsDxeStrings[];
> 
> No need to keep commented-out code in.
> 
> > +
> > +//
> > +// 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 (
> 
> I'm not a super fan of how this file integrates a custom memory test with a
> direct (copy) graphical progress indicator. There are both common memory
> test and common progress indicators - please use those instead. And
> improve them if they are currently insufficient for your needs.

Could you indicate where are those common libraries? Thanks.

> 
> > diff --git
> > a/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/Platfor
> > mBootManager.c
> > b/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/Platfor
> > mBootManager.c
> > new file mode 100644
> > index 00000000..9ef85089
> > --- /dev/null
> > +++
> b/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/Pla
> > +++ tformBootManager.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
> > +rights reserved.<BR> Copyright (c) 2015, Intel Corporation. All
> > +rights reserved.<BR>
> > +
> > +SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#include "PlatformBootManager.h"
> > +
> > +
> > +EFI_GUID mUefiShellFileGuid = { 0x7C04A583, 0x9E3E, 0x4f1c, {0xAD,
> > +0x65, 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 = PlatformBootManagerMemoryTest (MemoryTestLevel);
> > +    return;
> > +  }
> > +
> > +  //
> > +  // Perform system diagnostic
> > +  //
> > +  Status = 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 equal.
> > +
> > +  @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 = 0; Index < Count; Index++) {
> > +    if ((Key->OptionType == Array[Index].OptionType) &&
> > +        (Key->Attributes == Array[Index].Attributes) &&
> > +        (StrCmp (Key->Description, Array[Index].Description) == 0) &&
> > +        (CompareMem (Key->FilePath, Array[Index].FilePath,
> GetDevicePathSize (Key->FilePath)) == 0) &&
> > +        (Key->OptionalDataSize == Array[Index].OptionalDataSize) &&
> > +        (CompareMem (Key->OptionalData, Array[Index].OptionalData, Key-
> >OptionalDataSize) == 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 = gBS->HandleProtocol (gImageHandle,
> &gEfiLoadedImageProtocolGuid, (VOID **) &LoadedImage);
> > +  ASSERT_EFI_ERROR (Status);
> > +
> > +  EfiInitializeFwVolDevicepathNode (&FileNode, FileGuid);
> > +  DevicePath = AppendDevicePathNode (
> > +                 DevicePathFromHandle (LoadedImage->DeviceHandle),
> > +                 (EFI_DEVICE_PATH_PROTOCOL *) &FileNode
> > +                 );
> > +
> > +  Status = EfiBootManagerInitializeLoadOption (
> > +             &NewOption,
> > +             LoadOptionNumberUnassigned,
> > +             LoadOptionTypeBoot,
> > +             Attributes,
> > +             Description,
> > +             DevicePath,
> > +             NULL,
> > +             0
> > +             );
> > +  if (!EFI_ERROR (Status)) {
> > +    BootOptions = EfiBootManagerGetLoadOptions (&BootOptionCount,
> LoadOptionTypeBoot);
> > +
> > +    OptionIndex = PlatformFindLoadOption (&NewOption, BootOptions,
> BootOptionCount);
> > +
> > +    if (OptionIndex == -1) {
> > +      Status = 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 = 0; gPlatformConsole[Index].DevicePath != NULL; Index++) {
> > +    DEBUG ((DEBUG_INFO, "Check gPlatformConsole %d\n", Index));
> > +    if ((gPlatformConsole[Index].ConnectType & CONSOLE_IN) ==
> CONSOLE_IN) {
> > +      Status = EfiBootManagerUpdateConsoleVariable (ConIn,
> gPlatformConsole[Index].DevicePath, NULL);
> > +      DEBUG ((DEBUG_INFO, "CONSOLE_IN variable set %s : %r\n",
> ConvertDevicePathToText (gPlatformConsole[Index].DevicePath, FALSE,
> FALSE), Status));
> 
> Some really long lines here, can we wrap them?
> 
> > +    }
> > +
> > +    if ((gPlatformConsole[Index].ConnectType & CONSOLE_OUT) ==
> CONSOLE_OUT) {
> > +      Status = EfiBootManagerUpdateConsoleVariable (ConOut,
> gPlatformConsole[Index].DevicePath, NULL);
> > +      DEBUG ((DEBUG_INFO, "CONSOLE_OUT variable set %s : %r\n",
> ConvertDevicePathToText (gPlatformConsole[Index].DevicePath, FALSE,
> FALSE), Status));
> > +    }
> > +
> > +    if ((gPlatformConsole[Index].ConnectType & STD_ERROR) ==
> STD_ERROR) {
> > +      Status = EfiBootManagerUpdateConsoleVariable (ErrOut,
> gPlatformConsole[Index].DevicePath, NULL);
> > +      DEBUG ((DEBUG_INFO, "STD_ERROR variable set %r", Status));
> > +    }
> > +  }
> > +
> > +  //
> > +  // Register ENTER as CONTINUE key
> > +  //
> > +  Enter.ScanCode    = SCAN_NULL;
> > +  Enter.UnicodeChar = CHAR_CARRIAGE_RETURN;
> > +  EfiBootManagerRegisterContinueKeyOption (0, &Enter, NULL);
> > +  //
> > +  // Map F2 to Boot Manager Menu
> > +  //
> > +  F2.ScanCode    = SCAN_F2;
> > +  F2.UnicodeChar = CHAR_NULL;
> > +  EfiBootManagerGetBootManagerMenu (&BootOption);
> > +  EfiBootManagerAddKeyOptionVariable (NULL, (UINT16)
> BootOption.OptionNumber, 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 = Black.Green = Black.Red = Black.Reserved = 0;
> > +  White.Blue = White.Green = White.Red = White.Reserved = 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 = PcdGet16 (PcdPlatformBootTimeOut);
> > +
> > +  Black.Blue = Black.Green = Black.Red = Black.Reserved = 0;
> > +  White.Blue = White.Green = White.Red = White.Reserved = 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 applications
> > +  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/Platform
> BootManager.h
> b/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/Platfor
> mBootManager.h
> > new file mode 100644
> > index 00000000..20d66758
> > --- /dev/null
> > +++
> b/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/Platfor
> mBootManager.h
> > @@ -0,0 +1,135 @@
> > +/**@file
> > +   Head file for BDS Platform specific code
> > +
> > +Copyright (c) 2016, Hewlett Packard Enterprise Development LP. All rights
> reserved.<BR>
> > +Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
> > +
> > +SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#ifndef _PLATFORM_BOOT_MANAGER_H_
> > +#define _PLATFORM_BOOT_MANAGER_H_
> 
> Please drop leading _.
> 
> > +
> > +#include <PiDxe.h>
> > +#include <IndustryStandard/Bmp.h>
> > +#include <Protocol/GenericMemoryTest.h>
> > +#include <Protocol/LoadedImage.h>
> > +#include <Protocol/UgaDraw.h>
> > +#include <Protocol/GraphicsOutput.h>
> > +#include <Protocol/BootLogo.h>
> > +#include <Protocol/DevicePath.h>
> > +
> > +#include <Library/DebugLib.h>
> > +#include <Library/BaseMemoryLib.h>
> > +#include <Library/UefiBootServicesTableLib.h>
> > +#include <Library/UefiRuntimeServicesTableLib.h>
> > +#include <Library/MemoryAllocationLib.h>
> > +#include <Library/BaseLib.h>
> > +#include <Library/UefiRuntimeServicesTableLib.h>
> > +#include <Library/UefiLib.h>
> > +#include <Library/UefiBootManagerLib.h>
> > +#include <Library/PcdLib.h>
> > +#include <Library/DevicePathLib.h>
> > +#include <Library/HiiLib.h>
> > +#include <Library/PrintLib.h>
> > +#include <Library/DxeServicesLib.h>
> 
> Please remove any includes not needed by this file, and add them to
> the files that actually use them.
> 
> > +
> > +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, 0x72,
> 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
> from going
> > +  to the video device. Put up LogoFile on every video device that is a
> console.
> > +
> > +  @param[in]  LogoFile   File name of logo to display on the center of the
> screen.
> > +
> > +  @retval EFI_SUCCESS     ConsoleControl has been flipped to graphics and
> 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 output
> devices
> > +
> > +  @retval EFI_SUCCESS     UGA devices are back in text mode and synced
> up.
> > +
> > +**/
> > +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/Platform
> BootManagerLib.inf
> b/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/Platfor
> mBootManagerLib.inf
> > new file mode 100644
> > index 00000000..92c31db4
> > --- /dev/null
> > +++
> b/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/Platfor
> mBootManagerLib.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
> rights reserved.<BR>
> > +#  Copyright (c) 2012 - 2015, Intel Corporation. All rights reserved.<BR>
> > +#
> > +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +#
> > +##
> > +
> > +[Defines]
> > +  INF_VERSION                    = 0x00010005
> 
> Please bump specification version.
> 
> > +  BASE_NAME                      = PlatformBootManagerLib
> > +  FILE_GUID                      = 7DDA7916-6139-4D46-A415-30E854AF3BC7
> > +  MODULE_TYPE                    = DXE_DRIVER
> > +  VERSION_STRING                 = 1.0
> > +  LIBRARY_CLASS                  = PlatformBootManagerLib|DXE_DRIVER
> > +
> > +#
> > +# The following information is for reference only and not required by the
> build tools.
> > +#
> > +#  VALID_ARCHITECTURES           = 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
> 
> Please sort Sources, Packages and LibraryClasses alphabetically.
> 
> > +
> > +[Guids]
> > +
> > +[Protocols]
> > +  gEfiGenericMemTestProtocolGuid  ## CONSUMES
> > +  gEfiGraphicsOutputProtocolGuid  ## CONSUMES
> > +  gEfiUgaDrawProtocolGuid         ## CONSUMES
> 
> You're hopefully not really using UGA, so please drop that.
> 
> > +
> > +[Pcd]
> > +  gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut
> > +  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutRow
> > +  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutColumn
> > +  gEfiMdePkgTokenSpaceGuid.PcdUgaConsumeSupport
> > +  gEfiMdeModulePkgTokenSpaceGuid.PcdConInConnectOnDemand
> > +  gUefiRiscVPlatformPkgTokenSpaceGuid.PcdBootlogoOnlyEnable
> 
> Please sort Pcds alphabetically.
> 
> > diff --git
> a/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/Platform
> Data.c
> b/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/Platfor
> mData.c
> > new file mode 100644
> > index 00000000..3208051e
> > --- /dev/null
> > +++
> b/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/Platfor
> mData.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 rights
> reserved.<BR>
> > +Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
> > +
> > +SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#include "PlatformBootManager.h"
> > +
> > +//
> > +// Platform specific serial device path
> > +//
> > +SERIAL_CONSOLE_DEVICE_PATH gSerialConsoleDevicePath0 = {
> > +  {
> > +    { 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[] = {
> > +  {
> > +    (EFI_DEVICE_PATH_PROTOCOL *) &gSerialConsoleDevicePath0,
> > +    CONSOLE_OUT | CONSOLE_IN
> > +  },
> > +  {
> > +    NULL,
> > +    0
> > +  }
> > +};
> > diff --git
> a/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/Strings.u
> ni
> b/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/Strings.
> uni
> > new file mode 100644
> > index 00000000..73bf5d51
> > --- /dev/null
> > +++
> b/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/Strings.
> uni
> > @@ -0,0 +1,28 @@
> > +///** @file
> > +//
> > +//    String definitions for PlatformBootManagerLib.
> > +//
> > +//  Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All
> rights reserved.<BR>
> > +//  Copyright (c) 2004 - 2015, Intel Corporation. All rights reserved.<BR>
> > +//
> > +//  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +//
> > +//**/
> > +
> > +/=#
> > +
> > +#langdef   en-US "English"
> > +#langdef   fr-FR "Français"
> > +
> > +#string STR_PERFORM_MEM_TEST           #language en-US  "Perform
> memory test (ESC to skip)"
> > +                                       #language fr-FR  "Exécute l'examen de mémoire (ESC
> pour sauter)"
> > +#string STR_MEMORY_TEST_PERCENT        #language en-US  "% of the
> system memory tested OK"
> > +                                       #language fr-FR  "% de la mémoire de système
> essayée D'ACCORD"
> > +#string STR_ESC_TO_SKIP_MEM_TEST       #language en-US  "Press ESC
> key to skip memory test"
> > +                                       #language fr-FR  "Appuie sur ESC sauter examen de
> mémoire"
> > +#string STR_MEM_TEST_COMPLETED         #language en-US  " bytes of
> system memory tested OK\r\n"
> > +                                       #language fr-FR  "octets dela mémoire de système
> essayée D'ACCORD\r\n"
> 
> if there's a space before 'bytes' you probably want one before
> 'octets'.
> 
> /
>     Leif
> 
> > +#string STR_SYSTEM_MEM_ERROR           #language en-US  "System
> encounters memory errors"
> > +                                       #language fr-FR  "le Système rencontre les erreurs de
> mémoire"
> > +#string STR_START_BOOT_OPTION          #language en-US  "Start boot
> option"
> > +                                       #language fr-FR  "l'option de botte de Début"
> > --
> > 2.12.0.windows.1
> >
> >
> >
> >
> 
> 


-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.

View/Reply Online (#49226): https://edk2.groups.io/g/devel/message/49226
Mute This Topic: https://groups.io/mt/34196357/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub  [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-

Re: [edk2-devel] [plaforms/devel-riscv-v2 PATCHv2 09/14] U500Pkg/Library: Initial version of PlatformBootManagerLib
Posted by Leif Lindholm 6 years, 3 months ago
On Fri, Oct 18, 2019 at 06:23:05AM +0000, Abner Chang wrote:
> > -----Original Message-----
> > From: devel@edk2.groups.io [mailto:devel@edk2.groups.io] On Behalf Of
> > Leif Lindholm
> > Sent: Thursday, October 3, 2019 6:03 AM
> > To: devel@edk2.groups.io; Chen, Gilbert <gilbert.chen@hpe.com>
> > Cc: Palmer Dabbelt <palmer@sifive.com>
> > Subject: Re: [edk2-devel] [plaforms/devel-riscv-v2 PATCHv2 09/14]
> > U500Pkg/Library: Initial version of PlatformBootManagerLib
> > 
> > On Thu, Sep 19, 2019 at 11:51:26AM +0800, Gilbert Chen wrote:
> > > SiFive RISC-V U500 Platform Boot Manager library.
> > 
> > First of all, let me say that I think before upstreaming to master, you ought to
> > look into merging PlatformBootManagerLibs for all Risc-V platforms. Like we
> > have for *most* ARM/AARCH64 platforms with
> > ArmPkg/Library/PlatformBootManagerLib/.
> > 
> > (Longer-term we should merge them all together into a single one.)
> > 
> > > Signed-off-by: Gilbert Chen <gilbert.chen@hpe.com>
> > > ---
> > >  .../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/PlatformBootManagerLib/MemoryT
> > es
> > > t.c  create mode 100644
> > >
> > Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/PlatformB
> > > ootManager.c  create mode 100644
> > >
> > Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/PlatformB
> > > ootManager.h  create mode 100644
> > >
> > Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/PlatformB
> > > ootManagerLib.inf  create mode 100644
> > >
> > Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/PlatformD
> > > ata.c  create mode 100644
> > > Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/Strings.u
> > > ni
> > >
> > > diff --git
> > >
> > a/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/Memory
> > T
> > > est.c
> > >
> > b/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/Memor
> > yT
> > > est.c
> > > new file mode 100644
> > > index 00000000..8c6d89e9
> > > --- /dev/null
> > > +++
> > b/Platform/RiscV/SiFive/U500Pkg/Library/PlatformBootManagerLib/Mem
> > > +++ oryTest.c
> > 
> > Why build a MemoryTest into the PlatformBootManagerLib?
>
> Why not to do memory if platform provides memory test protocol?

The question was why build it into the PlatformBootManagerLib?
I would much prefer something like what is done in existing plaforms
with gEfiGenericMemTestProtocolGuid.

> > 
> > > @@ -0,0 +1,682 @@
> > > +/** @file
> > > +  Perform the RISC-V platform memory test
> > > +
> > > +Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All
> > > +rights reserved.<BR> Copyright (c) 2004 - 2015, Intel Corporation.
> > > +All rights reserved.<BR>
> > > +
> > > +SPDX-License-Identifier: BSD-2-Clause-Patent
> > > +
> > > +**/
> > > +
> > > +#include "PlatformBootManager.h"
> > > +
> > > +EFI_HII_HANDLE gStringPackHandle = NULL;
> > > +EFI_GUID       mPlatformBootManagerStringPackGuid = {
> > > +  0x154dd51, 0x9079, 0x4a10, { 0x89, 0x5c, 0x9c, 0x7, 0x72, 0x81,
> > > +0x57, 0x88 }
> > > +  };
> > > +// extern UINT8  BdsDxeStrings[];
> > 
> > No need to keep commented-out code in.
> > 
> > > +
> > > +//
> > > +// 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 (
> > 
> > I'm not a super fan of how this file integrates a custom memory test with a
> > direct (copy) graphical progress indicator. There are both common memory
> > test and common progress indicators - please use those instead. And
> > improve them if they are currently insufficient for your needs.
> 
> Could you indicate where are those common libraries? Thanks.

There is MdeModulePkg/Library/DisplayUpdateProgressLibGraphics and
MdeModulePkg/Library/DisplayUpdateProgressLibText.

/
    Leif

-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.

View/Reply Online (#49308): https://edk2.groups.io/g/devel/message/49308
Mute This Topic: https://groups.io/mt/34196357/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub  [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-