/** @file ;****************************************************************************** ;* Copyright (c) 2014 - 2020 , Insyde Software Corporation. 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 #include #include #include #include #include #include #include #include VOID DumpCmosInVariableValue ( UINT8 *CmosInVariable ) { UINTN Index; for (Index = 0; Index < CMOS_TOTAL_LENGTH; Index += 8) { DEBUG ( ( DEBUG_INFO | DEBUG_ERROR, "%02x %02x %02x %02x %02x %02x %02x %02x", \ CmosInVariable[Index], CmosInVariable[Index+1], \ CmosInVariable[Index+2], CmosInVariable[Index+3], \ CmosInVariable[Index+4], CmosInVariable[Index+5], \ CmosInVariable[Index+6], CmosInVariable[Index+7] \ ) ); } return; } VOID DumpCmosValue ( //[-start-190610-IB16990033-add]// VOID //[-end-190610-IB16990033-add]// ) { UINT8 Index; for (Index = 0; Index < (CMOS_TOTAL_LENGTH/2); Index += 8) { DEBUG ( ( DEBUG_INFO | DEBUG_ERROR, "%02x %02x %02x %02x %02x %02x %02x %02x", \ ReadCmos8 (Index), ReadCmos8 (Index+1), \ ReadCmos8 (Index+2), ReadCmos8 (Index+3), \ ReadCmos8 (Index+4), ReadCmos8 (Index+5), \ ReadCmos8 (Index+6), ReadCmos8 (Index+7) \ ) ); } for (Index = 0; Index < (CMOS_TOTAL_LENGTH/2); Index += 8) { DEBUG ( ( DEBUG_INFO | DEBUG_ERROR, "%02x %02x %02x %02x %02x %02x %02x %02x", \ ReadExtCmos8 (R_XCMOS_INDEX, R_XCMOS_DATA, Index), \ ReadExtCmos8 (R_XCMOS_INDEX, R_XCMOS_DATA, Index+1), \ ReadExtCmos8 (R_XCMOS_INDEX, R_XCMOS_DATA, Index+2), \ ReadExtCmos8 (R_XCMOS_INDEX, R_XCMOS_DATA, Index+3), \ ReadExtCmos8 (R_XCMOS_INDEX, R_XCMOS_DATA, Index+4), \ ReadExtCmos8 (R_XCMOS_INDEX, R_XCMOS_DATA, Index+5), \ ReadExtCmos8 (R_XCMOS_INDEX, R_XCMOS_DATA, Index+6), \ ReadExtCmos8 (R_XCMOS_INDEX, R_XCMOS_DATA, Index+7) \ ) ); } return; } /** This function gets registered as a callback to run the SaveCmosCallback function. @param[in] Event - A pointer to the Event that triggered the callback. @param[in] Context - A pointer to private data registered with the callback function. **/ VOID EFIAPI SaveCmosCallback ( IN EFI_EVENT Event, IN VOID *Context ) { EFI_STATUS Status; UINT8 Cmosbuffer[CMOS_TOTAL_LENGTH]; UINT8 CmosInVariable[CMOS_TOTAL_LENGTH]; UINT8 Index; UINT8 Address; UINTN Size; INTN Saveflag; CMOS_ELEMENT *CmosElement; Size = CMOS_TOTAL_LENGTH; Saveflag = 0; DEBUG ( ( DEBUG_INFO | DEBUG_ERROR, "SaveCmosCallback Start" ) ); for (Index = 0, Address = 0; Address < (CMOS_TOTAL_LENGTH/2); Index++, Address++) { Cmosbuffer[Index] = ReadCmos8 (Address); } for (Address = 0; Address < (CMOS_TOTAL_LENGTH/2); Index++, Address++) { Cmosbuffer[Index] = ReadExtCmos8 (R_XCMOS_INDEX, R_XCMOS_DATA, Address); } Status = gRT->GetVariable ( L"CmosVariable", &gCmosInVariableGuid, NULL, &Size, &CmosInVariable ); if (Status == EFI_SUCCESS) { DEBUG ( ( DEBUG_INFO | DEBUG_ERROR, "Current CmosVariable value" ) ); DumpCmosInVariableValue (CmosInVariable); DEBUG ( ( DEBUG_INFO | DEBUG_ERROR, "Current cmos value" ) ); DumpCmosValue (); CmosElement = (CMOS_ELEMENT *)PcdGetPtr (PcdSaveCmosFieldCompareList); Index = 0; while (((CmosElement[Index].Start_Offset != 0) && (CmosElement[Index].Length != 0)) && Saveflag == 0) { Address = CmosElement[Index].Start_Offset; Saveflag = CompareMem (&CmosInVariable[Address], &Cmosbuffer[Address], CmosElement[Index].Length); Index++; } if (Saveflag != 0) { DEBUG ( ( DEBUG_INFO | DEBUG_ERROR, "CmosVariable value is different from Cmos value" ) ); } } else { Saveflag = 1; DEBUG ( ( DEBUG_INFO | DEBUG_ERROR, "CmosVariable don't exist" ) ); } if ( Saveflag != 0) { DEBUG ( ( DEBUG_INFO | DEBUG_ERROR, "Update CmosVariable !!" ) ); Status = gRT->SetVariable ( L"CmosVariable", &gCmosInVariableGuid, EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, Size, (VOID *) Cmosbuffer ); DEBUG ( ( DEBUG_INFO | DEBUG_ERROR, "Save CmosVariable value" ) ); DumpCmosValue (); } else { DEBUG ( ( DEBUG_INFO | DEBUG_ERROR, "No update CmosVariable !!" ) ); } /// /// Closed the event to avoid call twice when launch shell /// gBS->CloseEvent (Event); } /** Install ReadyToboot callback event for Saving CMOS value in Variable. @param[in] ImageHandle - A handle for this module @param[in] SystemTable - A pointer to the EFI System Table @retval Status **/ EFI_STATUS EFIAPI SaveCmosEntryPoint ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; EFI_EVENT ReadyToBootEvent; /// /// Create callback to run SaveCmosCallback /// Status = EfiCreateEventReadyToBootEx ( TPL_CALLBACK, SaveCmosCallback, NULL, &ReadyToBootEvent ); ASSERT_EFI_ERROR (Status); return Status; }