From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by mx.groups.io with SMTP id smtpd.web10.46507.1685355455795454568 for ; Mon, 29 May 2023 03:17:35 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=TJiMVTAG; spf=pass (domain: kernel.org, ip: 139.178.84.217, mailfrom: ardb@kernel.org) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 505DE61405; Mon, 29 May 2023 10:17:35 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 4942EC4339E; Mon, 29 May 2023 10:17:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1685355454; bh=BgnlFUhzNAq+8USYKlaYlB4CojZT38DS5rSboQ27d9I=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=TJiMVTAGmhXqYd2fow2pPjfrLctS9DJ+Oga4Uf4rigpl1yOlKu1vPkOhr+gCpovhT yY+yNNecwhhT5AzPtF1nV/6JQ2mChamCu6zoIIGQEh94c9oih1W3SinHrr02JZ28SR QQfAHhJQWPXiKZKRbqzC8oTJcHgBFD++Dwkmx9LtmOE2NAAL7dhhRfCFXE+iQUR5dW d/usJJKDaOBDeQDcJhORrSDNvNxIk5MOjaa5egB1x3Dlh+yTuQ3WycJU9hWSaBRj2w aSO7jaVJLxIyBm5ktqk/fOCWcmoRPbxexSGV+oeZh6edhcT2D4nwNg4CC5V1wYNsgN eFiGhihNn2HUQ== From: "Ard Biesheuvel" To: devel@edk2.groups.io Cc: Ard Biesheuvel , Ray Ni , Jiewen Yao , Gerd Hoffmann , Taylor Beebe , Oliver Smith-Denny , Dandan Bi , Liming Gao , "Kinney, Michael D" , Leif Lindholm , Michael Kubacki Subject: [RFC PATCH 06/11] MdeModulePkg/DxeCore: Expose memory mapped FV protocol when possible Date: Mon, 29 May 2023 12:17:00 +0200 Message-Id: <20230529101705.2476949-7-ardb@kernel.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230529101705.2476949-1-ardb@kernel.org> References: <20230529101705.2476949-1-ardb@kernel.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Expose the EDK2 specific memory mapped FV protocol in addition to the firmware volume protocol defined by PI when the underlying firmware volume block protocol informs us that the firmware volume is memory mapped. This permits the image loader to access any FFS files in the image directly, rather than requiring it to load a cached copy into memory via the ReadFile() API. This avoids a redundant memcpy(). Signed-off-by: Ard Biesheuvel --- MdeModulePkg/Core/Dxe/FwVol/FwVol.c | 113 +++++++++++++++++++- MdeModulePkg/Core/Dxe/FwVol/FwVolDriver.h | 31 ++++++ 2 files changed, 140 insertions(+), 4 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/FwVol/FwVol.c b/MdeModulePkg/Core/Dxe/Fw= Vol/FwVol.c index 153bfecafa7772ea..f7f236496686bc36 100644 --- a/MdeModulePkg/Core/Dxe/FwVol/FwVol.c +++ b/MdeModulePkg/Core/Dxe/FwVol/FwVol.c @@ -41,7 +41,8 @@ FV_DEVICE mFvDevice =3D { 0,=0D 0,=0D FALSE,=0D - FALSE=0D + FALSE,=0D + { MemoryMappedFvGetLocationAndSize },=0D };=0D =0D //=0D @@ -676,11 +677,13 @@ NotifyFwVolBlock ( //=0D // Install an New FV protocol on the existing handle=0D //=0D - Status =3D CoreInstallProtocolInterface (=0D + Status =3D CoreInstallMultipleProtocolInterfaces (=0D &Handle,=0D &gEfiFirmwareVolume2ProtocolGuid,=0D - EFI_NATIVE_INTERFACE,=0D - &FvDevice->Fv=0D + &FvDevice->Fv,=0D + (FvDevice->IsMemoryMapped ? &gEdkiiMemoryMappedFvProtoc= olGuid : NULL),=0D + &FvDevice->MemoryMappedFv,=0D + NULL=0D );=0D ASSERT_EFI_ERROR (Status);=0D } else {=0D @@ -722,3 +725,105 @@ FwVolDriverInit ( );=0D return EFI_SUCCESS;=0D }=0D +=0D +/**=0D + Get the physical address and size of a file's section in a memory mapped= FV=0D +=0D + @param[in] This The protocol pointer=0D + @param[in] NameGuid The name GUID of the file=0D + @param[in] SectionType The file section from which to retrieve addres= s and size=0D + @param[out] FileAddress The physical address of the file=0D + @param[out] FileSize The size of the file=0D + @param[out] AuthStatus The authentication status associated with the = file=0D +=0D + @retval EFI_SUCCESS Information about the file was retrieved = successfully.=0D + @retval EFI_INVALID_PARAMETER FileAddress was NULL, FileSize was NULL, = AuthStatus=0D + was NULL.=0D + @retval EFI_NOT_FOUND No section of the specified type could be= located in=0D + the specified file.=0D +=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +MemoryMappedFvGetLocationAndSize (=0D + IN EDKII_MEMORY_MAPPED_FV_PROTOCOL *This,=0D + IN CONST EFI_GUID *NameGuid,=0D + IN EFI_SECTION_TYPE SectionType,=0D + OUT EFI_PHYSICAL_ADDRESS *FileAddress,=0D + OUT UINTN *FileSize,=0D + OUT UINT32 *AuthStatus=0D + )=0D +{=0D + FV_DEVICE *FvDevice;=0D + EFI_STATUS Status;=0D + EFI_FV_FILETYPE FileType;=0D + EFI_FV_FILE_ATTRIBUTES FileAttributes;=0D + EFI_GUID FileNameGuid;=0D + FFS_FILE_LIST_ENTRY *FfsFileEntry;=0D + EFI_COMMON_SECTION_HEADER *Section;=0D + UINTN FvFileSize;=0D + UINTN SectionLength;=0D + UINTN HeaderLength;=0D +=0D + FvDevice =3D FV_DEVICE_FROM_MMFV (This);=0D + FfsFileEntry =3D NULL;=0D +=0D + do {=0D + FileType =3D 0;=0D + Status =3D FvGetNextFile (=0D + &FvDevice->Fv,=0D + &FfsFileEntry,=0D + &FileType,=0D + &FileNameGuid,=0D + &FileAttributes,=0D + &FvFileSize=0D + );=0D + if (EFI_ERROR (Status)) {=0D + return EFI_NOT_FOUND;=0D + }=0D + } while (!CompareGuid (&FileNameGuid, NameGuid));=0D +=0D + //=0D + // Skip over file header=0D + //=0D + if (IS_FFS_FILE2 (FfsFileEntry->FfsHeader)) {=0D + Section =3D (VOID *)((UINT8 *)FfsFileEntry->FfsHeader +=0D + sizeof (EFI_FFS_FILE_HEADER2));=0D + } else {=0D + Section =3D (VOID *)((UINT8 *)FfsFileEntry->FfsHeader +=0D + sizeof (EFI_FFS_FILE_HEADER));=0D + }=0D +=0D + do {=0D + if (IS_SECTION2 (Section)) {=0D + SectionLength =3D SECTION2_SIZE (Section);=0D + HeaderLength =3D sizeof (EFI_COMMON_SECTION_HEADER2);=0D + } else {=0D + SectionLength =3D SECTION_SIZE (Section);=0D + HeaderLength =3D sizeof (EFI_COMMON_SECTION_HEADER);=0D + }=0D +=0D + if (SectionLength > FvFileSize) {=0D + DEBUG ((DEBUG_WARN, "%a: %x > %x\n", __func__, SectionLength, FvFile= Size));=0D + break;=0D + }=0D +=0D + if (Section->Type =3D=3D SectionType) {=0D + *FileAddress =3D (UINTN)Section + HeaderLength;=0D + *FileSize =3D SectionLength - HeaderLength;=0D + *AuthStatus =3D FvDevice->AuthenticationStatus;=0D +=0D + return EFI_SUCCESS;=0D + }=0D +=0D + //=0D + // SectionLength is adjusted it is 4 byte aligned.=0D + // Go to the next section=0D + //=0D + SectionLength =3D ALIGN_VALUE (SectionLength, 4);=0D + Section =3D (EFI_COMMON_SECTION_HEADER *)((UINT8 *)Section + Sec= tionLength);=0D + FvFileSize -=3D SectionLength;=0D + } while (TRUE);=0D +=0D + return EFI_NOT_FOUND;=0D +}=0D diff --git a/MdeModulePkg/Core/Dxe/FwVol/FwVolDriver.h b/MdeModulePkg/Core/= Dxe/FwVol/FwVolDriver.h index 3403c812b2ebcb45..eb1b702c1ee0bd4f 100644 --- a/MdeModulePkg/Core/Dxe/FwVol/FwVolDriver.h +++ b/MdeModulePkg/Core/Dxe/FwVol/FwVolDriver.h @@ -40,10 +40,13 @@ typedef struct { UINT8 ErasePolarity;=0D BOOLEAN IsFfs3Fv;=0D BOOLEAN IsMemoryMapped;=0D + EDKII_MEMORY_MAPPED_FV_PROTOCOL MemoryMappedFv;=0D } FV_DEVICE;=0D =0D #define FV_DEVICE_FROM_THIS(a) CR(a, FV_DEVICE, Fv, FV2_DEVICE_SIGNATURE)= =0D =0D +#define FV_DEVICE_FROM_MMFV(a) CR(a, FV_DEVICE, MemoryMappedFv, FV2_DEVIC= E_SIGNATURE)=0D +=0D /**=0D Retrieves attributes, insures positive polarity of attribute bits, retur= ns=0D resulting attributes in output parameter.=0D @@ -384,4 +387,32 @@ IsValidFfsFile ( IN EFI_FFS_FILE_HEADER *FfsHeader=0D );=0D =0D +/**=0D + Get the physical address and size of a file's section in a memory mapped= FV=0D +=0D + @param[in] This The protocol pointer=0D + @param[in] NameGuid The name GUID of the file=0D + @param[in] SectionType The file section from which to retrieve addres= s and size=0D + @param[out] FileAddress The physical address of the file=0D + @param[out] FileSize The size of the file=0D + @param[out] AuthStatus The authentication status associated with the = file=0D +=0D + @retval EFI_SUCCESS Information about the file was retrieved = successfully.=0D + @retval EFI_INVALID_PARAMETER FileAddress was NULL, FileSize was NULL, = AuthStatus=0D + was NULL.=0D + @retval EFI_NOT_FOUND No section of the specified type could be= located in=0D + the specified file.=0D +=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +MemoryMappedFvGetLocationAndSize (=0D + IN EDKII_MEMORY_MAPPED_FV_PROTOCOL *This,=0D + IN CONST EFI_GUID *NameGuid,=0D + IN EFI_SECTION_TYPE SectionType,=0D + OUT EFI_PHYSICAL_ADDRESS *FileAddress,=0D + OUT UINTN *FileSize,=0D + OUT UINT32 *AuthStatus=0D + );=0D +=0D #endif=0D --=20 2.39.2