1/** @file
2  BIOS vendor information boot time changes.
3  Misc. subclass type 2.
4  SMBIOS type 0.
5
6Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
7This program and the accompanying materials
8are licensed and made available under the terms and conditions of the BSD License
9which accompanies this distribution.  The full text of the license may be found at
10http://opensource.org/licenses/bsd-license.php
11
12THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
14
15**/
16
17#include "MiscSubclassDriver.h"
18
19/**
20  This function returns the value & exponent to Base2 for a given
21  Hex value. This is used to calculate the BiosPhysicalDeviceSize.
22
23  @param Value                      The hex value which is to be converted into value-exponent form
24  @param Exponent                   The exponent out of the conversion
25
26  @retval EFI_SUCCESS               All parameters were valid and *Value & *Exponent have been set.
27  @retval EFI_INVALID_PARAMETER     Invalid parameter was found.
28
29**/
30EFI_STATUS
31GetValueExponentBase2(
32  IN OUT UINTN        *Value,
33  OUT    UINTN        *Exponent
34  )
35{
36  if ((Value == NULL) || (Exponent == NULL)) {
37    return EFI_INVALID_PARAMETER;
38  }
39
40  while ((*Value % 2) == 0) {
41    *Value=*Value/2;
42    (*Exponent)++;
43  }
44
45  return EFI_SUCCESS;
46}
47
48/**
49  Field Filling Function. Transform an EFI_EXP_BASE2_DATA to a byte, with '64k'
50  as the unit.
51
52  @param  Base2Data              Pointer to Base2_Data
53
54  @retval EFI_SUCCESS            Transform successfully.
55  @retval EFI_INVALID_PARAMETER  Invalid parameter was found.
56
57**/
58UINT16
59Base2ToByteWith64KUnit (
60  IN      EFI_EXP_BASE2_DATA  *Base2Data
61  )
62{
63  UINT16              Value;
64  UINT16              Exponent;
65
66  Value     = Base2Data->Value;
67  Exponent  = Base2Data->Exponent;
68  Exponent -= 16;
69  Value <<= Exponent;
70
71  return Value;
72}
73
74
75/**
76  This function makes boot time changes to the contents of the
77  MiscBiosVendor (Type 0).
78
79  @param  RecordData                 Pointer to copy of RecordData from the Data Table.
80
81  @retval EFI_SUCCESS                All parameters were valid.
82  @retval EFI_UNSUPPORTED            Unexpected RecordType value.
83  @retval EFI_INVALID_PARAMETER      Invalid parameter was found.
84
85**/
86MISC_SMBIOS_TABLE_FUNCTION(MiscBiosVendor)
87{
88  CHAR8                 *OptionalStrStart;
89  UINTN                 VendorStrLen;
90  UINTN                 VerStrLen;
91  UINTN                 DateStrLen;
92  CHAR16                *Version;
93  CHAR16                *ReleaseDate;
94  EFI_STATUS            Status;
95  EFI_STRING            Char16String;
96  STRING_REF            TokenToGet;
97  STRING_REF            TokenToUpdate;
98  SMBIOS_TABLE_TYPE0    *SmbiosRecord;
99  EFI_SMBIOS_HANDLE     SmbiosHandle;
100  EFI_MISC_BIOS_VENDOR *ForType0InputData;
101
102  ForType0InputData        = (EFI_MISC_BIOS_VENDOR *)RecordData;
103
104  //
105  // First check for invalid parameters.
106  //
107  if (RecordData == NULL) {
108    return EFI_INVALID_PARAMETER;
109  }
110
111  Version = (CHAR16 *) PcdGetPtr (PcdFirmwareVersionString);
112  if (StrLen (Version) > 0) {
113    TokenToUpdate = STRING_TOKEN (STR_MISC_BIOS_VERSION);
114    HiiSetString (mHiiHandle, TokenToUpdate, Version, NULL);
115  }
116
117  ReleaseDate = (CHAR16 *) PcdGetPtr (PcdFirmwareReleaseDateString);
118  if (StrLen(ReleaseDate) > 0) {
119    TokenToUpdate = STRING_TOKEN (STR_MISC_BIOS_RELEASE_DATE);
120    HiiSetString (mHiiHandle, TokenToUpdate, ReleaseDate, NULL);
121  }
122
123  TokenToGet = STRING_TOKEN (STR_MISC_BIOS_VENDOR);
124  Char16String = HiiGetPackageString(&gEfiCallerIdGuid, TokenToGet, NULL);
125  VendorStrLen = StrLen(Char16String);
126  if (VendorStrLen > SMBIOS_STRING_MAX_LENGTH) {
127    return EFI_UNSUPPORTED;
128  }
129
130  TokenToGet = STRING_TOKEN (STR_MISC_BIOS_VERSION);
131  Version = HiiGetPackageString(&gEfiCallerIdGuid, TokenToGet, NULL);
132  VerStrLen = StrLen(Version);
133  if (VerStrLen > SMBIOS_STRING_MAX_LENGTH) {
134    return EFI_UNSUPPORTED;
135  }
136
137  TokenToGet = STRING_TOKEN (STR_MISC_BIOS_RELEASE_DATE);
138  ReleaseDate = HiiGetPackageString(&gEfiCallerIdGuid, TokenToGet, NULL);
139  DateStrLen = StrLen(ReleaseDate);
140  if (DateStrLen > SMBIOS_STRING_MAX_LENGTH) {
141    return EFI_UNSUPPORTED;
142  }
143
144  //
145  // Two zeros following the last string.
146  //
147  SmbiosRecord = AllocatePool(sizeof (SMBIOS_TABLE_TYPE0) + VendorStrLen + 1 + VerStrLen + 1 + DateStrLen + 1 + 1);
148  ZeroMem(SmbiosRecord, sizeof (SMBIOS_TABLE_TYPE0) + VendorStrLen + 1 + VerStrLen + 1 + DateStrLen + 1 + 1);
149
150  SmbiosRecord->Hdr.Type = EFI_SMBIOS_TYPE_BIOS_INFORMATION;
151  SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE0);
152  //
153  // Make handle chosen by smbios protocol.add automatically.
154  //
155  SmbiosRecord->Hdr.Handle = 0;
156  //
157  // Vendor will be the 1st optional string following the formatted structure.
158  //
159  SmbiosRecord->Vendor = 1;
160  //
161  // Version will be the 2nd optional string following the formatted structure.
162  //
163  SmbiosRecord->BiosVersion = 2;
164  SmbiosRecord->BiosSegment = (UINT16)ForType0InputData->BiosStartingAddress;
165  //
166  // ReleaseDate will be the 3rd optional string following the formatted structure.
167  //
168  SmbiosRecord->BiosReleaseDate = 3;
169  //
170  // Nt32 has no PCD value to indicate BIOS Size, just fill 0 for simply.
171  //
172  SmbiosRecord->BiosSize = 0;
173  SmbiosRecord->BiosCharacteristics = *(MISC_BIOS_CHARACTERISTICS*)(&ForType0InputData->BiosCharacteristics1);
174  //
175  // CharacterExtensionBytes also store in ForType0InputData->BiosCharacteristics1 later two bytes to save size.
176  //
177  SmbiosRecord->BIOSCharacteristicsExtensionBytes[0] = *((UINT8 *) &ForType0InputData->BiosCharacteristics1 + 4);
178  SmbiosRecord->BIOSCharacteristicsExtensionBytes[1] = *((UINT8 *) &ForType0InputData->BiosCharacteristics1 + 5);
179
180  SmbiosRecord->SystemBiosMajorRelease = ForType0InputData->BiosMajorRelease;
181  SmbiosRecord->SystemBiosMinorRelease = ForType0InputData->BiosMinorRelease;
182  SmbiosRecord->EmbeddedControllerFirmwareMajorRelease = ForType0InputData->BiosEmbeddedFirmwareMajorRelease;
183  SmbiosRecord->EmbeddedControllerFirmwareMinorRelease = ForType0InputData->BiosEmbeddedFirmwareMinorRelease;
184
185  OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);
186  UnicodeStrToAsciiStr(Char16String, OptionalStrStart);
187  UnicodeStrToAsciiStr(Version, OptionalStrStart + VendorStrLen + 1);
188  UnicodeStrToAsciiStr(ReleaseDate, OptionalStrStart + VendorStrLen + 1 + VerStrLen + 1);
189  //
190  // Now we have got the full smbios record, call smbios protocol to add this record.
191  //
192  Status = AddSmbiosRecord (Smbios, &SmbiosHandle, (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord);
193
194  FreePool(SmbiosRecord);
195  return Status;
196}
197