/** @file Instance of BIOS Self-Healing Services Library. ;****************************************************************************** ;* Copyright (c) 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 #if (FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_TIGERLAKE || \ FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_ALDERLAKE) #include // PCI_DEVICE_NUMBER_PCH_ESPI, PCI_FUNCTION_NUMBER_PCH_ESPI #include // DEFAULT_PCI_BUS_NUMBER_PCH #include // R_SPI_CFG_BC, B_SPI_CFG_BC_TSS #include // PID_RTC_HOST #include // R_RTC_PCR_BUC, B_RTC_PCR_BUC_TS #include // HECI_FWS_REGISTER #include // ME_DEVICE_NUMBER #include // PciSegmentRead32 #include // MmioRead32 #include // MmPciBase #include // PchPcrAndThenOr32 #endif #if (FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_CEZANNE || \ FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_REMBRANDT) #include // CheckPspRecoveryFlagV2 #endif // // Block definition for TigerLake // #if (FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_TIGERLAKE) UINT32 mPrimaryFvBase[] = {FixedPcdGet32 (PcdFlashFirmwareBinariesFvBase)}; UINT32 mBackupFvBase[] = {FixedPcdGet32 (PcdFlashFvL05BackupIbbBase)}; UINT32 mBackupFvSize[] = {FixedPcdGet32 (PcdFlashFvL05BackupIbbSize)}; #endif //[-start-220125-BAIN000092-remove]// #ifndef LCFC_SUPPORT // // Block definition for AlderLake // #if (FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_ALDERLAKE) UINT32 mBackupFvBase[] = {FixedPcdGet32 (PcdFwResiliencyReservedBase)}; UINT32 mBackupFvSize[] = {FixedPcdGet32 (PcdFwResiliencyReservedSize)}; #endif #endif //[-end-220125-BAIN000092-remove]// // // Block definition for Cezanne // #if (FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_CEZANNE) UINT32 mPrimaryFvBase[] = { #ifdef CZN_COMBO_SUPPORT FixedPcdGet32 (PcdFlashCznPspDirLv2ABase), FixedPcdGet32 (PcdFlashCznBiosDirLv2ABase), #endif #ifdef LCN_COMBO_SUPPORT FixedPcdGet32 (PcdFlashRnPspDirLv2ABase), FixedPcdGet32 (PcdFlashRnBiosDirLv2ABase), #endif FixedPcdGet32 (PcdFlashFvRecovery2PadBase) }; UINT32 mBackupFvBase[] = { #ifdef CZN_COMBO_SUPPORT FixedPcdGet32 (PcdFlashCznPspDirLv2BBase), FixedPcdGet32 (PcdFlashCznBiosDirLv2BBase), #endif #ifdef LCN_COMBO_SUPPORT FixedPcdGet32 (PcdFlashRnPspDirLv2BBase), FixedPcdGet32 (PcdFlashRnBiosDirLv2BBase), #endif FixedPcdGet32 (PcdFlashFvRecoveryPadBase) }; UINT32 mBackupFvSize[] = { #ifdef CZN_COMBO_SUPPORT FixedPcdGet32 (PcdFlashCznPspDirLv2BSize), FixedPcdGet32 (PcdFlashCznBiosDirLv2BSize), #endif #ifdef LCN_COMBO_SUPPORT FixedPcdGet32 (PcdFlashRnPspDirLv2BSize), FixedPcdGet32 (PcdFlashRnBiosDirLv2BSize), #endif FixedPcdGet32 (PcdFlashFvRecoveryPadSize) }; #endif // // Block definition for Rembrandt // #if (FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_REMBRANDT) UINT32 mPrimaryFvBase[] = { FixedPcdGet32 (PcdFlashPspDirABase), FixedPcdGet32 (PcdFlashBiosDirABase), FixedPcdGet32 (PcdFlashFvRecoveryBase) }; UINT32 mBackupFvBase[] = { FixedPcdGet32 (PcdFlashPspDirBBase), FixedPcdGet32 (PcdFlashBiosDirBBase), FixedPcdGet32 (PcdFlashPeiFlashBBase) }; UINT32 mBackupFvSize[] = { FixedPcdGet32 (PcdFlashPspDirBSize), FixedPcdGet32 (PcdFlashBiosDirBSize), FixedPcdGet32 (PcdFlashPeiFlashBSize) }; #endif //[-start-220125-BAIN000092-remove]// #ifndef LCFC_SUPPORT UINT8 mPbbrSyncSignature[] = {'P', 'B', 'B', 'R', 'S', 'Y', 'N', 'C'}; UINT8 mPbbrSyncSignatureSize = sizeof (mPbbrSyncSignature); #endif //[-end-220125-BAIN000092-remove]// #if (FixedPcdGet32 (PcdL05ChipsetName) != L05_CHIPSET_NAME_ALDERLAKE) /** Retrieve IBB FV info. @param PrimaryFvBase Point to PrimaryFvBase table. @param BackupFvBase Point to BackupFvBase table. @param BackupFvSize Point to BackupFvSize table. @retval FvCount FV count. **/ UINTN RetrieveIbbFvInfo ( IN UINT32 **PrimaryFvBase, IN UINT32 **BackupFvBase, IN UINT32 **BackupFvSize ) { *PrimaryFvBase = mPrimaryFvBase; *BackupFvBase = mBackupFvBase; *BackupFvSize = mBackupFvSize; return (sizeof (mBackupFvBase) / sizeof (UINT32)); } /** Source data processing. @param FvBase FvBase of IBBR. @param Buffer Point to source buffer. @retval EFI_SUCCESS This function execute successfully. **/ EFI_STATUS PatchDataToBuffer ( IN UINT32 FvBase, IN VOID *Buffer ) { // // Cezanne only // #if (FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_CEZANNE) UINTN Index; EFI_L05_BSH_DATA_HEADER *BshDataHdr; EFI_L05_PATCH_DATA_HEADER *PatchDataHdr; VOID *PatchData; BshDataHdr = (EFI_L05_BSH_DATA_HEADER *) (UINTN) PcdGet32 (PcdFlashFvL05BshDataBase); PatchDataHdr = NULL; PatchData = NULL; if (BshDataHdr->PatchCount > 0) { PatchDataHdr = (EFI_L05_PATCH_DATA_HEADER *) ((UINTN) BshDataHdr + sizeof (EFI_L05_BSH_DATA_HEADER)); PatchData = (VOID *) ((UINTN) PatchDataHdr + sizeof (EFI_L05_PATCH_DATA_HEADER) * BshDataHdr->PatchCount); } for (Index = 0; Index < BshDataHdr->PatchCount; Index++) { if (FvBase == PatchDataHdr->FvBase) { CopyMem ((VOID *) ((UINTN) Buffer + PatchDataHdr->Offset), PatchData, PatchDataHdr->Size); } PatchData = (VOID *) ((UINTN) PatchData + PatchDataHdr->Size); PatchDataHdr = (EFI_L05_PATCH_DATA_HEADER *) ((UINTN) PatchDataHdr + sizeof (EFI_L05_PATCH_DATA_HEADER)); } #endif return EFI_SUCCESS; } //[-start-220125-BAIN000092-remove]// //#endif //[-end-220125-BAIN000092-remove]// /** Check if address is in backup IBB region. @retval TRUE Address is in backup IBB region. @retval FALSE Normal region. **/ BOOLEAN IsBackupIbbRegion ( IN UINT32 Address ) { UINTN Index; for (Index = 0; Index < (sizeof (mBackupFvBase) / sizeof (UINT32)); Index++) { if ((Address >= mBackupFvBase[Index]) && (Address < (mBackupFvBase[Index] + mBackupFvSize[Index]))) { return TRUE; } } return FALSE; } //[-start-220125-BAIN000092-add]// #endif //[-end-220125-BAIN000092-add]// /** Get Top Swap status. @retval TRUE Top Swap is enabled. @retval FALSE Top Swap is disabled. **/ BOOLEAN TopSwapStatus ( VOID ) { BOOLEAN TopSwapDetected = FALSE; #if (FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_TIGERLAKE || \ FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_ALDERLAKE) UINTN SpiPciBase; UINT32 Data32; // // Refer to Intel PCH EDS Volume 1 of 2 // Charpter 9 Pin Straps // GPP_B14 - The status of this strap is readable using the Top Swap bit // (Bus 0, Device 31, Function 0, Offset DCh, BIT4) // SpiPciBase = MmPciBase ( DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_ESPI, PCI_FUNCTION_NUMBER_PCH_ESPI ); Data32 = MmioRead32 (SpiPciBase + R_SPI_CFG_BC); TopSwapDetected = ((Data32 & B_SPI_CFG_BC_TSS) == B_SPI_CFG_BC_TSS) ? TRUE : FALSE; #endif #if (FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_CEZANNE || \ FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_REMBRANDT) TopSwapDetected = CheckPspRecoveryFlagV2 (); #endif DEBUG ((DEBUG_INFO, "%a() TopSwapDetected = %d\n", __FUNCTION__, TopSwapDetected)); return TopSwapDetected; } /** Set Top Swap status. @param TopSwapEnable Enable Top Swap or Disable it. @retval EFI_SUCCESS Top Swap set successfully. **/ EFI_STATUS TopSwapSet ( IN BOOLEAN TopSwapEnable ) { #if (FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_TIGERLAKE || \ FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_ALDERLAKE) // // Refer to Intel PCH EDS Volume 2 of 2 // RTC PCR Register // Chapter 34.2.2 Backed Up Control (BUC) - Offset 3414h // if (TopSwapEnable) { PchPcrAndThenOr32 (PID_RTC_HOST, R_RTC_PCR_BUC, ~0u, B_RTC_PCR_BUC_TS); } else { PchPcrAndThenOr32 (PID_RTC_HOST, R_RTC_PCR_BUC, (UINT32) ~B_RTC_PCR_BUC_TS, 0); } #endif #if (FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_CEZANNE || \ FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_REMBRANDT) // // Not support // #endif return EFI_SUCCESS; } /** Check if system is in manufacturing mode. @retval TRUE System is in manufacturing mode. @retval FALSE Normal mode. **/ BOOLEAN IsManufacturingMode ( VOID ) { EFI_STATUS Status; BOOLEAN IsMfgMode; Status = EFI_UNSUPPORTED; IsMfgMode = FALSE; Status = OemSvcGetMfgMode (&IsMfgMode); if (Status == EFI_MEDIA_CHANGED) { DEBUG ((DEBUG_INFO, "%a() IsMfgMode = %d\n", __FUNCTION__, IsMfgMode)); return IsMfgMode; } #if (FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_TIGERLAKE || \ FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_ALDERLAKE) HECI_FWS_REGISTER MeFirmwareStatus; MeFirmwareStatus.ul = PciSegmentRead32 (PCI_SEGMENT_LIB_ADDRESS (ME_SEGMENT, ME_BUS, ME_DEVICE_NUMBER, HECI_FUNCTION_NUMBER, R_ME_HFS)); DEBUG ((DEBUG_INFO, "%a() MeFirmwareStatus = %lx\n", __FUNCTION__, MeFirmwareStatus.ul)); IsMfgMode = (MeFirmwareStatus.r.SpiProtectionMode == 1) ? TRUE : FALSE; #endif #if (FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_CEZANNE || \ FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_REMBRANDT) // // If OemSvcGetMfgMode() is not implemented, system is not in manufacturing mode by default // IsMfgMode = FALSE; #endif DEBUG ((DEBUG_INFO, "%a() IsMfgMode = %d\n", __FUNCTION__, IsMfgMode)); return IsMfgMode; } //[-start-220125-BAIN000092-remove]// #ifndef LCFC_SUPPORT /** Check PBBR Sync in process signature. @param None @retval TRUE Need to sync PBBR. @retval FALSE No need to sync PBBR. **/ BOOLEAN CheckPbbrSyncFlag ( VOID ) { UINTN L05FvReservedBase; L05FvReservedBase = (UINTN) FixedPcdGet32 (PcdFlashFvReservedBase); if (L05FvReservedBase == 0) { return FALSE; } return (CompareMem ((VOID *)L05FvReservedBase, mPbbrSyncSignature, sizeof (mPbbrSyncSignature)) == 0) ? TRUE : FALSE; } #endif //[-end-220125-BAIN000092-remove]//