]> git.proxmox.com Git - mirror_edk2.git/blob - StandaloneMmPkg/Core/FwVol.c
StandaloneMmPkg: Fix ECC error 4002 in FwVol helper
[mirror_edk2.git] / StandaloneMmPkg / Core / FwVol.c
1 /**@file
2
3 Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
4 Copyright (c) 2016 - 2021, Arm Limited. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6
7 **/
8
9 #include "StandaloneMmCore.h"
10 #include <Library/FvLib.h>
11 #include <Library/ExtractGuidedSectionLib.h>
12
13 //
14 // List of file types supported by dispatcher
15 //
16 EFI_FV_FILETYPE mMmFileTypes[] = {
17 EFI_FV_FILETYPE_MM,
18 0xE, //EFI_FV_FILETYPE_MM_STANDALONE,
19 //
20 // Note: DXE core will process the FV image file, so skip it in MM core
21 // EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
22 //
23 };
24
25 EFI_STATUS
26 MmAddToDriverList (
27 IN EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader,
28 IN VOID *Pe32Data,
29 IN UINTN Pe32DataSize,
30 IN VOID *Depex,
31 IN UINTN DepexSize,
32 IN EFI_GUID *DriverName
33 );
34
35 BOOLEAN
36 FvHasBeenProcessed (
37 IN EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader
38 );
39
40 VOID
41 FvIsBeingProcessed (
42 IN EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader
43 );
44
45 /**
46 Given the pointer to the Firmware Volume Header find the
47 MM driver and return its PE32 image.
48
49 @param [in] FwVolHeader Pointer to memory mapped FV
50
51 @retval EFI_SUCCESS Success.
52 @retval EFI_INVALID_PARAMETER Invalid parameter.
53 @retval EFI_NOT_FOUND Could not find section data.
54 @retval EFI_OUT_OF_RESOURCES Out of resources.
55 @retval EFI_VOLUME_CORRUPTED Firmware volume is corrupted.
56 @retval EFI_UNSUPPORTED Operation not supported.
57
58 **/
59 EFI_STATUS
60 MmCoreFfsFindMmDriver (
61 IN EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader
62 )
63 {
64 EFI_STATUS Status;
65 EFI_STATUS DepexStatus;
66 EFI_FFS_FILE_HEADER *FileHeader;
67 EFI_FV_FILETYPE FileType;
68 VOID *Pe32Data;
69 UINTN Pe32DataSize;
70 VOID *Depex;
71 UINTN DepexSize;
72 UINTN Index;
73 EFI_COMMON_SECTION_HEADER *Section;
74 VOID *SectionData;
75 UINTN SectionDataSize;
76 UINT32 DstBufferSize;
77 VOID *ScratchBuffer;
78 UINT32 ScratchBufferSize;
79 VOID *DstBuffer;
80 UINT16 SectionAttribute;
81 UINT32 AuthenticationStatus;
82 EFI_FIRMWARE_VOLUME_HEADER *InnerFvHeader;
83
84 DEBUG ((DEBUG_INFO, "MmCoreFfsFindMmDriver - 0x%x\n", FwVolHeader));
85
86 if (FvHasBeenProcessed (FwVolHeader)) {
87 return EFI_SUCCESS;
88 }
89
90 FvIsBeingProcessed (FwVolHeader);
91
92 //
93 // First check for encapsulated compressed firmware volumes
94 //
95 FileHeader = NULL;
96 do {
97 Status = FfsFindNextFile (EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE,
98 FwVolHeader, &FileHeader);
99 if (EFI_ERROR (Status)) {
100 break;
101 }
102 Status = FfsFindSectionData (EFI_SECTION_GUID_DEFINED, FileHeader,
103 &SectionData, &SectionDataSize);
104 if (EFI_ERROR (Status)) {
105 break;
106 }
107 Section = (EFI_COMMON_SECTION_HEADER *)(FileHeader + 1);
108 Status = ExtractGuidedSectionGetInfo (Section, &DstBufferSize,
109 &ScratchBufferSize, &SectionAttribute);
110 if (EFI_ERROR (Status)) {
111 break;
112 }
113
114 //
115 // Allocate scratch buffer
116 //
117 ScratchBuffer = (VOID *)(UINTN)AllocatePages (EFI_SIZE_TO_PAGES (ScratchBufferSize));
118 if (ScratchBuffer == NULL) {
119 return EFI_OUT_OF_RESOURCES;
120 }
121
122 //
123 // Allocate destination buffer, extra one page for adjustment
124 //
125 DstBuffer = (VOID *)(UINTN)AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize));
126 if (DstBuffer == NULL) {
127 return EFI_OUT_OF_RESOURCES;
128 }
129
130 //
131 // Call decompress function
132 //
133 Status = ExtractGuidedSectionDecode (Section, &DstBuffer, ScratchBuffer,
134 &AuthenticationStatus);
135 FreePages (ScratchBuffer, EFI_SIZE_TO_PAGES (ScratchBufferSize));
136 if (EFI_ERROR (Status)) {
137 goto FreeDstBuffer;
138 }
139
140 DEBUG ((DEBUG_INFO,
141 "Processing compressed firmware volume (AuthenticationStatus == %x)\n",
142 AuthenticationStatus));
143
144 Status = FindFfsSectionInSections (DstBuffer, DstBufferSize,
145 EFI_SECTION_FIRMWARE_VOLUME_IMAGE, &Section);
146 if (EFI_ERROR (Status)) {
147 goto FreeDstBuffer;
148 }
149
150 InnerFvHeader = (VOID *)(Section + 1);
151 Status = MmCoreFfsFindMmDriver (InnerFvHeader);
152 if (EFI_ERROR (Status)) {
153 goto FreeDstBuffer;
154 }
155 } while (TRUE);
156
157 for (Index = 0; Index < sizeof (mMmFileTypes) / sizeof (mMmFileTypes[0]); Index++) {
158 DEBUG ((DEBUG_INFO, "Check MmFileTypes - 0x%x\n", mMmFileTypes[Index]));
159 FileType = mMmFileTypes[Index];
160 FileHeader = NULL;
161 do {
162 Status = FfsFindNextFile (FileType, FwVolHeader, &FileHeader);
163 if (!EFI_ERROR (Status)) {
164 Status = FfsFindSectionData (EFI_SECTION_PE32, FileHeader, &Pe32Data, &Pe32DataSize);
165 DEBUG ((DEBUG_INFO, "Find PE data - 0x%x\n", Pe32Data));
166 DepexStatus = FfsFindSectionData (EFI_SECTION_MM_DEPEX, FileHeader, &Depex, &DepexSize);
167 if (!EFI_ERROR (DepexStatus)) {
168 MmAddToDriverList (FwVolHeader, Pe32Data, Pe32DataSize, Depex, DepexSize, &FileHeader->Name);
169 }
170 }
171 } while (!EFI_ERROR (Status));
172 }
173
174 return EFI_SUCCESS;
175
176 FreeDstBuffer:
177 FreePages (DstBuffer, EFI_SIZE_TO_PAGES (DstBufferSize));
178
179 return Status;
180 }