1 /*++
2
3 Copyright (c) 2011 - 2014, Intel Corporation. All rights reserved
4
5
6 This program and the accompanying materials are licensed and made available under
7
8 the terms and conditions of the BSD License that accompanies this distribution.
9
10 The full text of the license may be found at
11
12 http://opensource.org/licenses/bsd-license.php.
13
14
15
16 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
17
18 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
19
20
21
22
23 Module Name:
24
25 BiosIdLib.c
26
27 Abstract:
28
29 Boot service DXE BIOS ID library implementation.
30
31 These functions in this file can be called during DXE and cannot be called during runtime
32 or in SMM which should use a RT or SMM library.
33
34 --*/
35
36 #include <PiDxe.h>
37 #include <Library/BaseLib.h>
38 #include <Library/HobLib.h>
39 #include <Library/UefiBootServicesTableLib.h>
40 #include <Library/BaseMemoryLib.h>
GetImageFromFv(IN EFI_FIRMWARE_VOLUME2_PROTOCOL * Fv,IN EFI_GUID * NameGuid,IN EFI_SECTION_TYPE SectionType,OUT VOID ** Buffer,OUT UINTN * Size)41 #include <Library/DebugLib.h>
42
43 #include <Library/BiosIdLib.h>
44 #include <Guid/BiosId.h>
45 #include <Protocol/FirmwareVolume2.h>
46 #include <Protocol/LoadedImage.h>
47
48
49 EFI_STATUS
50 GetImageFromFv (
51 IN EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv,
52 IN EFI_GUID *NameGuid,
53 IN EFI_SECTION_TYPE SectionType,
54 OUT VOID **Buffer,
55 OUT UINTN *Size
56 )
57 {
58 EFI_STATUS Status;
59 EFI_FV_FILETYPE FileType;
60 EFI_FV_FILE_ATTRIBUTES Attributes;
61 UINT32 AuthenticationStatus;
62
63 //
64 // Read desired section content in NameGuid file
65 //
66 *Buffer = NULL;
67 *Size = 0;
68 Status = Fv->ReadSection (
69 Fv,
70 NameGuid,
71 SectionType,
72 0,
73 Buffer,
74 Size,
75 &AuthenticationStatus
76 );
77
78 if (EFI_ERROR (Status) && (SectionType == EFI_SECTION_TE)) {
79 //
80 // Try reading PE32 section, since the TE section does not exist
81 //
82 *Buffer = NULL;
83 *Size = 0;
84 Status = Fv->ReadSection (
85 Fv,
86 NameGuid,
87 EFI_SECTION_PE32,
88 0,
89 Buffer,
90 Size,
91 &AuthenticationStatus
92 );
93 }
94
95 if (EFI_ERROR (Status) &&
96 ((SectionType == EFI_SECTION_TE) || (SectionType == EFI_SECTION_PE32))) {
97 //
98 // Try reading raw file, since the desired section does not exist
99 //
100 *Buffer = NULL;
101 *Size = 0;
102 Status = Fv->ReadFile (
103 Fv,
104 NameGuid,
105 Buffer,
106 Size,
107 &FileType,
108 &Attributes,
109 &AuthenticationStatus
110 );
111 }
112
113 return Status;
114 }
115
116
117 EFI_STATUS
118 GetImageEx (
119 IN EFI_HANDLE ImageHandle,
120 IN EFI_GUID *NameGuid,
121 IN EFI_SECTION_TYPE SectionType,
122 OUT VOID **Buffer,
123 OUT UINTN *Size,
124 BOOLEAN WithinImageFv
125 )
126 {
127 EFI_STATUS Status;
128 EFI_HANDLE *HandleBuffer;
129 UINTN HandleCount;
130 UINTN Index;
131 EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
132
133 EFI_FIRMWARE_VOLUME2_PROTOCOL *ImageFv;
134 EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;
135
136
137 if (ImageHandle == NULL && WithinImageFv) {
138 return EFI_INVALID_PARAMETER;
139 }
140
141 Status = EFI_NOT_FOUND;
142 ImageFv = NULL;
143 if (ImageHandle != NULL) {
144 Status = gBS->HandleProtocol (
145 ImageHandle,
146 &gEfiLoadedImageProtocolGuid,
147 (VOID **) &LoadedImage
148 );
149 if (EFI_ERROR (Status)) {
150 return Status;
151 }
152 Status = gBS->HandleProtocol (
153 LoadedImage->DeviceHandle,
154 &gEfiFirmwareVolume2ProtocolGuid,
155 (VOID **) &ImageFv
156 );
157 if (!EFI_ERROR (Status)) {
158 Status = GetImageFromFv (ImageFv, NameGuid, SectionType, Buffer, Size);
159 }
160 }
161
162 if (Status == EFI_SUCCESS || WithinImageFv) {
163 return Status;
164 }
165
166 Status = gBS->LocateHandleBuffer (
167 ByProtocol,
168 &gEfiFirmwareVolume2ProtocolGuid,
169 NULL,
170 &HandleCount,
171 &HandleBuffer
172 );
173 if (EFI_ERROR (Status)) {
174 return Status;
175 }
176
177 //
178 // Find desired image in all Fvs
179 //
180 for (Index = 0; Index < HandleCount; ++Index) {
181 Status = gBS->HandleProtocol (
182 HandleBuffer[Index],
183 &gEfiFirmwareVolume2ProtocolGuid,
184 (VOID**)&Fv
185 );
186
187 if (EFI_ERROR (Status)) {
188 gBS->FreePool(HandleBuffer);
189 return Status;
190 }
191
192 if (ImageFv != NULL && Fv == ImageFv) {
193 continue;
194 }
195
196 Status = GetImageFromFv (Fv, NameGuid, SectionType, Buffer, Size);
197
198 if (!EFI_ERROR (Status)) {
199 break;
200 }
201 }
202 gBS->FreePool(HandleBuffer);
203
204 //
205 // Not found image
206 //
207 if (Index == HandleCount) {
208 return EFI_NOT_FOUND;
209 }
210
211 return EFI_SUCCESS;
212 }
213
214 /**
215 This function returns BIOS ID by searching HOB or FV.
GetBiosId(OUT BIOS_ID_IMAGE * BiosIdImage)216
217 @param BiosIdImage The BIOS ID got from HOB or FV.
218
219 @retval EFI_SUCCESS All parameters were valid and BIOS ID has been got.
220 @retval EFI_NOT_FOUND BiosId image is not found, and no parameter will be modified.
221 @retval EFI_INVALID_PARAMETER The parameter is NULL.
222
223 **/
224 EFI_STATUS
225 GetBiosId (
226 OUT BIOS_ID_IMAGE *BiosIdImage
227 )
228
229 {
230 EFI_STATUS Status;
231 VOID *Address = NULL;
232 UINTN Size = 0;
233
234 DEBUG ((EFI_D_INFO, "Get BIOS ID from FV\n"));
235
236 Status = GetImageEx (
237 NULL,
238 &gEfiBiosIdGuid,
239 EFI_SECTION_RAW,
240 &Address,
241 &Size,
242 FALSE
243 );
244
245 if (Status == EFI_SUCCESS) {
246 //
247 // BiosId image is present in FV
248 //
249 if (Address != NULL) {
250 Size = sizeof (BIOS_ID_IMAGE);
251 gBS->CopyMem (
252 (void *) BiosIdImage,
253 Address,
254 Size
255 );
256 //
257 // GetImage () allocated buffer for Address, now clear it.
258 //
259 gBS->FreePool (Address);
260
261 DEBUG ((EFI_D_INFO, "Get BIOS ID from FV successfully\n"));
262 DEBUG ((EFI_D_INFO, "BIOS ID: %s\n", (CHAR16 *) (&(BiosIdImage->BiosIdString))));
263
264 return EFI_SUCCESS;
265 }
266 }
267 return EFI_NOT_FOUND;
268 }
269
270 /**
271 This function returns the Version & Release Date and Time by getting and converting
272 BIOS ID.
273
274 @param BiosVersion The Bios Version out of the conversion.
GetBiosVersionDateTime(OUT CHAR16 * BiosVersion,OPTIONAL OUT CHAR16 * BiosReleaseDate,OPTIONAL OUT CHAR16 * BiosReleaseTime OPTIONAL)275 @param BiosReleaseDate The Bios Release Date out of the conversion.
276 @param BiosReleaseTime - The Bios Release Time out of the conversion.
277
278 @retval EFI_SUCCESS - BIOS Version & Release Date and Time have been got successfully.
279 @retval EFI_NOT_FOUND - BiosId image is not found, and no parameter will be modified.
280 @retval EFI_INVALID_PARAMETER - All the parameters are NULL.
281
282 **/
283 EFI_STATUS
284 GetBiosVersionDateTime (
285 OUT CHAR16 *BiosVersion, OPTIONAL
286 OUT CHAR16 *BiosReleaseDate, OPTIONAL
287 OUT CHAR16 *BiosReleaseTime OPTIONAL
288 )
289 {
290 EFI_STATUS Status;
291 BIOS_ID_IMAGE BiosIdImage;
292
293 if ((BiosVersion == NULL) && (BiosReleaseDate == NULL) && (BiosReleaseTime == NULL)) {
294 return EFI_INVALID_PARAMETER;
295 }
296
297 Status = GetBiosId (&BiosIdImage);
298 if (EFI_ERROR (Status)) {
299 return EFI_NOT_FOUND;
300 }
301
302 if (BiosVersion != NULL) {
303 //
304 // Fill the BiosVersion data from the BIOS ID.
305 //
306 StrCpy (BiosVersion, (CHAR16 *) (&(BiosIdImage.BiosIdString)));
307 }
308
309 if (BiosReleaseDate != NULL) {
310 //
311 // Fill the build timestamp date from the BIOS ID in the "MM/DD/YY" format.
312 //
313 BiosReleaseDate[0] = BiosIdImage.BiosIdString.TimeStamp[2];
314 BiosReleaseDate[1] = BiosIdImage.BiosIdString.TimeStamp[3];
315 BiosReleaseDate[2] = (CHAR16) ((UINT8) ('/'));
316
317 BiosReleaseDate[3] = BiosIdImage.BiosIdString.TimeStamp[4];
318 BiosReleaseDate[4] = BiosIdImage.BiosIdString.TimeStamp[5];
319 BiosReleaseDate[5] = (CHAR16) ((UINT8) ('/'));
320
321 //
322 // Add 20 for SMBIOS table
323 // Current Linux kernel will misjudge 09 as year 0, so using 2009 for SMBIOS table
324 //
325 BiosReleaseDate[6] = '2';
326 BiosReleaseDate[7] = '0';
327 BiosReleaseDate[8] = BiosIdImage.BiosIdString.TimeStamp[0];
328 BiosReleaseDate[9] = BiosIdImage.BiosIdString.TimeStamp[1];
329
330 BiosReleaseDate[10] = (CHAR16) ((UINT8) ('\0'));
331 }
332
333 if (BiosReleaseTime != NULL) {
334
335 //
336 // Fill the build timestamp time from the BIOS ID in the "HH:MM" format.
337 //
338
339 BiosReleaseTime[0] = BiosIdImage.BiosIdString.TimeStamp[6];
340 BiosReleaseTime[1] = BiosIdImage.BiosIdString.TimeStamp[7];
341 BiosReleaseTime[2] = (CHAR16) ((UINT8) (':'));
342
343 BiosReleaseTime[3] = BiosIdImage.BiosIdString.TimeStamp[8];
344 BiosReleaseTime[4] = BiosIdImage.BiosIdString.TimeStamp[9];
345
346 BiosReleaseTime[5] = (CHAR16) ((UINT8) ('\0'));
347 }
348
349 return EFI_SUCCESS;
350 }
351
352