[Linaro-uefi,Linaro-uefi,v3] Hisilicon D03/D05: set boot option by BMC

Message ID 1495162486-34455-1-git-send-email-chenhui.sun@linaro.org
State New
Headers show

Commit Message

Chenhui Sun May 19, 2017, 2:54 a.m.
From: Chenhui Sun <chenhui.sun@linaro.com>

Support the feature that BIOS get boot option from BMC and
put it in the first boot order.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: huangming <huangming23@huawei.com>
Signed-off-by: Heyi Guo <guoheyi@huawei.com>
Signed-off-by: Yi Li <Phoenix.liyi@huawei.com>
Signed-off-by: Chenhui Sun <sunchenhui@huawei.com>
---
 Chips/Hisilicon/Include/Library/IpmiCmdLib.h       |  94 +++++
 .../Library/PlatformIntelBdsLib/IntelBdsPlatform.c | 437 +++++++++++++++++++++
 .../PlatformIntelBdsLib/PlatformIntelBdsLib.inf    |   4 +
 3 files changed, 535 insertions(+)
 create mode 100644 Chips/Hisilicon/Include/Library/IpmiCmdLib.h

Comments

Leif Lindholm May 19, 2017, 10:29 a.m. | #1
On Fri, May 19, 2017 at 10:54:46AM +0800, Chenhui Sun wrote:
> From: Chenhui Sun <chenhui.sun@linaro.com>
> 
> Support the feature that BIOS get boot option from BMC and
> put it in the first boot order.
> 
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: huangming <huangming23@huawei.com>
> Signed-off-by: Heyi Guo <guoheyi@huawei.com>
> Signed-off-by: Yi Li <Phoenix.liyi@huawei.com>
> Signed-off-by: Chenhui Sun <sunchenhui@huawei.com>

Thanks, this one looks good.

Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>

