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