public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
To: Michael D Kinney <michael.d.kinney@intel.com>,
	Leif Lindholm <leif.lindholm@linaro.org>
Cc: "edk2-devel@lists.01.org" <edk2-devel@lists.01.org>,
	Jiewen Yao <jiewen.yao@intel.com>,
	 Eric Dong <eric.dong@intel.com>, Star Zeng <star.zeng@intel.com>
Subject: Re: [Patch v3 1/2] MdeModulePkg/DxeCapsuleLibFmp: Add progress bar support
Date: Thu, 31 May 2018 15:03:51 +0200	[thread overview]
Message-ID: <CAKv+Gu9121_zx==KmqpzCoAxF7LoS6-NeoBoqb9aHdB_rHgrhA@mail.gmail.com> (raw)
In-Reply-To: <20180529161755.9424-2-michael.d.kinney@intel.com>

On 29 May 2018 at 18:17, Michael D Kinney <michael.d.kinney@intel.com> wrote:
> From: "Kinney, Michael D" <michael.d.kinney@intel.com>
>
> https://bugzilla.tianocore.org/show_bug.cgi?id=801
>
> Based on content from the following branch/commits:
> https://github.com/Microsoft/MS_UEFI/tree/share/MsCapsuleSupport
>
> * Change Update_Image_Progress() to UpdateImageProcess()
> * Call DisplayUpdateProgressLib from UpdateImageProgress().
> * Split out a boot service and runtime version of
>   UpdateImageProgress() so the DisplayUpdateProgressLib is
>   not used at runtime.
> * If gEdkiiFirmwareManagementProgressProtocolGuid is present,
>   then use its progress bar color and watchdog timer value.
> * If gEdkiiFirmwareManagementProgressProtocolGuid is not present,
>   then use default progress bar color and 5 min watchdog timer.
> * Remove Print() calls during capsule processing.  Instead,
>   the DisplayUpdateProgressLib is used to inform the user
>   of progress during a capsule update.
>
> Cc: Star Zeng <star.zeng@intel.com>
> Cc: Eric Dong <eric.dong@intel.com>
> Cc: Jiewen Yao <jiewen.yao@intel.com>
> Cc: Sean Brogan <sean.brogan@microsoft.com>
> Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com>
> Contributed-under: TianoCore Contribution Agreement 1.1

Mike,

I am trying to wire up this code for my platform, and I am having
trouble understanding how the pieces fit together.

I have merged your edk2 and edk2-platforms changes, and I have updated
my PerformFlashWriteWithProgress() implementation to invoke the
Progress() callback. Unfortunately, nothing happens when I run it.

Looking into the code in more detail, I am having trouble
understanding how this is ever supposed to work, given that:
- UpdateCapsule() is implemented by CapsuleRuntimeDxe, which is a
DXE_RUNTIME_DRIVER module
- CapsuleRuntimeDxe incorporates DxeRuntimeCapsuleLib.inf
- DxeRuntimeCapsuleLib.inf includes DxeCapsuleReportLibNull.c, and so
its SetFmpImageData() routine passes an empty implementation of
UpdateImageProgress() into Fmp->SetImage()

It seems to me that some pieces are missing, but the code is a bit
scattered so maybe I failed to incorporate a piece.

Thanks,
Ard.


