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