/** @file Reset scheduling library services Copyright (c) 2021, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include #include #include #include #include #include #include #include #include /** This function returns SiScheduleResetHob for library use **/ STATIC SI_SCHEDULE_RESET_HOB * SiScheduleGetResetData ( VOID ) { STATIC SI_SCHEDULE_RESET_HOB *SiScheduleResetHob = NULL; SI_SCHEDULE_RESET_HOB *SiScheduleResetHobTemp; VOID *HobPtr; if (SiScheduleResetHob != NULL) { return SiScheduleResetHob; } HobPtr = GetFirstGuidHob (&gSiScheduleResetHobGuid); if (HobPtr == NULL) { SiScheduleResetHobTemp = BuildGuidHob (&gSiScheduleResetHobGuid, sizeof (SI_SCHEDULE_RESET_HOB)); if (SiScheduleResetHobTemp == NULL) { ASSERT (FALSE); return SiScheduleResetHobTemp; } SiScheduleResetHobTemp->ResetType = 0xFF; DEBUG ((DEBUG_INFO, "SiScheduleResetSetType : Init SiScheduleResetHob\n")); } else { SiScheduleResetHobTemp = (SI_SCHEDULE_RESET_HOB*) GET_GUID_HOB_DATA (HobPtr); } SiScheduleResetHob = SiScheduleResetHobTemp; return SiScheduleResetHobTemp; } /** This function updates the reset information in SiScheduleResetHob @param[in] ResetType UEFI defined reset type. @param[in] ResetData Optional element used to introduce a platform specific reset. The exact type of the reset is defined by the EFI_GUID that follows the Null-terminated Unicode string. **/ VOID SiScheduleResetSetType ( IN EFI_RESET_TYPE ResetType, IN PCH_RESET_DATA *ResetData OPTIONAL ) { SI_SCHEDULE_RESET_HOB *SiScheduleResetHob; if (ResetType > EfiResetPlatformSpecific) { DEBUG ((DEBUG_INFO, "Unsupported Reset Type Requested\n")); return; } SiScheduleResetHob = SiScheduleGetResetData (); if (SiScheduleResetHob == NULL) { return; } DEBUG ((DEBUG_INFO, "SiScheduleResetSetType : Current Reset Type = 0x%x\n", SiScheduleResetHob->ResetType)); if (SiScheduleResetHob->ResetType == ResetType) { DEBUG ((DEBUG_INFO, "Current Reset Type is same as requested Reset Type\n")); return; } if (SiScheduleResetHob->ResetType == 0xFF) { // Init Reset Type to lowest ResetType SiScheduleResetHob->ResetType = EfiResetWarm; } // // ResetType Priority set as : ResetPlatformSpecific(3) > ResetShutdown(2) > ResetCold(0) > ResetWarm(1) // switch (ResetType) { case EfiResetWarm: break; case EfiResetCold: if (SiScheduleResetHob->ResetType == EfiResetWarm) { SiScheduleResetHob->ResetType = ResetType; } break; case EfiResetShutdown: if (SiScheduleResetHob->ResetType < ResetType) SiScheduleResetHob->ResetType = ResetType; break; case EfiResetPlatformSpecific: SiScheduleResetHob->ResetType = ResetType; SiScheduleResetHob->ResetData = *ResetData; break; } DEBUG ((DEBUG_INFO, "SiScheduleResetSetType : New Reset Type = 0x%x\n", SiScheduleResetHob->ResetType)); } /** This function returns TRUE or FALSE depending on whether a reset is required based on SiScheduleResetHob @retval BOOLEAN The function returns FALSE if no reset is required **/ BOOLEAN SiScheduleResetIsRequired ( VOID ) { VOID *HobPtr; HobPtr = NULL; HobPtr = GetFirstGuidHob (&gSiScheduleResetHobGuid); if (HobPtr == NULL) { return FALSE; } return TRUE; } /** This function performs reset based on SiScheduleResetHob @retval BOOLEAN The function returns FALSE if no reset is required **/ BOOLEAN SiScheduleResetPerformReset ( VOID ) { UINTN DataSize; SI_SCHEDULE_RESET_HOB *SiScheduleResetHob; if (!SiScheduleResetIsRequired ()) { return FALSE; } SiScheduleResetHob = SiScheduleGetResetData (); if (SiScheduleResetHob == NULL) { return TRUE; } DEBUG ((DEBUG_INFO, "SiScheduleResetPerformReset : Reset Type = 0x%x\n", SiScheduleResetHob->ResetType)); switch (SiScheduleResetHob->ResetType) { case EfiResetWarm: ResetWarm (); break; case EfiResetCold: ResetCold (); break; case EfiResetShutdown: ResetShutdown (); break; case EfiResetPlatformSpecific: DataSize = sizeof (PCH_RESET_DATA); ResetPlatformSpecific (DataSize, &SiScheduleResetHob->ResetData); break; } // Code should never reach here ASSERT (FALSE); return TRUE; }