From: Jiewen Yao Date: Thu, 21 Sep 2017 07:07:50 +0000 (+0800) Subject: IntelSiliconPkg/VtdPeiSample: Add premem support. X-Git-Tag: edk2-stable201903~3158 X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=commitdiff_plain;h=af807bb98682d0b11dc37188d80fb70687ae2512 IntelSiliconPkg/VtdPeiSample: Add premem support. Before memory is ready, this sample produces one VTd engine. After memory and silicon is initialized, this sample produces both IGD VTd engine and all-rest VTd engine by reinstall the FV_INFO_PPI. This update is to demonstrate how to support pre-mem VTd usage. Cc: Star Zeng Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Jiewen Yao Reviewed-by: Star Zeng --- diff --git a/IntelSiliconPkg/Feature/VTd/PlatformVTdInfoSamplePei/PlatformVTdInfoSamplePei.c b/IntelSiliconPkg/Feature/VTd/PlatformVTdInfoSamplePei/PlatformVTdInfoSamplePei.c index 6267da7233..852dc0e500 100644 --- a/IntelSiliconPkg/Feature/VTd/PlatformVTdInfoSamplePei/PlatformVTdInfoSamplePei.c +++ b/IntelSiliconPkg/Feature/VTd/PlatformVTdInfoSamplePei/PlatformVTdInfoSamplePei.c @@ -20,6 +20,7 @@ #include #include #include +#include #define R_SA_MCHBAR (0x48) #define R_SA_GGC (0x50) @@ -33,6 +34,8 @@ #define R_SA_MCHBAR_VTD1_OFFSET 0x5400 ///< HW UNIT for IGD #define R_SA_MCHBAR_VTD2_OFFSET 0x5410 ///< HW UNIT for all other - PEG, USB, SATA etc +EFI_GUID gEdkiiSiliconInitializedPpiGuid = {0x82a72dc8, 0x61ec, 0x403e, {0xb1, 0x5a, 0x8d, 0x7a, 0x3a, 0x71, 0x84, 0x98}}; + typedef struct { EFI_ACPI_DMAR_HEADER DmarHeader; // @@ -131,50 +134,188 @@ EFI_PEI_PPI_DESCRIPTOR mPlatformVTdInfoSampleDesc = { &mPlatformVTdSample }; +typedef struct { + EFI_ACPI_DMAR_HEADER DmarHeader; + // + // VTd engine 2 - all rest + // + EFI_ACPI_DMAR_DRHD_HEADER Drhd2; +} MY_VTD_INFO_NO_IGD_PPI; + +MY_VTD_INFO_NO_IGD_PPI mPlatformVTdNoIgdSample = { + { // DmarHeader + { // Header + EFI_ACPI_4_0_DMA_REMAPPING_TABLE_SIGNATURE, + sizeof(MY_VTD_INFO_NO_IGD_PPI), + EFI_ACPI_DMAR_REVISION, + }, + 0x26, // HostAddressWidth + }, + + { // Drhd2 + { // Header + EFI_ACPI_DMAR_TYPE_DRHD, + sizeof(EFI_ACPI_DMAR_DRHD_HEADER) + }, + EFI_ACPI_DMAR_DRHD_FLAGS_INCLUDE_PCI_ALL, // Flags + 0, // Reserved + 0, // SegmentNumber + 0xFED91000 // RegisterBaseAddress -- TO BE PATCHED + }, +}; + +EFI_PEI_PPI_DESCRIPTOR mPlatformVTdNoIgdInfoSampleDesc = { + (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gEdkiiVTdInfoPpiGuid, + &mPlatformVTdNoIgdSample +}; + /** - Patch Graphic UMA address in RMRR and base address. + Initialize VTd register. **/ VOID -PatchDmar ( +InitDmar ( VOID ) { UINT32 MchBar; - UINT16 IgdMode; - UINT16 GttMode; - UINT32 IgdMemSize; - UINT32 GttMemSize; - - /// - /// Calculate IGD memsize - /// - IgdMode = ((PciRead16 (PCI_LIB_ADDRESS(0, 0, 0, R_SA_GGC)) & B_SKL_SA_GGC_GMS_MASK) >> N_SKL_SA_GGC_GMS_OFFSET) & 0xFF; - if (IgdMode < 0xF0) { - IgdMemSize = IgdMode * 32 * (1024) * (1024); + + DEBUG ((DEBUG_INFO, "InitDmar\n")); + + MchBar = PciRead32 (PCI_LIB_ADDRESS(0, 0, 0, R_SA_MCHBAR)) & ~BIT0; + PciWrite32 (PCI_LIB_ADDRESS(0, 0, 0, R_SA_MCHBAR), 0xFED10000 | BIT0); + DEBUG ((DEBUG_INFO, "MchBar - %x\n", MchBar)); + + MmioWrite32 (MchBar + R_SA_MCHBAR_VTD2_OFFSET, (UINT32)mPlatformVTdSample.Drhd2.RegisterBaseAddress | 1); + DEBUG ((DEBUG_INFO, "VTd2 - %x\n", (MmioRead32 (MchBar + R_SA_MCHBAR_VTD2_OFFSET)))); +} + +/** + Patch Graphic UMA address in RMRR and base address. +**/ +EFI_PEI_PPI_DESCRIPTOR * +PatchDmar ( + VOID + ) +{ + UINT32 MchBar; + UINT16 IgdMode; + UINT16 GttMode; + UINT32 IgdMemSize; + UINT32 GttMemSize; + MY_VTD_INFO_PPI *PlatformVTdSample; + EFI_PEI_PPI_DESCRIPTOR *PlatformVTdInfoSampleDesc; + MY_VTD_INFO_NO_IGD_PPI *PlatformVTdNoIgdSample; + EFI_PEI_PPI_DESCRIPTOR *PlatformVTdNoIgdInfoSampleDesc; + + DEBUG ((DEBUG_INFO, "PatchDmar\n")); + + if (PciRead16 (PCI_LIB_ADDRESS(0, 2, 0, 0)) != 0xFFFF) { + PlatformVTdSample = AllocateCopyPool (sizeof(MY_VTD_INFO_PPI), &mPlatformVTdSample); + ASSERT(PlatformVTdSample != NULL); + PlatformVTdInfoSampleDesc = AllocateCopyPool (sizeof(EFI_PEI_PPI_DESCRIPTOR), &mPlatformVTdInfoSampleDesc); + ASSERT(PlatformVTdInfoSampleDesc != NULL); + PlatformVTdInfoSampleDesc->Ppi = PlatformVTdSample; + + /// + /// Calculate IGD memsize + /// + IgdMode = ((PciRead16 (PCI_LIB_ADDRESS(0, 0, 0, R_SA_GGC)) & B_SKL_SA_GGC_GMS_MASK) >> N_SKL_SA_GGC_GMS_OFFSET) & 0xFF; + if (IgdMode < 0xF0) { + IgdMemSize = IgdMode * 32 * (1024) * (1024); + } else { + IgdMemSize = 4 * (IgdMode - 0xF0 + 1) * (1024) * (1024); + } + + /// + /// Calculate GTT mem size + /// + GttMemSize = 0; + GttMode = (PciRead16 (PCI_LIB_ADDRESS(0, 0, 0, R_SA_GGC)) & B_SKL_SA_GGC_GGMS_MASK) >> N_SKL_SA_GGC_GGMS_OFFSET; + if (GttMode <= V_SKL_SA_GGC_GGMS_8MB) { + GttMemSize = (1 << GttMode) * (1024) * (1024); + } + + PlatformVTdSample->Rmrr1.ReservedMemoryRegionBaseAddress = (PciRead32 (PCI_LIB_ADDRESS(0, 0, 0, R_SA_TOLUD)) & ~(0x01)) - IgdMemSize - GttMemSize; + PlatformVTdSample->Rmrr1.ReservedMemoryRegionLimitAddress = PlatformVTdSample->Rmrr1.ReservedMemoryRegionBaseAddress + IgdMemSize + GttMemSize - 1; + + /// + /// Update DRHD structures of DmarTable + /// + MchBar = PciRead32 (PCI_LIB_ADDRESS(0, 0, 0, R_SA_MCHBAR)) & ~BIT0; + + if ((MmioRead32 (MchBar + R_SA_MCHBAR_VTD1_OFFSET) &~1) != 0) { + PlatformVTdSample->Drhd1.RegisterBaseAddress = (MmioRead32 (MchBar + R_SA_MCHBAR_VTD1_OFFSET) &~1); + } else { + MmioWrite32 (MchBar + R_SA_MCHBAR_VTD1_OFFSET, (UINT32)PlatformVTdSample->Drhd1.RegisterBaseAddress | 1); + } + DEBUG ((DEBUG_INFO, "VTd1 - %x\n", (MmioRead32 (MchBar + R_SA_MCHBAR_VTD1_OFFSET)))); + + if ((MmioRead32 (MchBar + R_SA_MCHBAR_VTD2_OFFSET) &~1) != 0) { + PlatformVTdSample->Drhd2.RegisterBaseAddress = (MmioRead32 (MchBar + R_SA_MCHBAR_VTD2_OFFSET) &~1); + } else { + MmioWrite32 (MchBar + R_SA_MCHBAR_VTD2_OFFSET, (UINT32)PlatformVTdSample->Drhd2.RegisterBaseAddress | 1); + } + DEBUG ((DEBUG_INFO, "VTd2 - %x\n", (MmioRead32 (MchBar + R_SA_MCHBAR_VTD2_OFFSET)))); + + return PlatformVTdInfoSampleDesc; } else { - IgdMemSize = 4 * (IgdMode - 0xF0 + 1) * (1024) * (1024); - } + PlatformVTdNoIgdSample = AllocateCopyPool (sizeof(MY_VTD_INFO_NO_IGD_PPI), &mPlatformVTdNoIgdSample); + ASSERT(PlatformVTdNoIgdSample != NULL); + PlatformVTdNoIgdInfoSampleDesc = AllocateCopyPool (sizeof(EFI_PEI_PPI_DESCRIPTOR), &mPlatformVTdNoIgdInfoSampleDesc); + ASSERT(PlatformVTdNoIgdInfoSampleDesc != NULL); + PlatformVTdNoIgdInfoSampleDesc->Ppi = PlatformVTdNoIgdSample; + + /// + /// Update DRHD structures of DmarTable + /// + MchBar = PciRead32 (PCI_LIB_ADDRESS(0, 0, 0, R_SA_MCHBAR)) & ~BIT0; - /// - /// Calculate GTT mem size - /// - GttMemSize = 0; - GttMode = (PciRead16 (PCI_LIB_ADDRESS(0, 0, 0, R_SA_GGC)) & B_SKL_SA_GGC_GGMS_MASK) >> N_SKL_SA_GGC_GGMS_OFFSET; - if (GttMode <= V_SKL_SA_GGC_GGMS_8MB) { - GttMemSize = (1 << GttMode) * (1024) * (1024); + if ((MmioRead32 (MchBar + R_SA_MCHBAR_VTD2_OFFSET) &~1) != 0) { + PlatformVTdNoIgdSample->Drhd2.RegisterBaseAddress = (MmioRead32 (MchBar + R_SA_MCHBAR_VTD2_OFFSET) &~1); + } else { + MmioWrite32 (MchBar + R_SA_MCHBAR_VTD2_OFFSET, (UINT32)PlatformVTdNoIgdSample->Drhd2.RegisterBaseAddress | 1); + } + DEBUG ((DEBUG_INFO, "VTd2 - %x\n", (MmioRead32 (MchBar + R_SA_MCHBAR_VTD2_OFFSET)))); + + return PlatformVTdNoIgdInfoSampleDesc; } +} - mPlatformVTdSample.Rmrr1.ReservedMemoryRegionBaseAddress = (PciRead32 (PCI_LIB_ADDRESS(0, 0, 0, R_SA_TOLUD)) & ~(0x01)) - IgdMemSize - GttMemSize; - mPlatformVTdSample.Rmrr1.ReservedMemoryRegionLimitAddress = mPlatformVTdSample.Rmrr1.ReservedMemoryRegionBaseAddress + IgdMemSize + GttMemSize - 1; +/** + The callback function for SiliconInitializedPpi. + It reinstalls VTD_INFO_PPI. - /// - /// Update DRHD structures of DmarTable - /// - MchBar = PciRead32 (PCI_LIB_ADDRESS(0, 0, 0, R_SA_MCHBAR)) & ~BIT0; - mPlatformVTdSample.Drhd1.RegisterBaseAddress = (MmioRead32 (MchBar + R_SA_MCHBAR_VTD1_OFFSET) &~1); - mPlatformVTdSample.Drhd2.RegisterBaseAddress = (MmioRead32 (MchBar + R_SA_MCHBAR_VTD2_OFFSET) &~1); + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] NotifyDescriptor Notify that this module published. + @param[in] Ppi PPI that was installed. + + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +EFIAPI +SiliconInitializedPpiNotifyCallback ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, + IN VOID *Ppi + ) +{ + EFI_STATUS Status; + EFI_PEI_PPI_DESCRIPTOR *PpiDesc; + + PpiDesc = PatchDmar (); + + Status = PeiServicesReInstallPpi (&mPlatformVTdNoIgdInfoSampleDesc, PpiDesc); + ASSERT_EFI_ERROR (Status); + return EFI_SUCCESS; } +EFI_PEI_NOTIFY_DESCRIPTOR mSiliconInitializedNotifyList = { + (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gEdkiiSiliconInitializedPpiGuid, + (EFI_PEIM_NOTIFY_ENTRY_POINT) SiliconInitializedPpiNotifyCallback +}; + /** Platform VTd Info sample driver. @@ -190,12 +331,37 @@ PlatformVTdInfoSampleInitialize ( IN CONST EFI_PEI_SERVICES **PeiServices ) { - EFI_STATUS Status; + EFI_STATUS Status; + BOOLEAN SiliconInitialized; + VOID *SiliconInitializedPpi; + EFI_PEI_PPI_DESCRIPTOR *PpiDesc; + + SiliconInitialized = FALSE; + // + // Check if silicon is initialized. + // + Status = PeiServicesLocatePpi ( + &gEdkiiSiliconInitializedPpiGuid, + 0, + NULL, + &SiliconInitializedPpi + ); + if (!EFI_ERROR(Status)) { + SiliconInitialized = TRUE; + } + DEBUG ((DEBUG_INFO, "SiliconInitialized - %x\n", SiliconInitialized)); + if (!SiliconInitialized) { + Status = PeiServicesNotifyPpi (&mSiliconInitializedNotifyList); + InitDmar (); - PatchDmar (); + Status = PeiServicesInstallPpi (&mPlatformVTdNoIgdInfoSampleDesc); + ASSERT_EFI_ERROR (Status); + } else { + PpiDesc = PatchDmar (); - Status = PeiServicesInstallPpi (&mPlatformVTdInfoSampleDesc); - ASSERT_EFI_ERROR (Status); + Status = PeiServicesInstallPpi (PpiDesc); + ASSERT_EFI_ERROR (Status); + } return Status; } diff --git a/IntelSiliconPkg/Feature/VTd/PlatformVTdInfoSamplePei/PlatformVTdInfoSamplePei.inf b/IntelSiliconPkg/Feature/VTd/PlatformVTdInfoSamplePei/PlatformVTdInfoSamplePei.inf index 96adb70edc..a4ffe51e2f 100644 --- a/IntelSiliconPkg/Feature/VTd/PlatformVTdInfoSamplePei/PlatformVTdInfoSamplePei.inf +++ b/IntelSiliconPkg/Feature/VTd/PlatformVTdInfoSamplePei/PlatformVTdInfoSamplePei.inf @@ -47,7 +47,7 @@ gEdkiiVTdInfoPpiGuid ## PRODUCES [Depex] - gEfiPeiMemoryDiscoveredPpiGuid + gEfiPeiMasterBootModePpiGuid [UserExtensions.TianoCore."ExtraFiles"] PlatformVTdInfoSamplePeiExtra.uni