]> git.proxmox.com Git - mirror_edk2.git/blob - MdePkg/Library/DxePiLib/DxePiLib.c
3261e08ade6db7cec3a77da643cc1b37b23d1ca1
[mirror_edk2.git] / MdePkg / Library / DxePiLib / DxePiLib.c
1 /** @file
2 Mde PI library functions.
3
4 Copyright (c) 2007, Intel Corporation<BR>
5 All rights reserved. This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
9
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13 **/
14
15 #include <PiDxe.h>
16 #include <Library/DebugLib.h>
17 #include <Library/MemoryAllocationLib.h>
18 #include <Library/UefiBootServicesTableLib.h>
19 #include <Protocol/FirmwareVolume2.h>
20 #include <Protocol/LoadedImage.h>
21
22
23 /**
24 Internal function which read the image specified by Firmware File GUID name and
25 the Firmware Section tyep from a specified Firmware Volume
26
27
28 @param Fv The Firmware Volume Protocol instance.
29 @param NameGuid The GUID name of a Firmware File.
30 @param SectionType The Firmware Section type.
31 @param Buffer On output, Buffer contains the the data read from the section in the Firmware File found.
32 @param Size On output, the size of Buffer.
33
34 @retval EFI_SUCCESS The image is found and data and size is returned.
35 @retval EFI_NOT_FOUND The image specified by NameGuid and SectionType can't be found.
36 @retval EFI_OUT_OF_RESOURCES There were not enough resources to allocate the output data buffer or complete the operations.
37 @retval EFI_DEVICE_ERROR A hardware error occurs during reading from the Firmware Volume.
38 @retval EFI_ACCESS_DENIED The firmware volume containing the searched Firmware File is configured to disallow reads.
39
40 **/
41 STATIC
42 EFI_STATUS
43 GetImageFromFv (
44 IN EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv,
45 IN CONST EFI_GUID *NameGuid,
46 IN EFI_SECTION_TYPE SectionType,
47 OUT VOID **Buffer,
48 OUT UINTN *Size
49 )
50 {
51 EFI_STATUS Status;
52 EFI_FV_FILETYPE FileType;
53 EFI_FV_FILE_ATTRIBUTES Attributes;
54 UINT32 AuthenticationStatus;
55
56 //
57 // Read desired section content in NameGuid file
58 //
59 *Buffer = NULL;
60 *Size = 0;
61 Status = Fv->ReadSection (
62 Fv,
63 NameGuid,
64 SectionType,
65 0,
66 Buffer,
67 Size,
68 &AuthenticationStatus
69 );
70
71 if (EFI_ERROR (Status) && (SectionType == EFI_SECTION_TE)) {
72 //
73 // Try reading PE32 section, since the TE section does not exist
74 //
75 *Buffer = NULL;
76 *Size = 0;
77 Status = Fv->ReadSection (
78 Fv,
79 NameGuid,
80 EFI_SECTION_PE32,
81 0,
82 Buffer,
83 Size,
84 &AuthenticationStatus
85 );
86 }
87
88 if (EFI_ERROR (Status) &&
89 ((SectionType == EFI_SECTION_TE) || (SectionType == EFI_SECTION_PE32))) {
90 //
91 // Try reading raw file, since the desired section does not exist
92 //
93 *Buffer = NULL;
94 *Size = 0;
95 Status = Fv->ReadFile (
96 Fv,
97 NameGuid,
98 Buffer,
99 Size,
100 &FileType,
101 &Attributes,
102 &AuthenticationStatus
103 );
104 }
105
106 return Status;
107 }
108
109 /**
110 Allocate and fill a buffer with an image identified by a Firmware File GUID name and a Firmware Section type.
111 The Firmware Volumes to search for the Firmware File can be specified to be either all Firmware Volumes
112 in the system, or the Firmware Volume which contains the Firmware File specified by an image handle.
113
114 If ImageHandle is NULL, all Firmware Volumes in the system will be searched. If ImageHandle is not NULL,
115 ImageHandle is interpreted as EFI_PEI_FILE_HANDLE for the implementation of this function for PEI phase.
116 The input parameter ImageHandle is interpreted as EFI_HANDLE, on which an EFI_LOADED_IMAGE_PROTOCOL
117 is installed, for the implementation of this function for DXE phase. The search always starts from the FV
118 identified by ImageHandle. If WithinImageFv is TRUE, search will only be performed on the first FV. If WithinImageFv
119 is FALSE, search will continue on other FVs if it fails on the first FV. The search order of Firmware Volumes is
120 deterministic but arbitrary if no new firmware volume is added into the system between each search.
121
122 The search order for the section type specified by SectionType in the Firmware File is using a depth-first
123 and left-to-right algorithm through all sections. The first section found to match SectionType will be returned.
124
125 If SectionType is EFI_SECTION_PE32, EFI_SECTION_PE32 will be used as Firmware Section type
126 to read Firmware Section data from the Firmware File. If no such section exists, the function will try
127 to read a Firmware File named with NameGuid. If no such file exists, EFI_NOT_FOUND is returned.
128
129 If SectionType is EFI_SECTION_TE, EFI_SECTION_TE will be used as Firmware Section type to read Firmware Section
130 data from the Firmware File. If no such section exists, EFI_SECTION_PE32 will be used as Firmware Section type to
131 read Firmware Section data from the Firmware File. If no such section exists, the function will try to read a Firmware
132 File named with NameGuid. If no such file exists, EFI_NOT_FOUND is returned.
133
134 The data and size is returned by Buffer and Size. The caller is responsible to free the Buffer allocated
135 by this function. This function can only be called at TPL_NOTIFY and below.
136
137 If ImageHandle is NULL and WithinImage is TRUE, then ASSERT ();
138 If NameGuid is NULL, then ASSERT();
139 If Buffer is NULL, then ASSERT();
140 If Size is NULL, then ASSERT().
141
142 @param NameGuid The GUID name of a Firmware File.
143 @param SectionType The Firmware Section type.
144 @param Buffer On output, Buffer contains the the data read from the section in the Firmware File found.
145 @param Size On output, the size of Buffer.
146
147 @retval EFI_SUCCESS The image is found and data and size is returned.
148 @retval EFI_NOT_FOUND The image specified by NameGuid and SectionType can't be found.
149 @retval EFI_OUT_OF_RESOURCES There were not enough resources to allocate the output data buffer or complete the operations.
150 @retval EFI_DEVICE_ERROR A hardware error occurs during reading from the Firmware Volume.
151 @retval EFI_ACCESS_DENIED The firmware volume containing the searched Firmware File is configured to disallow reads.
152
153 **/
154
155 EFI_STATUS
156 EFIAPI
157 GetSectionFromFvFile (
158 IN CONST VOID *ImageHandle,
159 IN CONST EFI_GUID *NameGuid,
160 IN EFI_SECTION_TYPE SectionType,
161 OUT VOID **Buffer,
162 OUT UINTN *Size,
163 IN BOOLEAN WithinImageFv
164 )
165 {
166 EFI_STATUS Status;
167 EFI_HANDLE *HandleBuffer;
168 UINTN HandleCount;
169 UINTN Index;
170 EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
171 EFI_FIRMWARE_VOLUME2_PROTOCOL *ImageFv;
172 EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;
173
174 ASSERT (NameGuid != NULL);
175 ASSERT (Buffer != NULL);
176 ASSERT (Size != NULL);
177 ASSERT (!(ImageHandle == NULL && WithinImageFv));
178
179 Status = EFI_NOT_FOUND;
180 ImageFv = NULL;
181 if (ImageHandle != NULL) {
182 Status = gBS->HandleProtocol (
183 (EFI_HANDLE *) ImageHandle,
184 &gEfiLoadedImageProtocolGuid,
185 (VOID **) &LoadedImage
186 );
187 if (EFI_ERROR (Status)) {
188 return Status;
189 }
190 Status = gBS->HandleProtocol (
191 LoadedImage->DeviceHandle,
192 &gEfiFirmwareVolume2ProtocolGuid,
193 (VOID **) &ImageFv
194 );
195 if (!EFI_ERROR (Status)) {
196 Status = GetImageFromFv (ImageFv, NameGuid, SectionType, Buffer, Size);
197 }
198 }
199
200 if (Status == EFI_SUCCESS || WithinImageFv) {
201 return Status;
202 }
203
204 HandleBuffer = NULL;
205 Status = gBS->LocateHandleBuffer (
206 ByProtocol,
207 &gEfiFirmwareVolume2ProtocolGuid,
208 NULL,
209 &HandleCount,
210 &HandleBuffer
211 );
212 if (EFI_ERROR (Status)) {
213 goto Done;
214 }
215
216 //
217 // Find desired image in all Fvs
218 //
219 for (Index = 0; Index < HandleCount; ++Index) {
220 Status = gBS->HandleProtocol (
221 HandleBuffer[Index],
222 &gEfiFirmwareVolume2ProtocolGuid,
223 (VOID**)&Fv
224 );
225
226 if (EFI_ERROR (Status)) {
227 goto Done;
228 }
229
230 if (ImageFv != NULL && Fv == ImageFv) {
231 continue;
232 }
233
234 Status = GetImageFromFv (Fv, NameGuid, SectionType, Buffer, Size);
235
236 if (!EFI_ERROR (Status)) {
237 goto Done;
238 }
239 }
240
241 //
242 // Not found image
243 //
244 if (Index == HandleCount) {
245 Status = EFI_NOT_FOUND;
246 }
247
248 Done:
249
250 if (HandleBuffer != NULL) {
251 FreePool(HandleBuffer);
252 }
253
254 return Status;
255 }
256