/** @file ;****************************************************************************** ;* Copyright (c) 2012 - 2015, Insyde Software Corp. All Rights Reserved. ;* ;* You may not reproduce, distribute, publish, display, perform, modify, adapt, ;* transmit, broadcast, present, recite, release, license or otherwise exploit ;* any part of this publication in any form, by any means, without the prior ;* written permission of Insyde Software Corporation. ;* ;****************************************************************************** */ #include "SmbiosOverride.h" #include "Library/MemoryAllocationLib.h" #include "Library/PrintLib.h" #include #include #ifdef L05_SPECIFIC_VARIABLE_SERVICE_ENABLE #include #endif EFI_L05_EEPROM_MAP_119 *mEepromBuffer; EFI_STATUS UpdateType0Pcd135 ( ) { EFI_STATUS Status; UINT8 ECMajor; UINT8 ECMinor; CHAR16 *UniString; UINT8 MinorVersion; Status = EFI_UNSUPPORTED; // // Type 00 - Offset 0x15 // UniString = (CHAR16 *) PcdGetPtr (PcdFirmwareVersionString); if (((UniString[6] == L'W') && (UniString[7] == L'W')) || ((UniString[6] == L'C') && (UniString[7] == L'L'))) { MinorVersion = ((UINT8) (UniString[4]) - 0x30) * 10; MinorVersion += ((UINT8) (UniString[5]) - 0x30) * 1; PcdSet8S (PcdL05Type00BIOSMinorRelease, MinorVersion); } // // Type 00 - Offset 0x16 & 0x17 // Status = OemSvcGetEcVersion (&ECMajor, &ECMinor); if (Status == EFI_MEDIA_CHANGED) { PcdSet8S (PcdL05Type00ECMajorRelease, ECMajor); PcdSet8S (PcdL05Type00ECMinorRelease, ECMinor); } return Status; } EFI_STATUS UpdateType1Pcd135 ( ) { VOID *Buffer; CHAR8 *String; UINTN StringLength; UINTN BufferSize; CHAR8 *StrBuf; UINT8 Index; //================================================================================================== //SMBIOS Type 1 // // By L05 EEPROM contents spec v1.12 and L05 Minimum BIOS Spec v1.26 3.4.6 // the SMBIOS type 01 offset 05h should be MTM (Machine Type and Model) Number // type 01 offset 06h should be Product Name // type 01 offset 07h should be Serial Number // type 01 offset 19h should be "LENOVO_MT_XXXXX" if MTM exist, else "LENOVO_BI_IDEAPADXX" // type 01 offset 1Ah should be Family Name // //================================================================================================== // // Type 01 - Offset 0x05 Product Name // if ((*(UINT32 *) mEepromBuffer->MachineTypeModel) != 0) { // // if the injected MTM number length is 10, 4, and 7, the MT is first four characters of the MTM string; // if the injected MTM number length is 5, then the injected data is MT. // switch (AsciiStrLen (mEepromBuffer->MachineTypeModel)) { // // MTM number length is 10, 4, and 7. // case NEW_MTM_PRODUCT_MTM_LENGTH: case NEW_MTM_PRODUCT_MTM_LENGTH2: case LI_PRODUCT_MTM_LENGTH: BufferSize = LI_MT_STR_LENGTH; break; // // MTM number length is 5 // case LC_PRODUCT_MTM_LENGTH: BufferSize = LC_MT_STR_LENGTH; break; default: BufferSize = 0; break; } if (BufferSize > 0) { // // Add '\0' // BufferSize++; String = AllocateZeroPool (BufferSize); AsciiStrnCpyS (String, BufferSize, (VOID *) mEepromBuffer->MachineTypeModel, BufferSize - 1); PcdSetPtrS (PcdL05Type01ProductName, &BufferSize, String); FreePool (String); } } // // Type 01 - Offset 0x06 Version // if ((*(UINT32 *) mEepromBuffer->ProductName) != 0) { BufferSize = L05_EEPROM_PRODUCT_NAME_LENGTH; PcdSetPtrS (PcdL05Type01Version, &BufferSize, (VOID *) mEepromBuffer->ProductName); } // // Type 01 - Offset 0x07 Serial Number // if ((*(UINT32 *) mEepromBuffer->L05SerialNumber) != 0) { BufferSize = L05_EEPROM_SERIAL_NUMBER_LENGTH; PcdSetPtrS (PcdL05Type01SerialNumber, &BufferSize, (VOID *) mEepromBuffer->L05SerialNumber); } // // Type 01 - Offset 0x08 UUID // BufferSize = L05_EEPROM_UUID_LENGTH; for (Index = 0; Index < BufferSize; Index++) { // // one of UUID members doesn't be 0x00, the UUID is valid // if (mEepromBuffer->Uuid[Index] != 0x00) { PcdSetPtrS (PcdL05Type01UUID, &BufferSize, (VOID *) mEepromBuffer->Uuid); break; } } // // Type 01 - Offset 0x19 SKU Number // // // ODM should check if MTM number is valid here. // If the MTM is valid, change the string value to "LENOVO_MT_XXXXX", else it should be "LENOVO_BI_IDEAPADXX" // The following code is a sample. ODM could change the MTM number validity check mechanism. // BufferSize = L05_EEPROM_MACHINE_TYPE_MODEL_LENGTH; String = AllocateZeroPool (sizeof (CHAR8) * 0xFF); Buffer = AllocateZeroPool (sizeof (CHAR8) * 0xFF); switch (AsciiStrLen (mEepromBuffer->MachineTypeModel)) { case LC_PRODUCT_MTM_LENGTH: // // If the MTM length is 5, the system is LC product, the all 5 characters are LC MT. // SKU string: LENOVO_MT_XXXXX_BU_idea_FM_PPPP // StringLength = LC_MT_STR_LENGTH; break; case LI_PRODUCT_MTM_LENGTH: // // If the MTM length is 7, the system is LI product, the first 4 characters are LI MT. // SKU string: LENOVO_MT_XXXX_BU_idea_FM_PPPP // StringLength = LI_MT_STR_LENGTH; break; case NEW_MTM_PRODUCT_MTM_LENGTH2: case NEW_MTM_PRODUCT_MTM_LENGTH: // // If the MTM length is 4 or 10, the system is new MTM product, the first 4 characters are MT. // SKU string: LENOVO_MT_XXXX_idea_FM_PPPP // StringLength = NEW_MTM_MT_STR_LENGTH; break; default: // // Other MTM length must be treated as invalid MTM. // SKU string: LENOVO_BI_IDEAPADXX_BU_idea_FM_PPPP // StringLength = 0; break; } // //Check MTM Exist or not // if (StringLength > 0) { StrBuf = AllocateZeroPool (sizeof (CHAR8) * (StringLength + 1)); AsciiStrnCpyS (StrBuf, sizeof (CHAR8) * (StringLength + 1), mEepromBuffer->MachineTypeModel, StringLength); StringLength = (UINT8) AsciiSPrint (String, 0xFF, "LENOVO_MT_%a_BU_idea_FM_%a\0", StrBuf, mEepromBuffer->ProductName ); FreePool (StrBuf); } else { StrCpyS (Buffer, (sizeof (CHAR8) * 0xFF) / sizeof (CHAR16), PcdGetPtr (PcdFirmwareVersionString)); StringLength = (UINT8) AsciiSPrint (String, 0xFF, "LENOVO_BI_IDEAPAD%c%c_BU_idea_FM_%a\0", ((CHAR8 *) Buffer)[0], ((CHAR8 *) Buffer)[2], mEepromBuffer->ProductName); } StringLength += 1; PcdSetPtrS (PcdL05Type01SKUNumber, &StringLength, (VOID *) String); FreePool (Buffer); // // Type 01 - Offset 0x1A Family // if ((*(UINT16 *) mEepromBuffer->FamilyName) != 0) { BufferSize = L05_EEPROM_FAMILY_NAME_LENGTH; PcdSetPtrS (PcdL05Type01Family, &BufferSize, (VOID *) mEepromBuffer->FamilyName); } return EFI_SUCCESS; } EFI_STATUS UpdateType2Pcd135 ( ) { UINTN BufferSize; CHAR8 VersionBuf [L05_EEPROM_OS_PN_NUMBER_LENGTH + L05_EEPROM_OS_DESCRIPTOR_LENGTH + 1]; #ifdef L05_SPECIFIC_VARIABLE_SERVICE_ENABLE EFI_STATUS Status; EFI_L05_VARIABLE_PROTOCOL *L05VariablePtr; UINT32 DataLength; CHAR8 *AssetTag; #endif //================================================================================================== //SMBIOS Type 2 // By L05 EEPROM contents spec v1.12 // the SMBIOS type 02 offset 05h should be Project Name // type 02 offset 07h should be L05 Serial Number // type 02 offset 08h should be Asset Tag //================================================================================================== // // Type 02 - Offset 0x05 Product // if ((*(UINT16 *) mEepromBuffer->ProjectName) != 0) { BufferSize = L05_EEPROM_PROJECT_NAME_LENGTH; PcdSetPtrS (PcdL05Type02Product, &BufferSize, (VOID *) mEepromBuffer->ProjectName); } // // Type 02 - Offset 0x06 Version Eerpom - OS PN Number & OS Descriptor // OS license information = OS PN Number(osp)+ OS Descriptor(oss) // if ((*(UINT16 *) mEepromBuffer->OSPNNumber) != 0 || (*(UINT32 *) mEepromBuffer->OSDescriptor) != 0) { ZeroMem (VersionBuf, L05_EEPROM_OS_PN_NUMBER_LENGTH + L05_EEPROM_OS_DESCRIPTOR_LENGTH + 2); BufferSize = AsciiStrLen (mEepromBuffer->OSPNNumber); // //To avoid no end of char // if (BufferSize > L05_EEPROM_OS_PN_NUMBER_LENGTH) { BufferSize = L05_EEPROM_OS_PN_NUMBER_LENGTH; } CopyMem (VersionBuf, mEepromBuffer->OSPNNumber, BufferSize); // // Add space between OS PN and OS Descriptor // SetMem (&VersionBuf[BufferSize], 1, 0x20); BufferSize += 1; // //OS PN Number + OS Descriptor // CopyMem (&VersionBuf[BufferSize], mEepromBuffer->OSDescriptor, L05_EEPROM_OS_DESCRIPTOR_LENGTH); BufferSize = BufferSize + L05_EEPROM_OS_DESCRIPTOR_LENGTH + 1; PcdSetPtrS (PcdL05Type02Version, &BufferSize, (VOID *) VersionBuf); // //Set OS Descriptor data to PcdL05OSLienceDescriptor // BufferSize = L05_EEPROM_OS_DESCRIPTOR_LENGTH; PcdSetPtrS (PcdL05OSLienceDescriptor, &BufferSize, (VOID *) mEepromBuffer->OSDescriptor); } // // Type 02 - Offset 0x07 Serial Number // if ((*(UINT32 *) mEepromBuffer->L05SerialNumber) != 0) { BufferSize = L05_EEPROM_SERIAL_NUMBER_LENGTH; PcdSetPtrS (PcdL05Type02SerialNumber, &BufferSize, (VOID *) mEepromBuffer->L05SerialNumber); } // // Type 02 - Offset 0x08 Asset Tag // #ifdef L05_SPECIFIC_VARIABLE_SERVICE_ENABLE Status = gBS->LocateProtocol (&gEfiL05VariableProtocolGuid, NULL, &L05VariablePtr); if (!EFI_ERROR (Status)) { AssetTag = AllocateZeroPool (L05_EEPROM_ASSET_TAG_LENGTH); Status = L05VariablePtr->GetVariable ( L05VariablePtr, &gL05AssetTagGuid, &DataLength, AssetTag ); if (!EFI_ERROR (Status)) { BufferSize = L05_EEPROM_ASSET_TAG_LENGTH; PcdSetPtrS (PcdL05Type02AssetTag, &BufferSize, (VOID *) AssetTag); } FreePool (AssetTag); } #else if ((*(UINT32 *) mEepromBuffer->AssetTag) != 0) { BufferSize = L05_EEPROM_ASSET_TAG_LENGTH; PcdSetPtrS (PcdL05Type02AssetTag, &BufferSize, (VOID *) mEepromBuffer->AssetTag); } #endif return EFI_SUCCESS; } EFI_STATUS UpdateType3Pcd135 ( ) { UINTN BufferSize; #ifdef L05_SPECIFIC_VARIABLE_SERVICE_ENABLE EFI_STATUS Status; EFI_L05_VARIABLE_PROTOCOL *L05VariablePtr; UINT32 DataLength; CHAR8 *AssetTag; #endif //================================================================================================== //SMBIOS Type 3 // By L05 EEPROM contents spec v1.12 // the SMBIOS type 03 offset 06h should be Product Name // type 03 offset 08h should be Asset Tag //================================================================================================== // // Type 03 - Offset 0x06 Version // if ((*(UINT32 *) mEepromBuffer->ProductName) != 0) { BufferSize = L05_EEPROM_PRODUCT_NAME_LENGTH; PcdSetPtrS (PcdL05Type03Version, &BufferSize, (VOID *) mEepromBuffer->ProductName); } // // Type 03 - Offset 0x07 Serial Number // if ((*(UINT32 *) mEepromBuffer->L05SerialNumber) != 0) { BufferSize = L05_EEPROM_SERIAL_NUMBER_LENGTH; PcdSetPtrS (PcdL05Type03SerialNumber, &BufferSize, (VOID *) mEepromBuffer->L05SerialNumber); } // // Type 03 - Offset 0x08 Asset Tag // #ifdef L05_SPECIFIC_VARIABLE_SERVICE_ENABLE Status = gBS->LocateProtocol (&gEfiL05VariableProtocolGuid, NULL, &L05VariablePtr); if (!EFI_ERROR (Status)) { AssetTag = AllocateZeroPool (L05_EEPROM_ASSET_TAG_LENGTH); Status = L05VariablePtr->GetVariable ( L05VariablePtr, &gL05AssetTagGuid, &DataLength, AssetTag ); if (!EFI_ERROR (Status)) { BufferSize = L05_EEPROM_ASSET_TAG_LENGTH; PcdSetPtrS (PcdL05Type03AssetTag, &BufferSize, (VOID *) AssetTag); } FreePool (AssetTag); } #else if ((*(UINT16 *) mEepromBuffer->AssetTag) != 0) { BufferSize = L05_EEPROM_ASSET_TAG_LENGTH; PcdSetPtrS (PcdL05Type03AssetTag, &BufferSize, (VOID *) mEepromBuffer->AssetTag); } #endif return EFI_SUCCESS; } EFI_STATUS UpdateType200Pcd135 ( ) { UINTN BufferSize; if ((*(UINT32 *) mEepromBuffer->MachineTypeModel) != 0) { BufferSize = L05_EEPROM_MACHINE_TYPE_MODEL_LENGTH; PcdSetPtrS (PcdL05Type200MTM, &BufferSize, (VOID *) mEepromBuffer->MachineTypeModel); } return EFI_SUCCESS; } EFI_STATUS ODMSetDMIData135 ( IN EFI_EVENT Event, IN VOID *Context ) { EFI_STATUS Status; UINTN L05EerpomBase; Status = EFI_UNSUPPORTED; Status = UpdateType0Pcd135 (); mEepromBuffer = AllocateZeroPool (sizeof (EFI_L05_EEPROM_MAP_119)); Status = OemSvcGetEepromData (mEepromBuffer, sizeof (EFI_L05_EEPROM_MAP_119)); if (Status == EFI_UNSUPPORTED) { L05EerpomBase = (UINTN) FdmGetNAtAddr (&gL05H2OFlashMapRegionEepromGuid, 1); gBS->CopyMem (mEepromBuffer, (VOID *) L05EerpomBase, sizeof (EFI_L05_EEPROM_MAP_119)); } Status = UpdateType1Pcd135 (); Status = UpdateType2Pcd135 (); Status = UpdateType3Pcd135 (); Status = UpdateType200Pcd135 (); gBS->CloseEvent (Event); return EFI_SUCCESS; }