Home | History | Annotate | Download | only in SmBiosMiscDxe
      1 /*++
      2 
      3 Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
      4 
      5   This program and the accompanying materials are licensed and made available under
      7   the terms and conditions of the BSD License that accompanies this distribution.
      9   The full text of the license may be found at
     11   http://opensource.org/licenses/bsd-license.php.
     13 
     15   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     17   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     19 
     21 
     23 
     24 Module Name:
     25 
     26   MiscBiosVendorFunction.c
     27 
     28 Abstract:
     29 
     30   BIOS vendor information boot time changes.
     31   Misc. subclass type 2.
     32   SMBIOS type 0.
     33 
     34 --*/
     35 
     36 
     37 #include "CommonHeader.h"
     38 
     39 #include "MiscSubclassDriver.h"
     40 #include <Library/BiosIdLib.h>
     41 #include <Library/SpiFlash.H>
     42 
     43 EFI_SPI_PROTOCOL  *mSpiProtocol = NULL;
     44 
     45 
     46 /**
     47   This function read the data from Spi Rom.
     48 
     49   @param BaseAddress                The starting address of the read.
     50   @param Byte                       The pointer to the destination buffer.
     51   @param Length                     The number of bytes.
     52   @param SpiRegionType              Spi Region Type.
     53 
     54   @retval Status
     55 
     56 **/
     57 EFI_STATUS
     58 FlashRead (
     59   IN  UINTN             BaseAddress,
     60   IN  UINT8             *Byte,
     61   IN  UINTN             Length,
     62   IN  SPI_REGION_TYPE   SpiRegionType
     63   )
     64 {
     65   EFI_STATUS            Status = EFI_SUCCESS;
     66   UINT32                SectorSize;
     67   UINT32                SpiAddress;
     68   UINT8                 Buffer[SECTOR_SIZE_4KB];
     69 
     70   SpiAddress = (UINT32)(UINTN)(BaseAddress);
     71   SectorSize = SECTOR_SIZE_4KB;
     72 
     73   Status = mSpiProtocol->Execute (
     74                            mSpiProtocol,
     75                            SPI_READ,
     76                            SPI_WREN,
     77                            TRUE,
     78                            TRUE,
     79                            FALSE,
     80                            (UINT32) SpiAddress,
     81                            SectorSize,
     82                            Buffer,
     83                            SpiRegionType
     84                            );
     85 
     86   if (EFI_ERROR (Status)) {
     87 #ifdef _SHOW_LOG_
     88     Print(L"Read SPI ROM Failed [%08x]\n", SpiAddress);
     89 #endif
     90     return Status;
     91   }
     92 
     93   CopyMem (Byte, (void *)Buffer, Length);
     94 
     95   return Status;
     96 }
     97 
     98 /**
     99   This function returns the value & exponent to Base2 for a given
    100   Hex value. This is used to calculate the BiosPhysicalDeviceSize.
    101 
    102   @param Value                      The hex value which is to be converted into value-exponent form
    103   @param Exponent                   The exponent out of the conversion
    104 
    105   @retval EFI_SUCCESS               All parameters were valid and *Value & *Exponent have been set.
    106   @retval EFI_INVALID_PARAMETER     Invalid parameter was found.
    107 
    108 **/
    109 EFI_STATUS
    110 GetValueExponentBase2(
    111   IN OUT UINTN        *Value,
    112   OUT    UINTN        *Exponent
    113   )
    114 {
    115   if ((Value == NULL) || (Exponent == NULL)) {
    116     return EFI_INVALID_PARAMETER;
    117   }
    118 
    119   while ((*Value % 2) == 0) {
    120     *Value=*Value/2;
    121     (*Exponent)++;
    122   }
    123 
    124   return EFI_SUCCESS;
    125 }
    126 
    127 /**
    128   Field Filling Function. Transform an EFI_EXP_BASE2_DATA to a byte, with '64k'
    129   as the unit.
    130 
    131   @param  Base2Data              Pointer to Base2_Data
    132 
    133   @retval EFI_SUCCESS            Transform successfully.
    134   @retval EFI_INVALID_PARAMETER  Invalid parameter was found.
    135 
    136 **/
    137 UINT16
    138 Base2ToByteWith64KUnit (
    139   IN      EFI_EXP_BASE2_DATA  *Base2Data
    140   )
    141 {
    142   UINT16              Value;
    143   UINT16              Exponent;
    144 
    145   Value     = Base2Data->Value;
    146   Exponent  = Base2Data->Exponent;
    147   Exponent -= 16;
    148   Value <<= Exponent;
    149 
    150   return Value;
    151 }
    152 
    153 
    154 /**
    155   This function makes boot time changes to the contents of the
    156   MiscBiosVendor (Type 0).
    157 
    158   @param  RecordData                 Pointer to copy of RecordData from the Data Table.
    159 
    160   @retval EFI_SUCCESS                All parameters were valid.
    161   @retval EFI_UNSUPPORTED            Unexpected RecordType value.
    162   @retval EFI_INVALID_PARAMETER      Invalid parameter was found.
    163 
    164 **/
    165 MISC_SMBIOS_TABLE_FUNCTION(MiscBiosVendor)
    166 {
    167   CHAR8                 *OptionalStrStart;
    168   UINTN                 VendorStrLen;
    169   UINTN                 VerStrLen;
    170   UINTN                 DateStrLen;
    171   CHAR16                *Version;
    172   CHAR16                *ReleaseDate;
    173   CHAR16                BiosVersion[100];         //Assuming that strings are < 100 UCHAR
    174   CHAR16                BiosReleaseDate[100];     //Assuming that strings are < 100 UCHAR
    175   CHAR16                BiosReleaseTime[100];     //Assuming that strings are < 100 UCHAR
    176   EFI_STATUS            Status;
    177   EFI_STRING            Char16String;
    178   STRING_REF            TokenToGet;
    179   STRING_REF            TokenToUpdate;
    180   SMBIOS_TABLE_TYPE0    *SmbiosRecord;
    181   EFI_SMBIOS_HANDLE     SmbiosHandle;
    182   EFI_MISC_BIOS_VENDOR *ForType0InputData;
    183   BIOS_ID_IMAGE         BiosIdImage;
    184   UINT16                UVerStr[32];
    185   UINTN                 LoopIndex;
    186   UINTN                 CopyIndex;
    187   MANIFEST_OEM_DATA     *IFWIVerStruct;
    188   UINT8                 *Data8 = NULL;
    189   UINT16                SpaceVer[2]={0x0020,0x0000};
    190   UINT16                BIOSVersionTemp[100];
    191 
    192   ForType0InputData        = (EFI_MISC_BIOS_VENDOR *)RecordData;
    193 
    194   //
    195   // First check for invalid parameters.
    196   //
    197   if (RecordData == NULL) {
    198     return EFI_INVALID_PARAMETER;
    199   }
    200   GetBiosId (&BiosIdImage);
    201 
    202   //
    203   //  Add VLV2 BIOS Version and Release data
    204   //
    205   SetMem(BiosVersion, sizeof(BiosVersion), 0);
    206   SetMem(BiosReleaseDate, sizeof(BiosReleaseDate), 0);
    207   SetMem(BiosReleaseTime, sizeof(BiosReleaseTime), 0);
    208   Status = GetBiosVersionDateTime (BiosVersion, BiosReleaseDate, BiosReleaseTime);
    209   DEBUG ((EFI_D_ERROR, "GetBiosVersionDateTime :%s %s %s \n", BiosVersion, BiosReleaseDate, BiosReleaseTime));
    210   if (StrLen (BiosVersion) > 0) {
    211     TokenToUpdate = STRING_TOKEN (STR_MISC_BIOS_VERSION);
    212     HiiSetString (mHiiHandle, TokenToUpdate, BiosVersion, NULL);
    213   }
    214 
    215   if (StrLen(BiosReleaseDate) > 0) {
    216     TokenToUpdate = STRING_TOKEN (STR_MISC_BIOS_RELEASE_DATE);
    217     HiiSetString (mHiiHandle, TokenToUpdate, BiosReleaseDate, NULL);
    218   }
    219 
    220   TokenToGet = STRING_TOKEN (STR_MISC_BIOS_VENDOR);
    221   Char16String = SmbiosMiscGetString (TokenToGet);
    222   VendorStrLen = StrLen(Char16String);
    223   if (VendorStrLen > SMBIOS_STRING_MAX_LENGTH) {
    224     return EFI_UNSUPPORTED;
    225   }
    226 
    227   TokenToGet = STRING_TOKEN (STR_MISC_BIOS_VERSION);
    228   Version = SmbiosMiscGetString (TokenToGet);
    229 
    230   ZeroMem (UVerStr, 2*32);
    231   ZeroMem (BIOSVersionTemp, 2*100);
    232   StrCat (BIOSVersionTemp,Version);
    233   Data8 = AllocatePool (SECTOR_SIZE_4KB);
    234   ZeroMem (Data8, SECTOR_SIZE_4KB);
    235 
    236   Status = gBS->LocateProtocol (
    237                   &gEfiSpiProtocolGuid,
    238                   NULL,
    239                  (VOID **)&mSpiProtocol
    240                  );
    241   if (!EFI_ERROR(Status)) {
    242     //
    243     // Get data form SPI ROM.
    244     //
    245     Status = FlashRead (
    246                MEM_IFWIVER_START,
    247                Data8,
    248                SECTOR_SIZE_4KB,
    249                EnumSpiRegionAll
    250                );
    251     if (!EFI_ERROR(Status)) {
    252       for(LoopIndex = 0; LoopIndex <= SECTOR_SIZE_4KB; LoopIndex++) {
    253         IFWIVerStruct = (MANIFEST_OEM_DATA *)(Data8 + LoopIndex);
    254         if(IFWIVerStruct->Signature == SIGNATURE_32('$','F','U','D')) {
    255           DEBUG ((EFI_D_ERROR, "the IFWI Length is:%d\n", IFWIVerStruct->IFWIVersionLen));
    256           if(IFWIVerStruct->IFWIVersionLen < 32) {
    257             for(CopyIndex = 0; CopyIndex < IFWIVerStruct->IFWIVersionLen; CopyIndex++) {
    258               UVerStr[CopyIndex] = (UINT16)IFWIVerStruct->IFWIVersion[CopyIndex];
    259             }
    260             UVerStr[CopyIndex] = 0x0000;
    261             DEBUG ((EFI_D_ERROR, "The IFWI Version is :%s,the IFWI Length is:%d\n", UVerStr,IFWIVerStruct->IFWIVersionLen));
    262             StrCat(BIOSVersionTemp,SpaceVer);
    263             StrCat(BIOSVersionTemp,UVerStr);
    264             DEBUG ((EFI_D_ERROR, "The BIOS and IFWI Version is :%s\n", BIOSVersionTemp));
    265           }
    266           break;
    267         }
    268       }
    269     }
    270   }
    271   FreePool(Data8);
    272 
    273   VerStrLen = StrLen(BIOSVersionTemp);
    274   if (VerStrLen > SMBIOS_STRING_MAX_LENGTH) {
    275     return EFI_UNSUPPORTED;
    276   }
    277 
    278   TokenToGet = STRING_TOKEN (STR_MISC_BIOS_RELEASE_DATE);
    279   ReleaseDate = SmbiosMiscGetString (TokenToGet);
    280   DateStrLen = StrLen(ReleaseDate);
    281   if (DateStrLen > SMBIOS_STRING_MAX_LENGTH) {
    282     return EFI_UNSUPPORTED;
    283   }
    284 
    285   //
    286   // Two zeros following the last string.
    287   //
    288   SmbiosRecord = AllocatePool(sizeof (SMBIOS_TABLE_TYPE0) + VendorStrLen + 1 + VerStrLen + 1 + DateStrLen + 1 + 1);
    289   ZeroMem(SmbiosRecord, sizeof (SMBIOS_TABLE_TYPE0) + VendorStrLen + 1 + VerStrLen + 1 + DateStrLen + 1 + 1);
    290 
    291   SmbiosRecord->Hdr.Type = EFI_SMBIOS_TYPE_BIOS_INFORMATION;
    292   SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE0);
    293 
    294   //
    295   // Make handle chosen by smbios protocol.add automatically.
    296   //
    297   SmbiosRecord->Hdr.Handle = 0;
    298 
    299   //
    300   // Vendor will be the 1st optional string following the formatted structure.
    301   //
    302   SmbiosRecord->Vendor = 1;
    303 
    304   //
    305   // Version will be the 2nd optional string following the formatted structure.
    306   //
    307   SmbiosRecord->BiosVersion = 2;
    308   SmbiosRecord->BiosSegment = (UINT16)ForType0InputData->BiosStartingAddress;
    309 
    310   //
    311   // ReleaseDate will be the 3rd optional string following the formatted structure.
    312   //
    313   SmbiosRecord->BiosReleaseDate = 3;
    314 
    315   //
    316   // Tiger has no PCD value to indicate BIOS Size, just fill 0 for simply.
    317   //
    318   SmbiosRecord->BiosSize = 0;
    319   SmbiosRecord->BiosCharacteristics = *(MISC_BIOS_CHARACTERISTICS*)(&ForType0InputData->BiosCharacteristics1);
    320 
    321   //
    322   // CharacterExtensionBytes also store in ForType0InputData->BiosCharacteristics1 later two bytes to save size.
    323   //
    324   SmbiosRecord->BIOSCharacteristicsExtensionBytes[0] = *((UINT8 *) &ForType0InputData->BiosCharacteristics1 + 4);
    325   SmbiosRecord->BIOSCharacteristicsExtensionBytes[1] = *((UINT8 *) &ForType0InputData->BiosCharacteristics1 + 5);
    326 
    327   SmbiosRecord->SystemBiosMajorRelease =  ForType0InputData->BiosMajorRelease;
    328   SmbiosRecord->SystemBiosMinorRelease =  ForType0InputData->BiosMinorRelease;
    329   SmbiosRecord->EmbeddedControllerFirmwareMajorRelease = ForType0InputData->BiosEmbeddedFirmwareMajorRelease;
    330   SmbiosRecord->EmbeddedControllerFirmwareMinorRelease = ForType0InputData->BiosEmbeddedFirmwareMinorRelease;
    331 
    332   OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);
    333   UnicodeStrToAsciiStr(Char16String, OptionalStrStart);
    334   UnicodeStrToAsciiStr(BIOSVersionTemp, OptionalStrStart + VendorStrLen + 1);
    335   UnicodeStrToAsciiStr(ReleaseDate, OptionalStrStart + VendorStrLen + 1 + VerStrLen + 1);
    336 
    337   //
    338   // Now we have got the full smbios record, call smbios protocol to add this record.
    339   //
    340   SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
    341   Status = Smbios-> Add(
    342                       Smbios,
    343                       NULL,
    344                       &SmbiosHandle,
    345                       (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord
    346                       );
    347 
    348   FreePool(SmbiosRecord);
    349   return Status;
    350 }
    351