/** @file Silicon related firmware version for telemetry driver @copyright INTEL CONFIDENTIAL Copyright 2018 - 2021 Intel Corporation. The source code contained or described herein and all documents related to the source code ("Material") are owned by Intel Corporation or its suppliers or licensors. Title to the Material remains with Intel Corporation or its suppliers and licensors. The Material may contain trade secrets and proprietary and confidential information of Intel Corporation and its suppliers and licensors, and is protected by worldwide copyright and trade secret laws and treaty provisions. No part of the Material may be used, copied, reproduced, modified, published, uploaded, posted, transmitted, distributed, or disclosed in any way without Intel's prior express written permission. No license under any patent, copyright, trade secret or other intellectual property right is granted to or conferred upon you by disclosure or delivery of the Materials, either expressly, by implication, inducement, estoppel or otherwise. Any license under such intellectual property rights must be express and approved by Intel in writing. Unless otherwise agreed by Intel in writing, you may not remove or alter this notice or any other notice embedded in Materials by Intel or Intel's suppliers or licensors in any way. This file contains an 'Intel Peripheral Driver' and is uniquely identified as "Intel Reference Module" and is licensed for Intel CPUs and chipsets under the terms of your license agreement with Intel or your vendor. This file may be modified by the user, subject to additional terms of the license agreement. @par Specification Reference: **/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "SiFirmwareVersionDxe.h" #include GLOBAL_REMOVE_IF_UNREFERENCED TELEMETRY_DATA_RECORD mPchFviTelemetryData[] = { { PCH_COMPONENT_ID, DEFAULT_FVI_TELEMETRY_VERSION, FVI_INTEL_SIGNATURE, }, { PCH_CRID_STATUS_COMPONENT_ID, DEFAULT_FVI_TELEMETRY_VERSION, FVI_INTEL_SIGNATURE, }, { PCH_CRID_ORIGINAL_COMPONENT_ID, DEFAULT_FVI_TELEMETRY_VERSION, FVI_INTEL_SIGNATURE, }, { PCH_CRID_NEW_COMPONENT_ID, DEFAULT_FVI_TELEMETRY_VERSION, FVI_INTEL_SIGNATURE, }, { PCH_RAID_VERSION_COMPONENT_ID, DEFAULT_FVI_TELEMETRY_VERSION, FVI_INTEL_SIGNATURE, }, { HSIO_LP_AX_COMPONENT_ID, FVI_PCH_ADL_LP_AX_HSIO_VERSION, FVI_INTEL_SIGNATURE, }, }; GLOBAL_REMOVE_IF_UNREFERENCED TELEMETRY_DATA_RECORD mSaFviTelemetryData[] = { { SA_RC_VERSION_COMPONENT_ID, DEFAULT_FVI_TELEMETRY_VERSION, FVI_INTEL_SIGNATURE, }, { SA_MEM_RC_VERSION_COMPONENT_ID, DEFAULT_FVI_TELEMETRY_VERSION, FVI_INTEL_SIGNATURE, }, { PCIE_VERSION_COMPONENT_ID, DEFAULT_FVI_TELEMETRY_VERSION, FVI_INTEL_SIGNATURE, }, { SA_CRID_STATUS_COMPONENT_ID, DEFAULT_FVI_TELEMETRY_VERSION, FVI_INTEL_SIGNATURE, }, { SA_CRID_ORIGINAL_COMPONENT_ID, DEFAULT_FVI_TELEMETRY_VERSION, FVI_INTEL_SIGNATURE, }, { SA_CRID_NEW_COMPONENT_ID, DEFAULT_FVI_TELEMETRY_VERSION, FVI_INTEL_SIGNATURE, }, { SA_VBIOS_VERSION_COMPONENT_ID, DEFAULT_FVI_TELEMETRY_VERSION, FVI_INTEL_SIGNATURE, }, { SA_IOM_COMPONENT_ID, DEFAULT_FVI_TELEMETRY_VERSION, FVI_INTEL_SIGNATURE, }, { SA_PHY_VERSION_COMPONENT_ID, DEFAULT_FVI_TELEMETRY_VERSION, FVI_INTEL_SIGNATURE, }, { SA_TBT_VERSION_COMPONENT_ID, DEFAULT_FVI_TELEMETRY_VERSION, FVI_INTEL_SIGNATURE, }, { SA_SAM_FW_VERSION_COMPONENT_ID, DEFAULT_FVI_TELEMETRY_VERSION, FVI_INTEL_SIGNATURE, }, }; GLOBAL_REMOVE_IF_UNREFERENCED TELEMETRY_DATA_RECORD mCpuFviTelemetryData[] = { { CPU_RC_VERSION_COMPONENT_ID, DEFAULT_FVI_TELEMETRY_VERSION, FVI_INTEL_SIGNATURE, }, { CPU_UCODE_VERSION_COMPONENT_ID, DEFAULT_FVI_TELEMETRY_VERSION, FVI_INTEL_SIGNATURE, }, { CPU_TXT_ACM_VERSION_COMPONENT_ID, DEFAULT_FVI_TELEMETRY_VERSION, FVI_INTEL_SIGNATURE, }, }; GLOBAL_REMOVE_IF_UNREFERENCED TELEMETRY_DATA_RECORD mMeFviTelemetryData[] = { { ME_RC_VERSION_COMPONENT_ID, DEFAULT_FVI_TELEMETRY_VERSION, FVI_INTEL_SIGNATURE, }, { ME_FIRMWARE_VERSION_COMPONENT_ID, DEFAULT_FVI_TELEMETRY_VERSION, FVI_INTEL_SIGNATURE, }, }; /** Update PCH-CRID Original Version Value and PCH-CRID New Version Value to PCH FVI telemetry data. @attention This function may receive untrusted input. PchSetup is external input, so this function will validate its data structure within this buffer before use. If HobPtr.Guid is NULL, then ASSERT(). @param[in] PchSetup pointer of Pch Setup Variable **/ VOID UpdatePchCridInfoInternal ( IN PCH_SETUP *PchSetup ) { PCH_INFO_HOB *PchInfoHob; EFI_PEI_HOB_POINTERS HobPtr; // // Do Crid programming as late as possible so others can get the ture PCH stepping. // HobPtr.Guid = GetFirstGuidHob (&gPchInfoHobGuid); ASSERT (HobPtr.Guid != NULL); PchInfoHob = (PCH_INFO_HOB *) GET_GUID_HOB_DATA (HobPtr.Guid); mPchFviTelemetryData[Pch_Crid_New].Version &= ~((UINT64) 0xFFFF); mPchFviTelemetryData[Pch_Crid_New].Version |= (UINT64) PchInfoHob->CridOrgRid; mPchFviTelemetryData[Pch_Crid_New].Version &= ~((UINT64) 0xFFFF); if ((PchSetup != NULL) && PchInfoHob->CridSupport && PchSetup->PchCrid) { mPchFviTelemetryData[Pch_Crid_New].Version |= (UINT64) PchInfoHob->CridNewRid; } else { mPchFviTelemetryData[Pch_Crid_New].Version |= (UINT64) PchInfoHob->CridOrgRid; } } /** Update PCH-CRID Original Version Value and PCH-CRID New Version Value to PCH FVI telemetry data. **/ VOID UpdatePchCridInfo ( VOID ) { EFI_STATUS Status; PCH_SETUP PchSetup; UINTN VariableSize; VariableSize = sizeof (PCH_SETUP); Status = gRT->GetVariable ( L"PchSetup", &gPchSetupVariableGuid, NULL, &VariableSize, &PchSetup ); ASSERT_EFI_ERROR (Status); UpdatePchCridInfoInternal (&PchSetup); } /** Set EfiFviRstOprom Version. @attention This function may receive untrusted input. DriverEfiVersion is external input, so this function will validate its data structure within this buffer before use. @param[in] DriverEfiVersion A pointer to the EFI_DRIVER_SUPPORTED_EFI_VERSION_PROTOCOL instance. **/ VOID SetEfiFviRstOpromVersion ( IN EFI_DRIVER_SUPPORTED_EFI_VERSION_PROTOCOL *DriverEfiVersion ) { UINT8 OpromVersion[2]; if (DriverEfiVersion != NULL) { OpromVersion[0] = (UINT8) ((DriverEfiVersion->FirmwareVersion & 0x00FF0000) >> 16); OpromVersion[1] = (UINT8) (DriverEfiVersion->FirmwareVersion & 0x000000FF); mPchFviTelemetryData[Raid_Ver].Version = 0x0; mPchFviTelemetryData[Raid_Ver].Version |= (((UINT64) OpromVersion[0] << VERSION_MAJOR_VERSION_SHIFT) | ((UINT64) OpromVersion[1] << VERSION_MINOR_VERSION_SHIFT)); } } /** Update OPROM -RTS- RAID version Value to PCH FVI telemetry data. **/ VOID UpdatePchFviRstOprom ( VOID ) { EFI_STATUS Status; UINTN Index; UINTN NumHandles; EFI_HANDLE *HandleBuffer; EFI_STRING DriverName; BOOLEAN FoundLegacyRaid; PCI_DATA_STRUCTURE *PcirBlockPtr; EFI_PCI_IO_PROTOCOL *PciIo; PCI_EXPANSION_ROM_HEADER *RomImage; EFI_COMPONENT_NAME2_PROTOCOL *ComponentName2; EFI_DRIVER_SUPPORTED_EFI_VERSION_PROTOCOL *DriverEfiVersion; FoundLegacyRaid = FALSE; // // Get all PCI IO protocols // Status = gBS->LocateHandleBuffer ( ByProtocol, &gEfiPciIoProtocolGuid, NULL, &NumHandles, &HandleBuffer ); if (!EFI_ERROR (Status)) { // // Find the RAID BIOS by checking each PCI IO handle for RST OPROM // for (Index = 0; Index < NumHandles; Index++) { Status = gBS->HandleProtocol ( HandleBuffer[Index], &gEfiPciIoProtocolGuid, (VOID **) &PciIo ); if (EFI_ERROR (Status) || (PciIo->RomImage == NULL)) { // // If this PCI device doesn't have a ROM image, skip to the next device. // continue; } RomImage = PciIo->RomImage; // // Get pointer to PCIR structure // PcirBlockPtr = (PCI_DATA_STRUCTURE *) ((UINTN) RomImage + RomImage->PcirOffset); // // Check if we have an RAID BIOS OPROM. // if ((RomImage->Signature == 0xAA55) && (PcirBlockPtr->ClassCode[0] == 0x00) && (PcirBlockPtr->ClassCode[1] == 0x04) && (PcirBlockPtr->ClassCode[2] == 0x01) ) { mPchFviTelemetryData[Raid_Ver].Version = 0x0; mPchFviTelemetryData[Raid_Ver].Version |= ((UINT64) ((PcirBlockPtr->CodeRevision & 0xFF00) >> 8) << VERSION_MAJOR_VERSION_SHIFT); mPchFviTelemetryData[Raid_Ver].Version |= ((UINT64) (PcirBlockPtr->CodeRevision & 0x00FF) << VERSION_MINOR_VERSION_SHIFT); FoundLegacyRaid = TRUE; } } } // // Search EFI RST OPROM // if (!FoundLegacyRaid) { Status = gBS->LocateHandleBuffer ( ByProtocol, &gEfiDriverSupportedEfiVersionProtocolGuid, NULL, &NumHandles, &HandleBuffer ); if (!EFI_ERROR (Status)) { for (Index = 0; Index < NumHandles; Index++) { Status = gBS->HandleProtocol ( HandleBuffer[Index], &gEfiComponentName2ProtocolGuid, (VOID **) &ComponentName2 ); if (EFI_ERROR (Status)) { continue; } Status = ComponentName2->GetDriverName (ComponentName2, "en-US", &DriverName); if (EFI_ERROR (Status)) { continue; } if ((StrnCmp (DriverName, RST_DRIVER_NAME1, StrLen (RST_DRIVER_NAME1)) == 0) || (StrnCmp (DriverName, RST_DRIVER_NAME2, StrLen (RST_DRIVER_NAME2)) == 0)) { Status = gBS->HandleProtocol ( HandleBuffer[Index], &gEfiDriverSupportedEfiVersionProtocolGuid, (VOID **) &DriverEfiVersion ); SetEfiFviRstOpromVersion (DriverEfiVersion); } } } } } /** Update PCH FVI Telemetry Version data. **/ VOID UpdatePchFviRcVersion( VOID ) { mPchFviTelemetryData[Rc_Ver].Version = (UINT64) PcdGet64 (PcdSiliconInitVersionValue); } /** Update OPROM - VBIOS Version version Value to SA FVI telemetry data. **/ VOID UpdateSaVbiosFviInfo ( VOID ) { UINT8 Data8; UINT64 McBaseAddress; UINT16 VbiosBuildNum; VbiosBuildNum = 0xFFFF; McBaseAddress = PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_MC_BUS, SA_MC_DEV, SA_MC_FUN, 0); Data8 = PciSegmentRead8 (McBaseAddress + PCI_REVISION_ID_OFFSET); S3BootScriptSaveMemWrite ( S3BootScriptWidthUint8, (UINTN) (PcdGet64 (PcdSiPciExpressBaseAddress) + McBaseAddress + PCI_REVISION_ID_OFFSET), 1, &Data8 ); mSaFviTelemetryData[Vbios_Ver].Version |= (UINT64) VbiosBuildNum; } /** Update SA FVI Telemetry Version data. **/ VOID UpdateSaFviTelemetryVersion( VOID ) { STATIC CONST SiMrcVersion MemRcVersionConst = {0, 0, 0, 0}; CONST SiMrcVersion *MemRcVersion; MEMORY_INFO_DATA_HOB *MemInfo; UINT64 McBaseAddress; UINT8 Data8; EFI_STATUS Status; UINTN VariableSize; SA_SETUP SaSetup; EFI_HOB_GUID_TYPE *GuidHob; TCSS_DATA_HOB *TcssHob; UINT8 Version[4]; UINT32 SamFwVersion; McBaseAddress = PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_MC_BUS, SA_MC_DEV, SA_MC_FUN, 0); /// /// Save CRID_ORIGINAL value before SaSecurityInit() executes CRID function. /// mSaFviTelemetryData[Crid_Original].Version = 0; mSaFviTelemetryData[Crid_Original].Version |= (UINT64) PciSegmentRead8 (McBaseAddress + PCI_REVISION_ID_OFFSET); /// /// Get SaSetup variable /// VariableSize = sizeof (SA_SETUP); Status = gRT->GetVariable ( L"SaSetup", &gSaSetupVariableGuid, NULL, &VariableSize, &SaSetup ); ASSERT_EFI_ERROR (Status); /// /// CRID configuration /// if (SaSetup.CridEnable == TRUE) { Data8 = CRID_DATA; DEBUG ((DEBUG_INFO, "CridEnable = %x\n", SaSetup.CridEnable)); } else { Data8 = CRID_LOCK; DEBUG ((DEBUG_INFO, "CridEnable = %x\n", SaSetup.CridEnable)); } PciSegmentWrite8 ((UINT64) (McBaseAddress + PCI_REVISION_ID_OFFSET), Data8); // // Search for the Memory Configuration GUID HOB. If it is not present, then // there's nothing we can do. It may not exist on the update path. // GuidHob = NULL; MemInfo = NULL; GuidHob = GetFirstGuidHob (&gSiMemoryInfoDataGuid); if (GuidHob != NULL) { MemInfo = (MEMORY_INFO_DATA_HOB *) GET_GUID_HOB_DATA (GuidHob); } if (MemInfo != NULL) { MemRcVersion = &MemInfo->Version; } else { MemRcVersion = &MemRcVersionConst; } mSaFviTelemetryData[Sa_Rc_Ver].Version = (UINT64) PcdGet64 (PcdSiliconInitVersionValue); mSaFviTelemetryData[Pcie_Ver].Version = (UINT64) PcdGet64 (PcdSiliconInitVersionValue); mSaFviTelemetryData[Mem_Rc_Ver].Version = 0; mSaFviTelemetryData[Mem_Rc_Ver].Version |= (((UINT64) MemRcVersion->Major << VERSION_MAJOR_VERSION_SHIFT) | ((UINT64) MemRcVersion->Minor << VERSION_MINOR_VERSION_SHIFT) | ((UINT64) MemRcVersion->Rev << VERSION_REVISION_SHIFT ) | ((UINT16) MemRcVersion->Build)); mSaFviTelemetryData[Crid_new].Version = 0; mSaFviTelemetryData[Crid_new].Version |= (UINT64) PciSegmentRead8 (McBaseAddress + PCI_REVISION_ID_OFFSET); // // Get TcssHob HOB // TcssHob = NULL; TcssHob = (TCSS_DATA_HOB *) GetFirstGuidHob (&gTcssHobGuid); if (TcssHob != NULL) { DEBUG ((EFI_D_INFO, "IomFwVersion = %08X\n", TcssHob->TcssData.IomFwVersion)); mSaFviTelemetryData[Iom_Fw_Ver].Version = 0; Version[0] = (UINT8) (TcssHob->TcssData.IomFwVersion >> 24); Version[1] = (UINT8) (TcssHob->TcssData.IomFwVersion >> 12); Version[2] = (UINT8) ((TcssHob->TcssData.IomFwVersion >> 8) & 0xF); Version[3] = (UINT8) (TcssHob->TcssData.IomFwVersion); mSaFviTelemetryData[Iom_Fw_Ver].Version |= (((UINT64) Version[0] << VERSION_MAJOR_VERSION_SHIFT) | ((UINT64) Version[1] << VERSION_MINOR_VERSION_SHIFT) | ((UINT64) Version[2] << VERSION_REVISION_SHIFT ) | ((UINT64) Version[3])); DEBUG ((EFI_D_INFO, "MgFwVersion = %04X\n", TcssHob->TcssData.MgImrStatus.Bits.MgFwVersion)); mSaFviTelemetryData[Phy_Ver].Version = 0; mSaFviTelemetryData[Phy_Ver].Version |= (UINT64)(UINT8) (TcssHob->TcssData.MgImrStatus.Bits.MgFwVersion); DEBUG ((EFI_D_INFO, "TbtFwVersion = %04X\n", TcssHob->TcssData.TbtImrStatus.Bits.TbtFwVersion)); mSaFviTelemetryData[Tbt_Fw_Ver].Version = 0; Version[0] = (UINT8) (DivU64x32 (TcssHob->TcssData.TbtImrStatus.Bits.TbtFwVersion, 100)); Version[1] = (UINT8) (ModU64x32 (TcssHob->TcssData.TbtImrStatus.Bits.TbtFwVersion, 100)); mSaFviTelemetryData[Tbt_Fw_Ver].Version |= (((UINT64) Version[0] << VERSION_MAJOR_VERSION_SHIFT) | ((UINT64) Version[1] << VERSION_MINOR_VERSION_SHIFT)); } if (IsSamEnabled ()) { SamFwVersion = GetSamFwInfo (); DEBUG ((DEBUG_INFO, "SamFwVersion = %08X\n", SamFwVersion)); Version[0] = (UINT8) (SamFwVersion >> 24); Version[1] = (UINT8) (SamFwVersion >> 12); Version[2] = (UINT8) ((SamFwVersion >> 8) & 0xF); Version[3] = (UINT8) (SamFwVersion); mSaFviTelemetryData[Sam_Fw_Ver].Version |= (((UINT64) Version[0] << VERSION_MAJOR_VERSION_SHIFT) | ((UINT64) Version[1] << VERSION_MINOR_VERSION_SHIFT) | ((UINT64) Version[2] << VERSION_REVISION_SHIFT ) | ((UINT64) Version[3])); } } /** Update CPU FVI Telemetry Version data. **/ VOID UpdateCpuFviTelemetryVersion( VOID ) { UINT32 UCodeRevision; UINT8 Version[4]; TXT_INFO_HOB *TxtInfoHob; mCpuFviTelemetryData[Cpu_Rc_Ver].Version = (UINT64) PcdGet64 (PcdSiliconInitVersionValue); UCodeRevision = GetCpuUcodeRevision (); mCpuFviTelemetryData[Ucode_Ver].Version = 0; Version[0] = (UINT8) ((UCodeRevision & 0xFF000000) >> 24); Version[1] = (UINT8) ((UCodeRevision & 0x00FF0000) >> 16); Version[2] = (UINT8) ((UCodeRevision & 0x0000FF00) >> 8); Version[3] = (UINT8) (UCodeRevision & 0x000000FF); mCpuFviTelemetryData[Ucode_Ver].Version |= (((UINT64) Version[0] << VERSION_MAJOR_VERSION_SHIFT) | ((UINT64) Version[1] << VERSION_MINOR_VERSION_SHIFT) | ((UINT64) Version[2] << VERSION_REVISION_SHIFT) | (UINT64) Version[3]); // // Get TxtInfoHob // TxtInfoHob = (TXT_INFO_HOB *) GetFirstGuidHob (&gTxtInfoHobGuid); if ((TxtInfoHob != NULL) && !(0 == TxtInfoHob->Data.AcmMajorVersion && 0 == TxtInfoHob->Data.AcmMinorVersion)) { mCpuFviTelemetryData[Txt_Ver].Version = 0; mCpuFviTelemetryData[Txt_Ver].Version |= (((UINT64) TxtInfoHob->Data.AcmMajorVersion << VERSION_MAJOR_VERSION_SHIFT) | ((UINT64) TxtInfoHob->Data.AcmMinorVersion << VERSION_MINOR_VERSION_SHIFT) | ((UINT64) TxtInfoHob->Data.AcmRevision << VERSION_REVISION_SHIFT)); } } /** Update ME FVI Telemetry Version data. **/ VOID UpdateMeFviTelemetryVersion( VOID ) { ME_BIOS_PAYLOAD_HOB *MbpHob; MbpHob = NULL; mMeFviTelemetryData[EnumMeRc] .Version= (UINT64) PcdGet64 (PcdSiliconInitVersionValue); // // Get the MBP Data. // MbpHob = GetFirstGuidHob (&gMeBiosPayloadHobGuid); if (MbpHob != NULL) { mMeFviTelemetryData[EnumMeFw].Version = 0; mMeFviTelemetryData[EnumMeFw].Version |= (((UINT64) MbpHob->MeBiosPayload.FwVersionName.MajorVersion << VERSION_MAJOR_VERSION_SHIFT) | ((UINT64) MbpHob->MeBiosPayload.FwVersionName.MinorVersion << VERSION_MINOR_VERSION_SHIFT) | ((UINT64) MbpHob->MeBiosPayload.FwVersionName.HotfixVersion << VERSION_REVISION_SHIFT) | ((UINT16) MbpHob->MeBiosPayload.FwVersionName.BuildVersion)); } else { DEBUG ((DEBUG_ERROR, "BuildMeFviHob: No MBP Data Protocol available\n")); } } /** Publish Pch table in AIP protocol. @retval EFI_SUCCESS The Pch data is published in AIP protocol. @retval EFI_ALREADY_STARTED There is already Pch table with Role and ImplementationID published in system. @retval EFI_OUT_OF_RESOURCES There is not enough system resource to publish HSTI data in AIP protocol. **/ EFI_STATUS EFIAPI InitializePchFviData ( VOID ) { EFI_STATUS Status; UINT16 RrcordCount; UINT8 Index; Index = 0; Status = EFI_SUCCESS; UpdatePchFviRcVersion (); UpdatePchCridInfo (); UpdatePchFviRstOprom (); RrcordCount = sizeof (mPchFviTelemetryData) / sizeof (TELEMETRY_DATA_RECORD); for (Index = 0; Index < RrcordCount; Index++) { Status = AppendTelemetryFviBlock (mPchFviTelemetryData[Index].ComponentId, mPchFviTelemetryData[Index].Version, mPchFviTelemetryData[Index].ProducerId); if (EFI_ERROR (Status)) { DEBUG ((EFI_D_ERROR, "PCH FVI: AppendTelemetryFviBlock returns %r.\n", Status)); return Status; } } return Status; } /** Publish Sa table in AIP protocol. @retval EFI_SUCCESS The Sa data is published in AIP protocol. @retval EFI_ALREADY_STARTED There is already Sa table with Role and ImplementationID published in system. @retval EFI_OUT_OF_RESOURCES There is not enough system resource to publish HSTI data in AIP protocol. **/ EFI_STATUS EFIAPI InitializeSaFviData ( VOID ) { EFI_STATUS Status; UINT16 RrcordCount; UINT8 Index; Index = 0; Status = EFI_SUCCESS; UpdateSaFviTelemetryVersion (); UpdateSaVbiosFviInfo (); RrcordCount = sizeof (mSaFviTelemetryData) / sizeof (TELEMETRY_DATA_RECORD); for (Index = 0; Index < RrcordCount; Index++) { Status = AppendTelemetryFviBlock (mSaFviTelemetryData[Index].ComponentId, mSaFviTelemetryData[Index].Version, mSaFviTelemetryData[Index].ProducerId); if (EFI_ERROR (Status)) { DEBUG ((EFI_D_ERROR, "SA FVI: AppendTelemetryFviBlock returns %r.\n", Status)); return Status; } } return Status; } /** Publish Sa table in AIP protocol. @retval EFI_SUCCESS The Sa data is published in AIP protocol. @retval EFI_ALREADY_STARTED There is already Sa table with Role and ImplementationID published in system. @retval EFI_OUT_OF_RESOURCES There is not enough system resource to publish HSTI data in AIP protocol. **/ EFI_STATUS EFIAPI InitializeCpuFviData ( VOID ) { EFI_STATUS Status; UINT16 RrcordCount; UINT8 Index; Index = 0; Status = EFI_SUCCESS; UpdateCpuFviTelemetryVersion (); RrcordCount = sizeof (mCpuFviTelemetryData) / sizeof (TELEMETRY_DATA_RECORD); for (Index = 0; Index < RrcordCount; Index++) { Status = AppendTelemetryFviBlock (mCpuFviTelemetryData[Index].ComponentId, mCpuFviTelemetryData[Index].Version, mCpuFviTelemetryData[Index].ProducerId); if (EFI_ERROR (Status)) { DEBUG ((EFI_D_ERROR, "CPU FVI: AppendTelemetryFviBlock returns %r.\n", Status)); return Status; } } return Status; } /** Publish Sa table in AIP protocol. @retval EFI_SUCCESS The Sa data is published in AIP protocol. @retval EFI_ALREADY_STARTED There is already Sa table with Role and ImplementationID published in system. @retval EFI_OUT_OF_RESOURCES There is not enough system resource to publish HSTI data in AIP protocol. **/ EFI_STATUS EFIAPI InitializeMeFviData ( VOID ) { EFI_STATUS Status; UINT16 RrcordCount; UINT8 Index; Index = 0; Status = EFI_SUCCESS; UpdateMeFviTelemetryVersion (); RrcordCount = sizeof (mMeFviTelemetryData) / sizeof (TELEMETRY_DATA_RECORD); for (Index = 0; Index < RrcordCount; Index++) { Status = AppendTelemetryFviBlock (mMeFviTelemetryData[Index].ComponentId, mMeFviTelemetryData[Index].Version, mMeFviTelemetryData[Index].ProducerId); if (EFI_ERROR (Status)) { DEBUG ((EFI_D_ERROR, "ME FVI: AppendTelemetryFviBlock returns %r.\n", Status)); return Status; } } return Status; } /** Call Publish Fvi Telemetry Info table in AIP protocol at the end of DXE @param[in] Event @param[in] *Context **/ VOID EFIAPI InitFviTelemetryAip ( IN EFI_EVENT Event, IN VOID *Context ) { EFI_STATUS Status; Status = EFI_SUCCESS; // // Install Aip // Status = InitializePchFviData (); if (EFI_ERROR (Status)) { DEBUG ((DEBUG_ERROR, "InitializePchFviData failed. Status: %r\n", Status)); } Status = InitializeSaFviData (); if (EFI_ERROR (Status)) { DEBUG ((DEBUG_ERROR, "InitializeSaFviData failed. Status: %r\n", Status)); } Status = InitializeCpuFviData (); if (EFI_ERROR (Status)) { DEBUG ((DEBUG_ERROR, "InitializeCpuFviData failed. Status: %r\n", Status)); } Status = InitializeMeFviData (); if (EFI_ERROR (Status)) { DEBUG ((DEBUG_ERROR, "InitializeMeFviData failed. Status: %r\n", Status)); } } /** This is driver entry point to install AIP protocol. @param[in] ImageHandle A handle for the image that is initializing this driver @param[in] SystemTable A pointer to the EFI system table @retval EFI_SUCCESS The initialization finished successfully. **/ EFI_STATUS EFIAPI SiFirmwareVersionDxe ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; EFI_EVENT EndOfDxeEvent; Status = gBS->CreateEventEx ( EVT_NOTIFY_SIGNAL, TPL_CALLBACK, InitFviTelemetryAip, NULL, &gEfiEndOfDxeEventGroupGuid, &EndOfDxeEvent ); ASSERT_EFI_ERROR (Status); return Status; }