From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=192.55.52.93; helo=mga11.intel.com; envelope-from=ruiyu.ni@intel.com; receiver=edk2-devel@lists.01.org Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 756752035BB16 for ; Wed, 22 Nov 2017 21:17:00 -0800 (PST) Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga102.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 22 Nov 2017 21:21:17 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.44,440,1505804400"; d="scan'208";a="6040486" Received: from fmsmsx104.amr.corp.intel.com ([10.18.124.202]) by fmsmga001.fm.intel.com with ESMTP; 22 Nov 2017 21:21:17 -0800 Received: from fmsmsx120.amr.corp.intel.com (10.18.124.208) by fmsmsx104.amr.corp.intel.com (10.18.124.202) with Microsoft SMTP Server (TLS) id 14.3.319.2; Wed, 22 Nov 2017 21:21:17 -0800 Received: from shsmsx152.ccr.corp.intel.com (10.239.6.52) by fmsmsx120.amr.corp.intel.com (10.18.124.208) with Microsoft SMTP Server (TLS) id 14.3.319.2; Wed, 22 Nov 2017 21:21:16 -0800 Received: from shsmsx104.ccr.corp.intel.com ([169.254.5.152]) by SHSMSX152.ccr.corp.intel.com ([169.254.6.93]) with mapi id 14.03.0319.002; Thu, 23 Nov 2017 13:21:14 +0800 From: "Ni, Ruiyu" To: Laszlo Ersek , edk2-devel-01 CC: Ard Biesheuvel , "Justen, Jordan L" , "Dong, Eric" , "Zeng, Star" Thread-Topic: [PATCH 3/5] MdeModulePkg/UefiBootManagerLib: report EDKII_OS_LOADER_DETAIL status code Thread-Index: AQHTY+3iRUVHeCXtuU+IX8hF+88Z1qMhUt7g Date: Thu, 23 Nov 2017 05:21:13 +0000 Message-ID: <734D49CCEBEEF84792F5B80ED585239D5BACE29B@SHSMSX104.ccr.corp.intel.com> References: <20171122235849.4177-1-lersek@redhat.com> <20171122235849.4177-4-lersek@redhat.com> In-Reply-To: <20171122235849.4177-4-lersek@redhat.com> Accept-Language: en-US, zh-CN X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [10.239.127.40] MIME-Version: 1.0 Subject: Re: [PATCH 3/5] MdeModulePkg/UefiBootManagerLib: report EDKII_OS_LOADER_DETAIL status code X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 23 Nov 2017 05:17:00 -0000 Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable 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 retrie= ved 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 > Cc: Ard Biesheuvel ; Justen, Jordan L > ; Ni, Ruiyu ; Dong, Eric > ; Zeng, Star > Subject: [PATCH 3/5] MdeModulePkg/UefiBootManagerLib: report > EDKII_OS_LOADER_DETAIL status code >=20 > The EfiBootManagerBoot() function reports progress codes about > LoadImage() preparation and failure, and StartImage() preparation and > failure. These codes are flat (scalar) constants. >=20 > Extend this by "broadcasting" the Boot#### option number, description, > device path, and -- on load / start failure -- the error result at the sa= me > 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. >=20 > Cc: Ard Biesheuvel > Cc: Jordan Justen > Cc: Ruiyu Ni > Cc: Eric Dong > Cc: Star Zeng > Ref: https://bugzilla.redhat.com/show_bug.cgi?id=3D1515418 > Contributed-under: TianoCore Contribution Agreement 1.1 > Signed-off-by: Laszlo Ersek > --- > 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(-) >=20 > 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] >=20 > ## 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 >=20 > 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 >=20 > [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 >=20 > [Pcd] >=20 > 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 > #include > #include > #include > #include > #include >=20 > #include #include > #include #include #include > > +#include >=20 > #include > #include > #include > #include > #include > #include > #include #include > #include #include > #include @@ -298,24 > +299,107 @@ BmStopHotkeyService ( >=20 > @retval EFI_NOT_FOUND The variable trying to be updated or de= leted > was not found. > **/ > EFI_STATUS > BmSetVariableAndReportStatusCodeOnError ( > IN CHAR16 *VariableName, > IN EFI_GUID *VendorGuid, > IN UINT32 Attributes, > IN UINTN DataSize, > IN VOID *Data > ); >=20 > +/** > + 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 th= e > + 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 th= e > + 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 i= s > + 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 OsLoaderDe= tail is > + NULL, the function does nothing. Otherw= ise, > + the Type and Status fields are overwrit= ten in > + OsLoaderDetail, and a status code is re= ported. > + > + @param[in] OsLoaderDetailSize The size returned by > BmCreateOsLoaderDetail(). > + If OsLoaderDetail is NULL, OsLoaderDeta= ilSize > + may be zero. > + > + @param[in] DetailType OsLoaderDetail->Type is set to DetailTy= pe > + before reporting the status code. The c= aller > + is responsible for passing an > + EDKII_OS_LOADER_DETAIL_TYPE_* value. > + > + @param[in] DetailStatus OsLoaderDetail->Status is set to Detail= Status > + 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 node= s of a > second device path instance. >=20 > @param Multi A pointer to a multi-instance device pat= h data > structure. > @param Single A pointer to a single-instance device pa= th data > structure. >=20 > @retval TRUE If the Single device path is contained w= ithin Multi > device path. > @retval FALSE The Single device path is not match with= in Multi > device path. >=20 > 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; >=20 > if (BootOption =3D=3D NULL) { > return; > } >=20 > if (BootOption->FilePath =3D=3D NULL || BootOption->OptionType !=3D > LoadOptionTypeBoot) { > BootOption->Status =3D EFI_INVALID_PARAMETER; > return; > } >=20 > + OsLoaderDetail =3D NULL; > + OsLoaderDetailSize =3D 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 =3D BmFindBootOptionInVariable (BootOption); > if (OptionNumber =3D=3D LoadOptionNumberUnassigned) { > Status =3D BmGetFreeOptionNumber (LoadOptionTypeBoot, &Uint16); > if (!EFI_ERROR (Status)) { > // > // Save the BootOption->OptionNumber to restore later > // > OptionNumber =3D Uint16; > OriginalOptionNumber =3D BootOption->OptionNumber; > @@ -1751,68 +1756,93 @@ EfiBootManagerBoot ( >=20 > // > // 6. Load EFI boot option to ImageHandle > // > DEBUG_CODE_BEGIN (); > if (BootOption->Description =3D=3D 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 (); >=20 > + // > + // Try to create the status code payload structure for detailed debug > + // reporting. > + // > + Status =3D BmCreateOsLoaderDetail (BootOption, &OsLoaderDetail, > + &OsLoaderDetailSize); > + if (EFI_ERROR (Status) && (Status !=3D EFI_UNSUPPORTED)) { > + DEBUG ((DEBUG_WARN | DEBUG_LOAD, > "[Bds]BmCreateOsLoaderDetail(): %r\n", > + Status)); > + } > + > ImageHandle =3D NULL; > RamDiskDevicePath =3D NULL; > if (DevicePathType (BootOption->FilePath) !=3D BBS_DEVICE_PATH) { > Status =3D EFI_NOT_FOUND; > FilePath =3D NULL; > EfiBootManagerConnectDevicePath (BootOption->FilePath, NULL); > FileBuffer =3D BmGetNextLoadOptionBuffer (LoadOptionTypeBoot, > BootOption->FilePath, &FilePath, &FileSize); > if (FileBuffer !=3D NULL) { > RamDiskDevicePath =3D BmGetRamDiskDevicePath (FilePath); >=20 > 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 =3D gBS->LoadImage ( > TRUE, > gImageHandle, > FilePath, > FileBuffer, > FileSize, > &ImageHandle > ); > } > if (FileBuffer !=3D NULL) { > FreePool (FileBuffer); > } > if (FilePath !=3D NULL) { > FreePool (FilePath); > } >=20 > if (EFI_ERROR (Status)) { > // > // Report Status Code to indicate that the failure to load boot op= tion > // > 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 =3D Status; > // > // Destroy the RAM disk > // > if (RamDiskDevicePath !=3D NULL) { > BmDestroyRamDisk (RamDiskDevicePath); > FreePool (RamDiskDevicePath); > } > - return; > + goto FreeOsLoaderDetail; > } > } >=20 > // > // Check to see if we should legacy BOOT. If yes then do the legacy bo= ot > // Write boot to OS performance data for Legacy boot > // > if ((DevicePathType (BootOption->FilePath) =3D=3D BBS_DEVICE_PATH) && > (DevicePathSubType (BootOption->FilePath) =3D=3D BBS_BBS_DP)) { > if (mBmLegacyBoot !=3D NULL) { > // > // Write boot to OS performance data for legacy boot. > // > @@ -1826,25 +1856,25 @@ EfiBootManagerBoot ( > NULL, > &LegacyBootEvent > ); > ASSERT_EFI_ERROR (Status); > ); >=20 > mBmLegacyBoot (BootOption); > } else { > BootOption->Status =3D EFI_UNSUPPORTED; > } >=20 > PERF_END_EX (gImageHandle, "BdsAttempt", NULL, 0, (UINT32) > OptionNumber); > - return; > + goto FreeOsLoaderDetail; > } >=20 > // > // Provide the image with its load options > // > Status =3D gBS->HandleProtocol (ImageHandle, > &gEfiLoadedImageProtocolGuid, (VOID **) &ImageInfo); > ASSERT_EFI_ERROR (Status); >=20 > if (!BmIsAutoCreateBootOption (BootOption)) { > ImageInfo->LoadOptionsSize =3D BootOption->OptionalDataSize; > ImageInfo->LoadOptions =3D 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); >=20 > // > // Write boot to OS performance data for UEFI boot > // > PERF_CODE ( > BmWriteBootToOsPerformanceData (NULL, NULL); > ); >=20 > REPORT_STATUS_CODE (EFI_PROGRESS_CODE, PcdGet32 > (PcdProgressCodeOsLoaderStart)); > + BmReportOsLoaderDetail ( > + OsLoaderDetail, > + OsLoaderDetailSize, > + EDKII_OS_LOADER_DETAIL_TYPE_START, > + 0 // DetailStatus -- unused here > + ); >=20 3. As above comment #1, this change is not needed. > Status =3D gBS->StartImage (ImageHandle, &BootOption->ExitDataSize, > &BootOption->ExitData); > DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Image Return Status =3D %r\n", > Status)); > BootOption->Status =3D 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); >=20 > // > // Destroy the RAM disk > // > if (RamDiskDevicePath !=3D NULL) { > BmDestroyRamDisk (RamDiskDevicePath); > FreePool (RamDiskDevicePath); > } >=20 > // > @@ -1912,24 +1954,29 @@ EfiBootManagerBoot ( > L"BootCurrent", > &gEfiGlobalVariableGuid, > 0, > 0, > NULL > ); > // > // Deleting variable with current variable implementation shouldn't fa= il. > // When BootXXXX (e.g.: BootManagerMenu) boots BootYYYY, exiting > BootYYYY causes BootCurrent deleted, > // exiting BootXXXX causes deleting BootCurrent returns EFI_NOT_FOUND. > // > ASSERT (Status =3D=3D EFI_SUCCESS || Status =3D=3D EFI_NOT_FOUND); > + > +FreeOsLoaderDetail: > + if (OsLoaderDetail !=3D NULL) { > + FreePool (OsLoaderDetail); > + } > } >=20 > /** > Check whether there is a instance in BlockIoDevicePath, which contain = multi > device path > instances, has the same partition node with HardDriveDevicePath device > path >=20 > @param BlockIoDevicePath Multi device path instances which need = to > check > @param HardDriveDevicePath A device path which starts with a hard > drive media > device path. >=20 > @retval TRUE There is a matched device path instance= . > @retval FALSE There is no matched device path instanc= e. > 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 > ); >=20 > FreePool (SetVariableStatus); > } > } >=20 > return Status; > } >=20 >=20 > +/** > + 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 th= e > + 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 th= e > + 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 i= s > + 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 >=3D LoadOptionNumberMax) { > + return EFI_INVALID_PARAMETER; > + } > + > + DescriptionSize =3D (BootOption->Description =3D=3D NULL) ? > + 0 : > + StrSize (BootOption->Description); DevicePathSize > + =3D GetDevicePathSize (BootOption->FilePath); PayloadSize =3D sizeof > + *Payload + DescriptionSize + DevicePathSize; > + > + if (DescriptionSize > MAX_UINT16 || > + DevicePathSize > MAX_UINT16 || > + PayloadSize > MAX_UINT16) { > + return EFI_BAD_BUFFER_SIZE; > + } > + > + Payload =3D AllocateZeroPool (PayloadSize); if (Payload =3D=3D NULL) = { > + return EFI_OUT_OF_RESOURCES; > + } > + VariableSizeData =3D (UINT8 *)(Payload + 1); > + > + // > + // Populate the variable size fields at the end of the payload. > + // > + CopyMem (VariableSizeData, BootOption->Description, DescriptionSize); > + VariableSizeData +=3D DescriptionSize; > + > + CopyMem (VariableSizeData, BootOption->FilePath, DevicePathSize); > + VariableSizeData +=3D DevicePathSize; > + > + ASSERT (VariableSizeData - (UINT8 *)Payload =3D=3D PayloadSize); > + > + // > + // Populate the fixed fields in the payload. Any members not listed > + below // remain zero-filled at this point. > + // > + Payload->BootOptionNumber =3D (UINT16)BootOption->OptionNumber; > + Payload->DescriptionSize =3D (UINT16)DescriptionSize; > + Payload->DevicePathSize =3D (UINT16)DevicePathSize; > + > + *OsLoaderDetail =3D Payload; > + *OsLoaderDetailSize =3D 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 OsLoaderDe= tail is > + NULL, the function does nothing. Otherw= ise, > + the Type and Status fields are overwrit= ten in > + OsLoaderDetail, and a status code is re= ported. > + > + @param[in] OsLoaderDetailSize The size returned by > BmCreateOsLoaderDetail(). > + If OsLoaderDetail is NULL, OsLoaderDeta= ilSize > + may be zero. > + > + @param[in] DetailType OsLoaderDetail->Type is set to DetailTy= pe > + before reporting the status code. The c= aller > + is responsible for passing an > + EDKII_OS_LOADER_DETAIL_TYPE_* value. > + > + @param[in] DetailStatus OsLoaderDetail->Status is set to Detail= Status > + 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 =3D=3D NULL) { > + return EFI_ABORTED; > + } > + > + OsLoaderDetail->Type =3D DetailType; > + OsLoaderDetail->Status =3D DetailStatus; > + > + Status =3D REPORT_STATUS_CODE_EX ( > + EFI_DEBUG_CODE, // Type > + PcdGet32 (PcdDebugCodeOsLoaderDetail), // Value > + 0, // Instance > + &gEfiCallerIdGuid, // CallerId > + &gEdkiiStatusCodeDataTypeOsLoaderDetailGuid, // > ExtendedDataGuid > + OsLoaderDetail, // ExtendedDat= a > + OsLoaderDetailSize // ExtendedDat= aSize > + ); > + return Status; > +} > + > + > /** > Print the device path info. >=20 > @param DevicePath The device path need to print. > **/ > VOID > BmPrintDp ( > EFI_DEVICE_PATH_PROTOCOL *DevicePath > ) > { > CHAR16 *Str; >=20 > -- > 2.14.1.3.gb7cf6e02401b >=20