> ---
>  Chips/Hisilicon/Include/Library/IpmiCmdLib.h       |  94 +++++
>  .../Library/PlatformIntelBdsLib/IntelBdsPlatform.c | 437 +++++++++++++++++++++
>  .../PlatformIntelBdsLib/PlatformIntelBdsLib.inf    |   4 +
>  3 files changed, 535 insertions(+)
>  create mode 100644 Chips/Hisilicon/Include/Library/IpmiCmdLib.h
> 
> diff --git a/Chips/Hisilicon/Include/Library/IpmiCmdLib.h b/Chips/Hisilicon/Include/Library/IpmiCmdLib.h
> new file mode 100644
> index 0000000..8868b76
> --- /dev/null
> +++ b/Chips/Hisilicon/Include/Library/IpmiCmdLib.h
> @@ -0,0 +1,94 @@
> +/** @file
> +*
> +*  Copyright (c) 2017, Hisilicon Limited. All rights reserved.
> +*  Copyright (c) 2017, Linaro Limited. All rights reserved.
> +*
> +*  This program and the accompanying materials
> +*  are licensed and made available under the terms and conditions of the BSD License
> +*  which accompanies this distribution.  The full text of the license may be found at
> +*  http://opensource.org/licenses/bsd-license.php
> +*
> +*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> +*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> +*
> +**/
> +
> +#ifndef _IPMI_CMD_LIB_H_
> +#define _IPMI_CMD_LIB_H_
> +
> +#define BOOT_OPTION_BOOT_FLAG_VALID         1
> +#define BOOT_OPTION_BOOT_FLAG_INVALID       0
> +
> +typedef enum {
> +  NoOverride = 0x0,
> +  ForcePxe,
> +  ForceDefaultHardDisk,
> +  ForceDefaultHardDiskSafeMode,
> +  ForceDefaultDiagnosticPartition,
> +  ForceDefaultCD,
> +  ForceSetupUtility,
> +  ForceRemoteRemovableMedia,
> +  ForceRemoteCD,
> +  ForcePrimaryRemoteMedia,
> +  ForceRemoteHardDisk = 0xB,
> +  ForcePrimaryRemovableMedia = 0xF
> +} BOOT_DEVICE_SELECTOR;
> +
> +//
> +// Get System Boot Option data structure
> +//
> +typedef struct {
> +  UINT8 ParameterVersion           :4;
> +  UINT8 Reserved1                  :4;
> +  UINT8 ParameterSelector          :7;
> +  UINT8 ParameterValid             :1;
> +  //
> +  // Boot Flags Data 1
> +  //
> +  UINT8 Reserved2                  :5;
> +  UINT8 BiosBootType               :1;
> +  UINT8 Persistent                 :1;
> +  UINT8 BootFlagsValid             :1;
> +  //
> +  // Boot Flags Data 2
> +  //
> +  UINT8 LockResetBtn               :1;
> +  UINT8 ScreenBlank                :1;
> +  UINT8 BootDeviceSelector         :4;
> +  UINT8 LockKeyboard               :1;
> +  UINT8 ClearCmos                  :1;
> +  //
> +  // Boot Flags Data 3
> +  //
> +  UINT8 ConsoleRedirectionControl  :2;
> +  UINT8 LockSleepBtn               :1;
> +  UINT8 UserPasswordByPass         :1;
> +  UINT8 Reserved3                  :1;
> +  UINT8 FirmwareVerbosity          :2;
> +  UINT8 LockPowerBtn               :1;
> +  //
> +  // Boot Flags Data 4
> +  //
> +  UINT8 MuxControlOverride         :3;
> +  UINT8 ShareModeOverride          :1;
> +  UINT8 Reserved4                  :4;
> +  //
> +  // Boot Flags Data 5
> +  //
> +  UINT8 DeviceInstanceSelector     :5;
> +  UINT8 Reserved5                  :3;
> +} IPMI_GET_BOOT_OPTION;
> +
> +EFI_STATUS
> +EFIAPI
> +IpmiCmdSetSysBootOptions (
> +  OUT IPMI_GET_BOOT_OPTION  *BootOption
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +IpmiCmdGetSysBootOptions (
> +  IN IPMI_GET_BOOT_OPTION   *BootOption
> +  );
> +
> +#endif
> diff --git a/Chips/Hisilicon/Library/PlatformIntelBdsLib/IntelBdsPlatform.c b/Chips/Hisilicon/Library/PlatformIntelBdsLib/IntelBdsPlatform.c
> index efefeb6..dc23e46 100644
> --- a/Chips/Hisilicon/Library/PlatformIntelBdsLib/IntelBdsPlatform.c
> +++ b/Chips/Hisilicon/Library/PlatformIntelBdsLib/IntelBdsPlatform.c
> @@ -21,16 +21,23 @@
>  
>  #include <IndustryStandard/Pci22.h>
>  #include <Library/DevicePathLib.h>
> +#include <Library/GenericBdsLib.h>
> +#include <Library/IpmiCmdLib.h>
>  #include <Library/PcdLib.h>
>  #include <Library/PlatformBdsLib.h>
> +#include <Library/PrintLib.h>
>  #include <Library/UefiLib.h>
>  #include <Protocol/DevicePath.h>
> +#include <Protocol/DevicePathToText.h>
>  #include <Protocol/GraphicsOutput.h>
>  #include <Protocol/PciIo.h>
>  #include <Protocol/PciRootBridgeIo.h>
> +#include <Guid/GlobalVariable.h>
>  
>  #include "IntelBdsPlatform.h"
>  
> +GUID gOemBootVaraibleGuid = {0xb7784577, 0x5aaf, 0x4557, {0xa1, 0x99,
> +  0xd4, 0xa4, 0x2f, 0x45, 0x06, 0xf8} };
>  
>  //3CEF354A-3B7A-4519-AD70-72A134698311
>  GUID gEblFileGuid = {0x3CEF354A, 0x3B7A, 0x4519, {0xAD, 0x70,
> @@ -142,6 +149,431 @@ STATIC PLATFORM_USB_KEYBOARD mUsbKeyboard = {
>    }
>  };
>  
> +STATIC
> +UINT16
> +GetBBSTypeFromFileSysPath (
> +  IN CHAR16                   *UsbPathTxt,
> +  IN CHAR16                   *FileSysPathTxt,
> +  IN EFI_DEVICE_PATH_PROTOCOL *FileSysPath
> +  )
> +{
> +  EFI_DEVICE_PATH_PROTOCOL *Node;
> +
> +  if (StrnCmp (UsbPathTxt, FileSysPathTxt, StrLen (UsbPathTxt)) == 0) {
> +    Node = FileSysPath;
> +    while (!IsDevicePathEnd (Node)) {
> +      if ((DevicePathType (Node) == MEDIA_DEVICE_PATH) &&
> +          (DevicePathSubType (Node) == MEDIA_CDROM_DP)) {
> +        return BBS_TYPE_CDROM;
> +      }
> +      Node = NextDevicePathNode (Node);
> +    }
> +  }
> +
> +  return BBS_TYPE_UNKNOWN;
> +}
> +
> +STATIC
> +UINT16
> +GetBBSTypeFromUsbPath (
> +  IN CONST EFI_DEVICE_PATH_PROTOCOL *UsbPath
> +  )
> +{
> +  EFI_STATUS                        Status;
> +  EFI_HANDLE                        *FileSystemHandles;
> +  UINTN                             NumberFileSystemHandles;
> +  UINTN                             Index;
> +  EFI_DEVICE_PATH_PROTOCOL          *FileSysPath;
> +  EFI_DEVICE_PATH_TO_TEXT_PROTOCOL  *DevPathToText;
> +  CHAR16                            *UsbPathTxt;
> +  CHAR16                            *FileSysPathTxt;
> +  UINT16                            Result;
> +
> +  Status = gBS->LocateProtocol (&gEfiDevicePathToTextProtocolGuid, NULL, (VOID **) &DevPathToText);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "Locate DevicePathToTextPro %r\n", Status));
> +    return BBS_TYPE_UNKNOWN;
> +  }
> +
> +  Result = BBS_TYPE_UNKNOWN;
> +  UsbPathTxt = DevPathToText->ConvertDevicePathToText (UsbPath, TRUE, TRUE);
> +  if (UsbPathTxt == NULL) {
> +    return Result;
> +  }
> +
> +  Status = gBS->LocateHandleBuffer (
> +                  ByProtocol,
> +                  &gEfiSimpleFileSystemProtocolGuid,
> +                  NULL,
> +                  &NumberFileSystemHandles,
> +                  &FileSystemHandles
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "Locate SimpleFileSystemProtocol error(%r)\n", Status));
> +    FreePool (UsbPathTxt);
> +    return BBS_TYPE_UNKNOWN;
> +  }
> +
> +  for (Index = 0; Index < NumberFileSystemHandles; Index++) {
> +    FileSysPath = DevicePathFromHandle (FileSystemHandles[Index]);
> +    FileSysPathTxt = DevPathToText->ConvertDevicePathToText (FileSysPath, TRUE, TRUE);
> +
> +    if (FileSysPathTxt == NULL) {
> +      continue;
> +    }
> +
> +    Result = GetBBSTypeFromFileSysPath (UsbPathTxt, FileSysPathTxt, FileSysPath);
> +    FreePool (FileSysPathTxt);
> +
> +    if (Result != BBS_TYPE_UNKNOWN) {
> +      break;
> +    }
> +  }
> +
> +  if (NumberFileSystemHandles != 0) {
> +    FreePool (FileSystemHandles);
> +  }
> +
> +  FreePool (UsbPathTxt);
> +
> +  return Result;
> +}
> +
> +STATIC
> +UINT16
> +GetBBSTypeFromMessagingDevicePath (
> +  IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
> +  IN EFI_DEVICE_PATH_PROTOCOL *Node
> +  )
> +{
> +  VENDOR_DEVICE_PATH       *Vendor;
> +  UINT16                   Result;
> +
> +  Result = BBS_TYPE_UNKNOWN;
> +
> +  switch (DevicePathSubType (Node)) {
> +  case MSG_MAC_ADDR_DP:
> +    Result = BBS_TYPE_EMBEDDED_NETWORK;
> +    break;
> +
> +  case MSG_USB_DP:
> +    Result = GetBBSTypeFromUsbPath (DevicePath);
> +    if (Result == BBS_TYPE_UNKNOWN) {
> +      Result =  BBS_TYPE_USB;
> +    }
> +    break;
> +
> +  case MSG_SATA_DP:
> +    Result = BBS_TYPE_HARDDRIVE;
> +    break;
> +
> +  case MSG_VENDOR_DP:
> +    Vendor = (VENDOR_DEVICE_PATH *) (Node);
> +    if ((&Vendor->Guid) != NULL) {
> +      if (CompareGuid (&Vendor->Guid, &((EFI_GUID) DEVICE_PATH_MESSAGING_SAS))) {
> +        Result = BBS_TYPE_HARDDRIVE;
> +      }
> +    }
> +    break;
> +
> +  default:
> +    Result = BBS_TYPE_UNKNOWN;
> +    break;
> +  }
> +
> +  return Result;
> +}
> +
> +STATIC
> +UINT16
> +GetBBSTypeByDevicePath (
> +  IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
> +  )
> +{
> +  EFI_DEVICE_PATH_PROTOCOL *Node;
> +  UINT16                   Result;
> +
> +  Result = BBS_TYPE_UNKNOWN;
> +  if (DevicePath == NULL) {
> +    return Result;
> +  }
> +
> +  Node = DevicePath;
> +  while (!IsDevicePathEnd (Node)) {
> +    switch (DevicePathType (Node)) {
> +    case MEDIA_DEVICE_PATH:
> +      if (DevicePathSubType (Node) == MEDIA_CDROM_DP) {
> +        Result = BBS_TYPE_CDROM;
> +      }
> +      break;
> +
> +    case MESSAGING_DEVICE_PATH:
> +      Result = GetBBSTypeFromMessagingDevicePath (DevicePath, Node);
> +      break;
> +
> +    default:
> +      Result = BBS_TYPE_UNKNOWN;
> +      break;
> +    }
> +
> +    if (Result != BBS_TYPE_UNKNOWN) {
> +      break;
> +    }
> +
> +    Node = NextDevicePathNode (Node);
> +  }
> +
> +  return Result;
> +}
> +
> +STATIC
> +EFI_STATUS
> +GetBmcBootOptionsSetting (
> +  OUT IPMI_GET_BOOT_OPTION *BmcBootOpt
> +  )
> +{
> +  EFI_STATUS   Status;
> +
> +  Status = IpmiCmdGetSysBootOptions (BmcBootOpt);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "Get iBMC BootOpts %r!\n", Status));
> +    return Status;
> +  }
> +
> +  if (BmcBootOpt->BootFlagsValid != BOOT_OPTION_BOOT_FLAG_VALID) {
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  if (BmcBootOpt->Persistent) {
> +    BmcBootOpt->BootFlagsValid = BOOT_OPTION_BOOT_FLAG_VALID;
> +  } else {
> +    BmcBootOpt->BootFlagsValid = BOOT_OPTION_BOOT_FLAG_INVALID;
> +  }
> +
> +  Status = IpmiCmdSetSysBootOptions (BmcBootOpt);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "Set iBMC BootOpts %r!\n", Status));
> +  }
> +
> +  return Status;
> +}
> +
> +STATIC
> +VOID
> +RestoreBootOrder (
> +  VOID
> +  )
> +{
> +  EFI_STATUS                Status;
> +  UINT16                    *BootOrder;
> +  UINTN                     BootOrderSize;
> +
> +  GetVariable2 (L"BootOrderBackup", &gOemBootVaraibleGuid, (VOID **) &BootOrder, &BootOrderSize);
> +  if (BootOrder == NULL) {
> +    return ;
> +  }
> +
> +  Print (L"Restore BootOrder(%d).\n", BootOrderSize / sizeof (UINT16));
> +
> +  Status = gRT->SetVariable (
> +                  L"BootOrder",
> +                  &gEfiGlobalVariableGuid,
> +                  EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
> +                  BootOrderSize,
> +                  BootOrder
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "SetVariable BootOrder %r!\n", Status));
> +  }
> +
> +  Status = gRT->SetVariable (
> +                  L"BootOrderBackup",
> +                  &gOemBootVaraibleGuid,
> +                  EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
> +                  0,
> +                  NULL
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "SetVariable BootOrderBackup %r!\n", Status));
> +  }
> +
> +  FreePool (BootOrder);
> +
> +  return;
> +}
> +
> +
> +VOID
> +RestoreBootOrderOnReadyToBoot (
> +  IN EFI_EVENT        Event,
> +  IN VOID             *Context
> +  )
> +{
> +  // restore BootOrder variable in normal condition.
> +  RestoreBootOrder ();
> +}
> +
> +STATIC
> +VOID
> +UpdateBootOrder (
> +  IN UINT16  *NewOrder,
> +  IN UINT16  *BootOrder,
> +  IN UINTN   BootOrderSize
> +  )
> +{
> +  EFI_STATUS  Status;
> +  EFI_EVENT   Event;
> +
> +  Status = gRT->SetVariable (
> +                  L"BootOrderBackup",
> +                  &gOemBootVaraibleGuid,
> +                  EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
> +                  BootOrderSize,
> +                  BootOrder
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    return;
> +  }
> +
> +  Status = gRT->SetVariable (
> +                  L"BootOrder",
> +                  &gEfiGlobalVariableGuid,
> +                  EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
> +                  BootOrderSize,
> +                  NewOrder
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    return;
> +  }
> +
> +  // Register notify function to restore BootOrder variable on ReadyToBoot Event.
> +  Status = gBS->CreateEventEx (
> +                  EVT_NOTIFY_SIGNAL,
> +                  TPL_CALLBACK,
> +                  RestoreBootOrderOnReadyToBoot,
> +                  NULL,
> +                  &gEfiEventReadyToBootGuid,
> +                  &Event
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "Create ready to boot event %r!\n", Status));
> +  }
> +
> +  return;
> +}
> +
> +STATIC
> +VOID
> +SetBootOrder (
> +  IN UINT16 BootType
> +  )
> +{
> +  UINT16                       *NewOrder;
> +  UINT16                       *RemainBoots;
> +  UINT16                       *BootOrder;
> +  UINTN                        BootOrderSize;
> +  CHAR16                       OptionName[sizeof ("Boot####")];
> +  UINTN                        Index;
> +  LIST_ENTRY                   BootOptionList;
> +  BDS_COMMON_OPTION            *Option;
> +  UINTN                        SelectCnt;
> +  UINTN                        RemainCnt;
> +
> +  InitializeListHead (&BootOptionList);
> +
> +  GetEfiGlobalVariable2 (L"BootOrder", (VOID **) &BootOrder, &BootOrderSize);
> +  if (BootOrder == NULL) {
> +    return ;
> +  }
> +
> +  NewOrder = AllocatePool (BootOrderSize);
> +  RemainBoots = AllocatePool (BootOrderSize);
> +  if ((NewOrder == NULL) || (RemainBoots == NULL)) {
> +    DEBUG ((DEBUG_ERROR, "Out of resources."));
> +    goto Exit;
> +  }
> +
> +  SelectCnt = 0;
> +  RemainCnt = 0;
> +
> +  for (Index = 0; Index < BootOrderSize / sizeof (UINT16); Index++) {
> +    UnicodeSPrint (OptionName, sizeof (OptionName), L"Boot%04x", BootOrder[Index]);
> +    Option = BdsLibVariableToOption (&BootOptionList, OptionName);
> +    if (Option == NULL) {
> +      DEBUG ((DEBUG_ERROR, "Boot%04x is invalid option!\n", BootOrder[Index]));
> +      continue;
> +    }
> +
> +    if (GetBBSTypeByDevicePath (Option->DevicePath) == BootType) {
> +      NewOrder[SelectCnt++] = BootOrder[Index];
> +    } else {
> +      RemainBoots[RemainCnt++] = BootOrder[Index];
> +    }
> +  }
> +
> +  if (SelectCnt != 0) {
> +    // append RemainBoots to NewOrder
> +    for (Index = 0; Index < RemainCnt; Index++) {
> +      NewOrder[SelectCnt + Index] = RemainBoots[Index];
> +    }
> +
> +    if (CompareMem (NewOrder, BootOrder, BootOrderSize) != 0) {
> +      UpdateBootOrder (NewOrder, BootOrder, BootOrderSize);
> +    }
> +  }
> +
> +Exit:
> +  FreePool (BootOrder);
> +  if (NewOrder != NULL) {
> +    FreePool (NewOrder);
> +  }
> +  if (RemainBoots != NULL) {
> +    FreePool (RemainBoots);
> +  }
> +
> +  return ;
> +}
> +
> +STATIC
> +VOID
> +HandleBmcBootType (
> +  VOID
> +  )
> +{
> +  EFI_STATUS                Status;
> +  IPMI_GET_BOOT_OPTION      BmcBootOpt;
> +  UINT16                    BootType;
> +
> +  Status = GetBmcBootOptionsSetting (&BmcBootOpt);
> +  if (EFI_ERROR (Status)) {
> +    return;
> +  }
> +
> +  Print (L"Boot Type from BMC is %x\n", BmcBootOpt.BootDeviceSelector);
> +
> +  switch (BmcBootOpt.BootDeviceSelector) {
> +  case ForcePxe:
> +    BootType = BBS_TYPE_EMBEDDED_NETWORK;
> +    break;
> +
> +  case ForcePrimaryRemovableMedia:
> +    BootType = BBS_TYPE_USB;
> +    break;
> +
> +  case ForceDefaultHardDisk:
> +    BootType = BBS_TYPE_HARDDRIVE;
> +    break;
> +
> +  case ForceDefaultCD:
> +    BootType = BBS_TYPE_CDROM;
> +    break;
> +
> +  default:
> +    return;
> +  }
> +
> +  SetBootOrder (BootType);
> +}
>  
>  //
>  // BDS Platform Functions
> @@ -159,6 +591,10 @@ PlatformBdsInit (
>  {
>    //Signal EndofDxe Event
>    EfiEventGroupSignal(&gEfiEndOfDxeEventGroupGuid);
> +
> +  // restore BootOrder variable if previous BMC boot override attempt
> +  // left it in a modified state
> +  RestoreBootOrder ();
>  }
>  
>  
> @@ -473,6 +909,7 @@ PlatformBdsPolicyBehavior (
>    Print (L"Press Enter to boot OS immediately.\n");
>    Print (L"Press any other key in %d seconds to stop automatical booting...\n", PcdGet16(PcdPlatformBootTimeOut));
>    PlatformBdsEnterFrontPage (PcdGet16(PcdPlatformBootTimeOut), TRUE);
> +  HandleBmcBootType ();
>  }
>  
>  /**
> diff --git a/Chips/Hisilicon/Library/PlatformIntelBdsLib/PlatformIntelBdsLib.inf b/Chips/Hisilicon/Library/PlatformIntelBdsLib/PlatformIntelBdsLib.inf
> index baceb57..41ceb89 100644
> --- a/Chips/Hisilicon/Library/PlatformIntelBdsLib/PlatformIntelBdsLib.inf
> +++ b/Chips/Hisilicon/Library/PlatformIntelBdsLib/PlatformIntelBdsLib.inf
> @@ -42,6 +42,7 @@
>    IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
>    MdeModulePkg/MdeModulePkg.dec
>    MdePkg/MdePkg.dec
> +  OpenPlatformPkg/Chips/Hisilicon/HisiPkg.dec
>  
>  [LibraryClasses]
>    BaseLib
> @@ -49,6 +50,7 @@
>    DebugLib
>    DevicePathLib
>    GenericBdsLib
> +  IpmiCmdLib
>    MemoryAllocationLib
>    PcdLib
>    PrintLib
> @@ -68,12 +70,14 @@
>  
>  [Guids]
>    gEfiEndOfDxeEventGroupGuid
> +  gEfiEventReadyToBootGuid
>    gEfiFileInfoGuid
>    gEfiFileSystemInfoGuid
>    gEfiFileSystemVolumeLabelInfoIdGuid
>  
>  [Protocols]
>    gEfiDevicePathProtocolGuid
> +  gEfiDevicePathToTextProtocolGuid
>    gEfiGraphicsOutputProtocolGuid
>    gEfiLoadedImageProtocolGuid
>    gEfiPciRootBridgeIoProtocolGuid
> -- 
> 1.9.1
>
Chenhui Sun May 20, 2017, 12:24 a.m. | #2
Thanks Leif,

I also put these three patches(include thed03/d05 ipmi patch) on 
ssh://git@git.linaro.org/people/heyi.guo/OpenPlatformPkg.git,

branch: rp-17.04-07.


Thanks and Regards,

Chenhui Sun


在 2017/5/19 18:29, Leif Lindholm 写道:
> On Fri, May 19, 2017 at 10:54:46AM +0800, Chenhui Sun wrote:
>> From: Chenhui Sun <chenhui.sun@linaro.com>
>>
>> Support the feature that BIOS get boot option from BMC and
>> put it in the first boot order.
>>
>> Contributed-under: TianoCore Contribution Agreement 1.0
>> Signed-off-by: huangming <huangming23@huawei.com>
>> Signed-off-by: Heyi Guo <guoheyi@huawei.com>
>> Signed-off-by: Yi Li <Phoenix.liyi@huawei.com>
>> Signed-off-by: Chenhui Sun <sunchenhui@huawei.com>
> Thanks, this one looks good.
>
> Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
>
>> ---
>>   Chips/Hisilicon/Include/Library/IpmiCmdLib.h       |  94 +++++
>>   .../Library/PlatformIntelBdsLib/IntelBdsPlatform.c | 437 +++++++++++++++++++++
>>   .../PlatformIntelBdsLib/PlatformIntelBdsLib.inf    |   4 +
>>   3 files changed, 535 insertions(+)
>>   create mode 100644 Chips/Hisilicon/Include/Library/IpmiCmdLib.h
>>
>> diff --git a/Chips/Hisilicon/Include/Library/IpmiCmdLib.h b/Chips/Hisilicon/Include/Library/IpmiCmdLib.h
>> new file mode 100644
>> index 0000000..8868b76
>> --- /dev/null
>> +++ b/Chips/Hisilicon/Include/Library/IpmiCmdLib.h
>> @@ -0,0 +1,94 @@
>> +/** @file
>> +*
>> +*  Copyright (c) 2017, Hisilicon Limited. All rights reserved.
>> +*  Copyright (c) 2017, Linaro Limited. All rights reserved.
>> +*
>> +*  This program and the accompanying materials
>> +*  are licensed and made available under the terms and conditions of the BSD License
>> +*  which accompanies this distribution.  The full text of the license may be found at
>> +*  http://opensource.org/licenses/bsd-license.php
>> +*
>> +*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
>> +*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
>> +*
>> +**/
>> +
>> +#ifndef _IPMI_CMD_LIB_H_
>> +#define _IPMI_CMD_LIB_H_
>> +
>> +#define BOOT_OPTION_BOOT_FLAG_VALID         1
>> +#define BOOT_OPTION_BOOT_FLAG_INVALID       0
>> +
>> +typedef enum {
>> +  NoOverride = 0x0,
>> +  ForcePxe,
>> +  ForceDefaultHardDisk,
>> +  ForceDefaultHardDiskSafeMode,
>> +  ForceDefaultDiagnosticPartition,
>> +  ForceDefaultCD,
>> +  ForceSetupUtility,
>> +  ForceRemoteRemovableMedia,
>> +  ForceRemoteCD,
>> +  ForcePrimaryRemoteMedia,
>> +  ForceRemoteHardDisk = 0xB,
>> +  ForcePrimaryRemovableMedia = 0xF
>> +} BOOT_DEVICE_SELECTOR;
>> +
>> +//
>> +// Get System Boot Option data structure
>> +//
>> +typedef struct {
>> +  UINT8 ParameterVersion           :4;
>> +  UINT8 Reserved1                  :4;
>> +  UINT8 ParameterSelector          :7;
>> +  UINT8 ParameterValid             :1;
>> +  //
>> +  // Boot Flags Data 1
>> +  //
>> +  UINT8 Reserved2                  :5;
>> +  UINT8 BiosBootType               :1;
>> +  UINT8 Persistent                 :1;
>> +  UINT8 BootFlagsValid             :1;
>> +  //
>> +  // Boot Flags Data 2
>> +  //
>> +  UINT8 LockResetBtn               :1;
>> +  UINT8 ScreenBlank                :1;
>> +  UINT8 BootDeviceSelector         :4;
>> +  UINT8 LockKeyboard               :1;
>> +  UINT8 ClearCmos                  :1;
>> +  //
>> +  // Boot Flags Data 3
>> +  //
>> +  UINT8 ConsoleRedirectionControl  :2;
>> +  UINT8 LockSleepBtn               :1;
>> +  UINT8 UserPasswordByPass         :1;
>> +  UINT8 Reserved3                  :1;
>> +  UINT8 FirmwareVerbosity          :2;
>> +  UINT8 LockPowerBtn               :1;
>> +  //
>> +  // Boot Flags Data 4
>> +  //
>> +  UINT8 MuxControlOverride         :3;
>> +  UINT8 ShareModeOverride          :1;
>> +  UINT8 Reserved4                  :4;
>> +  //
>> +  // Boot Flags Data 5
>> +  //
>> +  UINT8 DeviceInstanceSelector     :5;
>> +  UINT8 Reserved5                  :3;
>> +} IPMI_GET_BOOT_OPTION;
>> +
>> +EFI_STATUS
>> +EFIAPI
>> +IpmiCmdSetSysBootOptions (
>> +  OUT IPMI_GET_BOOT_OPTION  *BootOption
>> +  );
>> +
>> +EFI_STATUS
>> +EFIAPI
>> +IpmiCmdGetSysBootOptions (
>> +  IN IPMI_GET_BOOT_OPTION   *BootOption
>> +  );
>> +
>> +#endif
>> diff --git a/Chips/Hisilicon/Library/PlatformIntelBdsLib/IntelBdsPlatform.c b/Chips/Hisilicon/Library/PlatformIntelBdsLib/IntelBdsPlatform.c
>> index efefeb6..dc23e46 100644
>> --- a/Chips/Hisilicon/Library/PlatformIntelBdsLib/IntelBdsPlatform.c
>> +++ b/Chips/Hisilicon/Library/PlatformIntelBdsLib/IntelBdsPlatform.c
>> @@ -21,16 +21,23 @@
>>   
>>   #include <IndustryStandard/Pci22.h>
>>   #include <Library/DevicePathLib.h>
>> +#include <Library/GenericBdsLib.h>
>> +#include <Library/IpmiCmdLib.h>
>>   #include <Library/PcdLib.h>
>>   #include <Library/PlatformBdsLib.h>
>> +#include <Library/PrintLib.h>
>>   #include <Library/UefiLib.h>
>>   #include <Protocol/DevicePath.h>
>> +#include <Protocol/DevicePathToText.h>
>>   #include <Protocol/GraphicsOutput.h>
>>   #include <Protocol/PciIo.h>
>>   #include <Protocol/PciRootBridgeIo.h>
>> +#include <Guid/GlobalVariable.h>
>>   
>>   #include "IntelBdsPlatform.h"
>>   
>> +GUID gOemBootVaraibleGuid = {0xb7784577, 0x5aaf, 0x4557, {0xa1, 0x99,
>> +  0xd4, 0xa4, 0x2f, 0x45, 0x06, 0xf8} };
>>   
>>   //3CEF354A-3B7A-4519-AD70-72A134698311
>>   GUID gEblFileGuid = {0x3CEF354A, 0x3B7A, 0x4519, {0xAD, 0x70,
>> @@ -142,6 +149,431 @@ STATIC PLATFORM_USB_KEYBOARD mUsbKeyboard = {
>>     }
>>   };
>>   
>> +STATIC
>> +UINT16
>> +GetBBSTypeFromFileSysPath (
>> +  IN CHAR16                   *UsbPathTxt,
>> +  IN CHAR16                   *FileSysPathTxt,
>> +  IN EFI_DEVICE_PATH_PROTOCOL *FileSysPath
>> +  )
>> +{
>> +  EFI_DEVICE_PATH_PROTOCOL *Node;
>> +
>> +  if (StrnCmp (UsbPathTxt, FileSysPathTxt, StrLen (UsbPathTxt)) == 0) {
>> +    Node = FileSysPath;
>> +    while (!IsDevicePathEnd (Node)) {
>> +      if ((DevicePathType (Node) == MEDIA_DEVICE_PATH) &&
>> +          (DevicePathSubType (Node) == MEDIA_CDROM_DP)) {
>> +        return BBS_TYPE_CDROM;
>> +      }
>> +      Node = NextDevicePathNode (Node);
>> +    }
>> +  }
>> +
>> +  return BBS_TYPE_UNKNOWN;
>> +}
>> +
>> +STATIC
>> +UINT16
>> +GetBBSTypeFromUsbPath (
>> +  IN CONST EFI_DEVICE_PATH_PROTOCOL *UsbPath
>> +  )
>> +{
>> +  EFI_STATUS                        Status;
>> +  EFI_HANDLE                        *FileSystemHandles;
>> +  UINTN                             NumberFileSystemHandles;
>> +  UINTN                             Index;
>> +  EFI_DEVICE_PATH_PROTOCOL          *FileSysPath;
>> +  EFI_DEVICE_PATH_TO_TEXT_PROTOCOL  *DevPathToText;
>> +  CHAR16                            *UsbPathTxt;
>> +  CHAR16                            *FileSysPathTxt;
>> +  UINT16                            Result;
>> +
>> +  Status = gBS->LocateProtocol (&gEfiDevicePathToTextProtocolGuid, NULL, (VOID **) &DevPathToText);
>> +  if (EFI_ERROR (Status)) {
>> +    DEBUG ((DEBUG_ERROR, "Locate DevicePathToTextPro %r\n", Status));
>> +    return BBS_TYPE_UNKNOWN;
>> +  }
>> +
>> +  Result = BBS_TYPE_UNKNOWN;
>> +  UsbPathTxt = DevPathToText->ConvertDevicePathToText (UsbPath, TRUE, TRUE);
>> +  if (UsbPathTxt == NULL) {
>> +    return Result;
>> +  }
>> +
>> +  Status = gBS->LocateHandleBuffer (
>> +                  ByProtocol,
>> +                  &gEfiSimpleFileSystemProtocolGuid,
>> +                  NULL,
>> +                  &NumberFileSystemHandles,
>> +                  &FileSystemHandles
>> +                  );
>> +  if (EFI_ERROR (Status)) {
>> +    DEBUG ((DEBUG_ERROR, "Locate SimpleFileSystemProtocol error(%r)\n", Status));
>> +    FreePool (UsbPathTxt);
>> +    return BBS_TYPE_UNKNOWN;
>> +  }
>> +
>> +  for (Index = 0; Index < NumberFileSystemHandles; Index++) {
>> +    FileSysPath = DevicePathFromHandle (FileSystemHandles[Index]);
>> +    FileSysPathTxt = DevPathToText->ConvertDevicePathToText (FileSysPath, TRUE, TRUE);
>> +
>> +    if (FileSysPathTxt == NULL) {
>> +      continue;
>> +    }
>> +
>> +    Result = GetBBSTypeFromFileSysPath (UsbPathTxt, FileSysPathTxt, FileSysPath);
>> +    FreePool (FileSysPathTxt);
>> +
>> +    if (Result != BBS_TYPE_UNKNOWN) {
>> +      break;
>> +    }
>> +  }
>> +
>> +  if (NumberFileSystemHandles != 0) {
>> +    FreePool (FileSystemHandles);
>> +  }
>> +
>> +  FreePool (UsbPathTxt);
>> +
>> +  return Result;
>> +}
>> +
>> +STATIC
>> +UINT16
>> +GetBBSTypeFromMessagingDevicePath (
>> +  IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
>> +  IN EFI_DEVICE_PATH_PROTOCOL *Node
>> +  )
>> +{
>> +  VENDOR_DEVICE_PATH       *Vendor;
>> +  UINT16                   Result;
>> +
>> +  Result = BBS_TYPE_UNKNOWN;
>> +
>> +  switch (DevicePathSubType (Node)) {
>> +  case MSG_MAC_ADDR_DP:
>> +    Result = BBS_TYPE_EMBEDDED_NETWORK;
>> +    break;
>> +
>> +  case MSG_USB_DP:
>> +    Result = GetBBSTypeFromUsbPath (DevicePath);
>> +    if (Result == BBS_TYPE_UNKNOWN) {
>> +      Result =  BBS_TYPE_USB;
>> +    }
>> +    break;
>> +
>> +  case MSG_SATA_DP:
>> +    Result = BBS_TYPE_HARDDRIVE;
>> +    break;
>> +
>> +  case MSG_VENDOR_DP:
>> +    Vendor = (VENDOR_DEVICE_PATH *) (Node);
>> +    if ((&Vendor->Guid) != NULL) {
>> +      if (CompareGuid (&Vendor->Guid, &((EFI_GUID) DEVICE_PATH_MESSAGING_SAS))) {
>> +        Result = BBS_TYPE_HARDDRIVE;
>> +      }
>> +    }
>> +    break;
>> +
>> +  default:
>> +    Result = BBS_TYPE_UNKNOWN;
>> +    break;
>> +  }
>> +
>> +  return Result;
>> +}
>> +
>> +STATIC
>> +UINT16
>> +GetBBSTypeByDevicePath (
>> +  IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
>> +  )
>> +{
>> +  EFI_DEVICE_PATH_PROTOCOL *Node;
>> +  UINT16                   Result;
>> +
>> +  Result = BBS_TYPE_UNKNOWN;
>> +  if (DevicePath == NULL) {
>> +    return Result;
>> +  }
>> +
>> +  Node = DevicePath;
>> +  while (!IsDevicePathEnd (Node)) {
>> +    switch (DevicePathType (Node)) {
>> +    case MEDIA_DEVICE_PATH:
>> +      if (DevicePathSubType (Node) == MEDIA_CDROM_DP) {
>> +        Result = BBS_TYPE_CDROM;
>> +      }
>> +      break;
>> +
>> +    case MESSAGING_DEVICE_PATH:
>> +      Result = GetBBSTypeFromMessagingDevicePath (DevicePath, Node);
>> +      break;
>> +
>> +    default:
>> +      Result = BBS_TYPE_UNKNOWN;
>> +      break;
>> +    }
>> +
>> +    if (Result != BBS_TYPE_UNKNOWN) {
>> +      break;
>> +    }
>> +
>> +    Node = NextDevicePathNode (Node);
>> +  }
>> +
>> +  return Result;
>> +}
>> +
>> +STATIC
>> +EFI_STATUS
>> +GetBmcBootOptionsSetting (
>> +  OUT IPMI_GET_BOOT_OPTION *BmcBootOpt
>> +  )
>> +{
>> +  EFI_STATUS   Status;
>> +
>> +  Status = IpmiCmdGetSysBootOptions (BmcBootOpt);
>> +  if (EFI_ERROR (Status)) {
>> +    DEBUG ((DEBUG_ERROR, "Get iBMC BootOpts %r!\n", Status));
>> +    return Status;
>> +  }
>> +
>> +  if (BmcBootOpt->BootFlagsValid != BOOT_OPTION_BOOT_FLAG_VALID) {
>> +    return EFI_NOT_FOUND;
>> +  }
>> +
>> +  if (BmcBootOpt->Persistent) {
>> +    BmcBootOpt->BootFlagsValid = BOOT_OPTION_BOOT_FLAG_VALID;
>> +  } else {
>> +    BmcBootOpt->BootFlagsValid = BOOT_OPTION_BOOT_FLAG_INVALID;
>> +  }
>> +
>> +  Status = IpmiCmdSetSysBootOptions (BmcBootOpt);
>> +  if (EFI_ERROR (Status)) {
>> +    DEBUG ((DEBUG_ERROR, "Set iBMC BootOpts %r!\n", Status));
>> +  }
>> +
>> +  return Status;
>> +}
>> +
>> +STATIC
>> +VOID
>> +RestoreBootOrder (
>> +  VOID
>> +  )
>> +{
>> +  EFI_STATUS                Status;
>> +  UINT16                    *BootOrder;
>> +  UINTN                     BootOrderSize;
>> +
>> +  GetVariable2 (L"BootOrderBackup", &gOemBootVaraibleGuid, (VOID **) &BootOrder, &BootOrderSize);
>> +  if (BootOrder == NULL) {
>> +    return ;
>> +  }
>> +
>> +  Print (L"Restore BootOrder(%d).\n", BootOrderSize / sizeof (UINT16));
>> +
>> +  Status = gRT->SetVariable (
>> +                  L"BootOrder",
>> +                  &gEfiGlobalVariableGuid,
>> +                  EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
>> +                  BootOrderSize,
>> +                  BootOrder
>> +                  );
>> +  if (EFI_ERROR (Status)) {
>> +    DEBUG ((DEBUG_ERROR, "SetVariable BootOrder %r!\n", Status));
>> +  }
>> +
>> +  Status = gRT->SetVariable (
>> +                  L"BootOrderBackup",
>> +                  &gOemBootVaraibleGuid,
>> +                  EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
>> +                  0,
>> +                  NULL
>> +                  );
>> +  if (EFI_ERROR (Status)) {
>> +    DEBUG ((DEBUG_ERROR, "SetVariable BootOrderBackup %r!\n", Status));
>> +  }
>> +
>> +  FreePool (BootOrder);
>> +
>> +  return;
>> +}
>> +
>> +
>> +VOID
>> +RestoreBootOrderOnReadyToBoot (
>> +  IN EFI_EVENT        Event,
>> +  IN VOID             *Context
>> +  )
>> +{
>> +  // restore BootOrder variable in normal condition.
>> +  RestoreBootOrder ();
>> +}
>> +
>> +STATIC
>> +VOID
>> +UpdateBootOrder (
>> +  IN UINT16  *NewOrder,
>> +  IN UINT16  *BootOrder,
>> +  IN UINTN   BootOrderSize
>> +  )
>> +{
>> +  EFI_STATUS  Status;
>> +  EFI_EVENT   Event;
>> +
>> +  Status = gRT->SetVariable (
>> +                  L"BootOrderBackup",
>> +                  &gOemBootVaraibleGuid,
>> +                  EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
>> +                  BootOrderSize,
>> +                  BootOrder
>> +                  );
>> +  if (EFI_ERROR (Status)) {
>> +    return;
>> +  }
>> +
>> +  Status = gRT->SetVariable (
>> +                  L"BootOrder",
>> +                  &gEfiGlobalVariableGuid,
>> +                  EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
>> +                  BootOrderSize,
>> +                  NewOrder
>> +                  );
>> +  if (EFI_ERROR (Status)) {
>> +    return;
>> +  }
>> +
>> +  // Register notify function to restore BootOrder variable on ReadyToBoot Event.
>> +  Status = gBS->CreateEventEx (
>> +                  EVT_NOTIFY_SIGNAL,
>> +                  TPL_CALLBACK,
>> +                  RestoreBootOrderOnReadyToBoot,
>> +                  NULL,
>> +                  &gEfiEventReadyToBootGuid,
>> +                  &Event
>> +                  );
>> +  if (EFI_ERROR (Status)) {
>> +    DEBUG ((DEBUG_ERROR, "Create ready to boot event %r!\n", Status));
>> +  }
>> +
>> +  return;
>> +}
>> +
>> +STATIC
>> +VOID
>> +SetBootOrder (
>> +  IN UINT16 BootType
>> +  )
>> +{
>> +  UINT16                       *NewOrder;
>> +  UINT16                       *RemainBoots;
>> +  UINT16                       *BootOrder;
>> +  UINTN                        BootOrderSize;
>> +  CHAR16                       OptionName[sizeof ("Boot####")];
>> +  UINTN                        Index;
>> +  LIST_ENTRY                   BootOptionList;
>> +  BDS_COMMON_OPTION            *Option;
>> +  UINTN                        SelectCnt;
>> +  UINTN                        RemainCnt;
>> +
>> +  InitializeListHead (&BootOptionList);
>> +
>> +  GetEfiGlobalVariable2 (L"BootOrder", (VOID **) &BootOrder, &BootOrderSize);
>> +  if (BootOrder == NULL) {
>> +    return ;
>> +  }
>> +
>> +  NewOrder = AllocatePool (BootOrderSize);
>> +  RemainBoots = AllocatePool (BootOrderSize);
>> +  if ((NewOrder == NULL) || (RemainBoots == NULL)) {
>> +    DEBUG ((DEBUG_ERROR, "Out of resources."));
>> +    goto Exit;
>> +  }
>> +
>> +  SelectCnt = 0;
>> +  RemainCnt = 0;
>> +
>> +  for (Index = 0; Index < BootOrderSize / sizeof (UINT16); Index++) {
>> +    UnicodeSPrint (OptionName, sizeof (OptionName), L"Boot%04x", BootOrder[Index]);
>> +    Option = BdsLibVariableToOption (&BootOptionList, OptionName);
>> +    if (Option == NULL) {
>> +      DEBUG ((DEBUG_ERROR, "Boot%04x is invalid option!\n", BootOrder[Index]));
>> +      continue;
>> +    }
>> +
>> +    if (GetBBSTypeByDevicePath (Option->DevicePath) == BootType) {
>> +      NewOrder[SelectCnt++] = BootOrder[Index];
>> +    } else {
>> +      RemainBoots[RemainCnt++] = BootOrder[Index];
>> +    }
>> +  }
>> +
>> +  if (SelectCnt != 0) {
>> +    // append RemainBoots to NewOrder
>> +    for (Index = 0; Index < RemainCnt; Index++) {
>> +      NewOrder[SelectCnt + Index] = RemainBoots[Index];
>> +    }
>> +
>> +    if (CompareMem (NewOrder, BootOrder, BootOrderSize) != 0) {
>> +      UpdateBootOrder (NewOrder, BootOrder, BootOrderSize);
>> +    }
>> +  }
>> +
>> +Exit:
>> +  FreePool (BootOrder);
>> +  if (NewOrder != NULL) {
>> +    FreePool (NewOrder);
>> +  }
>> +  if (RemainBoots != NULL) {
>> +    FreePool (RemainBoots);
>> +  }
>> +
>> +  return ;
>> +}
>> +
>> +STATIC
>> +VOID
>> +HandleBmcBootType (
>> +  VOID
>> +  )
>> +{
>> +  EFI_STATUS                Status;
>> +  IPMI_GET_BOOT_OPTION      BmcBootOpt;
>> +  UINT16                    BootType;
>> +
>> +  Status = GetBmcBootOptionsSetting (&BmcBootOpt);
>> +  if (EFI_ERROR (Status)) {
>> +    return;
>> +  }
>> +
>> +  Print (L"Boot Type from BMC is %x\n", BmcBootOpt.BootDeviceSelector);
>> +
>> +  switch (BmcBootOpt.BootDeviceSelector) {
>> +  case ForcePxe:
>> +    BootType = BBS_TYPE_EMBEDDED_NETWORK;
>> +    break;
>> +
>> +  case ForcePrimaryRemovableMedia:
>> +    BootType = BBS_TYPE_USB;
>> +    break;
>> +
>> +  case ForceDefaultHardDisk:
>> +    BootType = BBS_TYPE_HARDDRIVE;
>> +    break;
>> +
>> +  case ForceDefaultCD:
>> +    BootType = BBS_TYPE_CDROM;
>> +    break;
>> +
>> +  default:
>> +    return;
>> +  }
>> +
>> +  SetBootOrder (BootType);
>> +}
>>   
>>   //
>>   // BDS Platform Functions
>> @@ -159,6 +591,10 @@ PlatformBdsInit (
>>   {
>>     //Signal EndofDxe Event
>>     EfiEventGroupSignal(&gEfiEndOfDxeEventGroupGuid);
>> +
>> +  // restore BootOrder variable if previous BMC boot override attempt
>> +  // left it in a modified state
>> +  RestoreBootOrder ();
>>   }
>>   
>>   
>> @@ -473,6 +909,7 @@ PlatformBdsPolicyBehavior (
>>     Print (L"Press Enter to boot OS immediately.\n");
>>     Print (L"Press any other key in %d seconds to stop automatical booting...\n", PcdGet16(PcdPlatformBootTimeOut));
>>     PlatformBdsEnterFrontPage (PcdGet16(PcdPlatformBootTimeOut), TRUE);
>> +  HandleBmcBootType ();
>>   }
>>   
>>   /**
>> diff --git a/Chips/Hisilicon/Library/PlatformIntelBdsLib/PlatformIntelBdsLib.inf b/Chips/Hisilicon/Library/PlatformIntelBdsLib/PlatformIntelBdsLib.inf
>> index baceb57..41ceb89 100644
>> --- a/Chips/Hisilicon/Library/PlatformIntelBdsLib/PlatformIntelBdsLib.inf
>> +++ b/Chips/Hisilicon/Library/PlatformIntelBdsLib/PlatformIntelBdsLib.inf
>> @@ -42,6 +42,7 @@
>>     IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
>>     MdeModulePkg/MdeModulePkg.dec
>>     MdePkg/MdePkg.dec
>> +  OpenPlatformPkg/Chips/Hisilicon/HisiPkg.dec
>>   
>>   [LibraryClasses]
>>     BaseLib
>> @@ -49,6 +50,7 @@
>>     DebugLib
>>     DevicePathLib
>>     GenericBdsLib
>> +  IpmiCmdLib
>>     MemoryAllocationLib
>>     PcdLib
>>     PrintLib
>> @@ -68,12 +70,14 @@
>>   
>>   [Guids]
>>     gEfiEndOfDxeEventGroupGuid
>> +  gEfiEventReadyToBootGuid
>>     gEfiFileInfoGuid
>>     gEfiFileSystemInfoGuid
>>     gEfiFileSystemVolumeLabelInfoIdGuid
>>   
>>   [Protocols]
>>     gEfiDevicePathProtocolGuid
>> +  gEfiDevicePathToTextProtocolGuid
>>     gEfiGraphicsOutputProtocolGuid
>>     gEfiLoadedImageProtocolGuid
>>     gEfiPciRootBridgeIoProtocolGuid
>> -- 
>> 1.9.1
>>

Patch hide | download patch | download mbox

diff --git a/Chips/Hisilicon/Include/Library/IpmiCmdLib.h b/Chips/Hisilicon/Include/Library/IpmiCmdLib.h
new file mode 100644
index 0000000..8868b76
--- /dev/null
+++ b/Chips/Hisilicon/Include/Library/IpmiCmdLib.h
@@ -0,0 +1,94 @@ 
+/** @file
+*
+*  Copyright (c) 2017, Hisilicon Limited. All rights reserved.
+*  Copyright (c) 2017, Linaro Limited. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#ifndef _IPMI_CMD_LIB_H_
+#define _IPMI_CMD_LIB_H_
+
+#define BOOT_OPTION_BOOT_FLAG_VALID         1
+#define BOOT_OPTION_BOOT_FLAG_INVALID       0
+
+typedef enum {
+  NoOverride = 0x0,
+  ForcePxe,
+  ForceDefaultHardDisk,
+  ForceDefaultHardDiskSafeMode,
+  ForceDefaultDiagnosticPartition,
+  ForceDefaultCD,
+  ForceSetupUtility,
+  ForceRemoteRemovableMedia,
+  ForceRemoteCD,
+  ForcePrimaryRemoteMedia,
+  ForceRemoteHardDisk = 0xB,
+  ForcePrimaryRemovableMedia = 0xF
+} BOOT_DEVICE_SELECTOR;
+
+//
+// Get System Boot Option data structure
+//
+typedef struct {
+  UINT8 ParameterVersion           :4;
+  UINT8 Reserved1                  :4;
+  UINT8 ParameterSelector          :7;
+  UINT8 ParameterValid             :1;
+  //
+  // Boot Flags Data 1
+  //
+  UINT8 Reserved2                  :5;
+  UINT8 BiosBootType               :1;
+  UINT8 Persistent                 :1;
+  UINT8 BootFlagsValid             :1;
+  //
+  // Boot Flags Data 2
+  //
+  UINT8 LockResetBtn               :1;
+  UINT8 ScreenBlank                :1;
+  UINT8 BootDeviceSelector         :4;
+  UINT8 LockKeyboard               :1;
+  UINT8 ClearCmos                  :1;
+  //
+  // Boot Flags Data 3
+  //
+  UINT8 ConsoleRedirectionControl  :2;
+  UINT8 LockSleepBtn               :1;
+  UINT8 UserPasswordByPass         :1;
+  UINT8 Reserved3                  :1;
+  UINT8 FirmwareVerbosity          :2;
+  UINT8 LockPowerBtn               :1;
+  //
+  // Boot Flags Data 4
+  //
+  UINT8 MuxControlOverride         :3;
+  UINT8 ShareModeOverride          :1;
+  UINT8 Reserved4                  :4;
+  //
+  // Boot Flags Data 5
+  //
+  UINT8 DeviceInstanceSelector     :5;
+  UINT8 Reserved5                  :3;
+} IPMI_GET_BOOT_OPTION;
+
+EFI_STATUS
+EFIAPI
+IpmiCmdSetSysBootOptions (
+  OUT IPMI_GET_BOOT_OPTION  *BootOption
+  );
+
+EFI_STATUS
+EFIAPI
+IpmiCmdGetSysBootOptions (
+  IN IPMI_GET_BOOT_OPTION   *BootOption
+  );
+
+#endif
diff --git a/Chips/Hisilicon/Library/PlatformIntelBdsLib/IntelBdsPlatform.c b/Chips/Hisilicon/Library/PlatformIntelBdsLib/IntelBdsPlatform.c
index efefeb6..dc23e46 100644
--- a/Chips/Hisilicon/Library/PlatformIntelBdsLib/IntelBdsPlatform.c
+++ b/Chips/Hisilicon/Library/PlatformIntelBdsLib/IntelBdsPlatform.c
@@ -21,16 +21,23 @@ 
 
 #include <IndustryStandard/Pci22.h>
 #include <Library/DevicePathLib.h>
+#include <Library/GenericBdsLib.h>
+#include <Library/IpmiCmdLib.h>
 #include <Library/PcdLib.h>
 #include <Library/PlatformBdsLib.h>
+#include <Library/PrintLib.h>
 #include <Library/UefiLib.h>
 #include <Protocol/DevicePath.h>
+#include <Protocol/DevicePathToText.h>
 #include <Protocol/GraphicsOutput.h>
 #include <Protocol/PciIo.h>
 #include <Protocol/PciRootBridgeIo.h>
+#include <Guid/GlobalVariable.h>
 
 #include "IntelBdsPlatform.h"
 
+GUID gOemBootVaraibleGuid = {0xb7784577, 0x5aaf, 0x4557, {0xa1, 0x99,
+  0xd4, 0xa4, 0x2f, 0x45, 0x06, 0xf8} };
 
 //3CEF354A-3B7A-4519-AD70-72A134698311
 GUID gEblFileGuid = {0x3CEF354A, 0x3B7A, 0x4519, {0xAD, 0x70,
@@ -142,6 +149,431 @@  STATIC PLATFORM_USB_KEYBOARD mUsbKeyboard = {
   }
 };
 
+STATIC
+UINT16
+GetBBSTypeFromFileSysPath (
+  IN CHAR16                   *UsbPathTxt,
+  IN CHAR16                   *FileSysPathTxt,
+  IN EFI_DEVICE_PATH_PROTOCOL *FileSysPath
+  )
+{
+  EFI_DEVICE_PATH_PROTOCOL *Node;
+
+  if (StrnCmp (UsbPathTxt, FileSysPathTxt, StrLen (UsbPathTxt)) == 0) {
+    Node = FileSysPath;
+    while (!IsDevicePathEnd (Node)) {
+      if ((DevicePathType (Node) == MEDIA_DEVICE_PATH) &&
+          (DevicePathSubType (Node) == MEDIA_CDROM_DP)) {
+        return BBS_TYPE_CDROM;
+      }
+      Node = NextDevicePathNode (Node);
+    }
+  }
+
+  return BBS_TYPE_UNKNOWN;
+}
+
+STATIC
+UINT16
+GetBBSTypeFromUsbPath (
+  IN CONST EFI_DEVICE_PATH_PROTOCOL *UsbPath
+  )
+{
+  EFI_STATUS                        Status;
+  EFI_HANDLE                        *FileSystemHandles;
+  UINTN                             NumberFileSystemHandles;
+  UINTN                             Index;
+  EFI_DEVICE_PATH_PROTOCOL          *FileSysPath;
+  EFI_DEVICE_PATH_TO_TEXT_PROTOCOL  *DevPathToText;
+  CHAR16                            *UsbPathTxt;
+  CHAR16                            *FileSysPathTxt;
+  UINT16                            Result;
+
+  Status = gBS->LocateProtocol (&gEfiDevicePathToTextProtocolGuid, NULL, (VOID **) &DevPathToText);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Locate DevicePathToTextPro %r\n", Status));
+    return BBS_TYPE_UNKNOWN;
+  }
+
+  Result = BBS_TYPE_UNKNOWN;
+  UsbPathTxt = DevPathToText->ConvertDevicePathToText (UsbPath, TRUE, TRUE);
+  if (UsbPathTxt == NULL) {
+    return Result;
+  }
+
+  Status = gBS->LocateHandleBuffer (
+                  ByProtocol,
+                  &gEfiSimpleFileSystemProtocolGuid,
+                  NULL,
+                  &NumberFileSystemHandles,
+                  &FileSystemHandles
+                  );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Locate SimpleFileSystemProtocol error(%r)\n", Status));
+    FreePool (UsbPathTxt);
+    return BBS_TYPE_UNKNOWN;
+  }
+
+  for (Index = 0; Index < NumberFileSystemHandles; Index++) {
+    FileSysPath = DevicePathFromHandle (FileSystemHandles[Index]);
+    FileSysPathTxt = DevPathToText->ConvertDevicePathToText (FileSysPath, TRUE, TRUE);
+
+    if (FileSysPathTxt == NULL) {
+      continue;
+    }
+
+    Result = GetBBSTypeFromFileSysPath (UsbPathTxt, FileSysPathTxt, FileSysPath);
+    FreePool (FileSysPathTxt);
+
+    if (Result != BBS_TYPE_UNKNOWN) {
+      break;
+    }
+  }
+
+  if (NumberFileSystemHandles != 0) {
+    FreePool (FileSystemHandles);
+  }
+
+  FreePool (UsbPathTxt);
+
+  return Result;
+}
+
+STATIC
+UINT16
+GetBBSTypeFromMessagingDevicePath (
+  IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+  IN EFI_DEVICE_PATH_PROTOCOL *Node
+  )
+{
+  VENDOR_DEVICE_PATH       *Vendor;
+  UINT16                   Result;
+
+  Result = BBS_TYPE_UNKNOWN;
+
+  switch (DevicePathSubType (Node)) {
+  case MSG_MAC_ADDR_DP:
+    Result = BBS_TYPE_EMBEDDED_NETWORK;
+    break;
+
+  case MSG_USB_DP:
+    Result = GetBBSTypeFromUsbPath (DevicePath);
+    if (Result == BBS_TYPE_UNKNOWN) {
+      Result =  BBS_TYPE_USB;
+    }
+    break;
+
+  case MSG_SATA_DP:
+    Result = BBS_TYPE_HARDDRIVE;
+    break;
+
+  case MSG_VENDOR_DP:
+    Vendor = (VENDOR_DEVICE_PATH *) (Node);
+    if ((&Vendor->Guid) != NULL) {
+      if (CompareGuid (&Vendor->Guid, &((EFI_GUID) DEVICE_PATH_MESSAGING_SAS))) {
+        Result = BBS_TYPE_HARDDRIVE;
+      }
+    }
+    break;
+
+  default:
+    Result = BBS_TYPE_UNKNOWN;
+    break;
+  }
+
+  return Result;
+}
+
+STATIC
+UINT16
+GetBBSTypeByDevicePath (
+  IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
+  )
+{
+  EFI_DEVICE_PATH_PROTOCOL *Node;
+  UINT16                   Result;
+
+  Result = BBS_TYPE_UNKNOWN;
+  if (DevicePath == NULL) {
+    return Result;
+  }
+
+  Node = DevicePath;
+  while (!IsDevicePathEnd (Node)) {
+    switch (DevicePathType (Node)) {
+    case MEDIA_DEVICE_PATH:
+      if (DevicePathSubType (Node) == MEDIA_CDROM_DP) {
+        Result = BBS_TYPE_CDROM;
+      }
+      break;
+
+    case MESSAGING_DEVICE_PATH:
+      Result = GetBBSTypeFromMessagingDevicePath (DevicePath, Node);
+      break;
+
+    default:
+      Result = BBS_TYPE_UNKNOWN;
+      break;
+    }
+
+    if (Result != BBS_TYPE_UNKNOWN) {
+      break;
+    }
+
+    Node = NextDevicePathNode (Node);
+  }
+
+  return Result;
+}
+
+STATIC
+EFI_STATUS
+GetBmcBootOptionsSetting (
+  OUT IPMI_GET_BOOT_OPTION *BmcBootOpt
+  )
+{
+  EFI_STATUS   Status;
+
+  Status = IpmiCmdGetSysBootOptions (BmcBootOpt);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Get iBMC BootOpts %r!\n", Status));
+    return Status;
+  }
+
+  if (BmcBootOpt->BootFlagsValid != BOOT_OPTION_BOOT_FLAG_VALID) {
+    return EFI_NOT_FOUND;
+  }
+
+  if (BmcBootOpt->Persistent) {
+    BmcBootOpt->BootFlagsValid = BOOT_OPTION_BOOT_FLAG_VALID;
+  } else {
+    BmcBootOpt->BootFlagsValid = BOOT_OPTION_BOOT_FLAG_INVALID;
+  }
+
+  Status = IpmiCmdSetSysBootOptions (BmcBootOpt);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Set iBMC BootOpts %r!\n", Status));
+  }
+
+  return Status;
+}
+
+STATIC
+VOID
+RestoreBootOrder (
+  VOID
+  )
+{
+  EFI_STATUS                Status;
+  UINT16                    *BootOrder;
+  UINTN                     BootOrderSize;
+
+  GetVariable2 (L"BootOrderBackup", &gOemBootVaraibleGuid, (VOID **) &BootOrder, &BootOrderSize);
+  if (BootOrder == NULL) {
+    return ;
+  }
+
+  Print (L"Restore BootOrder(%d).\n", BootOrderSize / sizeof (UINT16));
+
+  Status = gRT->SetVariable (
+                  L"BootOrder",
+                  &gEfiGlobalVariableGuid,
+                  EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+                  BootOrderSize,
+                  BootOrder
+                  );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "SetVariable BootOrder %r!\n", Status));
+  }
+
+  Status = gRT->SetVariable (
+                  L"BootOrderBackup",
+                  &gOemBootVaraibleGuid,
+                  EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+                  0,
+                  NULL
+                  );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "SetVariable BootOrderBackup %r!\n", Status));
+  }
+
+  FreePool (BootOrder);
+
+  return;
+}
+
+
+VOID
+RestoreBootOrderOnReadyToBoot (
+  IN EFI_EVENT        Event,
+  IN VOID             *Context
+  )
+{
+  // restore BootOrder variable in normal condition.
+  RestoreBootOrder ();
+}
+
+STATIC
+VOID
+UpdateBootOrder (
+  IN UINT16  *NewOrder,
+  IN UINT16  *BootOrder,
+  IN UINTN   BootOrderSize
+  )
+{
+  EFI_STATUS  Status;
+  EFI_EVENT   Event;
+
+  Status = gRT->SetVariable (
+                  L"BootOrderBackup",
+                  &gOemBootVaraibleGuid,
+                  EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+                  BootOrderSize,
+                  BootOrder
+                  );
+  if (EFI_ERROR (Status)) {
+    return;
+  }
+
+  Status = gRT->SetVariable (
+                  L"BootOrder",
+                  &gEfiGlobalVariableGuid,
+                  EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+                  BootOrderSize,
+                  NewOrder
+                  );
+  if (EFI_ERROR (Status)) {
+    return;
+  }
+
+  // Register notify function to restore BootOrder variable on ReadyToBoot Event.
+  Status = gBS->CreateEventEx (
+                  EVT_NOTIFY_SIGNAL,
+                  TPL_CALLBACK,
+                  RestoreBootOrderOnReadyToBoot,
+                  NULL,
+                  &gEfiEventReadyToBootGuid,
+                  &Event
+                  );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Create ready to boot event %r!\n", Status));
+  }
+
+  return;
+}
+
+STATIC
+VOID
+SetBootOrder (
+  IN UINT16 BootType
+  )
+{
+  UINT16                       *NewOrder;
+  UINT16                       *RemainBoots;
+  UINT16                       *BootOrder;
+  UINTN                        BootOrderSize;
+  CHAR16                       OptionName[sizeof ("Boot####")];
+  UINTN                        Index;
+  LIST_ENTRY                   BootOptionList;
+  BDS_COMMON_OPTION            *Option;
+  UINTN                        SelectCnt;
+  UINTN                        RemainCnt;
+
+  InitializeListHead (&BootOptionList);
+
+  GetEfiGlobalVariable2 (L"BootOrder", (VOID **) &BootOrder, &BootOrderSize);
+  if (BootOrder == NULL) {
+    return ;
+  }
+
+  NewOrder = AllocatePool (BootOrderSize);
+  RemainBoots = AllocatePool (BootOrderSize);
+  if ((NewOrder == NULL) || (RemainBoots == NULL)) {
+    DEBUG ((DEBUG_ERROR, "Out of resources."));
+    goto Exit;
+  }
+
+  SelectCnt = 0;
+  RemainCnt = 0;
+
+  for (Index = 0; Index < BootOrderSize / sizeof (UINT16); Index++) {
+    UnicodeSPrint (OptionName, sizeof (OptionName), L"Boot%04x", BootOrder[Index]);
+    Option = BdsLibVariableToOption (&BootOptionList, OptionName);
+    if (Option == NULL) {
+      DEBUG ((DEBUG_ERROR, "Boot%04x is invalid option!\n", BootOrder[Index]));
+      continue;
+    }
+
+    if (GetBBSTypeByDevicePath (Option->DevicePath) == BootType) {
+      NewOrder[SelectCnt++] = BootOrder[Index];
+    } else {
+      RemainBoots[RemainCnt++] = BootOrder[Index];
+    }
+  }
+
+  if (SelectCnt != 0) {
+    // append RemainBoots to NewOrder
+    for (Index = 0; Index < RemainCnt; Index++) {
+      NewOrder[SelectCnt + Index] = RemainBoots[Index];
+    }
+
+    if (CompareMem (NewOrder, BootOrder, BootOrderSize) != 0) {
+      UpdateBootOrder (NewOrder, BootOrder, BootOrderSize);
+    }
+  }
+
+Exit:
+  FreePool (BootOrder);
+  if (NewOrder != NULL) {
+    FreePool (NewOrder);
+  }
+  if (RemainBoots != NULL) {
+    FreePool (RemainBoots);
+  }
+
+  return ;
+}
+
+STATIC
+VOID
+HandleBmcBootType (
+  VOID
+  )
+{
+  EFI_STATUS                Status;
+  IPMI_GET_BOOT_OPTION      BmcBootOpt;
+  UINT16                    BootType;
+
+  Status = GetBmcBootOptionsSetting (&BmcBootOpt);
+  if (EFI_ERROR (Status)) {
+    return;
+  }
+
+  Print (L"Boot Type from BMC is %x\n", BmcBootOpt.BootDeviceSelector);
+
+  switch (BmcBootOpt.BootDeviceSelector) {
+  case ForcePxe:
+    BootType = BBS_TYPE_EMBEDDED_NETWORK;
+    break;
+
+  case ForcePrimaryRemovableMedia:
+    BootType = BBS_TYPE_USB;
+    break;
+
+  case ForceDefaultHardDisk:
+    BootType = BBS_TYPE_HARDDRIVE;
+    break;
+
+  case ForceDefaultCD:
+    BootType = BBS_TYPE_CDROM;
+    break;
+
+  default:
+    return;
+  }
+
+  SetBootOrder (BootType);
+}
 
 //
 // BDS Platform Functions
@@ -159,6 +591,10 @@  PlatformBdsInit (
 {
   //Signal EndofDxe Event
   EfiEventGroupSignal(&gEfiEndOfDxeEventGroupGuid);
+
+  // restore BootOrder variable if previous BMC boot override attempt
+  // left it in a modified state
+  RestoreBootOrder ();
 }
 
 
@@ -473,6 +909,7 @@  PlatformBdsPolicyBehavior (
   Print (L"Press Enter to boot OS immediately.\n");
   Print (L"Press any other key in %d seconds to stop automatical booting...\n", PcdGet16(PcdPlatformBootTimeOut));
   PlatformBdsEnterFrontPage (PcdGet16(PcdPlatformBootTimeOut), TRUE);
+  HandleBmcBootType ();
 }
 
 /**
diff --git a/Chips/Hisilicon/Library/PlatformIntelBdsLib/PlatformIntelBdsLib.inf b/Chips/Hisilicon/Library/PlatformIntelBdsLib/PlatformIntelBdsLib.inf
index baceb57..41ceb89 100644
--- a/Chips/Hisilicon/Library/PlatformIntelBdsLib/PlatformIntelBdsLib.inf
+++ b/Chips/Hisilicon/Library/PlatformIntelBdsLib/PlatformIntelBdsLib.inf
@@ -42,6 +42,7 @@ 
   IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
   MdeModulePkg/MdeModulePkg.dec
   MdePkg/MdePkg.dec
+  OpenPlatformPkg/Chips/Hisilicon/HisiPkg.dec
 
 [LibraryClasses]
   BaseLib
@@ -49,6 +50,7 @@ 
   DebugLib
   DevicePathLib
   GenericBdsLib
+  IpmiCmdLib
   MemoryAllocationLib
   PcdLib
   PrintLib
@@ -68,12 +70,14 @@ 
 
 [Guids]
   gEfiEndOfDxeEventGroupGuid
+  gEfiEventReadyToBootGuid
   gEfiFileInfoGuid
   gEfiFileSystemInfoGuid
   gEfiFileSystemVolumeLabelInfoIdGuid
 
 [Protocols]
   gEfiDevicePathProtocolGuid
+  gEfiDevicePathToTextProtocolGuid
   gEfiGraphicsOutputProtocolGuid
   gEfiLoadedImageProtocolGuid
   gEfiPciRootBridgeIoProtocolGuid