3 Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
12 MiscBiosVendorFunction.c
16 BIOS vendor information boot time changes.
17 Misc. subclass type 2.
23 #include "CommonHeader.h"
25 #include "MiscSubclassDriver.h"
26 #include <Library/BiosIdLib.h>
27 #include <Library/SpiFlash.H>
29 EFI_SPI_PROTOCOL
*mSpiProtocol
= NULL
;
33 This function read the data from Spi Rom.
35 @param BaseAddress The starting address of the read.
36 @param Byte The pointer to the destination buffer.
37 @param Length The number of bytes.
38 @param SpiRegionType Spi Region Type.
48 IN SPI_REGION_TYPE SpiRegionType
51 EFI_STATUS Status
= EFI_SUCCESS
;
54 UINT8 Buffer
[SECTOR_SIZE_4KB
];
56 SpiAddress
= (UINT32
)(UINTN
)(BaseAddress
);
57 SectorSize
= SECTOR_SIZE_4KB
;
59 Status
= mSpiProtocol
->Execute (
72 if (EFI_ERROR (Status
)) {
74 Print(L
"Read SPI ROM Failed [%08x]\n", SpiAddress
);
79 CopyMem (Byte
, (void *)Buffer
, Length
);
85 This function returns the value & exponent to Base2 for a given
86 Hex value. This is used to calculate the BiosPhysicalDeviceSize.
88 @param Value The hex value which is to be converted into value-exponent form
89 @param Exponent The exponent out of the conversion
91 @retval EFI_SUCCESS All parameters were valid and *Value & *Exponent have been set.
92 @retval EFI_INVALID_PARAMETER Invalid parameter was found.
96 GetValueExponentBase2(
101 if ((Value
== NULL
) || (Exponent
== NULL
)) {
102 return EFI_INVALID_PARAMETER
;
105 while ((*Value
% 2) == 0) {
114 Field Filling Function. Transform an EFI_EXP_BASE2_DATA to a byte, with '64k'
117 @param Base2Data Pointer to Base2_Data
119 @retval EFI_SUCCESS Transform successfully.
120 @retval EFI_INVALID_PARAMETER Invalid parameter was found.
124 Base2ToByteWith64KUnit (
125 IN EFI_EXP_BASE2_DATA
*Base2Data
131 Value
= Base2Data
->Value
;
132 Exponent
= Base2Data
->Exponent
;
141 This function makes boot time changes to the contents of the
142 MiscBiosVendor (Type 0).
144 @param RecordData Pointer to copy of RecordData from the Data Table.
146 @retval EFI_SUCCESS All parameters were valid.
147 @retval EFI_UNSUPPORTED Unexpected RecordType value.
148 @retval EFI_INVALID_PARAMETER Invalid parameter was found.
151 MISC_SMBIOS_TABLE_FUNCTION(MiscBiosVendor
)
153 CHAR8
*OptionalStrStart
;
159 CHAR16 BiosVersion
[100]; //Assuming that strings are < 100 UCHAR
160 CHAR16 BiosReleaseDate
[100]; //Assuming that strings are < 100 UCHAR
161 CHAR16 BiosReleaseTime
[100]; //Assuming that strings are < 100 UCHAR
163 EFI_STRING Char16String
;
164 STRING_REF TokenToGet
;
165 STRING_REF TokenToUpdate
;
166 SMBIOS_TABLE_TYPE0
*SmbiosRecord
;
167 EFI_SMBIOS_HANDLE SmbiosHandle
;
168 EFI_MISC_BIOS_VENDOR
*ForType0InputData
;
169 BIOS_ID_IMAGE BiosIdImage
;
173 MANIFEST_OEM_DATA
*IFWIVerStruct
;
175 UINT16 SpaceVer
[2]={0x0020,0x0000};
176 UINT16 BIOSVersionTemp
[100];
178 ForType0InputData
= (EFI_MISC_BIOS_VENDOR
*)RecordData
;
181 // First check for invalid parameters.
183 if (RecordData
== NULL
) {
184 return EFI_INVALID_PARAMETER
;
186 GetBiosId (&BiosIdImage
);
189 // Add VLV2 BIOS Version and Release data
191 SetMem(BiosVersion
, sizeof(BiosVersion
), 0);
192 SetMem(BiosReleaseDate
, sizeof(BiosReleaseDate
), 0);
193 SetMem(BiosReleaseTime
, sizeof(BiosReleaseTime
), 0);
194 Status
= GetBiosVersionDateTime (BiosVersion
, BiosReleaseDate
, BiosReleaseTime
);
195 DEBUG ((EFI_D_ERROR
, "GetBiosVersionDateTime :%s %s %s \n", BiosVersion
, BiosReleaseDate
, BiosReleaseTime
));
196 if (StrLen (BiosVersion
) > 0) {
197 TokenToUpdate
= STRING_TOKEN (STR_MISC_BIOS_VERSION
);
198 HiiSetString (mHiiHandle
, TokenToUpdate
, BiosVersion
, NULL
);
201 if (StrLen(BiosReleaseDate
) > 0) {
202 TokenToUpdate
= STRING_TOKEN (STR_MISC_BIOS_RELEASE_DATE
);
203 HiiSetString (mHiiHandle
, TokenToUpdate
, BiosReleaseDate
, NULL
);
206 TokenToGet
= STRING_TOKEN (STR_MISC_BIOS_VENDOR
);
207 Char16String
= SmbiosMiscGetString (TokenToGet
);
208 VendorStrLen
= StrLen(Char16String
);
209 if (VendorStrLen
> SMBIOS_STRING_MAX_LENGTH
) {
210 return EFI_UNSUPPORTED
;
213 TokenToGet
= STRING_TOKEN (STR_MISC_BIOS_VERSION
);
214 Version
= SmbiosMiscGetString (TokenToGet
);
216 ZeroMem (UVerStr
, 2*32);
217 ZeroMem (BIOSVersionTemp
, 2*100);
218 StrCat (BIOSVersionTemp
,Version
);
219 Data8
= AllocatePool (SECTOR_SIZE_4KB
);
220 ZeroMem (Data8
, SECTOR_SIZE_4KB
);
222 Status
= gBS
->LocateProtocol (
223 &gEfiSpiProtocolGuid
,
225 (VOID
**)&mSpiProtocol
227 if (!EFI_ERROR(Status
)) {
229 // Get data form SPI ROM.
237 if (!EFI_ERROR(Status
)) {
238 for(LoopIndex
= 0; LoopIndex
<= SECTOR_SIZE_4KB
; LoopIndex
++) {
239 IFWIVerStruct
= (MANIFEST_OEM_DATA
*)(Data8
+ LoopIndex
);
240 if(IFWIVerStruct
->Signature
== SIGNATURE_32('$','F','U','D')) {
241 DEBUG ((EFI_D_ERROR
, "the IFWI Length is:%d\n", IFWIVerStruct
->IFWIVersionLen
));
242 if(IFWIVerStruct
->IFWIVersionLen
< 32) {
243 for(CopyIndex
= 0; CopyIndex
< IFWIVerStruct
->IFWIVersionLen
; CopyIndex
++) {
244 UVerStr
[CopyIndex
] = (UINT16
)IFWIVerStruct
->IFWIVersion
[CopyIndex
];
246 UVerStr
[CopyIndex
] = 0x0000;
247 DEBUG ((EFI_D_ERROR
, "The IFWI Version is :%s,the IFWI Length is:%d\n", UVerStr
,IFWIVerStruct
->IFWIVersionLen
));
248 StrCat(BIOSVersionTemp
,SpaceVer
);
249 StrCat(BIOSVersionTemp
,UVerStr
);
250 DEBUG ((EFI_D_ERROR
, "The BIOS and IFWI Version is :%s\n", BIOSVersionTemp
));
259 VerStrLen
= StrLen(BIOSVersionTemp
);
260 if (VerStrLen
> SMBIOS_STRING_MAX_LENGTH
) {
261 return EFI_UNSUPPORTED
;
264 TokenToGet
= STRING_TOKEN (STR_MISC_BIOS_RELEASE_DATE
);
265 ReleaseDate
= SmbiosMiscGetString (TokenToGet
);
266 DateStrLen
= StrLen(ReleaseDate
);
267 if (DateStrLen
> SMBIOS_STRING_MAX_LENGTH
) {
268 return EFI_UNSUPPORTED
;
272 // Two zeros following the last string.
274 SmbiosRecord
= AllocatePool(sizeof (SMBIOS_TABLE_TYPE0
) + VendorStrLen
+ 1 + VerStrLen
+ 1 + DateStrLen
+ 1 + 1);
275 ZeroMem(SmbiosRecord
, sizeof (SMBIOS_TABLE_TYPE0
) + VendorStrLen
+ 1 + VerStrLen
+ 1 + DateStrLen
+ 1 + 1);
277 SmbiosRecord
->Hdr
.Type
= EFI_SMBIOS_TYPE_BIOS_INFORMATION
;
278 SmbiosRecord
->Hdr
.Length
= sizeof (SMBIOS_TABLE_TYPE0
);
281 // Make handle chosen by smbios protocol.add automatically.
283 SmbiosRecord
->Hdr
.Handle
= 0;
286 // Vendor will be the 1st optional string following the formatted structure.
288 SmbiosRecord
->Vendor
= 1;
291 // Version will be the 2nd optional string following the formatted structure.
293 SmbiosRecord
->BiosVersion
= 2;
294 SmbiosRecord
->BiosSegment
= (UINT16
)ForType0InputData
->BiosStartingAddress
;
297 // ReleaseDate will be the 3rd optional string following the formatted structure.
299 SmbiosRecord
->BiosReleaseDate
= 3;
302 // Tiger has no PCD value to indicate BIOS Size, just fill 0 for simply.
304 SmbiosRecord
->BiosSize
= 0;
305 SmbiosRecord
->BiosCharacteristics
= *(MISC_BIOS_CHARACTERISTICS
*)(&ForType0InputData
->BiosCharacteristics1
);
308 // CharacterExtensionBytes also store in ForType0InputData->BiosCharacteristics1 later two bytes to save size.
310 SmbiosRecord
->BIOSCharacteristicsExtensionBytes
[0] = *((UINT8
*) &ForType0InputData
->BiosCharacteristics1
+ 4);
311 SmbiosRecord
->BIOSCharacteristicsExtensionBytes
[1] = *((UINT8
*) &ForType0InputData
->BiosCharacteristics1
+ 5);
313 SmbiosRecord
->SystemBiosMajorRelease
= ForType0InputData
->BiosMajorRelease
;
314 SmbiosRecord
->SystemBiosMinorRelease
= ForType0InputData
->BiosMinorRelease
;
315 SmbiosRecord
->EmbeddedControllerFirmwareMajorRelease
= ForType0InputData
->BiosEmbeddedFirmwareMajorRelease
;
316 SmbiosRecord
->EmbeddedControllerFirmwareMinorRelease
= ForType0InputData
->BiosEmbeddedFirmwareMinorRelease
;
318 OptionalStrStart
= (CHAR8
*)(SmbiosRecord
+ 1);
319 UnicodeStrToAsciiStr(Char16String
, OptionalStrStart
);
320 UnicodeStrToAsciiStr(BIOSVersionTemp
, OptionalStrStart
+ VendorStrLen
+ 1);
321 UnicodeStrToAsciiStr(ReleaseDate
, OptionalStrStart
+ VendorStrLen
+ 1 + VerStrLen
+ 1);
324 // Now we have got the full smbios record, call smbios protocol to add this record.
326 SmbiosHandle
= SMBIOS_HANDLE_PI_RESERVED
;
327 Status
= Smbios
-> Add(
331 (EFI_SMBIOS_TABLE_HEADER
*) SmbiosRecord
334 FreePool(SmbiosRecord
);