/** @file ;****************************************************************************** ;* Copyright (c) 2018, 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 "BiosPostLogoDiyDxe.h" BOOLEAN mLogoDiySupport = FALSE; L05_CUSTOMIZE_POST_LOGO_FORMAT_TABLE mCustomizePostLogoFormatTable[] = { // SupportFormat, IsSupported, FileNameExtension, Format {L05_CUSTOMIZE_POST_LOGO_SUPPORT_FORMAT_JPG, TRUE, L".jpg", EfiBadgingSupportFormatJPEG}, {L05_CUSTOMIZE_POST_LOGO_SUPPORT_FORMAT_TGA, TRUE, L".tga", EfiBadgingSupportFormatTGA }, {L05_CUSTOMIZE_POST_LOGO_SUPPORT_FORMAT_PCX, TRUE, L".pcx", EfiBadgingSupportFormatPCX }, {L05_CUSTOMIZE_POST_LOGO_SUPPORT_FORMAT_GIF, TRUE, L".gif", EfiBadgingSupportFormatGIF }, {L05_CUSTOMIZE_POST_LOGO_SUPPORT_FORMAT_BMP, TRUE, L".bmp", EfiBadgingSupportFormatBMP }, {L05_CUSTOMIZE_POST_LOGO_SUPPORT_FORMAT_PNG, TRUE, L".png", EfiBadgingSupportFormatPNG }, }; UINTN mCustomizePostLogoFormatTableCount = sizeof (mCustomizePostLogoFormatTable) / sizeof (L05_CUSTOMIZE_POST_LOGO_FORMAT_TABLE); /** Prepare customize POST logo Version and CRC control for tool reference. @retval EFI_SUCCESS The operation completed successfully. @retval Others An unexpected error occurred. **/ EFI_STATUS InitCustomizePostLogoVcm ( VOID ) { EFI_STATUS Status; LENOVO_ESP_CUSTOMIZE_POST_LOGO_VCM L05EspCustomizePostLogoVcm; UINTN VarSize; ZeroMem (&L05EspCustomizePostLogoVcm, sizeof (LENOVO_ESP_CUSTOMIZE_POST_LOGO_VCM)); VarSize = sizeof (LENOVO_ESP_CUSTOMIZE_POST_LOGO_VCM); Status = gRT->GetVariable ( L05_BIOS_LOGO_DIY_VERSION_CRC_CONTROL_VARIABLE_NAME, &gEfiL05EspCustomizePostLogoVcmVariableGuid, NULL, &VarSize, &L05EspCustomizePostLogoVcm ); L05EspCustomizePostLogoVcm.Version = L05_LOGO_DIY_VERSION; // // Set L05EspCustomizePostLogoVcm variable. // Status = gRT->SetVariable ( L05_BIOS_LOGO_DIY_VERSION_CRC_CONTROL_VARIABLE_NAME, &gEfiL05EspCustomizePostLogoVcmVariableGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE, sizeof (LENOVO_ESP_CUSTOMIZE_POST_LOGO_VCM), &L05EspCustomizePostLogoVcm ); return Status; } /** Prepare customize POST logo information for tool reference. @param NativeResolutionX A pointer to native horizontal resolution of a panel. @param NativeResolutionY A pointer to native vertical resolution of a panel. @retval EFI_SUCCESS The operation completed successfully. @retval Others An unexpected error occurred. **/ EFI_STATUS InitCustomizePostLogoInfo ( IN UINT32 NativeResolutionX, IN UINT32 NativeResolutionY ) { EFI_STATUS Status; UINTN BufferSize; LENOVO_ESP_CUSTOMIZE_POST_LOGO_INFO L05EspCustomizePostLogoInfo; UINTN Index; UINT8 TempSupportFormat; ZeroMem (&L05EspCustomizePostLogoInfo, sizeof (LENOVO_ESP_CUSTOMIZE_POST_LOGO_INFO)); BufferSize = sizeof (LENOVO_ESP_CUSTOMIZE_POST_LOGO_INFO); Status = gRT->GetVariable ( L05_BIOS_LOGO_DIY_ESP_VARIABLE_NAME, &gEfiL05EspCustomizePostLogoInfoVariableGuid, NULL, &BufferSize, &L05EspCustomizePostLogoInfo ); if (!EFI_ERROR (Status)) { mLogoDiySupport = L05EspCustomizePostLogoInfo.LogoDiySupport; } // // Init LENOVO_ESP_CUSTOMIZE_POST_LOGO_INFO data. // L05EspCustomizePostLogoInfo.HorizontalResolution = NativeResolutionX; L05EspCustomizePostLogoInfo.VerticalResolution = NativeResolutionY; // // Provide an interface for customize POST LOGO support format. // Status = OemSvcCustomizePostLogoSupportFormat (&L05EspCustomizePostLogoInfo.LogoSupportFormat); if (Status != EFI_MEDIA_CHANGED) { L05EspCustomizePostLogoInfo.LogoSupportFormat.Bits.JPG = TRUE; L05EspCustomizePostLogoInfo.LogoSupportFormat.Bits.TGA = TRUE; L05EspCustomizePostLogoInfo.LogoSupportFormat.Bits.PCX = TRUE; L05EspCustomizePostLogoInfo.LogoSupportFormat.Bits.GIF = TRUE; L05EspCustomizePostLogoInfo.LogoSupportFormat.Bits.BMP = TRUE; L05EspCustomizePostLogoInfo.LogoSupportFormat.Bits.PNG = TRUE; } // // Init the logo format is supported. // for (Index = 0; Index < mCustomizePostLogoFormatTableCount; Index++) { TempSupportFormat = mCustomizePostLogoFormatTable[Index].SupportFormat; mCustomizePostLogoFormatTable[Index].IsSupported = ((L05EspCustomizePostLogoInfo.LogoSupportFormat.Data8 & TempSupportFormat) == TempSupportFormat) ? TRUE : FALSE; } // // Set L05_BIOS_LOGO_DIY_ESP_VARIABLE_NAME variable. // Status = gRT->SetVariable ( L05_BIOS_LOGO_DIY_ESP_VARIABLE_NAME, &gEfiL05EspCustomizePostLogoInfoVariableGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE, sizeof (LENOVO_ESP_CUSTOMIZE_POST_LOGO_INFO), &L05EspCustomizePostLogoInfo ); return Status; } /** Prepare file name & format of customize POST logo when customize POST logo exist in ESP. @param NativeResolutionX A pointer to native horizontal resolution of a panel. @param NativeResolutionY A pointer to native vertical resolution of a panel. @retval EFI_SUCCESS The operation completed successfully. @retval Others An unexpected error occurred. **/ EFI_STATUS InitCustomizePostLogoFromEsp ( IN UINT32 NativeResolutionX, IN UINT32 NativeResolutionY ) { EFI_STATUS Status; UINTN HandleArrayCount; EFI_HANDLE *HandleArray; UINTN Index; EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *SimpleFileSystem; EFI_FILE *Root; EFI_FILE *FolderHandle; EFI_FILE *FileHandle; CHAR16 FileNameBuffer[100]; L05_BIOS_LOGO_DIY_ESP_FILE_NAME_DATA *CustomizePostLogoFileNameData; UINTN FileNameDataDataSize; UINTN FormatIndex; // // [2.3 Switch to Enable/disable Logo DIY] // In order to reduce POST time for normal BIOS, spec defines a bit in LENOVO_ESP_CUSTOMIZE_POST_LOGO_INFO // UEFI variable as a switch to enable/disable this Logo DIY function as below, default is disabled. // if (!mLogoDiySupport) { return EFI_UNSUPPORTED; } // // [2.2 Display Logo Picture during POST] // BIOS need to read logo picture from ESP in BIOS POST. // Status = gBS->LocateHandleBuffer ( ByProtocol, &gEfiPartTypeSystemPartGuid, NULL, &HandleArrayCount, &HandleArray ); if (EFI_ERROR (Status)) { return EFI_UNSUPPORTED; } // // Scan each system partition. // for (Index = 0; Index < HandleArrayCount; Index++) { Status = gBS->HandleProtocol (HandleArray[Index], &gEfiSimpleFileSystemProtocolGuid, (VOID **) &SimpleFileSystem); if (EFI_ERROR (Status)) { continue; } Root = NULL; FolderHandle = NULL; FileHandle = NULL; Status = SimpleFileSystem->OpenVolume (SimpleFileSystem, &Root); if (EFI_ERROR (Status)) { continue; } // // Try to open the logo picture folder from ESP. // Status = Root->Open (Root, &FolderHandle, L05_BIOS_LOGO_DIY_ESP_FOLDER_PATH, EFI_FILE_MODE_READ, 0); if (EFI_ERROR (Status)) { Root->Close (Root); continue; } // // Scan each supported logo format. // for (FormatIndex = 0; FormatIndex < mCustomizePostLogoFormatTableCount; FormatIndex++) { if (!mCustomizePostLogoFormatTable[FormatIndex].IsSupported) { continue; } ZeroMem (FileNameBuffer, sizeof (FileNameBuffer)); // // [2.1 Store Logo Picture into HDD] // Customers need to change picture name as "mylogo_*x*", format as: PNG, JPEG, BMP; // "*x*" is picture resolution // for example: mylogo_3840x2160.png, mylogo_1920x1080.jpg, mylogo_1280x1024.bmp. // // [2.2 Display Logo Picture during POST] // BIOS detect Panel resolution, and then select related picture to show as BIOS power on logo. // // Combine file name by "mylogo_" + NativeResolutionX "x" + NativeResolutionY + FileNameExtension. // UnicodeSPrint ( FileNameBuffer, sizeof (FileNameBuffer), L"%s%dx%d%s", L05_BIOS_LOGO_DIY_ESP_NAME_SIG, NativeResolutionX, NativeResolutionY, mCustomizePostLogoFormatTable[FormatIndex].FileNameExtension ); // // Try to open the logo picture from ESP. // Status = FolderHandle->Open (FolderHandle, &FileHandle, FileNameBuffer, EFI_FILE_MODE_READ, 0); if (!EFI_ERROR (Status)) { // // Allocate L05_BIOS_LOGO_DIY_ESP_FILE_NAME_DATA Pool. // FileNameDataDataSize = sizeof (L05_BIOS_LOGO_DIY_ESP_FILE_NAME_DATA) + StrSize (FileNameBuffer) - sizeof (CHAR16); CustomizePostLogoFileNameData = AllocateZeroPool (FileNameDataDataSize); // // Set logo format & file name. // CustomizePostLogoFileNameData->Format = mCustomizePostLogoFormatTable[FormatIndex].Format; StrCpyS (CustomizePostLogoFileNameData->FileName, (FileNameDataDataSize - sizeof (EFI_BADGING_SUPPORT_FORMAT)) / sizeof(CHAR16), FileNameBuffer); // // Set L05_BIOS_LOGO_DIY_ESP_FILE_NAME_VARIABLE_NAME variable. // Status = gRT->SetVariable ( L05_BIOS_LOGO_DIY_ESP_FILE_NAME_VARIABLE_NAME, &gEfiL05EspCustomizePostLogoInfoVariableGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, FileNameDataDataSize, CustomizePostLogoFileNameData ); if (!EFI_ERROR (Status)) { // // Set PcdL05CustomizeLogoFromEspFlag. // PcdSetBoolS (PcdL05CustomizeLogoFromEspFlag, TRUE); } FileHandle->Close (FileHandle); FolderHandle->Close (FolderHandle); Root->Close (Root); gBS->FreePool (CustomizePostLogoFileNameData); return Status; } } FolderHandle->Close (FolderHandle); Root->Close (Root); } return EFI_NOT_FOUND; } /** Prepare customize POST logo related resource and information. @retval EFI_SUCCESS The operation completed successfully. @retval Others An unexpected error occurred. **/ EFI_STATUS CoreInitCustomizePostLogo ( VOID ) { EFI_STATUS Status; EFI_EDID_DISCOVERED_PROTOCOL *EdidDiscovered; UINT32 NativeResolutionX; UINT32 NativeResolutionY; Status = gBS->LocateProtocol ( &gEfiEdidDiscoveredProtocolGuid, NULL, (VOID **) &EdidDiscovered ); if (EFI_ERROR (Status)) { return Status; } // // [2.2 Display Logo Picture during POST] // BIOS detect Panel resolution, and then select related picture to show as BIOS power on logo. // Status = GetResolutionByEdid (EdidDiscovered, &NativeResolutionX, &NativeResolutionY); if (EFI_ERROR (Status)) { return Status; } // // Check native resolution is valid. // if (NativeResolutionX == 0 || NativeResolutionY == 0) { return EFI_INVALID_PARAMETER; } // // Init customize post logo. // Status = InitCustomizePostLogoInfo (NativeResolutionX, NativeResolutionY); if (EFI_ERROR (Status)) { return Status; } // // Init customize post logo Vcm. // Status = InitCustomizePostLogoVcm (); if (EFI_ERROR (Status)) { return Status; } // // Init customize post logo from ESP. // Status = InitCustomizePostLogoFromEsp (NativeResolutionX, NativeResolutionY); if (EFI_ERROR (Status)) { return Status; } return Status; } //[-start-220104-BAIN000084-Modify]// /** Callback function to init customize post logo info & init customize post logo from ESP. @param[in] Event The event that is signaled. @param[in] Context Pointer to the context data. **/ VOID EFIAPI L05EndOfBdsConnectCallback ( IN EFI_EVENT Event, IN VOID *Context ) { EFI_STATUS Status; VOID *Interface; // // Check gL05EndOfBdsConnectProtocolGuid is ready. // Status = gBS->LocateProtocol ( &gL05EndOfBdsConnectProtocolGuid, NULL, (VOID **) &Interface ); if (EFI_ERROR (Status)) { return; } Status = CoreInitCustomizePostLogo (); if (!EFI_ERROR (Status) || !mLogoDiySupport) { gBS->CloseEvent (Event); } return; } /** Callback function to init customize post logo info & init customize post logo from ESP. @param[in] Event The event that is signaled. @param[in] Context Pointer to the context data. **/ VOID EFIAPI L05EndOfHdpConnectCallback ( IN EFI_EVENT Event, IN VOID *Context ) { EFI_STATUS Status; VOID *Interface; // // Check gL05EndOfHdpConnectProtocolGuid is ready. // Status = gBS->LocateProtocol ( &gL05EndOfHdpConnectProtocolGuid, NULL, (VOID **) &Interface ); if (EFI_ERROR (Status)) { return; } Status = CoreInitCustomizePostLogo (); if (!EFI_ERROR (Status) || !mLogoDiySupport) { gBS->CloseEvent (Event); } return; } /** BIOS POST LOGO diy DXE entry @param ImageHandle The firmware allocated handle for the UEFI image. @param SystemTable A pointer to the EFI System Table. @retval EFI_SUCCESS The operation completed successfully. @retval Others An unexpected error occurred. **/ EFI_STATUS L05BiosPostLogoDiyDxeEntry ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { VOID *Registration; Registration = NULL; if ((PcdGetBool (PcdH2OHddPasswordSupported) && PcdGetBool (PcdH2OHddPasswordUefiOsFastBootSupport)) || !PcdGetBool (PcdH2OHddPasswordSupported)) { // // Register gL05EndOfBdsConnectProtocolGuid protocol notify function. // EfiCreateProtocolNotifyEvent ( &gL05EndOfBdsConnectProtocolGuid, TPL_NOTIFY, L05EndOfBdsConnectCallback, NULL, &Registration ); } else { // // Register gL05EndOfHdpConnectProtocolGuid protocol notify function. // EfiCreateProtocolNotifyEvent ( &gL05EndOfHdpConnectProtocolGuid, TPL_NOTIFY, L05EndOfHdpConnectCallback, NULL, &Registration ); } return EFI_SUCCESS; } //[-end-220104-BAIN000084-Modify]//