From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id ADC6321D0A261 for ; Sun, 13 Aug 2017 21:14:08 -0700 (PDT) Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by orsmga101.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 13 Aug 2017 21:16:31 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.41,372,1498546800"; d="scan'208";a="299729991" Received: from fmsmsx105.amr.corp.intel.com ([10.18.124.203]) by fmsmga004.fm.intel.com with ESMTP; 13 Aug 2017 21:16:31 -0700 Received: from fmsmsx151.amr.corp.intel.com (10.18.125.4) by FMSMSX105.amr.corp.intel.com (10.18.124.203) with Microsoft SMTP Server (TLS) id 14.3.319.2; Sun, 13 Aug 2017 21:16:31 -0700 Received: from shsmsx152.ccr.corp.intel.com (10.239.6.52) by FMSMSX151.amr.corp.intel.com (10.18.125.4) with Microsoft SMTP Server (TLS) id 14.3.319.2; Sun, 13 Aug 2017 21:16:30 -0700 Received: from shsmsx102.ccr.corp.intel.com ([169.254.2.183]) by SHSMSX152.ccr.corp.intel.com ([169.254.6.135]) with mapi id 14.03.0319.002; Mon, 14 Aug 2017 12:16:29 +0800 From: "Yao, Jiewen" To: "Zeng, Star" , "edk2-devel@lists.01.org" Thread-Topic: [PATCH V2 2/2] IntelSiliconPkg/IntelVTdDxe: Improve performance. Thread-Index: AQHTFLDWCz5clh/SukCUIIyjnvi2AKKDPsag Date: Mon, 14 Aug 2017 04:16:28 +0000 Message-ID: <74D8A39837DF1E4DA445A8C0B3885C503A990951@shsmsx102.ccr.corp.intel.com> References: <1502463267-5056-1-git-send-email-jiewen.yao@intel.com> <1502463267-5056-3-git-send-email-jiewen.yao@intel.com> <0C09AFA07DD0434D9E2A0C6AEB0483103B918992@shsmsx102.ccr.corp.intel.com> In-Reply-To: <0C09AFA07DD0434D9E2A0C6AEB0483103B918992@shsmsx102.ccr.corp.intel.com> Accept-Language: zh-CN, en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: dlp-product: dlpe-windows dlp-version: 10.0.102.7 dlp-reaction: no-action x-originating-ip: [10.239.127.40] MIME-Version: 1.0 Subject: Re: [PATCH V2 2/2] IntelSiliconPkg/IntelVTdDxe: Improve performance. X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 14 Aug 2017 04:14:08 -0000 Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Thanks. I will update that. > -----Original Message----- > From: Zeng, Star > Sent: Monday, August 14, 2017 11:53 AM > To: Yao, Jiewen ; edk2-devel@lists.01.org > Cc: Zeng, Star > Subject: RE: [PATCH V2 2/2] IntelSiliconPkg/IntelVTdDxe: Improve performa= nce. >=20 > Two minor comments, others are good to me. Reviewed-by: Star Zeng > >=20 > 1. In commit log, add WriteBackDataCacheRange() and remove duplicated "to= "? > CLFLUSH is used to to only flush the context table or second level page t= able if > they are changed. > -> > CLFLUSH by WriteBackDataCacheRange() is used to only flush the context ta= ble > or second level page table if they are changed. >=20 > 2. PERF_CODE can be used. >=20 > PERF_CODE_BEGIN(); > AsciiSPrint (PerfToken, sizeof(PerfToken), > "VTD(S%04x.B%02x.D%02x.F%02x)", Segment, SourceId.Bits.Bus, > SourceId.Bits.Device, SourceId.Bits.Function); > PERF_START (gImageHandle, PerfToken, "IntelVTD", 0); > PERF_CODE_END(); >=20 > -> >=20 > PERF_CODE ( > AsciiSPrint (PerfToken, sizeof(PerfToken), > "VTD(S%04x.B%02x.D%02x.F%02x)", Segment, SourceId.Bits.Bus, > SourceId.Bits.Device, SourceId.Bits.Function); > PERF_START (gImageHandle, PerfToken, "IntelVTD", 0); > ); >=20 >=20 > Thanks, > Star > -----Original Message----- > From: Yao, Jiewen > Sent: Friday, August 11, 2017 10:54 PM > To: edk2-devel@lists.01.org > Cc: Zeng, Star > Subject: [PATCH V2 2/2] IntelSiliconPkg/IntelVTdDxe: Improve performance. >=20 > This patch is to improve IOMMU performance. > All WBINVD is removed due to performance issue. > CLFLUSH is used to to only flush the context table or second level page t= able if > they are changed. >=20 > This patch also removed some unused functions. >=20 > Cc: Star Zeng > Contributed-under: TianoCore Contribution Agreement 1.0 > Signed-off-by: Jiewen Yao > --- > IntelSiliconPkg/IntelVTdDxe/DmaProtection.h | 57 ++--- > IntelSiliconPkg/IntelVTdDxe/IntelVTdDxe.c | 10 + > IntelSiliconPkg/IntelVTdDxe/IntelVTdDxe.inf | 3 + > IntelSiliconPkg/IntelVTdDxe/PciInfo.c | 12 + > IntelSiliconPkg/IntelVTdDxe/TranslationTable.c | 58 ++++- > IntelSiliconPkg/IntelVTdDxe/TranslationTableEx.c | 2 + > IntelSiliconPkg/IntelVTdDxe/VtdReg.c | 260 +++++++----------= --- > 7 files changed, 186 insertions(+), 216 deletions(-) >=20 > diff --git a/IntelSiliconPkg/IntelVTdDxe/DmaProtection.h > b/IntelSiliconPkg/IntelVTdDxe/DmaProtection.h > index 8cfa69c..c3b57a0 100644 > --- a/IntelSiliconPkg/IntelVTdDxe/DmaProtection.h > +++ b/IntelSiliconPkg/IntelVTdDxe/DmaProtection.h > @@ -25,6 +25,9 @@ > #include > #include > #include > +#include #include > + #include >=20 > #include > #include > @@ -58,6 +61,8 @@ typedef struct { > UINTN PciDescriptorMaxNumber; > BOOLEAN *IsRealPciDevice; > VTD_SOURCE_ID *PciDescriptors; > + // for statistic analysis > + UINTN *AccessCount; > } PCI_DEVICE_INFORMATION; >=20 > typedef struct { > @@ -68,6 +73,7 @@ typedef struct { > VTD_ROOT_ENTRY *RootEntryTable; > VTD_EXT_ROOT_ENTRY *ExtRootEntryTable; > VTD_SECOND_LEVEL_PAGING_ENTRY *FixedSecondLevelPagingEntry; > + BOOLEAN HasDirtyContext; > BOOLEAN HasDirtyPages; > PCI_DEVICE_INFORMATION PciDeviceInfo; > } VTD_UNIT_INFORMATION; > @@ -125,40 +131,6 @@ DisableDmar ( > ); >=20 > /** > - Invalid VTd IOTLB page. > - > - @param[in] VtdIndex The index of VTd engine. > - @param[in] Address The address of IOTLB page. > - @param[in] AddressMode The address mode of IOTLB page. > - @param[in] DomainIdentifier The domain ID of the source. > - > - @retval EFI_SUCCESS VTd IOTLB page is invalidated. > - @retval EFI_DEVICE_ERROR VTd IOTLB page is not invalidated. > -**/ > -EFI_STATUS > -InvalidateVtdIOTLBPage ( > - IN UINTN VtdIndex, > - IN UINT64 Address, > - IN UINT8 AddressMode, > - IN UINT16 DomainIdentifier > - ); > - > -/** > - Invalid VTd IOTLB domain. > - > - @param[in] VtdIndex The index of VTd engine. > - @param[in] DomainIdentifier The domain ID of the source. > - > - @retval EFI_SUCCESS VTd IOTLB domain is invalidated. > - @retval EFI_DEVICE_ERROR VTd IOTLB domain is not invalidated. > -**/ > -EFI_STATUS > -InvalidateVtdIOTLBDomain ( > - IN UINTN VtdIndex, > - IN UINT16 DomainIdentifier > - ); > - > -/** > Invalid VTd global IOTLB. >=20 > @param[in] VtdIndex The index of VTd engine. > @@ -362,6 +334,7 @@ DumpSecondLevelPagingEntry ( EFI_STATUS > SetPageAttribute ( > IN UINTN VtdIndex, > + IN UINT16 DomainIdentifier, > IN VTD_SECOND_LEVEL_PAGING_ENTRY *SecondLevelPagingEntry, > IN UINT64 BaseAddress, > IN UINT64 Length, > @@ -500,4 +473,20 @@ AllocateZeroPages ( > IN UINTN Pages > ); >=20 > +/** > + Flush VTD page table and context table memory. > + > + This action is to make sure the IOMMU engine can get final data in mem= ory. > + > + @param[in] VtdIndex The index used to identify a VTd engine. > + @param[in] Base The base address of memory to be > flushed. > + @param[in] Size The size of memory in bytes to be flushe= d. > +**/ > +VOID > +FlushPageTableMemory ( > + IN UINTN VtdIndex, > + IN UINTN Base, > + IN UINTN Size > + ); > + > #endif > diff --git a/IntelSiliconPkg/IntelVTdDxe/IntelVTdDxe.c > b/IntelSiliconPkg/IntelVTdDxe/IntelVTdDxe.c > index d22222d..7feaaf5 100644 > --- a/IntelSiliconPkg/IntelVTdDxe/IntelVTdDxe.c > +++ b/IntelSiliconPkg/IntelVTdDxe/IntelVTdDxe.c > @@ -227,6 +227,7 @@ VTdSetAttribute ( > EFI_STATUS Status; > UINT16 Segment; > VTD_SOURCE_ID SourceId; > + CHAR8 PerfToken[sizeof("VTD(S0000.B00.D00.F00)")]; >=20 > DumpVtdIfError (); >=20 > @@ -239,8 +240,17 @@ VTdSetAttribute ( > DEBUG ((DEBUG_VERBOSE, "PCI(S%x.B%x.D%x.F%x) ", Segment, > SourceId.Bits.Bus, SourceId.Bits.Device, SourceId.Bits.Function)); > DEBUG ((DEBUG_VERBOSE, "(0x%lx~0x%lx) - %lx\n", DeviceAddress, Length, > IoMmuAccess)); >=20 > + PERF_CODE_BEGIN(); > + AsciiSPrint (PerfToken, sizeof(PerfToken), > "VTD(S%04x.B%02x.D%02x.F%02x)", Segment, SourceId.Bits.Bus, > SourceId.Bits.Device, SourceId.Bits.Function); > + PERF_START (gImageHandle, PerfToken, "IntelVTD", 0); > + PERF_CODE_END(); > + > Status =3D SetAccessAttribute (Segment, SourceId, DeviceAddress, Lengt= h, > IoMmuAccess); >=20 > + PERF_CODE_BEGIN(); > + PERF_END (gImageHandle, PerfToken, "IntelVTD", 0); > + PERF_CODE_END(); > + > return Status; > } >=20 > diff --git a/IntelSiliconPkg/IntelVTdDxe/IntelVTdDxe.inf > b/IntelSiliconPkg/IntelVTdDxe/IntelVTdDxe.inf > index 6a61c13..697932e 100644 > --- a/IntelSiliconPkg/IntelVTdDxe/IntelVTdDxe.inf > +++ b/IntelSiliconPkg/IntelVTdDxe/IntelVTdDxe.inf > @@ -57,6 +57,9 @@ > BaseMemoryLib > MemoryAllocationLib > UefiLib > + CacheMaintenanceLib > + PerformanceLib > + PrintLib >=20 > [Guids] > gEfiEventExitBootServicesGuid ## CONSUMES ## Event > diff --git a/IntelSiliconPkg/IntelVTdDxe/PciInfo.c > b/IntelSiliconPkg/IntelVTdDxe/PciInfo.c > index d5f096f..27e253d 100644 > --- a/IntelSiliconPkg/IntelVTdDxe/PciInfo.c > +++ b/IntelSiliconPkg/IntelVTdDxe/PciInfo.c > @@ -77,6 +77,7 @@ RegisterPciDevice ( > UINTN Index; > BOOLEAN *NewIsRealPciDevice; > VTD_SOURCE_ID *NewPciDescriptors; > + UINTN *NewAccessCount; >=20 > PciDeviceInfo =3D &mVtdUnitInformation[VtdIndex].PciDeviceInfo; >=20 > @@ -112,6 +113,12 @@ RegisterPciDevice ( > FreePool (NewIsRealPciDevice); > return EFI_OUT_OF_RESOURCES; > } > + NewAccessCount =3D AllocateZeroPool (sizeof(*NewAccessCount) * > (PciDeviceInfo->PciDescriptorMaxNumber + MAX_PCI_DESCRIPTORS)); > + if (NewAccessCount =3D=3D NULL) { > + FreePool (NewIsRealPciDevice); > + FreePool (NewPciDescriptors); > + return EFI_OUT_OF_RESOURCES; > + } > PciDeviceInfo->PciDescriptorMaxNumber +=3D MAX_PCI_DESCRIPTORS; > if (PciDeviceInfo->IsRealPciDevice !=3D NULL) { > CopyMem (NewIsRealPciDevice, PciDeviceInfo->IsRealPciDevice, > sizeof(*NewIsRealPciDevice) * PciDeviceInfo->PciDescriptorNumber); > @@ -123,6 +130,11 @@ RegisterPciDevice ( > FreePool (PciDeviceInfo->PciDescriptors); > } > PciDeviceInfo->PciDescriptors =3D NewPciDescriptors; > + if (PciDeviceInfo->AccessCount !=3D NULL) { > + CopyMem (NewAccessCount, PciDeviceInfo->AccessCount, > sizeof(*NewAccessCount) * PciDeviceInfo->PciDescriptorNumber); > + FreePool (PciDeviceInfo->AccessCount); > + } > + PciDeviceInfo->AccessCount =3D NewAccessCount; > } >=20 > ASSERT (PciDeviceInfo->PciDescriptorNumber < > PciDeviceInfo->PciDescriptorMaxNumber); > diff --git a/IntelSiliconPkg/IntelVTdDxe/TranslationTable.c > b/IntelSiliconPkg/IntelVTdDxe/TranslationTable.c > index 961d7ca..80fc823 100644 > --- a/IntelSiliconPkg/IntelVTdDxe/TranslationTable.c > +++ b/IntelSiliconPkg/IntelVTdDxe/TranslationTable.c > @@ -124,6 +124,7 @@ CreateContextEntry ( > RootEntry->Bits.ContextTablePointerHi =3D (UINT32) RShiftU64 > ((UINT64)(UINTN)Buffer, 32); > RootEntry->Bits.Present =3D 1; > Buffer =3D (UINT8 *)Buffer + EFI_PAGES_TO_SIZE (ContextPages); > + FlushPageTableMemory (VtdIndex, (UINTN)RootEntry, > + sizeof(*RootEntry)); > } >=20 > ContextEntryTable =3D (VTD_CONTEXT_ENTRY > *)(UINTN)VTD_64BITS_ADDRESS(RootEntry->Bits.ContextTablePointerLo, > RootEntry->Bits.ContextTablePointerHi) ; @@ -142,6 +143,7 @@ > CreateContextEntry ( > ContextEntry->Bits.AddressWidth =3D 0x2; > break; > } > + FlushPageTableMemory (VtdIndex, (UINTN)ContextEntry, > + sizeof(*ContextEntry)); > } >=20 > return EFI_SUCCESS; > @@ -250,8 +252,11 @@ CreateSecondLevelPagingEntryTable ( > goto Done; > } > } > + FlushPageTableMemory (VtdIndex, (UINTN)Lvl2PtEntry, SIZE_4KB); > } > + FlushPageTableMemory (VtdIndex, (UINTN)&Lvl3PtEntry[Lvl3Start], > + (UINTN)&Lvl3PtEntry[Lvl3End + 1] - (UINTN)&Lvl3PtEntry[Lvl3Start]); > } > + FlushPageTableMemory (VtdIndex, (UINTN)&Lvl4PtEntry[Lvl4Start], > + (UINTN)&Lvl4PtEntry[Lvl4End + 1] - (UINTN)&Lvl4PtEntry[Lvl4Start]); >=20 > Done: > return SecondLevelPagingEntry; > @@ -429,9 +434,10 @@ InvalidatePageEntry ( > IN UINTN VtdIndex > ) > { > - if (mVtdUnitInformation[VtdIndex].HasDirtyPages) { > + if (mVtdUnitInformation[VtdIndex].HasDirtyContext || > + mVtdUnitInformation[VtdIndex].HasDirtyPages) { > InvalidateVtdIOTLBGlobal (VtdIndex); > } > + mVtdUnitInformation[VtdIndex].HasDirtyContext =3D FALSE; > mVtdUnitInformation[VtdIndex].HasDirtyPages =3D FALSE; } >=20 > @@ -498,6 +504,7 @@ PageAttributeToLength ( > /** > Return page table entry to match the address. >=20 > + @param[in] VtdIndex The index used to identify a VTd > engine. > @param[in] SecondLevelPagingEntry The second level paging entry in > VTd table for the device. > @param[in] Address The address to be checked. > @param[out] PageAttributes The page attribute of the page > entry. > @@ -506,6 +513,7 @@ PageAttributeToLength ( **/ VOID * > GetSecondLevelPageTableEntry ( > + IN UINTN VtdIndex, > IN VTD_SECOND_LEVEL_PAGING_ENTRY *SecondLevelPagingEntry, > IN PHYSICAL_ADDRESS Address, > OUT PAGE_ATTRIBUTE *PageAttribute > @@ -535,6 +543,7 @@ GetSecondLevelPageTableEntry ( > return NULL; > } > SetSecondLevelPagingEntryAttribute > ((VTD_SECOND_LEVEL_PAGING_ENTRY *)&L4PageTable[Index4], > EDKII_IOMMU_ACCESS_READ | EDKII_IOMMU_ACCESS_WRITE); > + FlushPageTableMemory (VtdIndex, (UINTN)&L4PageTable[Index4], > + sizeof(L4PageTable[Index4])); > } >=20 > L3PageTable =3D (UINT64 *)(UINTN)(L4PageTable[Index4] & > PAGING_4K_ADDRESS_MASK_64); @@ -547,6 +556,7 @@ > GetSecondLevelPageTableEntry ( > return NULL; > } > SetSecondLevelPagingEntryAttribute > ((VTD_SECOND_LEVEL_PAGING_ENTRY *)&L3PageTable[Index3], > EDKII_IOMMU_ACCESS_READ | EDKII_IOMMU_ACCESS_WRITE); > + FlushPageTableMemory (VtdIndex, (UINTN)&L3PageTable[Index3], > + sizeof(L3PageTable[Index3])); > } > if ((L3PageTable[Index3] & VTD_PG_PS) !=3D 0) { > // 1G > @@ -559,6 +569,7 @@ GetSecondLevelPageTableEntry ( > L2PageTable[Index2] =3D Address & PAGING_2M_ADDRESS_MASK_64; > SetSecondLevelPagingEntryAttribute > ((VTD_SECOND_LEVEL_PAGING_ENTRY *)&L2PageTable[Index2], 0); > L2PageTable[Index2] |=3D VTD_PG_PS; > + FlushPageTableMemory (VtdIndex, (UINTN)&L2PageTable[Index2], > + sizeof(L2PageTable[Index2])); > } > if ((L2PageTable[Index2] & VTD_PG_PS) !=3D 0) { > // 2M > @@ -579,12 +590,14 @@ GetSecondLevelPageTableEntry ( > /** > Modify memory attributes of page entry. >=20 > + @param[in] VtdIndex The index used to identify a VTd engine. > @param[in] PageEntry The page entry. > @param[in] IoMmuAccess The IOMMU access. > @param[out] IsModified TRUE means page table modified. FALSE > means page table not modified. > **/ > VOID > ConvertSecondLevelPageEntryAttribute ( > + IN UINTN VtdIndex, > IN VTD_SECOND_LEVEL_PAGING_ENTRY *PageEntry, > IN UINT64 IoMmuAccess, > OUT BOOLEAN *IsModified > @@ -595,6 +608,7 @@ ConvertSecondLevelPageEntryAttribute ( >=20 > CurrentPageEntry =3D PageEntry->Uint64; > SetSecondLevelPagingEntryAttribute (PageEntry, IoMmuAccess); > + FlushPageTableMemory (VtdIndex, (UINTN)PageEntry, > + sizeof(*PageEntry)); > NewPageEntry =3D PageEntry->Uint64; > if (CurrentPageEntry !=3D NewPageEntry) { > *IsModified =3D TRUE; > @@ -639,6 +653,7 @@ NeedSplitPage ( > /** > This function splits one page entry to small page entries. >=20 > + @param[in] VtdIndex The index used to identify a VTd engine. > @param[in] PageEntry The page entry to be splitted. > @param[in] PageAttribute The page attribute of the page entry. > @param[in] SplitAttribute How to split the page entry. > @@ -649,6 +664,7 @@ NeedSplitPage ( > **/ > RETURN_STATUS > SplitSecondLevelPage ( > + IN UINTN VtdIndex, > IN VTD_SECOND_LEVEL_PAGING_ENTRY *PageEntry, > IN PAGE_ATTRIBUTE PageAttribute, > IN PAGE_ATTRIBUTE SplitAttribute > @@ -675,8 +691,11 @@ SplitSecondLevelPage ( > for (Index =3D 0; Index < SIZE_4KB / sizeof(UINT64); Index++) { > NewPageEntry[Index] =3D (BaseAddress + SIZE_4KB * Index) | > (PageEntry->Uint64 & PAGE_PROGATE_BITS); > } > + FlushPageTableMemory (VtdIndex, (UINTN)NewPageEntry, SIZE_4KB); > + > PageEntry->Uint64 =3D (UINT64)(UINTN)NewPageEntry; > SetSecondLevelPagingEntryAttribute (PageEntry, > EDKII_IOMMU_ACCESS_READ | EDKII_IOMMU_ACCESS_WRITE); > + FlushPageTableMemory (VtdIndex, (UINTN)PageEntry, > + sizeof(*PageEntry)); > return RETURN_SUCCESS; > } else { > return RETURN_UNSUPPORTED; > @@ -697,8 +716,11 @@ SplitSecondLevelPage ( > for (Index =3D 0; Index < SIZE_4KB / sizeof(UINT64); Index++) { > NewPageEntry[Index] =3D (BaseAddress + SIZE_2MB * Index) | > VTD_PG_PS | (PageEntry->Uint64 & PAGE_PROGATE_BITS); > } > + FlushPageTableMemory (VtdIndex, (UINTN)NewPageEntry, SIZE_4KB); > + > PageEntry->Uint64 =3D (UINT64)(UINTN)NewPageEntry; > SetSecondLevelPagingEntryAttribute (PageEntry, > EDKII_IOMMU_ACCESS_READ | EDKII_IOMMU_ACCESS_WRITE); > + FlushPageTableMemory (VtdIndex, (UINTN)PageEntry, > + sizeof(*PageEntry)); > return RETURN_SUCCESS; > } else { > return RETURN_UNSUPPORTED; > @@ -730,6 +752,7 @@ SplitSecondLevelPage ( EFI_STATUS > SetSecondLevelPagingAttribute ( > IN UINTN VtdIndex, > + IN UINT16 DomainIdentifier, > IN VTD_SECOND_LEVEL_PAGING_ENTRY *SecondLevelPagingEntry, > IN UINT64 BaseAddress, > IN UINT64 Length, > @@ -756,7 +779,7 @@ SetSecondLevelPagingAttribute ( > } >=20 > while (Length !=3D 0) { > - PageEntry =3D GetSecondLevelPageTableEntry (SecondLevelPagingEntry, > BaseAddress, &PageAttribute); > + PageEntry =3D GetSecondLevelPageTableEntry (VtdIndex, > + SecondLevelPagingEntry, BaseAddress, &PageAttribute); > if (PageEntry =3D=3D NULL) { > DEBUG ((DEBUG_ERROR, "PageEntry - NULL\n")); > return RETURN_UNSUPPORTED; > @@ -764,7 +787,7 @@ SetSecondLevelPagingAttribute ( > PageEntryLength =3D PageAttributeToLength (PageAttribute); > SplitAttribute =3D NeedSplitPage (BaseAddress, Length, PageAttribute= ); > if (SplitAttribute =3D=3D PageNone) { > - ConvertSecondLevelPageEntryAttribute (PageEntry, IoMmuAccess, > &IsEntryModified); > + ConvertSecondLevelPageEntryAttribute (VtdIndex, PageEntry, > + IoMmuAccess, &IsEntryModified); > if (IsEntryModified) { > mVtdUnitInformation[VtdIndex].HasDirtyPages =3D TRUE; > } > @@ -774,7 +797,7 @@ SetSecondLevelPagingAttribute ( > BaseAddress +=3D PageEntryLength; > Length -=3D PageEntryLength; > } else { > - Status =3D SplitSecondLevelPage (PageEntry, PageAttribute, SplitAt= tribute); > + Status =3D SplitSecondLevelPage (VtdIndex, PageEntry, > + PageAttribute, SplitAttribute); > if (RETURN_ERROR (Status)) { > DEBUG ((DEBUG_ERROR, "SplitSecondLevelPage - %r\n", Status)); > return RETURN_UNSUPPORTED; > @@ -787,8 +810,6 @@ SetSecondLevelPagingAttribute ( > } > } >=20 > - InvalidatePageEntry (VtdIndex); > - > return EFI_SUCCESS; > } >=20 > @@ -814,6 +835,7 @@ SetSecondLevelPagingAttribute ( EFI_STATUS > SetPageAttribute ( > IN UINTN VtdIndex, > + IN UINT16 DomainIdentifier, > IN VTD_SECOND_LEVEL_PAGING_ENTRY *SecondLevelPagingEntry, > IN UINT64 BaseAddress, > IN UINT64 Length, > @@ -823,7 +845,7 @@ SetPageAttribute ( > EFI_STATUS Status; > Status =3D EFI_NOT_FOUND; > if (SecondLevelPagingEntry !=3D NULL) { > - Status =3D SetSecondLevelPagingAttribute (VtdIndex, > SecondLevelPagingEntry, BaseAddress, Length, IoMmuAccess); > + Status =3D SetSecondLevelPagingAttribute (VtdIndex, DomainIdentifier= , > + SecondLevelPagingEntry, BaseAddress, Length, IoMmuAccess); > } > return Status; > } > @@ -862,6 +884,8 @@ SetAccessAttribute ( > VTD_CONTEXT_ENTRY *ContextEntry; > VTD_SECOND_LEVEL_PAGING_ENTRY *SecondLevelPagingEntry; > UINT64 Pt; > + UINTN PciDescriptorIndex; > + UINT16 DomainIdentifier; >=20 > SecondLevelPagingEntry =3D NULL; >=20 > @@ -873,6 +897,13 @@ SetAccessAttribute ( > return EFI_DEVICE_ERROR; > } >=20 > + PciDescriptorIndex =3D GetPciDescriptor (VtdIndex, Segment, SourceId); > + mVtdUnitInformation[VtdIndex].PciDeviceInfo.AccessCount[PciDescriptorI > + ndex]++; > + // > + // DomainId should not be 0. > + // > + DomainIdentifier =3D (UINT16)(PciDescriptorIndex + 1); > + > if (ExtContextEntry !=3D NULL) { > if (ExtContextEntry->Bits.Present =3D=3D 0) { > SecondLevelPagingEntry =3D CreateSecondLevelPagingEntry (VtdIndex,= 0); > @@ -881,9 +912,11 @@ SetAccessAttribute ( >=20 > ExtContextEntry->Bits.SecondLevelPageTranslationPointerLo =3D (UIN= T32) > Pt; > ExtContextEntry->Bits.SecondLevelPageTranslationPointerHi =3D (UIN= T32) > RShiftU64(Pt, 20); > - ExtContextEntry->Bits.DomainIdentifier =3D (UINT16) GetPciDescript= or > (VtdIndex, Segment, SourceId); > + ExtContextEntry->Bits.DomainIdentifier =3D DomainIdentifier; > ExtContextEntry->Bits.Present =3D 1; > + FlushPageTableMemory (VtdIndex, (UINTN)ExtContextEntry, > + sizeof(*ExtContextEntry)); > DumpDmarExtContextEntryTable > (mVtdUnitInformation[VtdIndex].ExtRootEntryTable); > + mVtdUnitInformation[VtdIndex].HasDirtyContext =3D TRUE; > } else { > SecondLevelPagingEntry =3D (VOID > *)(UINTN)VTD_64BITS_ADDRESS(ExtContextEntry->Bits.SecondLevelPageTransla > tionPointerLo, ExtContextEntry->Bits.SecondLevelPageTranslationPointerHi)= ; > DEBUG ((DEBUG_VERBOSE,"SecondLevelPagingEntry - 0x%x (S%04x > B%02x D%02x F%02x)\n", SecondLevelPagingEntry, Segment, SourceId.Bits.Bus= , > SourceId.Bits.Device, SourceId.Bits.Function)); @@ -896,9 +929,11 @@ > SetAccessAttribute ( >=20 > ContextEntry->Bits.SecondLevelPageTranslationPointerLo =3D (UINT32= ) Pt; > ContextEntry->Bits.SecondLevelPageTranslationPointerHi =3D (UINT32= ) > RShiftU64(Pt, 20); > - ContextEntry->Bits.DomainIdentifier =3D (UINT16) GetPciDescriptor > (VtdIndex, Segment, SourceId); > + ContextEntry->Bits.DomainIdentifier =3D DomainIdentifier; > ContextEntry->Bits.Present =3D 1; > + FlushPageTableMemory (VtdIndex, (UINTN)ContextEntry, > + sizeof(*ContextEntry)); > DumpDmarContextEntryTable > (mVtdUnitInformation[VtdIndex].RootEntryTable); > + mVtdUnitInformation[VtdIndex].HasDirtyContext =3D TRUE; > } else { > SecondLevelPagingEntry =3D (VOID > *)(UINTN)VTD_64BITS_ADDRESS(ContextEntry->Bits.SecondLevelPageTranslatio > nPointerLo, ContextEntry->Bits.SecondLevelPageTranslationPointerHi); > DEBUG ((DEBUG_VERBOSE,"SecondLevelPagingEntry - 0x%x (S%04x > B%02x D%02x F%02x)\n", SecondLevelPagingEntry, Segment, SourceId.Bits.Bus= , > SourceId.Bits.Device, SourceId.Bits.Function)); @@ -911,6 +946,7 @@ > SetAccessAttribute ( > if (SecondLevelPagingEntry !=3D > mVtdUnitInformation[VtdIndex].FixedSecondLevelPagingEntry) { > Status =3D SetPageAttribute ( > VtdIndex, > + DomainIdentifier, > SecondLevelPagingEntry, > BaseAddress, > Length, > @@ -922,6 +958,8 @@ SetAccessAttribute ( > } > } >=20 > + InvalidatePageEntry (VtdIndex); > + > return EFI_SUCCESS; > } >=20 > @@ -965,11 +1003,13 @@ AlwaysEnablePageAttribute ( > ExtContextEntry->Bits.SecondLevelPageTranslationPointerHi =3D (UINT3= 2) > RShiftU64(Pt, 20); > ExtContextEntry->Bits.DomainIdentifier =3D ((1 << > (UINT8)((UINTN)mVtdUnitInformation[VtdIndex].CapReg.Bits.ND * 2 + 4)) - 1= ); > ExtContextEntry->Bits.Present =3D 1; > + FlushPageTableMemory (VtdIndex, (UINTN)ExtContextEntry, > + sizeof(*ExtContextEntry)); > } else if (ContextEntry !=3D NULL) { > ContextEntry->Bits.SecondLevelPageTranslationPointerLo =3D (UINT32) = Pt; > ContextEntry->Bits.SecondLevelPageTranslationPointerHi =3D (UINT32) > RShiftU64(Pt, 20); > ContextEntry->Bits.DomainIdentifier =3D ((1 << > (UINT8)((UINTN)mVtdUnitInformation[VtdIndex].CapReg.Bits.ND * 2 + 4)) - 1= ); > ContextEntry->Bits.Present =3D 1; > + FlushPageTableMemory (VtdIndex, (UINTN)ContextEntry, > + sizeof(*ContextEntry)); > } >=20 > return EFI_SUCCESS; > diff --git a/IntelSiliconPkg/IntelVTdDxe/TranslationTableEx.c > b/IntelSiliconPkg/IntelVTdDxe/TranslationTableEx.c > index 65ed16e..9d4e6ea 100644 > --- a/IntelSiliconPkg/IntelVTdDxe/TranslationTableEx.c > +++ b/IntelSiliconPkg/IntelVTdDxe/TranslationTableEx.c > @@ -73,6 +73,7 @@ CreateExtContextEntry ( > ExtRootEntry->Bits.UpperContextTablePointerLo =3D (UINT32) RShift= U64 > ((UINT64)(UINTN)Buffer, 12) + 1; > ExtRootEntry->Bits.UpperContextTablePointerHi =3D (UINT32) RShift= U64 > (RShiftU64 ((UINT64)(UINTN)Buffer, 12) + 1, 20); > ExtRootEntry->Bits.UpperPresent =3D 1; > + FlushPageTableMemory (VtdIndex, (UINTN)ExtRootEntry, > + sizeof(*ExtRootEntry)); > Buffer =3D (UINT8 *)Buffer + EFI_PAGES_TO_SIZE (ContextPages); > } >=20 > @@ -92,6 +93,7 @@ CreateExtContextEntry ( > ExtContextEntry->Bits.AddressWidth =3D 0x2; > break; > } > + FlushPageTableMemory (VtdIndex, (UINTN)ExtContextEntry, > + sizeof(*ExtContextEntry)); > } >=20 > return EFI_SUCCESS; > diff --git a/IntelSiliconPkg/IntelVTdDxe/VtdReg.c > b/IntelSiliconPkg/IntelVTdDxe/VtdReg.c > index f36e3de..b1178b7 100644 > --- a/IntelSiliconPkg/IntelVTdDxe/VtdReg.c > +++ b/IntelSiliconPkg/IntelVTdDxe/VtdReg.c > @@ -20,43 +20,62 @@ VTD_UNIT_INFORMATION > *mVtdUnitInformation; > BOOLEAN mVtdEnabled; >=20 > /** > - Invalid VTd global IOTLB. > + Flush VTD page table and context table memory. >=20 > - @param[in] VtdIndex The index of VTd engine. > + This action is to make sure the IOMMU engine can get final data in mem= ory. >=20 > - @retval EFI_SUCCESS VTd global IOTLB is invalidated. > - @retval EFI_DEVICE_ERROR VTd global IOTLB is not invalidated. > + @param[in] VtdIndex The index used to identify a VTd engine. > + @param[in] Base The base address of memory to be > flushed. > + @param[in] Size The size of memory in bytes to be flushe= d. > **/ > -EFI_STATUS > -InvalidateVtdIOTLBGlobal ( > +VOID > +FlushPageTableMemory ( > + IN UINTN VtdIndex, > + IN UINTN Base, > + IN UINTN Size > + ) > +{ > + if (mVtdUnitInformation[VtdIndex].ECapReg.Bits.C =3D=3D 0) { > + WriteBackDataCacheRange ((VOID *)Base, Size); > + } > +} > + > +/** > + Flush VTd engine write buffer. > + > + @param[in] VtdIndex The index used to identify a VTd engine. > +**/ > +VOID > +FlushWriteBuffer ( > IN UINTN VtdIndex > ) > { > - UINT64 Reg64; > UINT32 Reg32; >=20 > - if (!mVtdEnabled) { > - return EFI_SUCCESS; > + if (mVtdUnitInformation[VtdIndex].CapReg.Bits.RWBF !=3D 0) { > + Reg32 =3D MmioRead32 > (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress + R_GSTS_REG); > + MmioWrite32 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress + > R_GCMD_REG, Reg32 | B_GMCD_REG_WBF); > + do { > + Reg32 =3D MmioRead32 > (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress + R_GSTS_REG); > + } while ((Reg32 & B_GSTS_REG_WBF) !=3D 0); > } > +} >=20 > - DEBUG((DEBUG_VERBOSE, "InvalidateVtdIOTLBGlobal(%d)\n", VtdIndex)); > - > - AsmWbinvd(); > +/** > + Invalidate VTd context cache. >=20 > - // > - // Write Buffer Flush before invalidation > - // > - Reg32 =3D MmioRead32 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress > + R_CAP_REG); > - if ((Reg32 & B_CAP_REG_RWBF) !=3D 0) { > - MmioWrite32 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress + > R_GCMD_REG, B_GMCD_REG_WBF); > - } > + @param[in] VtdIndex The index used to identify a VTd engine. > +**/ > +EFI_STATUS > +InvalidateContextCache ( > + IN UINTN VtdIndex > + ) > +{ > + UINT64 Reg64; >=20 > - // > - // Invalidate the context cache > - // > Reg64 =3D MmioRead64 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress > + R_CCMD_REG); > if ((Reg64 & B_CCMD_REG_ICC) !=3D 0) { > - DEBUG ((DEBUG_ERROR,"ERROR: InvalidateVtdIOTLBGlobal: > B_CCMD_REG_ICC is set for VTD(%d)\n",VtdIndex)); > + DEBUG ((DEBUG_ERROR,"ERROR: InvalidateContextCache: > B_CCMD_REG_ICC > + is set for VTD(%d)\n",VtdIndex)); > return EFI_DEVICE_ERROR; > } >=20 > @@ -68,97 +87,29 @@ InvalidateVtdIOTLBGlobal ( > Reg64 =3D MmioRead64 > (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress + R_CCMD_REG); > } while ((Reg64 & B_CCMD_REG_ICC) !=3D 0); >=20 > - // > - // Invalidate the IOTLB cache > - // > - > - Reg64 =3D MmioRead64 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress > + (mVtdUnitInformation[VtdIndex].ECapReg.Bits.IRO * 16) + R_IOTLB_REG); > - if ((Reg64 & B_IOTLB_REG_IVT) !=3D 0) { > - DEBUG ((DEBUG_ERROR,"ERROR: InvalidateVtdIOTLBGlobal: > B_IOTLB_REG_IVT is set for VTD(%d)\n", VtdIndex)); > - return EFI_DEVICE_ERROR; > - } > - > - Reg64 &=3D ((~B_IOTLB_REG_IVT) & (~B_IOTLB_REG_IIRG_MASK)); > - Reg64 |=3D (B_IOTLB_REG_IVT | V_IOTLB_REG_IIRG_GLOBAL); > - MmioWrite64 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress + > (mVtdUnitInformation[VtdIndex].ECapReg.Bits.IRO * 16) + R_IOTLB_REG, > Reg64); > - > - do { > - Reg64 =3D MmioRead64 > (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress + > (mVtdUnitInformation[VtdIndex].ECapReg.Bits.IRO * 16) + R_IOTLB_REG); > - } while ((Reg64 & B_IOTLB_REG_IVT) !=3D 0); > - > - // > - // Disable VTd > - // > - MmioWrite32 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress + > R_GCMD_REG, B_GMCD_REG_SRTP); > - do { > - Reg32 =3D MmioRead32 > (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress + R_GSTS_REG); > - } while((Reg32 & B_GSTS_REG_RTPS) =3D=3D 0); > - > - // > - // Enable VTd > - // > - MmioWrite32 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress + > R_GCMD_REG, B_GMCD_REG_TE); > - do { > - Reg32 =3D MmioRead32 > (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress + R_GSTS_REG); > - } while ((Reg32 & B_GSTS_REG_TE) =3D=3D 0); > - > return EFI_SUCCESS; > } >=20 > /** > - Invalid VTd IOTLB domain. > - > - @param[in] VtdIndex The index of VTd engine. > - @param[in] DomainIdentifier The domain ID of the source. > + Invalidate VTd IOTLB. >=20 > - @retval EFI_SUCCESS VTd IOTLB domain is invalidated. > - @retval EFI_DEVICE_ERROR VTd IOTLB domain is not invalidated. > + @param[in] VtdIndex The index used to identify a VTd engine. > **/ > EFI_STATUS > -InvalidateVtdIOTLBDomain ( > - IN UINTN VtdIndex, > - IN UINT16 DomainIdentifier > +InvalidateIOTLB ( > + IN UINTN VtdIndex > ) > { > UINT64 Reg64; >=20 > - if (!mVtdEnabled) { > - return EFI_SUCCESS; > - } > - > - DEBUG((DEBUG_VERBOSE, "InvalidateVtdIOTLBDomain(%d): 0x%016lx > (0x%04x)\n", VtdIndex, DomainIdentifier)); > - > - // > - // Invalidate the context cache > - // > - Reg64 =3D MmioRead64 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress > + R_CCMD_REG); > - if ((Reg64 & B_CCMD_REG_ICC) !=3D 0) { > - DEBUG ((DEBUG_ERROR,"ERROR: InvalidateVtdIOTLBDomain: > B_CCMD_REG_ICC is set for VTD(%d)\n",VtdIndex)); > - return EFI_DEVICE_ERROR; > - } > - > - Reg64 &=3D ((~B_CCMD_REG_ICC) & (~B_CCMD_REG_CIRG_MASK)); > - Reg64 |=3D (B_CCMD_REG_ICC | V_CCMD_REG_CIRG_DOMAIN); > - Reg64 |=3D (B_CCMD_REG_ICC | V_CCMD_REG_CIRG_DOMAIN); > - MmioWrite64 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress + > R_CCMD_REG, Reg64); > - > - do { > - Reg64 =3D MmioRead64 > (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress + R_CCMD_REG); > - } while ((Reg64 & B_CCMD_REG_ICC) !=3D 0); > - > - // > - // Invalidate the IOTLB cache > - // > - > Reg64 =3D MmioRead64 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress > + (mVtdUnitInformation[VtdIndex].ECapReg.Bits.IRO * 16) + R_IOTLB_REG); > if ((Reg64 & B_IOTLB_REG_IVT) !=3D 0) { > - DEBUG ((DEBUG_ERROR,"ERROR: InvalidateVtdIOTLBDomain: > B_IOTLB_REG_IVT is set for VTD(%d)\n", VtdIndex)); > + DEBUG ((DEBUG_ERROR,"ERROR: InvalidateIOTLB: B_IOTLB_REG_IVT is set > + for VTD(%d)\n", VtdIndex)); > return EFI_DEVICE_ERROR; > } >=20 > Reg64 &=3D ((~B_IOTLB_REG_IVT) & (~B_IOTLB_REG_IIRG_MASK)); > - Reg64 |=3D (B_IOTLB_REG_IVT | V_IOTLB_REG_IIRG_DOMAIN); > - Reg64 |=3D LShiftU64 (DomainIdentifier, 32); > + Reg64 |=3D (B_IOTLB_REG_IVT | V_IOTLB_REG_IIRG_GLOBAL); > MmioWrite64 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress + > (mVtdUnitInformation[VtdIndex].ECapReg.Bits.IRO * 16) + R_IOTLB_REG, > Reg64); >=20 > do { > @@ -169,53 +120,41 @@ InvalidateVtdIOTLBDomain ( } >=20 > /** > - Invalid VTd IOTLB page. > + Invalid VTd global IOTLB. >=20 > @param[in] VtdIndex The index of VTd engine. > - @param[in] Address The address of IOTLB page. > - @param[in] AddressMode The address mode of IOTLB page. > - @param[in] DomainIdentifier The domain ID of the source. >=20 > - @retval EFI_SUCCESS VTd IOTLB page is invalidated. > - @retval EFI_DEVICE_ERROR VTd IOTLB page is not invalidated. > + @retval EFI_SUCCESS VTd global IOTLB is invalidated. > + @retval EFI_DEVICE_ERROR VTd global IOTLB is not invalidated. > **/ > EFI_STATUS > -InvalidateVtdIOTLBPage ( > - IN UINTN VtdIndex, > - IN UINT64 Address, > - IN UINT8 AddressMode, > - IN UINT16 DomainIdentifier > +InvalidateVtdIOTLBGlobal ( > + IN UINTN VtdIndex > ) > { > - UINT64 Reg64; > - UINT64 Data64; > - > if (!mVtdEnabled) { > return EFI_SUCCESS; > } >=20 > - DEBUG((DEBUG_VERBOSE, "InvalidateVtdIOTLBPage(%d): 0x%016lx > (0x%02x)\n", VtdIndex, Address, AddressMode)); > - > - if (mVtdUnitInformation[VtdIndex].CapReg.Bits.PSI !=3D 0) { > - Reg64 =3D MmioRead64 > (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress + > (mVtdUnitInformation[VtdIndex].ECapReg.Bits.IRO * 16) + R_IOTLB_REG); > - if ((Reg64 & B_IOTLB_REG_IVT) !=3D 0) { > - DEBUG ((DEBUG_ERROR,"ERROR: InvalidateVtdIOTLBPage: > B_IOTLB_REG_IVT is set for VTD(%d)\n", VtdIndex)); > - return EFI_DEVICE_ERROR; > - } > + DEBUG((DEBUG_VERBOSE, "InvalidateVtdIOTLBGlobal(%d)\n", VtdIndex)); >=20 > - Data64 =3D Address | AddressMode; > - MmioWrite64 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress + > (mVtdUnitInformation[VtdIndex].ECapReg.Bits.IRO * 16) + R_IVA_REG, Data64= ); > + // > + // Write Buffer Flush before invalidation // FlushWriteBuffer > + (VtdIndex); >=20 > - Reg64 &=3D ((~B_IOTLB_REG_IVT) & (~B_IOTLB_REG_IIRG_MASK)); > - Reg64 |=3D (B_IOTLB_REG_IVT | V_IOTLB_REG_IIRG_PAGE); > - Reg64 |=3D LShiftU64 (DomainIdentifier, 32); > - MmioWrite64 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress + > (mVtdUnitInformation[VtdIndex].ECapReg.Bits.IRO * 16) + R_IOTLB_REG, > Reg64); > + // > + // Invalidate the context cache > + // > + if (mVtdUnitInformation[VtdIndex].HasDirtyContext) { > + InvalidateContextCache (VtdIndex); > + } >=20 > - do { > - Reg64 =3D MmioRead64 > (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress + > (mVtdUnitInformation[VtdIndex].ECapReg.Bits.IRO * 16) + R_IOTLB_REG); > - } while ((Reg64 & B_IOTLB_REG_IVT) !=3D 0); > - } else { > - InvalidateVtdIOTLBGlobal (VtdIndex); > + // > + // Invalidate the IOTLB cache > + // > + if (mVtdUnitInformation[VtdIndex].HasDirtyContext || > mVtdUnitInformation[VtdIndex].HasDirtyPages) { > + InvalidateIOTLB (VtdIndex); > } >=20 > return EFI_SUCCESS; > @@ -268,11 +207,8 @@ EnableDmar ( > ) > { > UINTN Index; > - UINT64 Reg64; > UINT32 Reg32; >=20 > - AsmWbinvd(); > - > for (Index =3D 0; Index < mVtdUnitNumber; Index++) { > DEBUG((DEBUG_INFO, ">>>>>>EnableDmar() for engine [%d] \n", Index)); >=20 > @@ -299,48 +235,17 @@ EnableDmar ( > // > // Write Buffer Flush before invalidation > // > - Reg32 =3D MmioRead32 (mVtdUnitInformation[Index].VtdUnitBaseAddress = + > R_CAP_REG); > - if ((Reg32 & B_CAP_REG_RWBF) !=3D 0) { > - MmioWrite32 (mVtdUnitInformation[Index].VtdUnitBaseAddress + > R_GCMD_REG, B_GMCD_REG_WBF); > - } > + FlushWriteBuffer (Index); >=20 > // > // Invalidate the context cache > // > - Reg64 =3D MmioRead64 (mVtdUnitInformation[Index].VtdUnitBaseAddress = + > R_CCMD_REG); > - if ((Reg64 & B_CCMD_REG_ICC) !=3D 0) { > - DEBUG ((DEBUG_INFO,"ERROR: EnableDmar: B_CCMD_REG_ICC is set > for VTD(%d)\n",Index)); > - return EFI_DEVICE_ERROR; > - } > - > - Reg64 &=3D ((~B_CCMD_REG_ICC) & (~B_CCMD_REG_CIRG_MASK)); > - Reg64 |=3D (B_CCMD_REG_ICC | V_CCMD_REG_CIRG_GLOBAL); > - MmioWrite64 (mVtdUnitInformation[Index].VtdUnitBaseAddress + > R_CCMD_REG, Reg64); > - > - DEBUG((DEBUG_INFO, "EnableDmar: Waiting B_CCMD_REG_ICC ...\n")); > - do { > - Reg64 =3D MmioRead64 (mVtdUnitInformation[Index].VtdUnitBaseAddres= s > + R_CCMD_REG); > - } while ((Reg64 & B_CCMD_REG_ICC) !=3D 0); > + InvalidateContextCache (Index); >=20 > // > // Invalidate the IOTLB cache > // > - DEBUG((DEBUG_INFO, "EnableDmar: IRO 0x%x\n", > mVtdUnitInformation[Index].ECapReg.Bits.IRO)); > - > - Reg64 =3D MmioRead64 (mVtdUnitInformation[Index].VtdUnitBaseAddress = + > (mVtdUnitInformation[Index].ECapReg.Bits.IRO * 16) + R_IOTLB_REG); > - if ((Reg64 & B_IOTLB_REG_IVT) !=3D 0) { > - DEBUG ((DEBUG_INFO,"ERROR: EnableDmar: B_IOTLB_REG_IVT is set for > VTD(%d)\n", Index)); > - return EFI_DEVICE_ERROR; > - } > - > - Reg64 &=3D ((~B_IOTLB_REG_IVT) & (~B_IOTLB_REG_IIRG_MASK)); > - Reg64 |=3D (B_IOTLB_REG_IVT | V_IOTLB_REG_IIRG_GLOBAL); > - MmioWrite64 (mVtdUnitInformation[Index].VtdUnitBaseAddress + > (mVtdUnitInformation[Index].ECapReg.Bits.IRO * 16) + R_IOTLB_REG, Reg64); > - > - DEBUG((DEBUG_INFO, "EnableDmar: Waiting B_IOTLB_REG_IVT ...\n")); > - do { > - Reg64 =3D MmioRead64 (mVtdUnitInformation[Index].VtdUnitBaseAddres= s > + (mVtdUnitInformation[Index].ECapReg.Bits.IRO * 16) + R_IOTLB_REG); > - } while ((Reg64 & B_IOTLB_REG_IVT) !=3D 0); > + InvalidateIOTLB (Index); >=20 > // > // Enable VTd > @@ -371,20 +276,16 @@ DisableDmar ( > ) > { > UINTN Index; > + UINTN SubIndex; > UINT32 Reg32; >=20 > - AsmWbinvd(); > - > for (Index =3D 0; Index < mVtdUnitNumber; Index++) { > DEBUG((DEBUG_INFO, ">>>>>>DisableDmar() for engine [%d] \n", > Index)); >=20 > // > // Write Buffer Flush before invalidation > // > - Reg32 =3D MmioRead32 (mVtdUnitInformation[Index].VtdUnitBaseAddress = + > R_CAP_REG); > - if ((Reg32 & B_CAP_REG_RWBF) !=3D 0) { > - MmioWrite32 (mVtdUnitInformation[Index].VtdUnitBaseAddress + > R_GCMD_REG, B_GMCD_REG_WBF); > - } > + FlushWriteBuffer (Index); >=20 > // > // Disable VTd > @@ -402,6 +303,19 @@ DisableDmar ( >=20 > mVtdEnabled =3D FALSE; >=20 > + for (Index =3D 0; Index < mVtdUnitNumber; Index++) { > + DEBUG((DEBUG_INFO, "engine [%d] access\n", Index)); > + for (SubIndex =3D 0; SubIndex < > mVtdUnitInformation[Index].PciDeviceInfo.PciDescriptorNumber; SubIndex++)= { > + DEBUG ((DEBUG_INFO, " PCI S%04X B%02x D%02x F%02x - %d\n", > + mVtdUnitInformation[Index].Segment, > + > mVtdUnitInformation[Index].PciDeviceInfo.PciDescriptors[SubIndex].Bits.Bu= s, > + > mVtdUnitInformation[Index].PciDeviceInfo.PciDescriptors[SubIndex].Bits.De= vice > , > + > mVtdUnitInformation[Index].PciDeviceInfo.PciDescriptors[SubIndex].Bits.Fu= ncti > on, > + mVtdUnitInformation[Index].PciDeviceInfo.AccessCount[SubIndex] > + )); > + } > + } > + > return EFI_SUCCESS; > } >=20 > -- > 2.7.4.windows.1