/** @file This is the driver that initializes the Intel System Agent. @copyright INTEL CONFIDENTIAL Copyright 2014 - 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 "SaInitDxe.h" #include "SaInit.h" #include #include #include #include #include #if FixedPcdGetBool(PcdITbtEnable) == 1 #include #include #endif #include #include #include #include #include #include #include #include #include #if (FixedPcdGetBool (PcdVmdEnable) == 1) #include #include #include #include #include #endif #include #include #include #include /// /// Global Variables /// GLOBAL_REMOVE_IF_UNREFERENCED SYSTEM_AGENT_NVS_AREA_PROTOCOL mSaNvsAreaProtocol; GLOBAL_REMOVE_IF_UNREFERENCED SA_POLICY_PROTOCOL *mSaPolicy; /** A protocol callback which updates 64bits MMIO Base and Length in SA GNVS area **/ VOID UpdateSaGnvsForMmioResourceBaseLength ( VOID ) { EFI_PHYSICAL_ADDRESS PciBaseAddress; UINT32 Tolud; UINT64 Length; UINT64 McD0BaseAddress; UINTN ResMemLimit1; BOOLEAN EnableAbove4GBMmioBiosAssignemnt; VOID *CpuHob; UINT8 PhysicalAddressBits; UINT64 PhysicalAddressLimit; PciBaseAddress = 0; Tolud = 0; Length = 0; ResMemLimit1 = 0; EnableAbove4GBMmioBiosAssignemnt = CheckAbove4GbMmio (); CpuHob = NULL; PhysicalAddressBits = 0; PhysicalAddressLimit = 0; // // Read memory map registers // McD0BaseAddress = PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_MC_BUS, 0, 0, 0); Tolud = PciSegmentRead32 (McD0BaseAddress + R_SA_TOLUD) & B_SA_TOLUD_TOLUD_MASK; PciBaseAddress = Tolud; ResMemLimit1 = (UINTN) PcdGet64 (PcdSiPciExpressBaseAddress); Length = ResMemLimit1 - PciBaseAddress; CpuHob = GetFirstHob (EFI_HOB_TYPE_CPU); if (CpuHob != NULL) { PhysicalAddressBits = ((EFI_HOB_CPU *) CpuHob)->SizeOfMemorySpace; PhysicalAddressLimit = LShiftU64 (1, PhysicalAddressBits); } // // Check Enable Above 4GB MMIO or not // DEBUG ((DEBUG_INFO, "Update SA GNVS Area.\n")); mSaNvsAreaProtocol.Area->Mmio32Base = (UINT32) PciBaseAddress; mSaNvsAreaProtocol.Area->Mmio32Length = (UINT32) Length; if (EnableAbove4GBMmioBiosAssignemnt == TRUE) { if (PhysicalAddressBits != 0 && ( PhysicalAddressLimit % 0x4000000000) == 0) { // Checking Memory Size multiples of 256GB mSaNvsAreaProtocol.Area->Mmio64Base = BASE_256GB; // // Some platforms need to reserve MMIO space from PhysicalAddressLimit for P2SB usage. // mSaNvsAreaProtocol.Area->Mmio64Length = PhysicalAddressLimit - mSaNvsAreaProtocol.Area->Mmio64Base - ReserveMmio64Size (); } else { mSaNvsAreaProtocol.Area->Mmio64Base = BASE_256GB; mSaNvsAreaProtocol.Area->Mmio64Length = SIZE_256GB; } } DEBUG ((DEBUG_INFO, "SaNvsAreaProtocol.Area->Mmio64Base = %lx\n", mSaNvsAreaProtocol.Area->Mmio64Base)); DEBUG ((DEBUG_INFO, "SaNvsAreaProtocol.Area->Mmio64Length = %lx\n", mSaNvsAreaProtocol.Area->Mmio64Length)); DEBUG ((DEBUG_INFO, "SaNvsAreaProtocol.Area->Mmio32Base = %lx\n", mSaNvsAreaProtocol.Area->Mmio32Base)); DEBUG ((DEBUG_INFO, "SaNvsAreaProtocol.Area->Mmio32Length = %lx\n", mSaNvsAreaProtocol.Area->Mmio32Length)); } /** Initialize SA Nvs Area operation region. @retval EFI_SUCCESS initialized successfully @retval EFI_NOT_FOUND Nvs Area operation region is not found **/ EFI_STATUS PatchSaNvsAreaAddress ( VOID ) { EFI_STATUS Status; UINT32 Address; UINT16 Length; Address = (UINT32) (UINTN) mSaNvsAreaProtocol.Area; Length = (UINT16) sizeof (SYSTEM_AGENT_NVS_AREA); DEBUG ((DEBUG_INFO, "PatchSaNvsAreaAddress: SA NVS Address %x Length %x\n", Address, Length)); Status = UpdateNameAslCode (SIGNATURE_32 ('S','A','N','B'), &Address, sizeof (Address)); ASSERT_EFI_ERROR (Status); Status = UpdateNameAslCode (SIGNATURE_32 ('S','A','N','L'), &Length, sizeof (Length)); ASSERT_EFI_ERROR (Status); return EFI_SUCCESS; } /** Install SSDT Table @retval EFI_SUCCESS - SSDT Table load successful. **/ EFI_STATUS InstallSsdtAcpiTable ( IN GUID SsdtTableGuid, IN UINT64 Signature ) { EFI_STATUS Status; EFI_HANDLE *HandleBuffer; BOOLEAN LoadTable; UINTN NumberOfHandles; UINTN Index; INTN Instance; UINTN Size; UINT32 FvStatus; UINTN TableHandle; EFI_FV_FILETYPE FileType; EFI_FV_FILE_ATTRIBUTES Attributes; EFI_FIRMWARE_VOLUME2_PROTOCOL *FwVol; EFI_ACPI_TABLE_PROTOCOL *AcpiTable; EFI_ACPI_DESCRIPTION_HEADER *TableHeader; EFI_ACPI_COMMON_HEADER *Table; FwVol = NULL; Table = NULL; DEBUG ((DEBUG_INFO, "Loading SSDT Table GUID: %g\n", SsdtTableGuid)); /// /// Locate FV protocol. /// Status = gBS->LocateHandleBuffer ( ByProtocol, &gEfiFirmwareVolume2ProtocolGuid, NULL, &NumberOfHandles, &HandleBuffer ); ASSERT_EFI_ERROR (Status); /// /// Look for FV with ACPI storage file /// for (Index = 0; Index < NumberOfHandles; Index++) { /// /// Get the protocol on this handle /// This should not fail because of LocateHandleBuffer /// Status = gBS->HandleProtocol ( HandleBuffer[Index], &gEfiFirmwareVolume2ProtocolGuid, (VOID **) &FwVol ); ASSERT_EFI_ERROR (Status); if (FwVol == NULL) { return EFI_NOT_FOUND; } /// /// See if it has the ACPI storage file /// Size = 0; FvStatus = 0; Status = FwVol->ReadFile ( FwVol, &SsdtTableGuid, NULL, &Size, &FileType, &Attributes, &FvStatus ); /// /// If we found it, then we are done /// if (!EFI_ERROR (Status)) { break; } } /// /// Our exit status is determined by the success of the previous operations /// If the protocol was found, Instance already points to it. /// /// /// Free any allocated buffers /// FreePool (HandleBuffer); /// /// Sanity check that we found our data file /// ASSERT (FwVol); /// /// Locate ACPI tables /// Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **) &AcpiTable); /// /// Read tables from the storage file. /// if (FwVol == NULL) { ASSERT_EFI_ERROR (EFI_NOT_FOUND); return EFI_NOT_FOUND; } Instance = 0; while (Status == EFI_SUCCESS) { /// /// Read the ACPI tables /// Status = FwVol->ReadSection ( FwVol, &SsdtTableGuid, EFI_SECTION_RAW, Instance, (VOID **) &Table, &Size, &FvStatus ); if (!EFI_ERROR (Status)) { /// /// check and load HybridGraphics SSDT table /// LoadTable = FALSE; TableHeader = (EFI_ACPI_DESCRIPTION_HEADER *) Table; if (((EFI_ACPI_DESCRIPTION_HEADER *) TableHeader)->OemTableId == Signature) { /// /// This is the SSDT table that match the Signature /// DEBUG ((DEBUG_INFO, "Found out SSDT Table GUID: %g\n", SsdtTableGuid)); LoadTable = TRUE; } /// /// Add the table /// if (LoadTable) { TableHandle = 0; Status = AcpiTable->InstallAcpiTable ( AcpiTable, TableHeader, TableHeader->Length, &TableHandle ); } /// /// Increment the instance /// Instance++; Table = NULL; } } return EFI_SUCCESS; } /** This function gets registered as a callback to perform Dmar Igd @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 SaAcpiEndOfDxeCallback ( IN EFI_EVENT Event, IN VOID *Context ) { EFI_STATUS Status; DEBUG ((DEBUG_INFO, "%a - Start\n", __FUNCTION__)); if (PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, IGD_BUS_NUM, IGD_DEV_NUM, IGD_FUN_NUM, PCI_VENDOR_ID_OFFSET)) != 0xFFFF) { Status = PostPmInitEndOfDxe (); if (EFI_SUCCESS != Status) { DEBUG ((DEBUG_WARN, "[SA] EndOfDxe GraphicsInit Error, Status = %r \n", Status)); ASSERT_EFI_ERROR (Status); } } if (PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, IGD_BUS_NUM, IGD_DEV_NUM, IGD_FUN_NUM, PCI_VENDOR_ID_OFFSET)) != 0xFFFF) { Status = GetVbtEndOfDxe (); if (EFI_SUCCESS != Status) { DEBUG ((DEBUG_WARN, "[SA] EndOfDxe Op Region Error, Status = %r \n", Status)); } Status = UpdateIgdOpRegionEndOfDxe (); if (EFI_SUCCESS != Status) { DEBUG ((DEBUG_WARN, "[SA] EndOfDxe Update Op Region Error, Status = %r \n", Status)); } } PatchSaNvsAreaAddress(); DEBUG ((DEBUG_INFO, "%a - End\n", __FUNCTION__)); return; } #if (FixedPcdGetBool (PcdVmdEnable) == 1) /** Initializes VMD NVS area. **/ VOID VmdNvsInit ( VOID ) { VMD_INFO_HOB *VmdInfoHob; UINT8 VmdDevIndex; CPU_GENERATION CpuGeneration; CPU_FAMILY CpuFamily; VmdInfoHob = NULL; VmdInfoHob = (VMD_INFO_HOB *) GetFirstGuidHob (&gVmdInfoHobGuid); if (VmdInfoHob == NULL) { DEBUG ((DEBUG_INFO, "Vmd Info Hob not found\n")); return; } if ((mSaNvsAreaProtocol.Area->VmdEnable = IsVmdEnabled ()) == 1) { mSaNvsAreaProtocol.Area->VmdSataPort0to7 = 0; mSaNvsAreaProtocol.Area->VmdCpuRp = 0; mSaNvsAreaProtocol.Area->VmdRp1to8 = 0; mSaNvsAreaProtocol.Area->VmdRp9to16 = 0; mSaNvsAreaProtocol.Area->VmdRp17to24 = 0; CpuGeneration = GetCpuGeneration (); CpuFamily = GetCpuFamily (); if (VmdInfoHob != NULL) { for (VmdDevIndex = 0; VmdDevIndex < VMD_MAX_DEVICES; ++VmdDevIndex) { if (VmdInfoHob->VmdPortInfo.PortInfo[VmdDevIndex].PortEn) { if (VmdInfoHob->VmdPortInfo.PortInfo[VmdDevIndex].RpDev == SataDevNumber (0)) { DEBUG ((DEBUG_INFO, "SA VMD NVS protocol - SATA is mapped under VMD\n")); mSaNvsAreaProtocol.Area->VmdSataPort0to7 |= 0xFF; } if (CpuGeneration == EnumAdlCpu ) { if (CpuFamily == CPUID_FULL_FAMILY_MODEL_ALDERLAKE_DT_HALO ) { if ((VmdInfoHob->VmdPortInfo.PortInfo[VmdDevIndex].RpDev == SA_PEG1_DEV_NUM) && (VmdInfoHob->VmdPortInfo.PortInfo[VmdDevIndex].RpFunc == SA_PEG1_FUN_NUM)) { DEBUG ((DEBUG_INFO, "SA VMD NVS protocol - PEG11 Port - BDF 0/1/1 is mapped under VMD\n")); mSaNvsAreaProtocol.Area->VmdCpuRp |= 0x2; } } else if (CpuFamily == CPUID_FULL_FAMILY_MODEL_ALDERLAKE_MOBILE ) { if ((VmdInfoHob->VmdPortInfo.PortInfo[VmdDevIndex].RpDev == SA_PEG3_DEV_NUM) && (VmdInfoHob->VmdPortInfo.PortInfo[VmdDevIndex].RpFunc == SA_PEG2_FUN_NUM)) { DEBUG ((DEBUG_INFO, "SA VMD NVS protocol - PEG62 Port - BDF 0/6/2 is mapped under VMD\n")); mSaNvsAreaProtocol.Area->VmdCpuRp |= 0x10; } } } if ((VmdInfoHob->VmdPortInfo.PortInfo[VmdDevIndex].RpDev == SA_PEG0_DEV_NUM) && (VmdInfoHob->VmdPortInfo.PortInfo[VmdDevIndex].RpFunc == SA_PEG0_FUN_NUM)) { DEBUG ((DEBUG_INFO, "SA VMD NVS protocol - PEG10 Port - BDF 0/1/0 is mapped under VMD\n")); mSaNvsAreaProtocol.Area->VmdCpuRp |= 0x1; } else if ((VmdInfoHob->VmdPortInfo.PortInfo[VmdDevIndex].RpDev == SA_PEG2_DEV_NUM) && (VmdInfoHob->VmdPortInfo.PortInfo[VmdDevIndex].RpFunc == SA_PEG2_FUN_NUM)) { DEBUG ((DEBUG_INFO, "SA VMD NVS protocol - PEG12 Port - BDF 0/1/2 is mapped under VMD\n")); mSaNvsAreaProtocol.Area->VmdCpuRp |= 0x4; } else if ((VmdInfoHob->VmdPortInfo.PortInfo[VmdDevIndex].RpDev == SA_PEG3_DEV_NUM) && (VmdInfoHob->VmdPortInfo.PortInfo[VmdDevIndex].RpFunc == SA_PEG3_FUN_NUM)){ DEBUG ((DEBUG_INFO, "SA VMD NVS protocol - PEG60 Port - BDF 0/6/0 is mapped under VMD\n")); mSaNvsAreaProtocol.Area->VmdCpuRp |= 0x8; } else { DEBUG ((DEBUG_INFO, "SA VMD NVS protocol - PCH PCIe is remapped under VMD\n")); if (VmdInfoHob->VmdPortInfo.PortInfo[VmdDevIndex].RpDev == PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORT_1) { mSaNvsAreaProtocol.Area->VmdRp1to8 |= 0x1 << (VmdInfoHob->VmdPortInfo.PortInfo[VmdDevIndex].RpFunc); } else if (VmdInfoHob->VmdPortInfo.PortInfo[VmdDevIndex].RpDev == PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORT_9) { mSaNvsAreaProtocol.Area->VmdRp9to16 |= 0x1 << (VmdInfoHob->VmdPortInfo.PortInfo[VmdDevIndex].RpFunc); } else if (VmdInfoHob->VmdPortInfo.PortInfo[VmdDevIndex].RpDev == PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORT_17) { mSaNvsAreaProtocol.Area->VmdRp17to24 |= 0x1 << (VmdInfoHob->VmdPortInfo.PortInfo[VmdDevIndex].RpFunc); } else if (VmdInfoHob->VmdPortInfo.PortInfo[VmdDevIndex].RpDev == PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORT_25) { mSaNvsAreaProtocol.Area->VmdRp25to32 |= 0x1 << (VmdInfoHob->VmdPortInfo.PortInfo[VmdDevIndex].RpFunc); } } } } } } } #endif /** SystemAgent Acpi Initialization. @param[in] ImageHandle Handle for the image of this driver @retval EFI_SUCCESS The function completed successfully @retval EFI_OUT_OF_RESOURCES No enough buffer to allocate **/ EFI_STATUS EFIAPI SaAcpiInit ( IN EFI_HANDLE ImageHandle ) { EFI_STATUS Status; CPUID_VERSION_INFO_EAX CpuidVersionInfoEax; EFI_EVENT EndOfDxeEvent; PCIE_DXE_CONFIG *PcieDxeConfig; #if FixedPcdGetBool (PcdITbtEnable) == 1 TCSS_DATA_HOB *TcssHob; BOOLEAN CpuXhciExisted; #endif CPU_PCIE_HOB *CpuPcieHob; #if FixedPcdGetBool (PcdITbtEnable) == 1 CpuXhciExisted = FALSE; #endif AsmCpuid (CPUID_VERSION_INFO, &CpuidVersionInfoEax.Uint32, NULL, NULL, NULL); /// /// Get the platform setup policy. /// Status = gBS->LocateProtocol (&gSaPolicyProtocolGuid, NULL, (VOID **) &mSaPolicy); ASSERT_EFI_ERROR (Status); /// /// Install System Agent Global NVS protocol /// DEBUG ((DEBUG_INFO, "Install SA GNVS protocol\n")); Status = (gBS->AllocatePool) (EfiACPIMemoryNVS, sizeof (SYSTEM_AGENT_NVS_AREA), (VOID **) &mSaNvsAreaProtocol.Area); ASSERT_EFI_ERROR (Status); ZeroMem ((VOID *) mSaNvsAreaProtocol.Area, sizeof (SYSTEM_AGENT_NVS_AREA)); mSaNvsAreaProtocol.Area->XPcieCfgBaseAddress = (UINT32) (PcdGet64 (PcdSiPciExpressBaseAddress)); mSaNvsAreaProtocol.Area->CpuIdInfo = CpuidVersionInfoEax.Uint32; #if (FixedPcdGetBool (PcdVmdEnable) == 1) VmdNvsInit (); #endif /// /// Get CpuPcieHob HOB /// CpuPcieHob = NULL; CpuPcieHob = (CPU_PCIE_HOB *) GetFirstGuidHob (&gCpuPcieHobGuid); if (CpuPcieHob == NULL) { DEBUG((DEBUG_ERROR, "CpuPcieHob not found\n")); // @todo: Will add it back once it will get add into NVS library since currently it is failing for JSL //ASSERT(CpuPcieHob != NULL); //return EFI_NOT_FOUND; } else { mSaNvsAreaProtocol.Area->SlotSelection = CpuPcieHob->SlotSelection; DEBUG((DEBUG_INFO, "RpEnabledMask == %x\n", CpuPcieHob->RpEnabledMask)); if (CpuPcieHob->RpEnabledMask == 0) { DEBUG ((DEBUG_ERROR, "All CPU PCIe root ports are disabled!!\n")); } else { if (CpuPcieHob->RpEnabledMask & BIT0) { mSaNvsAreaProtocol.Area->CpuPcieRp0Enable = 1; } if (CpuPcieHob->RpEnabledMask & BIT1) { mSaNvsAreaProtocol.Area->CpuPcieRp1Enable = 1; } if (CpuPcieHob->RpEnabledMask & BIT2) { mSaNvsAreaProtocol.Area->CpuPcieRp2Enable = 1; } if (CpuPcieHob->RpEnabledMask & BIT3) { mSaNvsAreaProtocol.Area->CpuPcieRp3Enable = 1; } } mSaNvsAreaProtocol.Area->MaxPegPortNumber = GetMaxCpuPciePortNum (); Status = GetConfigBlock ((VOID *)mSaPolicy, &gPcieDxeConfigGuid, (VOID *)&PcieDxeConfig); ASSERT_EFI_ERROR (Status); } mSaNvsAreaProtocol.Area->SimicsEnvironment = (UINT8) IsSimicsEnvironment (); Status = gBS->InstallMultipleProtocolInterfaces ( &ImageHandle, &gSaNvsAreaProtocolGuid, &mSaNvsAreaProtocol, NULL ); ASSERT_EFI_ERROR (Status); /// /// GtPostInit Initialization /// DEBUG ((DEBUG_INFO, "Initializing GT ACPI tables\n")); GraphicsInit (ImageHandle, mSaPolicy); /// /// Audio (dHDA) Initialization /// /// /// Vtd Initialization /// DEBUG ((DEBUG_INFO, "Initializing VT-d ACPI tables\n")); VtdInit (mSaPolicy); /// /// IgdOpRegion Install Initialization /// DEBUG ((DEBUG_INFO, "Initializing IGD OpRegion\n")); IgdOpRegionInit (); /// /// Register an end of DXE event for SA ACPI to do tasks before invoking any UEFI drivers, /// applications, or connecting consoles,... /// Status = gBS->CreateEventEx ( EVT_NOTIFY_SIGNAL, TPL_CALLBACK, SaAcpiEndOfDxeCallback, NULL, &gEfiEndOfDxeEventGroupGuid, &EndOfDxeEvent ); /// /// Install System Agent Global NVS ACPI table /// Status = InstallSsdtAcpiTable (gSaSsdtAcpiTableStorageGuid, SIGNATURE_64 ('S', 'a', 'S', 's', 'd', 't', ' ', 0)); ASSERT_EFI_ERROR (Status); /// /// Update CPU PCIE RP NVS AREA /// UpdateCpuPcieNVS(); /// /// Install Intel Graphics SSDT /// Status = InstallSsdtAcpiTable (gGraphicsAcpiTableStorageGuid, SIGNATURE_64 ('I','g','f','x','S','s','d','t')); ASSERT_EFI_ERROR (Status); #if FixedPcdGetBool(PcdITbtEnable) == 1 if (0xFFFF != PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (0, XHCI_NORTH_BUS_NUM, XHCI_NORTH_DEV_NUM, XHCI_NORTH_FUNC_NUM, PCI_VENDOR_ID_OFFSET))) { CpuXhciExisted = TRUE; } if (CpuXhciExisted == TRUE) { /// /// Get TcssHob HOB /// TcssHob = (TCSS_DATA_HOB *) GetFirstGuidHob (&gTcssHobGuid); /// /// Install SEG SSDT table only if Multiple Segment is enabled /// if (TcssHob != NULL) { if (TcssHob->TcssData.PcieMultipleSegmentEnabled) { Status = InstallSsdtAcpiTable (gSegSsdtAcpiTableStorageGuid, SIGNATURE_64 ('S','e','g','S','s','d','t',0)); ASSERT_EFI_ERROR (Status); } /// /// Install TCSS SSDT Table /// Status = InstallSsdtAcpiTable (gTcssSsdtAcpiTableStorageGuid, SIGNATURE_64 ('T','c','s','s','S','s','d','t')); ASSERT_EFI_ERROR (Status); /// /// Update TCSS NVS AREA tables /// UpdateTcssNVS(); } } #endif /// /// Install IPU SSDT if IPU is present. /// if (PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, IPU_BUS_NUM, IPU_DEV_NUM, IPU_FUN_NUM, 0)) != V_SA_DEVICE_ID_INVALID) { Status = InstallSsdtAcpiTable (gIpuAcpiTableStorageGuid, SIGNATURE_64 ('I','p','u','S','s','d','t',0)); ASSERT_EFI_ERROR (Status); /// /// Update IPU NVS AREA tables /// UpdateIpuNvs(); } DEBUG ((DEBUG_INFO, "Initializing Hybrid Graphics (Dxe)\n")); #if FixedPcdGetBool(PcdHgEnable) == 1 DxeHybridGraphicsInit(); #endif return EFI_SUCCESS; }