From: "Ni, Ruiyu" <ruiyu.ni@intel.com>
To: Laszlo Ersek <lersek@redhat.com>,
edk2-devel-01 <edk2-devel@lists.01.org>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>,
"Justen, Jordan L" <jordan.l.justen@intel.com>,
"Dong, Eric" <eric.dong@intel.com>,
"Zeng, Star" <star.zeng@intel.com>
Subject: Re: [PATCH 3/5] MdeModulePkg/UefiBootManagerLib: report EDKII_OS_LOADER_DETAIL status code
Date: Thu, 23 Nov 2017 05:21:13 +0000 [thread overview]
Message-ID: <734D49CCEBEEF84792F5B80ED585239D5BACE29B@SHSMSX104.ccr.corp.intel.com> (raw)
In-Reply-To: <20171122235849.4177-4-lersek@redhat.com>
Laszlo,
When booting a boot option, UefiBootManagerBoot() sets a Boot#### variable
and saves #### to BootCurrent variable.
So all the details (except the EDKII_OS_LOADER_DETAIL.Status) can be retrieved
from reading Boot#### variable.
4 more comments below.
Thanks/Ray
> -----Original Message-----
> From: Laszlo Ersek [mailto:lersek@redhat.com]
> Sent: Thursday, November 23, 2017 7:59 AM
> To: edk2-devel-01 <edk2-devel@lists.01.org>
> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>; Justen, Jordan L
> <jordan.l.justen@intel.com>; Ni, Ruiyu <ruiyu.ni@intel.com>; Dong, Eric
> <eric.dong@intel.com>; Zeng, Star <star.zeng@intel.com>
> Subject: [PATCH 3/5] MdeModulePkg/UefiBootManagerLib: report
> EDKII_OS_LOADER_DETAIL status code
>
> The EfiBootManagerBoot() function reports progress codes about
> LoadImage() preparation and failure, and StartImage() preparation and
> failure. These codes are flat (scalar) constants.
>
> Extend this by "broadcasting" the Boot#### option number, description,
> device path, and -- on load / start failure -- the error result at the same
> locations, through EFI_DEBUG_CODE reporting. Use the
> PcdDebugCodeOsLoaderDetail status code value and the
> EDKII_OS_LOADER_DETAIL status code structure introduced earlier in this
> series.
>
> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> Cc: Jordan Justen <jordan.l.justen@intel.com>
> Cc: Ruiyu Ni <ruiyu.ni@intel.com>
> Cc: Eric Dong <eric.dong@intel.com>
> Cc: Star Zeng <star.zeng@intel.com>
> Ref: https://bugzilla.redhat.com/show_bug.cgi?id=1515418
> Contributed-under: TianoCore Contribution Agreement 1.1
> Signed-off-by: Laszlo Ersek <lersek@redhat.com>
> ---
> MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf | 2
> +
> MdeModulePkg/Library/UefiBootManagerLib/InternalBm.h | 84
> ++++++++++
> MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c | 51 +++++-
> MdeModulePkg/Library/UefiBootManagerLib/BmMisc.c | 166
> ++++++++++++++++++++
> 4 files changed, 301 insertions(+), 2 deletions(-)
>
> diff --git
> a/MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf
> b/MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf
> index ad4901db5713..633906fc6ca4 100644
> --- a/MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf
> +++
> b/MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf
> @@ -79,24 +79,25 @@ [Guids]
>
> ## SOMETIMES_PRODUCES ## Variable:L"BootCurrent" (The boot option of
> current boot)
> ## SOMETIMES_CONSUMES ## Variable:L"BootXX" (Boot option variable)
> ## SOMETIMES_CONSUMES ## Variable:L"BootOrder" (The boot option
> array)
> ## SOMETIMES_CONSUMES ## Variable:L"DriverOrder" (The driver order
> list)
> ## SOMETIMES_CONSUMES ## Variable:L"ConIn" (The device path of
> console in device)
> ## SOMETIMES_CONSUMES ## Variable:L"ConOut" (The device path of
> console out device)
> ## SOMETIMES_CONSUMES ## Variable:L"ErrOut" (The device path of
> error out device)
> gEfiGlobalVariableGuid
>
> gPerformanceProtocolGuid ## SOMETIMES_CONSUMES ##
> Variable:L"PerfDataMemAddr" (The ACPI address of performance data)
> gEdkiiStatusCodeDataTypeVariableGuid ## SOMETIMES_CONSUMES
> ## GUID
> + gEdkiiStatusCodeDataTypeOsLoaderDetailGuid ##
> SOMETIMES_CONSUMES ## GUID
> gEfiDiskInfoAhciInterfaceGuid ## SOMETIMES_CONSUMES ##
> GUID
> gEfiDiskInfoIdeInterfaceGuid ## SOMETIMES_CONSUMES ## GUID
> gEfiDiskInfoScsiInterfaceGuid ## SOMETIMES_CONSUMES ## GUID
> gEfiDiskInfoSdMmcInterfaceGuid ## SOMETIMES_CONSUMES ##
> GUID
>
> [Protocols]
> gEfiPciRootBridgeIoProtocolGuid ## CONSUMES
> gEfiSimpleFileSystemProtocolGuid ## SOMETIMES_CONSUMES
> gEfiLoadFileProtocolGuid ## SOMETIMES_CONSUMES
> gEfiSimpleTextOutProtocolGuid ## SOMETIMES_CONSUMES
> gEfiPciIoProtocolGuid ## SOMETIMES_CONSUMES
> gEfiLoadedImageProtocolGuid ## CONSUMES
> @@ -112,16 +113,17 @@ [Protocols]
> gEfiUsbIoProtocolGuid ## SOMETIMES_CONSUMES
> gEfiNvmExpressPassThruProtocolGuid ## SOMETIMES_CONSUMES
> gEfiDiskInfoProtocolGuid ## SOMETIMES_CONSUMES
> gEfiDriverHealthProtocolGuid ## SOMETIMES_CONSUMES
> gEfiFormBrowser2ProtocolGuid ## SOMETIMES_CONSUMES
> gEfiRamDiskProtocolGuid ## SOMETIMES_CONSUMES
> gEfiDeferredImageLoadProtocolGuid ## SOMETIMES_CONSUMES
>
> [Pcd]
>
> gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationC
> hange ## SOMETIMES_CONSUMES
> gEfiMdeModulePkgTokenSpaceGuid.PcdProgressCodeOsLoaderLoad
> ## SOMETIMES_CONSUMES
> gEfiMdeModulePkgTokenSpaceGuid.PcdProgressCodeOsLoaderStart
> ## SOMETIMES_CONSUMES
> + gEfiMdeModulePkgTokenSpaceGuid.PcdDebugCodeOsLoaderDetail
> ## SOMETIMES_CONSUMES
> gEfiMdeModulePkgTokenSpaceGuid.PcdErrorCodeSetVariable ##
> SOMETIMES_CONSUMES
> gEfiMdeModulePkgTokenSpaceGuid.PcdBootManagerMenuFile
> ## CONSUMES
> gEfiMdeModulePkgTokenSpaceGuid.PcdDriverHealthConfigureForm
> ## SOMETIMES_CONSUMES
> gEfiMdeModulePkgTokenSpaceGuid.PcdMaxRepairCount ##
> CONSUMES
> diff --git a/MdeModulePkg/Library/UefiBootManagerLib/InternalBm.h
> b/MdeModulePkg/Library/UefiBootManagerLib/InternalBm.h
> index 0224bd34a9ed..ddcb0347aef6 100644
> --- a/MdeModulePkg/Library/UefiBootManagerLib/InternalBm.h
> +++ b/MdeModulePkg/Library/UefiBootManagerLib/InternalBm.h
> @@ -44,24 +44,25 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF
> ANY KIND, EITHER EXPRESS OR IMPLIED.
> #include <Protocol/BootLogo.h>
> #include <Protocol/DriverHealth.h>
> #include <Protocol/FormBrowser2.h>
> #include <Protocol/VariableLock.h>
> #include <Protocol/RamDisk.h>
> #include <Protocol/DeferredImageLoad.h>
>
> #include <Guid/MemoryTypeInformation.h> #include <Guid/FileInfo.h>
> #include <Guid/GlobalVariable.h> #include <Guid/Performance.h> #include
> <Guid/StatusCodeDataTypeVariable.h>
> +#include <Guid/StatusCodeDataTypeOsLoaderDetail.h>
>
> #include <Library/PrintLib.h>
> #include <Library/DebugLib.h>
> #include <Library/BaseMemoryLib.h>
> #include <Library/UefiBootServicesTableLib.h>
> #include <Library/UefiRuntimeServicesTableLib.h>
> #include <Library/UefiLib.h>
> #include <Library/MemoryAllocationLib.h> #include
> <Library/DxeServicesTableLib.h> #include <Library/HobLib.h> #include
> <Library/BaseLib.h> #include <Library/DevicePathLib.h> @@ -298,24
> +299,107 @@ BmStopHotkeyService (
>
> @retval EFI_NOT_FOUND The variable trying to be updated or deleted
> was not found.
> **/
> EFI_STATUS
> BmSetVariableAndReportStatusCodeOnError (
> IN CHAR16 *VariableName,
> IN EFI_GUID *VendorGuid,
> IN UINT32 Attributes,
> IN UINTN DataSize,
> IN VOID *Data
> );
>
> +/**
> + Dynamically allocate and initialize an EDKII_OS_LOADER_DETAIL status
> +code
> + payload.
> +
> + @param[in] BootOption Capture the OptionNumber, FilePath and
> + Description fields of BootOption in the
> + EDKII_OS_LOADER_DETAIL payload.
> +
> + @param[out] OsLoaderDetail On successful return, set to the
> + EDKII_OS_LOADER_DETAIL object that has been
> + allocated and initialized. On failure, not
> + modified.
> +
> + @param[out] OsLoaderDetailSize On successful return, set to the size of
> the
> + EDKII_OS_LOADER_DETAIL object that has been
> + allocated and initialized. On failure, not
> + modified.
> +
> + @retval EFI_UNSUPPORTED EFI_DEBUG_CODE reporting is disabled in
> the
> + platform.
> +
> + @retval EFI_INVALID_PARAMETER BootOption->OptionNumber is not in
> + 0x0000..0xFFFF, inclusive.
> +
> + @retval EFI_BAD_BUFFER_SIZE BootOption->FilePath and/or
> + BootOption->Description would exceed the
> + UINT16 size limits presented by
> + EDKII_OS_LOADER_DETAIL or
> + EFI_STATUS_CODE_DATA.
> +
> + @retval EFI_OUT_OF_RESOURCES Memory allocation failed.
> +
> + @retval EFI_SUCCESS The EDKII_OS_LOADER_DETAIL object has
> been
> + allocated and initialized. The caller is
> + responsible for freeing the object with
> + FreePool().
> +**/
> +EFI_STATUS
> +BmCreateOsLoaderDetail (
> + IN CONST EFI_BOOT_MANAGER_LOAD_OPTION *BootOption,
> + OUT EDKII_OS_LOADER_DETAIL **OsLoaderDetail,
> + OUT UINTN *OsLoaderDetailSize
> + );
> +
> +/**
> + Report an EFI_DEBUG_CODE status code with EDKII_OS_LOADER_DETAIL
> as
> +payload
> + (i.e., extended data).
> +
> + @param[in,out] OsLoaderDetail The EDKII_OS_LOADER_DETAIL payload
> previously
> + created with BmCreateOsLoaderDetail(), and
> + modified zero or more times by
> + BmReportOsLoaderDetail(). If OsLoaderDetail is
> + NULL, the function does nothing. Otherwise,
> + the Type and Status fields are overwritten in
> + OsLoaderDetail, and a status code is reported.
> +
> + @param[in] OsLoaderDetailSize The size returned by
> BmCreateOsLoaderDetail().
> + If OsLoaderDetail is NULL, OsLoaderDetailSize
> + may be zero.
> +
> + @param[in] DetailType OsLoaderDetail->Type is set to DetailType
> + before reporting the status code. The caller
> + is responsible for passing an
> + EDKII_OS_LOADER_DETAIL_TYPE_* value.
> +
> + @param[in] DetailStatus OsLoaderDetail->Status is set to DetailStatus
> + before reporting the status code.
> +
> + @retval EFI_UNSUPPORTED EFI_DEBUG_CODE reporting is disabled in the
> + platform.
> +
> + @retval EFI_ABORTED OsLoaderDetail is NULL.
> +
> + @return Values propagated from REPORT_STATUS_CODE_EX().
> +**/
> +EFI_STATUS
> +BmReportOsLoaderDetail (
> + IN OUT EDKII_OS_LOADER_DETAIL *OsLoaderDetail OPTIONAL,
> + IN UINTN OsLoaderDetailSize,
> + IN UINT32 DetailType,
> + IN EFI_STATUS DetailStatus
> + );
> +
> /**
> Function compares a device path data structure to that of all the nodes of a
> second device path instance.
>
> @param Multi A pointer to a multi-instance device path data
> structure.
> @param Single A pointer to a single-instance device path data
> structure.
>
> @retval TRUE If the Single device path is contained within Multi
> device path.
> @retval FALSE The Single device path is not match within Multi
> device path.
>
> diff --git a/MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c
> b/MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c
> index d6844823aa55..049afbf7d1f9 100644
> --- a/MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c
> +++ b/MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c
> @@ -1665,34 +1665,39 @@ EfiBootManagerBoot (
> EFI_STATUS Status;
> EFI_HANDLE ImageHandle;
> EFI_LOADED_IMAGE_PROTOCOL *ImageInfo;
> UINT16 Uint16;
> UINTN OptionNumber;
> UINTN OriginalOptionNumber;
> EFI_DEVICE_PATH_PROTOCOL *FilePath;
> EFI_DEVICE_PATH_PROTOCOL *RamDiskDevicePath;
> VOID *FileBuffer;
> UINTN FileSize;
> EFI_BOOT_LOGO_PROTOCOL *BootLogo;
> EFI_EVENT LegacyBootEvent;
> + EDKII_OS_LOADER_DETAIL *OsLoaderDetail;
> + UINTN OsLoaderDetailSize;
>
> if (BootOption == NULL) {
> return;
> }
>
> if (BootOption->FilePath == NULL || BootOption->OptionType !=
> LoadOptionTypeBoot) {
> BootOption->Status = EFI_INVALID_PARAMETER;
> return;
> }
>
> + OsLoaderDetail = NULL;
> + OsLoaderDetailSize = 0;
> +
> //
> // 1. Create Boot#### for a temporary boot if there is no match Boot####
> (i.e. a boot by selected a EFI Shell using "Boot From File")
> //
> OptionNumber = BmFindBootOptionInVariable (BootOption);
> if (OptionNumber == LoadOptionNumberUnassigned) {
> Status = BmGetFreeOptionNumber (LoadOptionTypeBoot, &Uint16);
> if (!EFI_ERROR (Status)) {
> //
> // Save the BootOption->OptionNumber to restore later
> //
> OptionNumber = Uint16;
> OriginalOptionNumber = BootOption->OptionNumber;
> @@ -1751,68 +1756,93 @@ EfiBootManagerBoot (
>
> //
> // 6. Load EFI boot option to ImageHandle
> //
> DEBUG_CODE_BEGIN ();
> if (BootOption->Description == NULL) {
> DEBUG ((DEBUG_INFO | DEBUG_LOAD, "[Bds]Booting from unknown
> device path\n"));
> } else {
> DEBUG ((DEBUG_INFO | DEBUG_LOAD, "[Bds]Booting %s\n", BootOption-
> >Description));
> }
> DEBUG_CODE_END ();
>
> + //
> + // Try to create the status code payload structure for detailed debug
> + // reporting.
> + //
> + Status = BmCreateOsLoaderDetail (BootOption, &OsLoaderDetail,
> + &OsLoaderDetailSize);
> + if (EFI_ERROR (Status) && (Status != EFI_UNSUPPORTED)) {
> + DEBUG ((DEBUG_WARN | DEBUG_LOAD,
> "[Bds]BmCreateOsLoaderDetail(): %r\n",
> + Status));
> + }
> +
> ImageHandle = NULL;
> RamDiskDevicePath = NULL;
> if (DevicePathType (BootOption->FilePath) != BBS_DEVICE_PATH) {
> Status = EFI_NOT_FOUND;
> FilePath = NULL;
> EfiBootManagerConnectDevicePath (BootOption->FilePath, NULL);
> FileBuffer = BmGetNextLoadOptionBuffer (LoadOptionTypeBoot,
> BootOption->FilePath, &FilePath, &FileSize);
> if (FileBuffer != NULL) {
> RamDiskDevicePath = BmGetRamDiskDevicePath (FilePath);
>
> REPORT_STATUS_CODE (EFI_PROGRESS_CODE, PcdGet32
> (PcdProgressCodeOsLoaderLoad));
> + BmReportOsLoaderDetail (
> + OsLoaderDetail,
> + OsLoaderDetailSize,
> + EDKII_OS_LOADER_DETAIL_TYPE_LOAD,
> + 0 // DetailStatus -- unused here
> + );
> +
1. With the BootCurrent, this change is not necessary because
others can hook PcdProgressCodeOsLoaderLoad to get the current
loading boot option.
> Status = gBS->LoadImage (
> TRUE,
> gImageHandle,
> FilePath,
> FileBuffer,
> FileSize,
> &ImageHandle
> );
> }
> if (FileBuffer != NULL) {
> FreePool (FileBuffer);
> }
> if (FilePath != NULL) {
> FreePool (FilePath);
> }
>
> if (EFI_ERROR (Status)) {
> //
> // Report Status Code to indicate that the failure to load boot option
> //
> REPORT_STATUS_CODE (
> EFI_ERROR_CODE | EFI_ERROR_MINOR,
> (EFI_SOFTWARE_DXE_BS_DRIVER |
> EFI_SW_DXE_BS_EC_BOOT_OPTION_LOAD_ERROR)
> );
> + BmReportOsLoaderDetail (
> + OsLoaderDetail,
> + OsLoaderDetailSize,
> + EDKII_OS_LOADER_DETAIL_TYPE_LOAD_ERROR,
> + Status
> + );
> +
2. I think firstly, the OsLoaderDetail is not needed.
Secondly, I prefer to submit a PI spec change to include extended
data for EFI_SW_DXE_BS_EC_BOOT_OPTION_LOAD_ERROR status code.
Instead of inventing a new status code.
> BootOption->Status = Status;
> //
> // Destroy the RAM disk
> //
> if (RamDiskDevicePath != NULL) {
> BmDestroyRamDisk (RamDiskDevicePath);
> FreePool (RamDiskDevicePath);
> }
> - return;
> + goto FreeOsLoaderDetail;
> }
> }
>
> //
> // Check to see if we should legacy BOOT. If yes then do the legacy boot
> // Write boot to OS performance data for Legacy boot
> //
> if ((DevicePathType (BootOption->FilePath) == BBS_DEVICE_PATH) &&
> (DevicePathSubType (BootOption->FilePath) == BBS_BBS_DP)) {
> if (mBmLegacyBoot != NULL) {
> //
> // Write boot to OS performance data for legacy boot.
> //
> @@ -1826,25 +1856,25 @@ EfiBootManagerBoot (
> NULL,
> &LegacyBootEvent
> );
> ASSERT_EFI_ERROR (Status);
> );
>
> mBmLegacyBoot (BootOption);
> } else {
> BootOption->Status = EFI_UNSUPPORTED;
> }
>
> PERF_END_EX (gImageHandle, "BdsAttempt", NULL, 0, (UINT32)
> OptionNumber);
> - return;
> + goto FreeOsLoaderDetail;
> }
>
> //
> // Provide the image with its load options
> //
> Status = gBS->HandleProtocol (ImageHandle,
> &gEfiLoadedImageProtocolGuid, (VOID **) &ImageInfo);
> ASSERT_EFI_ERROR (Status);
>
> if (!BmIsAutoCreateBootOption (BootOption)) {
> ImageInfo->LoadOptionsSize = BootOption->OptionalDataSize;
> ImageInfo->LoadOptions = BootOption->OptionalData;
> }
> @@ -1858,36 +1888,48 @@ EfiBootManagerBoot (
> // Before calling the image, enable the Watchdog Timer for 5 minutes
> period
> //
> gBS->SetWatchdogTimer (5 * 60, 0x0000, 0x00, NULL);
>
> //
> // Write boot to OS performance data for UEFI boot
> //
> PERF_CODE (
> BmWriteBootToOsPerformanceData (NULL, NULL);
> );
>
> REPORT_STATUS_CODE (EFI_PROGRESS_CODE, PcdGet32
> (PcdProgressCodeOsLoaderStart));
> + BmReportOsLoaderDetail (
> + OsLoaderDetail,
> + OsLoaderDetailSize,
> + EDKII_OS_LOADER_DETAIL_TYPE_START,
> + 0 // DetailStatus -- unused here
> + );
>
3. As above comment #1, this change is not needed.
> Status = gBS->StartImage (ImageHandle, &BootOption->ExitDataSize,
> &BootOption->ExitData);
> DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Image Return Status = %r\n",
> Status));
> BootOption->Status = Status;
> if (EFI_ERROR (Status)) {
> //
> // Report Status Code to indicate that boot failure
> //
> REPORT_STATUS_CODE (
> EFI_ERROR_CODE | EFI_ERROR_MINOR,
> (EFI_SOFTWARE_DXE_BS_DRIVER |
> EFI_SW_DXE_BS_EC_BOOT_OPTION_FAILED)
> );
> + BmReportOsLoaderDetail (
> + OsLoaderDetail,
> + OsLoaderDetailSize,
> + EDKII_OS_LOADER_DETAIL_TYPE_START_ERROR,
> + Status
> + );
> }
4. Similar comments to #2.
> PERF_END_EX (gImageHandle, "BdsAttempt", NULL, 0, (UINT32)
> OptionNumber);
>
> //
> // Destroy the RAM disk
> //
> if (RamDiskDevicePath != NULL) {
> BmDestroyRamDisk (RamDiskDevicePath);
> FreePool (RamDiskDevicePath);
> }
>
> //
> @@ -1912,24 +1954,29 @@ EfiBootManagerBoot (
> L"BootCurrent",
> &gEfiGlobalVariableGuid,
> 0,
> 0,
> NULL
> );
> //
> // Deleting variable with current variable implementation shouldn't fail.
> // When BootXXXX (e.g.: BootManagerMenu) boots BootYYYY, exiting
> BootYYYY causes BootCurrent deleted,
> // exiting BootXXXX causes deleting BootCurrent returns EFI_NOT_FOUND.
> //
> ASSERT (Status == EFI_SUCCESS || Status == EFI_NOT_FOUND);
> +
> +FreeOsLoaderDetail:
> + if (OsLoaderDetail != NULL) {
> + FreePool (OsLoaderDetail);
> + }
> }
>
> /**
> Check whether there is a instance in BlockIoDevicePath, which contain multi
> device path
> instances, has the same partition node with HardDriveDevicePath device
> path
>
> @param BlockIoDevicePath Multi device path instances which need to
> check
> @param HardDriveDevicePath A device path which starts with a hard
> drive media
> device path.
>
> @retval TRUE There is a matched device path instance.
> @retval FALSE There is no matched device path instance.
> diff --git a/MdeModulePkg/Library/UefiBootManagerLib/BmMisc.c
> b/MdeModulePkg/Library/UefiBootManagerLib/BmMisc.c
> index 81d365940043..29da896854b8 100644
> --- a/MdeModulePkg/Library/UefiBootManagerLib/BmMisc.c
> +++ b/MdeModulePkg/Library/UefiBootManagerLib/BmMisc.c
> @@ -369,24 +369,190 @@ BmSetVariableAndReportStatusCodeOnError (
> SetVariableStatus,
> sizeof (EDKII_SET_VARIABLE_STATUS) + NameSize + DataSize
> );
>
> FreePool (SetVariableStatus);
> }
> }
>
> return Status;
> }
>
>
> +/**
> + Dynamically allocate and initialize an EDKII_OS_LOADER_DETAIL status
> +code
> + payload.
> +
> + @param[in] BootOption Capture the OptionNumber, FilePath and
> + Description fields of BootOption in the
> + EDKII_OS_LOADER_DETAIL payload.
> +
> + @param[out] OsLoaderDetail On successful return, set to the
> + EDKII_OS_LOADER_DETAIL object that has been
> + allocated and initialized. On failure, not
> + modified.
> +
> + @param[out] OsLoaderDetailSize On successful return, set to the size of
> the
> + EDKII_OS_LOADER_DETAIL object that has been
> + allocated and initialized. On failure, not
> + modified.
> +
> + @retval EFI_UNSUPPORTED EFI_DEBUG_CODE reporting is disabled in
> the
> + platform.
> +
> + @retval EFI_INVALID_PARAMETER BootOption->OptionNumber is not in
> + 0x0000..0xFFFF, inclusive.
> +
> + @retval EFI_BAD_BUFFER_SIZE BootOption->FilePath and/or
> + BootOption->Description would exceed the
> + UINT16 size limits presented by
> + EDKII_OS_LOADER_DETAIL or
> + EFI_STATUS_CODE_DATA.
> +
> + @retval EFI_OUT_OF_RESOURCES Memory allocation failed.
> +
> + @retval EFI_SUCCESS The EDKII_OS_LOADER_DETAIL object has
> been
> + allocated and initialized. The caller is
> + responsible for freeing the object with
> + FreePool().
> +**/
> +EFI_STATUS
> +BmCreateOsLoaderDetail (
> + IN CONST EFI_BOOT_MANAGER_LOAD_OPTION *BootOption,
> + OUT EDKII_OS_LOADER_DETAIL **OsLoaderDetail,
> + OUT UINTN *OsLoaderDetailSize
> + )
> +{
> + UINTN DescriptionSize;
> + UINTN DevicePathSize;
> + UINTN PayloadSize;
> + EDKII_OS_LOADER_DETAIL *Payload;
> + UINT8 *VariableSizeData;
> +
> + if (!ReportDebugCodeEnabled ()) {
> + return EFI_UNSUPPORTED;
> + }
> +
> + if (BootOption->OptionNumber >= LoadOptionNumberMax) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + DescriptionSize = (BootOption->Description == NULL) ?
> + 0 :
> + StrSize (BootOption->Description); DevicePathSize
> + = GetDevicePathSize (BootOption->FilePath); PayloadSize = sizeof
> + *Payload + DescriptionSize + DevicePathSize;
> +
> + if (DescriptionSize > MAX_UINT16 ||
> + DevicePathSize > MAX_UINT16 ||
> + PayloadSize > MAX_UINT16) {
> + return EFI_BAD_BUFFER_SIZE;
> + }
> +
> + Payload = AllocateZeroPool (PayloadSize); if (Payload == NULL) {
> + return EFI_OUT_OF_RESOURCES;
> + }
> + VariableSizeData = (UINT8 *)(Payload + 1);
> +
> + //
> + // Populate the variable size fields at the end of the payload.
> + //
> + CopyMem (VariableSizeData, BootOption->Description, DescriptionSize);
> + VariableSizeData += DescriptionSize;
> +
> + CopyMem (VariableSizeData, BootOption->FilePath, DevicePathSize);
> + VariableSizeData += DevicePathSize;
> +
> + ASSERT (VariableSizeData - (UINT8 *)Payload == PayloadSize);
> +
> + //
> + // Populate the fixed fields in the payload. Any members not listed
> + below // remain zero-filled at this point.
> + //
> + Payload->BootOptionNumber = (UINT16)BootOption->OptionNumber;
> + Payload->DescriptionSize = (UINT16)DescriptionSize;
> + Payload->DevicePathSize = (UINT16)DevicePathSize;
> +
> + *OsLoaderDetail = Payload;
> + *OsLoaderDetailSize = PayloadSize;
> + return EFI_SUCCESS;
> +}
> +
> +
> +/**
> + Report an EFI_DEBUG_CODE status code with EDKII_OS_LOADER_DETAIL
> as
> +payload
> + (i.e., extended data).
> +
> + @param[in,out] OsLoaderDetail The EDKII_OS_LOADER_DETAIL payload
> previously
> + created with BmCreateOsLoaderDetail(), and
> + modified zero or more times by
> + BmReportOsLoaderDetail(). If OsLoaderDetail is
> + NULL, the function does nothing. Otherwise,
> + the Type and Status fields are overwritten in
> + OsLoaderDetail, and a status code is reported.
> +
> + @param[in] OsLoaderDetailSize The size returned by
> BmCreateOsLoaderDetail().
> + If OsLoaderDetail is NULL, OsLoaderDetailSize
> + may be zero.
> +
> + @param[in] DetailType OsLoaderDetail->Type is set to DetailType
> + before reporting the status code. The caller
> + is responsible for passing an
> + EDKII_OS_LOADER_DETAIL_TYPE_* value.
> +
> + @param[in] DetailStatus OsLoaderDetail->Status is set to DetailStatus
> + before reporting the status code.
> +
> + @retval EFI_UNSUPPORTED EFI_DEBUG_CODE reporting is disabled in the
> + platform.
> +
> + @retval EFI_ABORTED OsLoaderDetail is NULL.
> +
> + @return Values propagated from REPORT_STATUS_CODE_EX().
> +**/
> +EFI_STATUS
> +BmReportOsLoaderDetail (
> + IN OUT EDKII_OS_LOADER_DETAIL *OsLoaderDetail OPTIONAL,
> + IN UINTN OsLoaderDetailSize,
> + IN UINT32 DetailType,
> + IN EFI_STATUS DetailStatus
> + )
> +{
> + EFI_STATUS Status;
> +
> + if (!ReportDebugCodeEnabled ()) {
> + return EFI_UNSUPPORTED;
> + }
> +
> + if (OsLoaderDetail == NULL) {
> + return EFI_ABORTED;
> + }
> +
> + OsLoaderDetail->Type = DetailType;
> + OsLoaderDetail->Status = DetailStatus;
> +
> + Status = REPORT_STATUS_CODE_EX (
> + EFI_DEBUG_CODE, // Type
> + PcdGet32 (PcdDebugCodeOsLoaderDetail), // Value
> + 0, // Instance
> + &gEfiCallerIdGuid, // CallerId
> + &gEdkiiStatusCodeDataTypeOsLoaderDetailGuid, //
> ExtendedDataGuid
> + OsLoaderDetail, // ExtendedData
> + OsLoaderDetailSize // ExtendedDataSize
> + );
> + return Status;
> +}
> +
> +
> /**
> Print the device path info.
>
> @param DevicePath The device path need to print.
> **/
> VOID
> BmPrintDp (
> EFI_DEVICE_PATH_PROTOCOL *DevicePath
> )
> {
> CHAR16 *Str;
>
> --
> 2.14.1.3.gb7cf6e02401b
>
next prev parent reply other threads:[~2017-11-23 5:17 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-11-22 23:58 [PATCH 0/5] MdeModulePkg, OvmfPkg: more easily visible boot progress reporting Laszlo Ersek
2017-11-22 23:58 ` [PATCH 1/5] MdeModulePkg/BdsDxe: fall back to a Boot Manager Menu loop before hanging Laszlo Ersek
2017-11-23 3:43 ` Ni, Ruiyu
2017-11-23 13:09 ` Laszlo Ersek
2017-11-27 16:27 ` Laszlo Ersek
2017-11-22 23:58 ` [PATCH 2/5] MdeModulePkg: introduce the EDKII_OS_LOADER_DETAIL status code payload Laszlo Ersek
2017-11-22 23:58 ` [PATCH 3/5] MdeModulePkg/UefiBootManagerLib: report EDKII_OS_LOADER_DETAIL status code Laszlo Ersek
2017-11-23 5:21 ` Ni, Ruiyu [this message]
2017-11-23 14:03 ` Laszlo Ersek
2017-11-23 14:53 ` Ni, Ruiyu
2017-11-23 17:08 ` Laszlo Ersek
2017-11-23 23:00 ` Ni, Ruiyu
2017-11-22 23:58 ` [PATCH 4/5] OvmfPkg/PlatformBootManagerLib: print EDKII_OS_LOADER_DETAIL to ConOut Laszlo Ersek
2017-11-22 23:58 ` [PATCH 5/5] OvmfPkg: disable EFI_DEBUG_CODE reporting in RELEASE builds Laszlo Ersek
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=734D49CCEBEEF84792F5B80ED585239D5BACE29B@SHSMSX104.ccr.corp.intel.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