> ---
>  .../Library/DxeCapsuleLibFmp/DxeCapsuleLib.c       | 47 +++++++++---
>  .../Library/DxeCapsuleLibFmp/DxeCapsuleLib.inf     |  8 ++-
>  .../DxeCapsuleLibFmp/DxeCapsuleProcessLib.c        | 84 ++++++++++++++++------
>  .../DxeCapsuleLibFmp/DxeCapsuleProcessLibNull.c    | 21 +++++-
>  .../DxeCapsuleLibFmp/DxeRuntimeCapsuleLib.inf      |  7 +-
>  5 files changed, 131 insertions(+), 36 deletions(-)
>
> diff --git a/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleLib.c b/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleLib.c
> index 05fcd92deb..f0226eafa5 100644
> --- a/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleLib.c
> +++ b/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleLib.c
> @@ -45,6 +45,7 @@
>  #include <Protocol/GraphicsOutput.h>
>  #include <Protocol/EsrtManagement.h>
>  #include <Protocol/FirmwareManagement.h>
> +#include <Protocol/FirmwareManagementProgress.h>
>  #include <Protocol/DevicePath.h>
>
>  EFI_SYSTEM_RESOURCE_TABLE *mEsrtTable                  = NULL;
> @@ -53,6 +54,8 @@ BOOLEAN                   mIsVirtualAddrConverted      = FALSE;
>  BOOLEAN                   mDxeCapsuleLibEndOfDxe       = FALSE;
>  EFI_EVENT                 mDxeCapsuleLibEndOfDxeEvent  = NULL;
>
> +EDKII_FIRMWARE_MANAGEMENT_PROGRESS_PROTOCOL  *mFmpProgress = NULL;
> +
>  /**
>    Initialize capsule related variables.
>  **/
> @@ -101,18 +104,17 @@ RecordFmpCapsuleStatusVariable (
>    Function indicate the current completion progress of the firmware
>    update. Platform may override with own specific progress function.
>
> -  @param[in]  Completion    A value between 1 and 100 indicating the current completion progress of the firmware update
> +  @param[in]  Completion  A value between 1 and 100 indicating the current
> +                          completion progress of the firmware update
>
> -  @retval EFI_SUCESS    Input capsule is a correct FMP capsule.
> +  @retval EFI_SUCESS             The capsule update progress was updated.
> +  @retval EFI_INVALID_PARAMETER  Completion is greater than 100%.
>  **/
>  EFI_STATUS
>  EFIAPI
> -Update_Image_Progress (
> +UpdateImageProgress (
>    IN UINTN  Completion
> -  )
> -{
> -  return EFI_SUCCESS;
> -}
> +  );
>
>  /**
>    Return if this CapsuleGuid is a FMP capsule GUID or not.
> @@ -849,6 +851,19 @@ SetFmpImageData (
>      return Status;
>    }
>
> +  //
> +  // Lookup Firmware Management Progress Protocol before SetImage() is called
> +  // This is an optional protocol that may not be present on Handle.
> +  //
> +  Status = gBS->HandleProtocol (
> +                  Handle,
> +                  &gEdkiiFirmwareManagementProgressProtocolGuid,
> +                  (VOID **)&mFmpProgress
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    mFmpProgress = NULL;
> +  }
> +
>    if (ImageHeader->Version >= EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER_INIT_VERSION) {
>      Image = (UINT8 *)(ImageHeader + 1);
>    } else {
> @@ -873,21 +888,37 @@ SetFmpImageData (
>      DEBUG((DEBUG_INFO, "(UpdateHardwareInstance - 0x%x)", ImageHeader->UpdateHardwareInstance));
>    }
>    DEBUG((DEBUG_INFO, "\n"));
> +
> +  //
> +  // Before calling SetImage(), reset the progress bar to 0%
> +  //
> +  UpdateImageProgress (0);
> +
>    Status = Fmp->SetImage(
>                    Fmp,
>                    ImageHeader->UpdateImageIndex,          // ImageIndex
>                    Image,                                  // Image
>                    ImageHeader->UpdateImageSize,           // ImageSize
>                    VendorCode,                             // VendorCode
> -                  Update_Image_Progress,                  // Progress
> +                  UpdateImageProgress,                    // Progress
>                    &AbortReason                            // AbortReason
>                    );
> +  //
> +  // Set the progress bar to 100% after returning from SetImage()
> +  //
> +  UpdateImageProgress (100);
> +
>    DEBUG((DEBUG_INFO, "Fmp->SetImage - %r\n", Status));
>    if (AbortReason != NULL) {
>      DEBUG ((DEBUG_ERROR, "%s\n", AbortReason));
>      FreePool(AbortReason);
>    }
>
> +  //
> +  // Clear mFmpProgress after SetImage() returns
> +  //
> +  mFmpProgress = NULL;
> +
>    return Status;
>  }
>
> diff --git a/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleLib.inf b/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleLib.inf
> index 1d947101d3..8367264f76 100644
> --- a/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleLib.inf
> +++ b/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleLib.inf
> @@ -52,6 +52,7 @@ [LibraryClasses]
>    PrintLib
>    HobLib
>    BmpSupportLib
> +  DisplayUpdateProgressLib
>
>  [Pcd]
>    gEfiMdeModulePkgTokenSpaceGuid.PcdCapsuleMax                               ## CONSUMES
> @@ -66,9 +67,10 @@ [Pcd]
>    gEfiMdeModulePkgTokenSpaceGuid.PcdCapsuleStatusCodeResettingSystem         ## CONSUMES
>
>  [Protocols]
> -  gEsrtManagementProtocolGuid             ## CONSUMES
> -  gEfiFirmwareManagementProtocolGuid      ## CONSUMES
> -  gEdkiiVariableLockProtocolGuid          ## SOMETIMES_CONSUMES
> +  gEsrtManagementProtocolGuid                   ## CONSUMES
> +  gEfiFirmwareManagementProtocolGuid            ## CONSUMES
> +  gEdkiiVariableLockProtocolGuid                ## SOMETIMES_CONSUMES
> +  gEdkiiFirmwareManagementProgressProtocolGuid  ## SOMETIMES_CONSUMES
>
>  [Guids]
>    gEfiFmpCapsuleGuid                      ## SOMETIMES_CONSUMES ## GUID
> diff --git a/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleProcessLib.c b/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleProcessLib.c
> index ba3ff90b9f..26ca4e295f 100644
> --- a/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleProcessLib.c
> +++ b/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleProcessLib.c
> @@ -9,7 +9,7 @@
>    ProcessCapsules(), ProcessTheseCapsules() will receive untrusted
>    input and do basic validation.
>
> -  Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
> +  Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
>    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
> @@ -22,6 +22,7 @@
>
>  #include <PiDxe.h>
>  #include <Protocol/EsrtManagement.h>
> +#include <Protocol/FirmwareManagementProgress.h>
>
>  #include <Library/BaseLib.h>
>  #include <Library/DebugLib.h>
> @@ -34,9 +35,12 @@
>  #include <Library/HobLib.h>
>  #include <Library/ReportStatusCodeLib.h>
>  #include <Library/CapsuleLib.h>
> +#include <Library/DisplayUpdateProgressLib.h>
>
>  #include <IndustryStandard/WindowsUxCapsule.h>
>
> +extern EDKII_FIRMWARE_MANAGEMENT_PROGRESS_PROTOCOL  *mFmpProgress;
> +
>  /**
>    Return if this FMP is a system FMP or a device FMP, based upon CapsuleHeader.
>
> @@ -101,6 +105,62 @@ VOID                        **mCapsulePtr;
>  EFI_STATUS                  *mCapsuleStatusArray;
>  UINT32                      mCapsuleTotalNumber;
>
> +/**
> +  Function indicate the current completion progress of the firmware
> +  update. Platform may override with own specific progress function.
> +
> +  @param[in]  Completion  A value between 1 and 100 indicating the current
> +                          completion progress of the firmware update
> +
> +  @retval EFI_SUCESS             The capsule update progress was updated.
> +  @retval EFI_INVALID_PARAMETER  Completion is greater than 100%.
> +**/
> +EFI_STATUS
> +EFIAPI
> +UpdateImageProgress (
> +  IN UINTN  Completion
> +  )
> +{
> +  EFI_STATUS                           Status;
> +  UINTN                                Seconds;
> +  EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION  *Color;
> +
> +  DEBUG((DEBUG_INFO, "Update Progress - %d%%\n", Completion));
> +
> +  if (Completion > 100) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  //
> +  // Use a default timeout of 5 minutes if there is not FMP Progress Protocol.
> +  //
> +  Seconds = 5 * 60;
> +  Color   = NULL;
> +  if (mFmpProgress != NULL) {
> +    Seconds = mFmpProgress->WatchdogSeconds;
> +    Color   = &mFmpProgress->ProgressBarForegroundColor;
> +  }
> +
> +  //
> +  // Cancel the watchdog timer
> +  //
> +  gBS->SetWatchdogTimer (0, 0x0000, 0, NULL);
> +
> +  if (Completion != 100) {
> +    //
> +    // Arm the watchdog timer from PCD setting
> +    //
> +    if (Seconds != 0) {
> +      DEBUG ((DEBUG_VERBOSE, "Arm watchdog timer %d seconds\n", Seconds));
> +      gBS->SetWatchdogTimer (Seconds, 0x0000, 0, NULL);
> +    }
> +  }
> +
> +  Status = DisplayUpdateProgress (Completion, Color);
> +
> +  return Status;
> +}
> +
>  /**
>    This function initializes the mCapsulePtr, mCapsuleStatusArray and mCapsuleTotalNumber.
>  **/
> @@ -319,7 +379,6 @@ ProcessTheseCapsules (
>    EFI_STATUS                  Status;
>    EFI_CAPSULE_HEADER          *CapsuleHeader;
>    UINT32                      Index;
> -  BOOLEAN                     DisplayCapsuleExist;
>    ESRT_MANAGEMENT_PROTOCOL    *EsrtManagement;
>    UINT16                      EmbeddedDriverCount;
>
> @@ -354,12 +413,10 @@ ProcessTheseCapsules (
>    //
>    // If Windows UX capsule exist, process it first
>    //
> -  DisplayCapsuleExist = FALSE;
>    for (Index = 0; Index < mCapsuleTotalNumber; Index++) {
>      CapsuleHeader = (EFI_CAPSULE_HEADER*) mCapsulePtr [Index];
>      if (CompareGuid (&CapsuleHeader->CapsuleGuid, &gWindowsUxCapsuleGuid)) {
>        DEBUG ((DEBUG_INFO, "ProcessCapsuleImage (Ux) - 0x%x\n", CapsuleHeader));
> -      DisplayCapsuleExist = TRUE;
>        DEBUG ((DEBUG_INFO, "Display logo capsule is found.\n"));
>        Status = ProcessCapsuleImage (CapsuleHeader);
>        mCapsuleStatusArray [Index] = EFI_SUCCESS;
> @@ -368,12 +425,7 @@ ProcessTheseCapsules (
>      }
>    }
>
> -  if (!DisplayCapsuleExist) {
> -    //
> -    // Display Capsule not found. Display the default string.
> -    //
> -    Print (L"Updating the firmware ......\r\n");
> -  }
> +  DEBUG ((DEBUG_INFO, "Updating the firmware ......\n"));
>
>    //
>    // All capsules left are recognized by platform.
> @@ -411,7 +463,6 @@ ProcessTheseCapsules (
>            if (EFI_ERROR(Status)) {
>              REPORT_STATUS_CODE(EFI_ERROR_CODE, (EFI_SOFTWARE | PcdGet32(PcdStatusCodeSubClassCapsule) | PcdGet32(PcdCapsuleStatusCodeUpdateFirmwareFailed)));
>              DEBUG ((DEBUG_ERROR, "Capsule process failed!\n"));
> -            Print (L"Firmware update failed...\r\n");
>            } else {
>              REPORT_STATUS_CODE(EFI_PROGRESS_CODE, (EFI_SOFTWARE | PcdGet32(PcdStatusCodeSubClassCapsule) | PcdGet32(PcdCapsuleStatusCodeUpdateFirmwareSuccess)));
>            }
> @@ -447,18 +498,9 @@ DoResetSystem (
>    VOID
>    )
>  {
> -  UINTN                         Index;
> -
> -  REPORT_STATUS_CODE(EFI_PROGRESS_CODE, (EFI_SOFTWARE | PcdGet32(PcdStatusCodeSubClassCapsule) | PcdGet32(PcdCapsuleStatusCodeResettingSystem)));
> -
> -  Print(L"Capsule Request Cold Reboot.\n");
>    DEBUG((DEBUG_INFO, "Capsule Request Cold Reboot."));
>
> -  for (Index = 5; Index > 0; Index--) {
> -    Print(L"\rResetting system in %d seconds ...", Index);
> -    DEBUG((DEBUG_INFO, "\rResetting system in %d seconds ...", Index));
> -    gBS->Stall(1000000);
> -  }
> +  REPORT_STATUS_CODE(EFI_PROGRESS_CODE, (EFI_SOFTWARE | PcdGet32(PcdStatusCodeSubClassCapsule) | PcdGet32(PcdCapsuleStatusCodeResettingSystem)));
>
>    gRT->ResetSystem(EfiResetCold, EFI_SUCCESS, 0, NULL);
>
> diff --git a/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleProcessLibNull.c b/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleProcessLibNull.c
> index 07e9e46eae..274c1c4c1c 100644
> --- a/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleProcessLibNull.c
> +++ b/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleProcessLibNull.c
> @@ -3,7 +3,7 @@
>    Dummy function for runtime module, because CapsuleDxeRuntime
>    does not need call ProcessCapsules().
>
> -  Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
> +  Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
>    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
> @@ -17,6 +17,25 @@
>  #include <PiDxe.h>
>  #include <Library/CapsuleLib.h>
>
> +/**
> +  Function indicate the current completion progress of the firmware
> +  update. Platform may override with own specific progress function.
> +
> +  @param[in]  Completion  A value between 1 and 100 indicating the current
> +                          completion progress of the firmware update
> +
> +  @retval EFI_SUCESS             The capsule update progress was updated.
> +  @retval EFI_INVALID_PARAMETER  Completion is greater than 100%.
> +**/
> +EFI_STATUS
> +EFIAPI
> +UpdateImageProgress (
> +  IN UINTN  Completion
> +  )
> +{
> +  return EFI_SUCCESS;
> +}
> +
>  /**
>
>    This routine is called to process capsules.
> diff --git a/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeRuntimeCapsuleLib.inf b/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeRuntimeCapsuleLib.inf
> index 1659b13ef4..342df9e99c 100644
> --- a/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeRuntimeCapsuleLib.inf
> +++ b/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeRuntimeCapsuleLib.inf
> @@ -69,9 +69,10 @@ [Pcd]
>    gEfiMdeModulePkgTokenSpaceGuid.PcdCapsuleStatusCodeResettingSystem         ## CONSUMES
>
>  [Protocols]
> -  gEsrtManagementProtocolGuid             ## CONSUMES
> -  gEfiFirmwareManagementProtocolGuid      ## CONSUMES
> -  gEdkiiVariableLockProtocolGuid          ## SOMETIMES_CONSUMES
> +  gEsrtManagementProtocolGuid                   ## CONSUMES
> +  gEfiFirmwareManagementProtocolGuid            ## CONSUMES
> +  gEdkiiVariableLockProtocolGuid                ## SOMETIMES_CONSUMES
> +  gEdkiiFirmwareManagementProgressProtocolGuid  ## SOMETIMES_CONSUMES
>
>  [Guids]
>    gEfiFmpCapsuleGuid                      ## SOMETIMES_CONSUMES ## GUID
> --
> 2.14.2.windows.3
>
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org
> https://lists.01.org/mailman/listinfo/edk2-devel


  parent reply	other threads:[~2018-05-31 13:03 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-05-29 16:17 [Patch v3 0/2] Use DisplayUpdateProgressLib and PerformFlashWriteWithProgress() Michael D Kinney
2018-05-29 16:17 ` [Patch v3 1/2] MdeModulePkg/DxeCapsuleLibFmp: Add progress bar support Michael D Kinney
2018-05-31  9:43   ` Zeng, Star
2018-05-31 13:03   ` Ard Biesheuvel [this message]
2018-06-06 17:34   ` Ard Biesheuvel
2018-05-29 16:17 ` [Patch v3 2/2] SignedCapsulePkg/SystemFirmwareUpdateDxe: Use progress API Michael D Kinney
2018-06-06 17:35   ` Ard Biesheuvel

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAKv+Gu9121_zx==KmqpzCoAxF7LoS6-NeoBoqb9aHdB_rHgrhA@mail.gmail.com' \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox