From nobody Mon Feb 9 09:22:28 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) smtp.mailfrom=edk2-devel-bounces@lists.01.org Return-Path: Received: from ml01.01.org (ml01.01.org [198.145.21.10]) by mx.zohomail.com with SMTPS id 1511395144620221.05646062354026; Wed, 22 Nov 2017 15:59:04 -0800 (PST) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id B67B62035BB21; Wed, 22 Nov 2017 15:54:46 -0800 (PST) Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) (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 D67CC2034C5D9 for ; Wed, 22 Nov 2017 15:54:43 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 56EDA356EA; Wed, 22 Nov 2017 23:59:00 +0000 (UTC) Received: from lacos-laptop-7.usersys.redhat.com (ovpn-120-45.rdu2.redhat.com [10.10.120.45]) by smtp.corp.redhat.com (Postfix) with ESMTP id A2FD44A1; Wed, 22 Nov 2017 23:58:58 +0000 (UTC) X-Original-To: edk2-devel@lists.01.org Received-SPF: none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) client-ip=198.145.21.10; envelope-from=edk2-devel-bounces@lists.01.org; helo=ml01.01.org; Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=209.132.183.28; helo=mx1.redhat.com; envelope-from=lersek@redhat.com; receiver=edk2-devel@lists.01.org From: Laszlo Ersek To: edk2-devel-01 Date: Thu, 23 Nov 2017 00:58:47 +0100 Message-Id: <20171122235849.4177-4-lersek@redhat.com> In-Reply-To: <20171122235849.4177-1-lersek@redhat.com> References: <20171122235849.4177-1-lersek@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.30]); Wed, 22 Nov 2017 23:59:00 +0000 (UTC) Subject: [edk2] [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: , Cc: Ruiyu Ni , Jordan Justen , Eric Dong , Star Zeng , Ard Biesheuvel MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Errors-To: edk2-devel-bounces@lists.01.org Sender: "edk2-devel" X-ZohoMail: RSF_4 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" 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 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(-) 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 cur= rent 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 i= n device) ## SOMETIMES_CONSUMES ## Variable:L"ConOut" (The device path of console = out device) ## SOMETIMES_CONSUMES ## Variable:L"ErrOut" (The device path of error ou= t device) gEfiGlobalVariableGuid =20 gPerformanceProtocolGuid ## SOMETIMES_CONSUMES ## V= ariable:L"PerfDataMemAddr" (The ACPI address of performance data) gEdkiiStatusCodeDataTypeVariableGuid ## SOMETIMES_CONSUMES ## G= UID + gEdkiiStatusCodeDataTypeOsLoaderDetailGuid ## SOMETIMES_CONSUMES ## G= UID gEfiDiskInfoAhciInterfaceGuid ## SOMETIMES_CONSUMES ## G= UID gEfiDiskInfoIdeInterfaceGuid ## SOMETIMES_CONSUMES ## G= UID gEfiDiskInfoScsiInterfaceGuid ## SOMETIMES_CONSUMES ## G= UID gEfiDiskInfoSdMmcInterfaceGuid ## SOMETIMES_CONSUMES ## G= UID =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] gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange = ## 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/MdeModu= lePkg/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, EITH= ER 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 dele= ted 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 the + EDKII_OS_LOADER_DETAIL payload. + + @param[out] OsLoaderDetail On successful return, set to the + EDKII_OS_LOADER_DETAIL object that has b= een + allocated and initialized. On failure, n= ot + modified. + + @param[out] OsLoaderDetailSize On successful return, set to the size of= the + EDKII_OS_LOADER_DETAIL object that has b= een + allocated and initialized. On failure, n= ot + modified. + + @retval EFI_UNSUPPORTED EFI_DEBUG_CODE reporting is disabled in t= he + 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 payl= oad + (i.e., extended data). + + @param[in,out] OsLoaderDetail The EDKII_OS_LOADER_DETAIL payload previo= usly + created with BmCreateOsLoaderDetail(), and + modified zero or more times by + BmReportOsLoaderDetail(). If OsLoaderDeta= il is + NULL, the function does nothing. Otherwis= e, + the Type and Status fields are overwritte= n in + OsLoaderDetail, and a status code is repo= rted. + + @param[in] OsLoaderDetailSize The size returned by BmCreateOsLoaderDeta= il(). + If OsLoaderDetail is NULL, OsLoaderDetail= Size + may be zero. + + @param[in] DetailType OsLoaderDetail->Type is set to DetailType + before reporting the status code. The cal= ler + is responsible for passing an + EDKII_OS_LOADER_DETAIL_TYPE_* value. + + @param[in] DetailStatus OsLoaderDetail->Status is set to DetailSt= atus + 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. =20 @param Multi A pointer to a multi-instance device path = data structure. @param Single A pointer to a single-instance device path= data structure. =20 @retval TRUE If the Single device path is contained wit= hin Multi device path. @retval FALSE The Single device path is not match within= Multi device path. =20 diff --git a/MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c b/MdeModulePk= g/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 Load= OptionTypeBoot) { 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 pat= h\n")); } else { DEBUG ((DEBUG_INFO | DEBUG_LOAD, "[Bds]Booting %s\n", BootOption->Desc= ription)); } 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, BootOpti= on->FilePath, &FilePath, &FileSize); if (FileBuffer !=3D NULL) { RamDiskDevicePath =3D BmGetRamDiskDevicePath (FilePath); =20 REPORT_STATUS_CODE (EFI_PROGRESS_CODE, PcdGet32 (PcdProgressCodeOsLo= aderLoad)); + BmReportOsLoaderDetail ( + OsLoaderDetail, + OsLoaderDetailSize, + EDKII_OS_LOADER_DETAIL_TYPE_LOAD, + 0 // DetailStatus -- unused here + ); + 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 opti= on // REPORT_STATUS_CODE ( EFI_ERROR_CODE | EFI_ERROR_MINOR, (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_EC_BOOT_OPTION_LOAD_ER= ROR) ); + BmReportOsLoaderDetail ( + OsLoaderDetail, + OsLoaderDetailSize, + EDKII_OS_LOADER_DETAIL_TYPE_LOAD_ERROR, + Status + ); + 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 boot // Write boot to OS performance data for Legacy boot // if ((DevicePathType (BootOption->FilePath) =3D=3D BBS_DEVICE_PATH) && (D= evicePathSubType (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,=20 &LegacyBootEvent ); ASSERT_EFI_ERROR (Status); ); =20 mBmLegacyBoot (BootOption); } else { BootOption->Status =3D EFI_UNSUPPORTED; } =20 PERF_END_EX (gImageHandle, "BdsAttempt", NULL, 0, (UINT32) OptionNumbe= r); - return; + goto FreeOsLoaderDetail; } =20 // // Provide the image with its load options // Status =3D gBS->HandleProtocol (ImageHandle, &gEfiLoadedImageProtocolGui= d, (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 per= iod // 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 (PcdProgressCodeOsLoader= Start)); + BmReportOsLoaderDetail ( + OsLoaderDetail, + OsLoaderDetailSize, + EDKII_OS_LOADER_DETAIL_TYPE_START, + 0 // DetailStatus -- unused here + ); =20 Status =3D gBS->StartImage (ImageHandle, &BootOption->ExitDataSize, &Boo= tOption->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 + ); } 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 fail. // When BootXXXX (e.g.: BootManagerMenu) boots BootYYYY, exiting BootYYY= Y 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 mu= lti device path instances, has the same partition node with HardDriveDevicePath device p= ath =20 @param BlockIoDevicePath Multi device path instances which need to= check @param HardDriveDevicePath A device path which starts with a hard dr= ive media device path. =20 @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/MdeModulePk= g/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 the + EDKII_OS_LOADER_DETAIL payload. + + @param[out] OsLoaderDetail On successful return, set to the + EDKII_OS_LOADER_DETAIL object that has b= een + allocated and initialized. On failure, n= ot + modified. + + @param[out] OsLoaderDetailSize On successful return, set to the size of= the + EDKII_OS_LOADER_DETAIL object that has b= een + allocated and initialized. On failure, n= ot + modified. + + @retval EFI_UNSUPPORTED EFI_DEBUG_CODE reporting is disabled in t= he + 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 >=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 payl= oad + (i.e., extended data). + + @param[in,out] OsLoaderDetail The EDKII_OS_LOADER_DETAIL payload previo= usly + created with BmCreateOsLoaderDetail(), and + modified zero or more times by + BmReportOsLoaderDetail(). If OsLoaderDeta= il is + NULL, the function does nothing. Otherwis= e, + the Type and Status fields are overwritte= n in + OsLoaderDetail, and a status code is repo= rted. + + @param[in] OsLoaderDetailSize The size returned by BmCreateOsLoaderDeta= il(). + If OsLoaderDetail is NULL, OsLoaderDetail= Size + may be zero. + + @param[in] DetailType OsLoaderDetail->Type is set to DetailType + before reporting the status code. The cal= ler + is responsible for passing an + EDKII_OS_LOADER_DETAIL_TYPE_* value. + + @param[in] DetailStatus OsLoaderDetail->Status is set to DetailSt= atus + 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, // ExtendedDataG= uid + OsLoaderDetail, // ExtendedData + OsLoaderDetailSize // ExtendedDataS= ize + ); + 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 --=20 2.14.1.3.gb7cf6e02401b _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel