2 Firmware volume helper interfaces.
4 Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
5 Copyright (c) 2016 - 2021, Arm Limited. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
10 #include "StandaloneMmCore.h"
11 #include <Library/FvLib.h>
12 #include <Library/ExtractGuidedSectionLib.h>
15 // List of file types supported by dispatcher
17 EFI_FV_FILETYPE mMmFileTypes
[] = {
19 0xE, //EFI_FV_FILETYPE_MM_STANDALONE,
21 // Note: DXE core will process the FV image file, so skip it in MM core
22 // EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
28 IN EFI_FIRMWARE_VOLUME_HEADER
*FwVolHeader
,
30 IN UINTN Pe32DataSize
,
33 IN EFI_GUID
*DriverName
38 IN EFI_FIRMWARE_VOLUME_HEADER
*FwVolHeader
43 IN EFI_FIRMWARE_VOLUME_HEADER
*FwVolHeader
47 Given the pointer to the Firmware Volume Header find the
48 MM driver and return its PE32 image.
50 @param [in] FwVolHeader Pointer to memory mapped FV
52 @retval EFI_SUCCESS Success.
53 @retval EFI_INVALID_PARAMETER Invalid parameter.
54 @retval EFI_NOT_FOUND Could not find section data.
55 @retval EFI_OUT_OF_RESOURCES Out of resources.
56 @retval EFI_VOLUME_CORRUPTED Firmware volume is corrupted.
57 @retval EFI_UNSUPPORTED Operation not supported.
61 MmCoreFfsFindMmDriver (
62 IN EFI_FIRMWARE_VOLUME_HEADER
*FwVolHeader
66 EFI_STATUS DepexStatus
;
67 EFI_FFS_FILE_HEADER
*FileHeader
;
68 EFI_FV_FILETYPE FileType
;
74 EFI_COMMON_SECTION_HEADER
*Section
;
76 UINTN SectionDataSize
;
79 UINT32 ScratchBufferSize
;
81 UINT16 SectionAttribute
;
82 UINT32 AuthenticationStatus
;
83 EFI_FIRMWARE_VOLUME_HEADER
*InnerFvHeader
;
85 DEBUG ((DEBUG_INFO
, "MmCoreFfsFindMmDriver - 0x%x\n", FwVolHeader
));
87 if (FvHasBeenProcessed (FwVolHeader
)) {
91 FvIsBeingProcessed (FwVolHeader
);
94 // First check for encapsulated compressed firmware volumes
98 Status
= FfsFindNextFile (EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
,
99 FwVolHeader
, &FileHeader
);
100 if (EFI_ERROR (Status
)) {
103 Status
= FfsFindSectionData (EFI_SECTION_GUID_DEFINED
, FileHeader
,
104 &SectionData
, &SectionDataSize
);
105 if (EFI_ERROR (Status
)) {
108 Section
= (EFI_COMMON_SECTION_HEADER
*)(FileHeader
+ 1);
109 Status
= ExtractGuidedSectionGetInfo (Section
, &DstBufferSize
,
110 &ScratchBufferSize
, &SectionAttribute
);
111 if (EFI_ERROR (Status
)) {
116 // Allocate scratch buffer
118 ScratchBuffer
= (VOID
*)(UINTN
)AllocatePages (EFI_SIZE_TO_PAGES (ScratchBufferSize
));
119 if (ScratchBuffer
== NULL
) {
120 return EFI_OUT_OF_RESOURCES
;
124 // Allocate destination buffer, extra one page for adjustment
126 DstBuffer
= (VOID
*)(UINTN
)AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize
));
127 if (DstBuffer
== NULL
) {
128 return EFI_OUT_OF_RESOURCES
;
132 // Call decompress function
134 Status
= ExtractGuidedSectionDecode (Section
, &DstBuffer
, ScratchBuffer
,
135 &AuthenticationStatus
);
136 FreePages (ScratchBuffer
, EFI_SIZE_TO_PAGES (ScratchBufferSize
));
137 if (EFI_ERROR (Status
)) {
142 "Processing compressed firmware volume (AuthenticationStatus == %x)\n",
143 AuthenticationStatus
));
145 Status
= FindFfsSectionInSections (DstBuffer
, DstBufferSize
,
146 EFI_SECTION_FIRMWARE_VOLUME_IMAGE
, &Section
);
147 if (EFI_ERROR (Status
)) {
151 InnerFvHeader
= (VOID
*)(Section
+ 1);
152 Status
= MmCoreFfsFindMmDriver (InnerFvHeader
);
153 if (EFI_ERROR (Status
)) {
158 for (Index
= 0; Index
< sizeof (mMmFileTypes
) / sizeof (mMmFileTypes
[0]); Index
++) {
159 DEBUG ((DEBUG_INFO
, "Check MmFileTypes - 0x%x\n", mMmFileTypes
[Index
]));
160 FileType
= mMmFileTypes
[Index
];
163 Status
= FfsFindNextFile (FileType
, FwVolHeader
, &FileHeader
);
164 if (!EFI_ERROR (Status
)) {
165 Status
= FfsFindSectionData (EFI_SECTION_PE32
, FileHeader
, &Pe32Data
, &Pe32DataSize
);
166 DEBUG ((DEBUG_INFO
, "Find PE data - 0x%x\n", Pe32Data
));
167 DepexStatus
= FfsFindSectionData (EFI_SECTION_MM_DEPEX
, FileHeader
, &Depex
, &DepexSize
);
168 if (!EFI_ERROR (DepexStatus
)) {
169 MmAddToDriverList (FwVolHeader
, Pe32Data
, Pe32DataSize
, Depex
, DepexSize
, &FileHeader
->Name
);
172 } while (!EFI_ERROR (Status
));
178 FreePages (DstBuffer
, EFI_SIZE_TO_PAGES (DstBufferSize
));