From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) (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 7205421E945F3 for ; Tue, 19 Sep 2017 23:30:34 -0700 (PDT) Received: from orsmga004.jf.intel.com ([10.7.209.38]) by orsmga104.jf.intel.com with ESMTP; 19 Sep 2017 23:33:39 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.42,420,1500966000"; d="scan'208";a="130565777" Received: from fmsmsx108.amr.corp.intel.com ([10.18.124.206]) by orsmga004.jf.intel.com with ESMTP; 19 Sep 2017 23:33:39 -0700 Received: from shsmsx151.ccr.corp.intel.com (10.239.6.50) by FMSMSX108.amr.corp.intel.com (10.18.124.206) with Microsoft SMTP Server (TLS) id 14.3.319.2; Tue, 19 Sep 2017 23:33:39 -0700 Received: from shsmsx102.ccr.corp.intel.com ([169.254.2.175]) by SHSMSX151.ccr.corp.intel.com ([169.254.3.98]) with mapi id 14.03.0319.002; Wed, 20 Sep 2017 14:33:36 +0800 From: "Yao, Jiewen" To: "Zeng, Star" , "edk2-devel@lists.01.org" Thread-Topic: [PATCH 2/3] IntelSiliconPkg/IntelVTdPmrPei: Parse RMRR table. Thread-Index: AQHTMdnObXg6T2WhFkC+lI4gJD2PE6K8yfIAgACHFkA= Date: Wed, 20 Sep 2017 06:33:36 +0000 Message-ID: <74D8A39837DF1E4DA445A8C0B3885C503A9BF4B5@shsmsx102.ccr.corp.intel.com> References: <1505628407-7368-1-git-send-email-jiewen.yao@intel.com> <1505628407-7368-3-git-send-email-jiewen.yao@intel.com> <0C09AFA07DD0434D9E2A0C6AEB0483103B976906@shsmsx102.ccr.corp.intel.com> <0C09AFA07DD0434D9E2A0C6AEB0483103B97691F@shsmsx102.ccr.corp.intel.com> In-Reply-To: <0C09AFA07DD0434D9E2A0C6AEB0483103B97691F@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: 11.0.0.116 dlp-reaction: no-action x-originating-ip: [10.239.127.40] MIME-Version: 1.0 Subject: Re: [PATCH 2/3] IntelSiliconPkg/IntelVTdPmrPei: Parse RMRR table. 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: Wed, 20 Sep 2017 06:30:34 -0000 Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Yes, Typo. will be fixed. > -----Original Message----- > From: Zeng, Star > Sent: Wednesday, September 20, 2017 2:30 PM > To: Yao, Jiewen ; edk2-devel@lists.01.org > Cc: Zeng, Star > Subject: RE: [PATCH 2/3] IntelSiliconPkg/IntelVTdPmrPei: Parse RMRR table= . >=20 > Sorry, should it be "rest"? >=20 > -----Original Message----- > From: Zeng, Star > Sent: Wednesday, September 20, 2017 2:29 PM > To: Yao, Jiewen ; edk2-devel@lists.01.org > Cc: Zeng, Star > Subject: RE: [PATCH 2/3] IntelSiliconPkg/IntelVTdPmrPei: Parse RMRR table= . >=20 > The typo "reset" in commit log? Should it be "reset"? >=20 > Thanks, > Star > -----Original Message----- > From: Yao, Jiewen > Sent: Sunday, September 17, 2017 2:07 PM > To: edk2-devel@lists.01.org > Cc: Zeng, Star > Subject: [PATCH 2/3] IntelSiliconPkg/IntelVTdPmrPei: Parse RMRR table. >=20 > In order to support PEI graphic, we let VTdPmrPei driver parse DMAR table= RMRR > entry and allow the UMA access. >=20 > If a system has no PEI IGD, no RMRR is needed. The behavior is unchanged. >=20 > If a system has PEI IGD, it must report RMRR in PEI phase. > The PeiVTdPrm will program the IGD VTd engine to skip the RMRR region, an= d > program the reset PCI VTd engine to skip the another DMA buffer allocated= in PEI > phase for other device driver. >=20 > Cc: Star Zeng > Contributed-under: TianoCore Contribution Agreement 1.1 > Signed-off-by: Jiewen Yao > --- > IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmr.c | 52 +- > IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.c | 581 > +++++++++++++++++++- > IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.h | 20 +- > 3 files changed, 624 insertions(+), 29 deletions(-) >=20 > diff --git a/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmr.c > b/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmr.c > index ef08e29..be841aa 100644 > --- a/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmr.c > +++ b/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmr.c > @@ -22,7 +22,7 @@ >=20 > #include "IntelVTdPmrPei.h" >=20 > -extern EDKII_VTD_INFO_PPI *mVTdInfoPpi; > +extern VTD_INFO *mVTdInfo; >=20 > /** > Get protected low memory alignment. > @@ -60,7 +60,7 @@ GetPhmrAlignment ( > UINT64 Data64; > UINT8 HostAddressWidth; >=20 > - HostAddressWidth =3D mVTdInfoPpi->HostAddressWidth; > + HostAddressWidth =3D mVTdInfo->HostAddressWidth; >=20 > MmioWrite64 (VtdUnitBaseAddress + R_PMEN_HIGH_BASE_REG, > 0xFFFFFFFFFFFFFFFF); > Data64 =3D MmioRead64 (VtdUnitBaseAddress + R_PMEN_HIGH_BASE_REG); > @@ -73,11 +73,13 @@ GetPhmrAlignment ( > /** > Get protected low memory alignment. >=20 > + @param EngineMask The mask of the VTd engine to be accessed. > + > @return protected low memory alignment. > **/ > UINT32 > GetLowMemoryAlignment ( > - VOID > + IN UINT64 EngineMask > ) > { > UINTN Index; > @@ -85,8 +87,11 @@ GetLowMemoryAlignment ( > UINT32 FinalAlignment; >=20 > FinalAlignment =3D 0; > - for (Index =3D 0; Index < mVTdInfoPpi->VTdEngineCount; Index++) { > - Alignment =3D GetPlmrAlignment > ((UINTN)mVTdInfoPpi->VTdEngineAddress[Index]); > + for (Index =3D 0; Index < mVTdInfo->VTdEngineCount; Index++) { > + if ((EngineMask & LShiftU64(1, Index)) =3D=3D 0) { > + continue; > + } > + Alignment =3D GetPlmrAlignment > + ((UINTN)mVTdInfo->VTdEngineAddress[Index]); > if (FinalAlignment < Alignment) { > FinalAlignment =3D Alignment; > } > @@ -97,11 +102,13 @@ GetLowMemoryAlignment ( > /** > Get protected high memory alignment. >=20 > + @param EngineMask The mask of the VTd engine to be accessed. > + > @return protected high memory alignment. > **/ > UINT64 > GetHighMemoryAlignment ( > - VOID > + IN UINT64 EngineMask > ) > { > UINTN Index; > @@ -109,8 +116,11 @@ GetHighMemoryAlignment ( > UINT64 FinalAlignment; >=20 > FinalAlignment =3D 0; > - for (Index =3D 0; Index < mVTdInfoPpi->VTdEngineCount; Index++) { > - Alignment =3D GetPhmrAlignment > ((UINTN)mVTdInfoPpi->VTdEngineAddress[Index]); > + for (Index =3D 0; Index < mVTdInfo->VTdEngineCount; Index++) { > + if ((EngineMask & LShiftU64(1, Index)) =3D=3D 0) { > + continue; > + } > + Alignment =3D GetPhmrAlignment > + ((UINTN)mVTdInfo->VTdEngineAddress[Index]); > if (FinalAlignment < Alignment) { > FinalAlignment =3D Alignment; > } > @@ -246,6 +256,7 @@ SetPmrRegion ( > /** > Set DMA protected region. >=20 > + @param EngineMask The mask of the VTd engine to be accessed. > @param LowMemoryBase The protected low memory region base. > @param LowMemoryLength The protected low memory region length. > @param HighMemoryBase The protected high memory region base. > @@ -256,6 +267,7 @@ SetPmrRegion ( > **/ > EFI_STATUS > SetDmaProtectedRange ( > + IN UINT64 EngineMask, > IN UINT32 LowMemoryBase, > IN UINT32 LowMemoryLength, > IN UINT64 HighMemoryBase, > @@ -265,12 +277,15 @@ SetDmaProtectedRange ( > UINTN Index; > EFI_STATUS Status; >=20 > - DEBUG ((DEBUG_INFO, "SetDmaProtectedRange - [0x%x, 0x%x] [0x%lx, > 0x%lx]\n", LowMemoryBase, LowMemoryLength, HighMemoryBase, > HighMemoryLength)); > + DEBUG ((DEBUG_INFO, "SetDmaProtectedRange(0x%lx) - [0x%x, 0x%x] > + [0x%lx, 0x%lx]\n", EngineMask, LowMemoryBase, LowMemoryLength, > + HighMemoryBase, HighMemoryLength)); >=20 > - for (Index =3D 0; Index < mVTdInfoPpi->VTdEngineCount; Index++) { > - DisablePmr ((UINTN)mVTdInfoPpi->VTdEngineAddress[Index]); > + for (Index =3D 0; Index < mVTdInfo->VTdEngineCount; Index++) { > + if ((EngineMask & LShiftU64(1, Index)) =3D=3D 0) { > + continue; > + } > + DisablePmr ((UINTN)mVTdInfo->VTdEngineAddress[Index]); > Status =3D SetPmrRegion ( > - (UINTN)mVTdInfoPpi->VTdEngineAddress[Index], > + (UINTN)mVTdInfo->VTdEngineAddress[Index], > LowMemoryBase, > LowMemoryLength, > HighMemoryBase, > @@ -279,7 +294,7 @@ SetDmaProtectedRange ( > if (EFI_ERROR(Status)) { > return Status; > } > - Status =3D EnablePmr ((UINTN)mVTdInfoPpi->VTdEngineAddress[Index]); > + Status =3D EnablePmr ((UINTN)mVTdInfo->VTdEngineAddress[Index]); > if (EFI_ERROR(Status)) { > return Status; > } > @@ -291,11 +306,13 @@ SetDmaProtectedRange ( > /** > Diable DMA protection. >=20 > + @param EngineMask The mask of the VTd engine to be accessed. > + > @retval DMA protection is disabled. > **/ > EFI_STATUS > DisableDmaProtection ( > - VOID > + IN UINT64 EngineMask > ) > { > UINTN Index; > @@ -303,8 +320,11 @@ DisableDmaProtection ( >=20 > DEBUG ((DEBUG_INFO, "DisableDmaProtection\n")); >=20 > - for (Index =3D 0; Index < mVTdInfoPpi->VTdEngineCount; Index++) { > - Status =3D DisablePmr ((UINTN)mVTdInfoPpi->VTdEngineAddress[Index]); > + for (Index =3D 0; Index < mVTdInfo->VTdEngineCount; Index++) { > + if ((EngineMask & LShiftU64(1, Index)) =3D=3D 0) { > + continue; > + } > + Status =3D DisablePmr ((UINTN)mVTdInfo->VTdEngineAddress[Index]); > if (EFI_ERROR(Status)) { > return Status; > } > diff --git a/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.c > b/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.c > index d118b7e..063e8cd 100644 > --- a/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.c > +++ b/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.c > @@ -29,7 +29,9 @@ >=20 > #define TOTAL_DMA_BUFFER_SIZE SIZE_4MB >=20 > -EDKII_VTD_INFO_PPI *mVTdInfoPpi; > +EFI_ACPI_DMAR_HEADER *mAcpiDmarTable; > +VTD_INFO *mVTdInfo; > +UINT64 mEngineMask; > UINTN mDmaBufferBase; > UINTN mDmaBufferSize =3D > TOTAL_DMA_BUFFER_SIZE; > UINTN mDmaBufferCurrentTop; > @@ -48,15 +50,19 @@ typedef struct { >=20 > PEI Memory Layout: >=20 > + +------------------+ <=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D PHMR.Limit (Top of > memory) > + | Mem Resource | > + | | > + > +------------------+ <------- EfiMemoryTop > | PEI allocated | > - =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D+ > + =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D+ <=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D PHMR.= Base > ^ | Commom Buf | > | | -------------- | > DMA Buffer | * DMA FREE * | > | | -------------- | > V | Read/Write Buf | > - =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D+ > + =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D+ <=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D PLMR.= Limit > | PEI allocated | > | -------------- | <------- EfiFreeMemoryTop > | * PEI FREE * | > @@ -70,6 +76,9 @@ typedef struct { > | Mem Alloc Hob | > +------------------+ >=20 > + | | > + | Mem Resource | > + +------------------+ <=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D PLMR.Base (0) > **/ >=20 >=20 > @@ -457,20 +466,21 @@ DumpPhitHob ( > /** > Get the highest memory. >=20 > - @param HobList the HOB list. > - > @return the highest memory. > **/ > UINT64 > GetTopMemory ( > - IN VOID *HobList > + VOID > ) > { > + VOID *HobList; > EFI_PEI_HOB_POINTERS Hob; > EFI_HOB_RESOURCE_DESCRIPTOR *ResourceHob; > UINT64 TopMemory; > UINT64 ResourceTop; >=20 > + HobList =3D GetHobList (); > + > TopMemory =3D 0; > for (Hob.Raw =3D HobList; !END_OF_HOB_LIST (Hob); Hob.Raw =3D > GET_NEXT_HOB (Hob)) { > if (GET_HOB_TYPE (Hob) =3D=3D EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) > { @@ -525,8 +535,8 @@ InitDmaProtection ( >=20 > ASSERT (PhitHob->EfiMemoryBottom < PhitHob->EfiMemoryTop); >=20 > - LowMemoryAlignment =3D GetLowMemoryAlignment (); > - HighMemoryAlignment =3D GetHighMemoryAlignment (); > + LowMemoryAlignment =3D GetLowMemoryAlignment (mEngineMask); > + HighMemoryAlignment =3D GetHighMemoryAlignment (mEngineMask); > if (LowMemoryAlignment < HighMemoryAlignment) { > MemoryAlignment =3D (UINTN)HighMemoryAlignment; > } else { > @@ -542,9 +552,10 @@ InitDmaProtection ( > LowBottom =3D 0; > LowTop =3D *DmaBufferBase; > HighBottom =3D *DmaBufferBase + DmaBufferSize; > - HighTop =3D GetTopMemory (HobList); > + HighTop =3D GetTopMemory (); >=20 > Status =3D SetDmaProtectedRange ( > + mEngineMask, > (UINT32)LowBottom, > (UINT32)(LowTop - LowBottom), > HighBottom, > @@ -559,6 +570,541 @@ InitDmaProtection ( } >=20 > /** > + Dump DMAR DeviceScopeEntry. > + > + @param[in] DmarDeviceScopeEntry DMAR DeviceScopeEntry **/ VOID > +DumpDmarDeviceScopeEntry ( > + IN EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER > *DmarDeviceScopeEntry > + ) > +{ > + UINTN PciPathNumber; > + UINTN PciPathIndex; > + EFI_ACPI_DMAR_PCI_PATH *PciPath; > + > + if (DmarDeviceScopeEntry =3D=3D NULL) { > + return; > + } > + > + DEBUG ((DEBUG_INFO, > + " > ************************************************************* > ************\n" > + )); > + DEBUG ((DEBUG_INFO, > + " * DMA-Remapping Device Scope Entry Structure > *\n" > + )); > + DEBUG ((DEBUG_INFO, > + " > ************************************************************* > ************\n" > + )); > + DEBUG ((DEBUG_INFO, > + (sizeof(UINTN) =3D=3D sizeof(UINT64)) ? > + " DMAR Device Scope Entry address ...................... 0x%016lx= \n" : > + " DMAR Device Scope Entry address ...................... 0x%08x\n= ", > + DmarDeviceScopeEntry > + )); > + DEBUG ((DEBUG_INFO, > + " Device Scope Entry Type ............................ 0x%02x\n= ", > + DmarDeviceScopeEntry->Type > + )); > + switch (DmarDeviceScopeEntry->Type) { case > + EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_ENDPOINT: > + DEBUG ((DEBUG_INFO, > + " PCI Endpoint Device\n" > + )); > + break; > + case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE: > + DEBUG ((DEBUG_INFO, > + " PCI Sub-hierachy\n" > + )); > + break; > + default: > + break; > + } > + DEBUG ((DEBUG_INFO, > + " Length ............................................. 0x%02x\n= ", > + DmarDeviceScopeEntry->Length > + )); > + DEBUG ((DEBUG_INFO, > + " Enumeration ID ..................................... 0x%02x\n= ", > + DmarDeviceScopeEntry->EnumerationId > + )); > + DEBUG ((DEBUG_INFO, > + " Starting Bus Number ................................ 0x%02x\n= ", > + DmarDeviceScopeEntry->StartBusNumber > + )); > + > + PciPathNumber =3D (DmarDeviceScopeEntry->Length - > + sizeof(EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER)) / > + sizeof(EFI_ACPI_DMAR_PCI_PATH); PciPath =3D (EFI_ACPI_DMAR_PCI_PATH > *)(DmarDeviceScopeEntry + 1); for (PciPathIndex =3D 0; PciPathIndex < > PciPathNumber; PciPathIndex++) { > + DEBUG ((DEBUG_INFO, > + " Device ............................................. 0x%02x= \n", > + PciPath[PciPathIndex].Device > + )); > + DEBUG ((DEBUG_INFO, > + " Function ........................................... 0x%02x= \n", > + PciPath[PciPathIndex].Function > + )); > + } > + > + DEBUG ((DEBUG_INFO, > + " > ************************************************************* > ************\n\n" > + )); > + > + return; > +} > + > +/** > + Dump DMAR RMRR table. > + > + @param[in] Rmrr DMAR RMRR table > +**/ > +VOID > +DumpDmarRmrr ( > + IN EFI_ACPI_DMAR_RMRR_HEADER *Rmrr > + ) > +{ > + EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER > *DmarDeviceScopeEntry; > + INTN RmrrLen; > + > + if (Rmrr =3D=3D NULL) { > + return; > + } > + > + DEBUG ((DEBUG_INFO, > + " > ************************************************************* > **************\n" > + )); > + DEBUG ((DEBUG_INFO, > + " * Reserved Memory Region Reporting Structure > *\n" > + )); > + DEBUG ((DEBUG_INFO, > + " > ************************************************************* > **************\n" > + )); > + DEBUG ((DEBUG_INFO, > + (sizeof(UINTN) =3D=3D sizeof(UINT64)) ? > + " RMRR address ........................................... 0x%016lx= \n" : > + " RMRR address ........................................... 0x%08x\n= ", > + Rmrr > + )); > + DEBUG ((DEBUG_INFO, > + " Type ................................................. 0x%04x\n= ", > + Rmrr->Header.Type > + )); > + DEBUG ((DEBUG_INFO, > + " Length ............................................... 0x%04x\n= ", > + Rmrr->Header.Length > + )); > + DEBUG ((DEBUG_INFO, > + " Segment Number ....................................... 0x%04x\n= ", > + Rmrr->SegmentNumber > + )); > + DEBUG ((DEBUG_INFO, > + " Reserved Memory Region Base Address .................. 0x%016lx= \n", > + Rmrr->ReservedMemoryRegionBaseAddress > + )); > + DEBUG ((DEBUG_INFO, > + " Reserved Memory Region Limit Address ................. 0x%016lx= \n", > + Rmrr->ReservedMemoryRegionLimitAddress > + )); > + > + RmrrLen =3D Rmrr->Header.Length - > sizeof(EFI_ACPI_DMAR_RMRR_HEADER); > + DmarDeviceScopeEntry =3D > (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER > + *)(Rmrr + 1); while (RmrrLen > 0) { > + DumpDmarDeviceScopeEntry (DmarDeviceScopeEntry); > + RmrrLen -=3D DmarDeviceScopeEntry->Length; > + DmarDeviceScopeEntry =3D > (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER > + *)((UINTN)DmarDeviceScopeEntry + DmarDeviceScopeEntry->Length); } > + > + DEBUG ((DEBUG_INFO, > + " > ************************************************************* > **************\n\n" > + )); > + > + return; > +} > + > +/** > + Dump DMAR DRHD table. > + > + @param[in] Drhd DMAR DRHD table > +**/ > +VOID > +DumpDmarDrhd ( > + IN EFI_ACPI_DMAR_DRHD_HEADER *Drhd > + ) > +{ > + EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER > *DmarDeviceScopeEntry; > + INTN DrhdLen; > + > + if (Drhd =3D=3D NULL) { > + return; > + } > + > + DEBUG ((DEBUG_INFO, > + " > ************************************************************* > **************\n" > + )); > + DEBUG ((DEBUG_INFO, > + " * DMA-Remapping Hardware Definition Structure > *\n" > + )); > + DEBUG ((DEBUG_INFO, > + " > ************************************************************* > **************\n" > + )); > + DEBUG ((DEBUG_INFO, > + (sizeof(UINTN) =3D=3D sizeof(UINT64)) ? > + " DRHD address ........................................... 0x%016lx= \n" : > + " DRHD address ........................................... 0x%08x\n= ", > + Drhd > + )); > + DEBUG ((DEBUG_INFO, > + " Type ................................................. 0x%04x\n= ", > + Drhd->Header.Type > + )); > + DEBUG ((DEBUG_INFO, > + " Length ............................................... 0x%04x\n= ", > + Drhd->Header.Length > + )); > + DEBUG ((DEBUG_INFO, > + " Flags ................................................ 0x%02x\n= ", > + Drhd->Flags > + )); > + DEBUG ((DEBUG_INFO, > + " INCLUDE_PCI_ALL .................................... 0x%02x\n= ", > + Drhd->Flags & EFI_ACPI_DMAR_DRHD_FLAGS_INCLUDE_PCI_ALL > + )); > + DEBUG ((DEBUG_INFO, > + " Segment Number ....................................... 0x%04x\n= ", > + Drhd->SegmentNumber > + )); > + DEBUG ((DEBUG_INFO, > + " Register Base Address ................................ 0x%016lx= \n", > + Drhd->RegisterBaseAddress > + )); > + > + DrhdLen =3D Drhd->Header.Length - sizeof(EFI_ACPI_DMAR_DRHD_HEADER); > + DmarDeviceScopeEntry =3D > (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER > + *)(Drhd + 1); while (DrhdLen > 0) { > + DumpDmarDeviceScopeEntry (DmarDeviceScopeEntry); > + DrhdLen -=3D DmarDeviceScopeEntry->Length; > + DmarDeviceScopeEntry =3D > (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER > + *)((UINTN)DmarDeviceScopeEntry + DmarDeviceScopeEntry->Length); } > + > + DEBUG ((DEBUG_INFO, > + " > ************************************************************* > **************\n\n" > + )); > + > + return; > +} > + > +/** > + Dump DMAR ACPI table. > + > + @param[in] Dmar DMAR ACPI table > +**/ > +VOID > +DumpAcpiDMAR ( > + IN EFI_ACPI_DMAR_HEADER *Dmar > + ) > +{ > + EFI_ACPI_DMAR_STRUCTURE_HEADER *DmarHeader; > + INTN DmarLen; > + > + if (Dmar =3D=3D NULL) { > + return; > + } > + > + // > + // Dump Dmar table > + // > + DEBUG ((DEBUG_INFO, > + > "************************************************************* > ****************\n" > + )); > + DEBUG ((DEBUG_INFO, > + "* DMAR Table > *\n" > + )); > + DEBUG ((DEBUG_INFO, > + > "************************************************************* > ****************\n" > + )); > + > + DEBUG ((DEBUG_INFO, > + (sizeof(UINTN) =3D=3D sizeof(UINT64)) ? > + "DMAR address ............................................. 0x%016lx= \n" : > + "DMAR address ............................................. 0x%08x\n= ", > + Dmar > + )); > + > + DEBUG ((DEBUG_INFO, > + " Table Contents:\n" > + )); > + DEBUG ((DEBUG_INFO, > + " Host Address Width ................................... 0x%02x\n= ", > + Dmar->HostAddressWidth > + )); > + DEBUG ((DEBUG_INFO, > + " Flags ................................................ 0x%02x\n= ", > + Dmar->Flags > + )); > + DEBUG ((DEBUG_INFO, > + " INTR_REMAP ......................................... 0x%02x\n= ", > + Dmar->Flags & EFI_ACPI_DMAR_FLAGS_INTR_REMAP > + )); > + DEBUG ((DEBUG_INFO, > + " X2APIC_OPT_OUT_SET ................................. 0x%02x\n= ", > + Dmar->Flags & EFI_ACPI_DMAR_FLAGS_X2APIC_OPT_OUT > + )); > + > + DmarLen =3D Dmar->Header.Length - sizeof(EFI_ACPI_DMAR_HEADER); > + DmarHeader =3D (EFI_ACPI_DMAR_STRUCTURE_HEADER *)(Dmar + 1); while > + (DmarLen > 0) { > + switch (DmarHeader->Type) { > + case EFI_ACPI_DMAR_TYPE_DRHD: > + DumpDmarDrhd ((EFI_ACPI_DMAR_DRHD_HEADER *)DmarHeader); > + break; > + case EFI_ACPI_DMAR_TYPE_RMRR: > + DumpDmarRmrr ((EFI_ACPI_DMAR_RMRR_HEADER *)DmarHeader); > + break; > + default: > + break; > + } > + DmarLen -=3D DmarHeader->Length; > + DmarHeader =3D (EFI_ACPI_DMAR_STRUCTURE_HEADER > *)((UINTN)DmarHeader + > + DmarHeader->Length); } > + > + DEBUG ((DEBUG_INFO, > + > "************************************************************* > ****************\n\n" > + )); > + > + return; > +} > + > +/** > + Get VTd engine number. > + > + @return the VTd engine number. > +**/ > +UINTN > +GetVtdEngineNumber ( > + VOID > + ) > +{ > + EFI_ACPI_DMAR_STRUCTURE_HEADER *DmarHeader; > + UINTN VtdIndex; > + > + VtdIndex =3D 0; > + DmarHeader =3D (EFI_ACPI_DMAR_STRUCTURE_HEADER > +*)((UINTN)(mAcpiDmarTable + 1)); > + while ((UINTN)DmarHeader < (UINTN)mAcpiDmarTable + > mAcpiDmarTable->Header.Length) { > + switch (DmarHeader->Type) { > + case EFI_ACPI_DMAR_TYPE_DRHD: > + VtdIndex++; > + break; > + default: > + break; > + } > + DmarHeader =3D (EFI_ACPI_DMAR_STRUCTURE_HEADER > *)((UINTN)DmarHeader + > +DmarHeader->Length); > + } > + return VtdIndex ; > +} > + > +/** > + Process DMAR DHRD table. > + > + @param[in] VtdIndex The index of VTd engine. > + @param[in] DmarDrhd The DRHD table. > +**/ > +VOID > +ProcessDhrd ( > + IN UINTN VtdIndex, > + IN EFI_ACPI_DMAR_DRHD_HEADER *DmarDrhd > + ) > +{ > + DEBUG ((DEBUG_INFO," VTD (%d) BaseAddress - 0x%016lx\n", VtdIndex, > +DmarDrhd->RegisterBaseAddress)); > + mVTdInfo->VTdEngineAddress[VtdIndex] =3D > DmarDrhd->RegisterBaseAddress; > +} > + > +/** > + Parse DMAR DRHD table. > + > + @return EFI_SUCCESS The DMAR DRHD table is parsed. > +**/ > +EFI_STATUS > +ParseDmarAcpiTableDrhd ( > + VOID > + ) > +{ > + EFI_ACPI_DMAR_STRUCTURE_HEADER *DmarHeader; > + UINTN VtdUnitNumber; > + UINTN VtdIndex; > + > + VtdUnitNumber =3D GetVtdEngineNumber (); if (VtdUnitNumber =3D=3D 0) = { > + return EFI_UNSUPPORTED; > + } > + > + mVTdInfo =3D AllocateZeroPool (sizeof(VTD_INFO) + (VtdUnitNumber - 1) = * > + sizeof(UINT64)); if (mVTdInfo =3D=3D NULL) { > + return EFI_OUT_OF_RESOURCES; > + } > + mVTdInfo->HostAddressWidth =3D mAcpiDmarTable->HostAddressWidth; > + mVTdInfo->VTdEngineCount =3D VtdUnitNumber; > + > + VtdIndex =3D 0; > + DmarHeader =3D (EFI_ACPI_DMAR_STRUCTURE_HEADER > + *)((UINTN)(mAcpiDmarTable + 1)); while ((UINTN)DmarHeader < > (UINTN)mAcpiDmarTable + mAcpiDmarTable->Header.Length) { > + switch (DmarHeader->Type) { > + case EFI_ACPI_DMAR_TYPE_DRHD: > + ASSERT (VtdIndex < VtdUnitNumber); > + ProcessDhrd (VtdIndex, (EFI_ACPI_DMAR_DRHD_HEADER > *)DmarHeader); > + VtdIndex++; > + > + break; > + > + default: > + break; > + } > + DmarHeader =3D (EFI_ACPI_DMAR_STRUCTURE_HEADER > *)((UINTN)DmarHeader + > + DmarHeader->Length); } ASSERT (VtdIndex =3D=3D VtdUnitNumber); > + > + // > + // Initialize the engine mask to all. > + // > + mEngineMask =3D LShiftU64 (1, VtdUnitNumber) - 1; > + > + return EFI_SUCCESS; > +} > + > +/** > + Return the VTd engine index according to the Segment and DevScopeEntry= . > + > + @param Segment The segment of the VTd engine > + @param DevScopeEntry The DevScopeEntry of the VTd engine > + > + @return The VTd engine index according to the Segment and DevScopeEntr= y. > + @retval -1 The VTd engine is not found. > +**/ > +UINTN > +GetVTdEngineFromDevScopeEntry ( > + IN UINT16 Segment, > + IN EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *DevScopeEntry > + ) > +{ > + EFI_ACPI_DMAR_STRUCTURE_HEADER *DmarHeader; > + UINTN VtdIndex; > + EFI_ACPI_DMAR_DRHD_HEADER *DmarDrhd; > + EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER > *ThisDevScopeEntry; > + > + VtdIndex =3D 0; > + DmarHeader =3D (EFI_ACPI_DMAR_STRUCTURE_HEADER > +*)((UINTN)(mAcpiDmarTable + 1)); > + while ((UINTN)DmarHeader < (UINTN)mAcpiDmarTable + > mAcpiDmarTable->Header.Length) { > + switch (DmarHeader->Type) { > + case EFI_ACPI_DMAR_TYPE_DRHD: > + DmarDrhd =3D (EFI_ACPI_DMAR_DRHD_HEADER *)DmarHeader; > + if (DmarDrhd->SegmentNumber !=3D Segment) { > + // Mismatch > + break; > + } > + if ((DmarDrhd->Header.Length =3D=3D > sizeof(EFI_ACPI_DMAR_DRHD_HEADER)) || > + ((DmarDrhd->Flags & > EFI_ACPI_DMAR_DRHD_FLAGS_INCLUDE_PCI_ALL) !=3D 0)) { > + // No DevScopeEntry > + // Do not handle PCI_ALL > + break; > + } > + ThisDevScopeEntry =3D > (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *)((UINTN)(DmarDrhd + > 1)); > + while ((UINTN)ThisDevScopeEntry < (UINTN)DmarDrhd + > DmarDrhd->Header.Length) { > + if ((ThisDevScopeEntry->Length =3D=3D DevScopeEntry->Length) && > + (CompareMem (ThisDevScopeEntry, DevScopeEntry, > DevScopeEntry->Length) =3D=3D 0)) { > + return VtdIndex; > + } > + ThisDevScopeEntry =3D > (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER > *)((UINTN)ThisDevScopeEntry + ThisDevScopeEntry->Length); > + } > + break; > + default: > + break; > + } > + DmarHeader =3D (EFI_ACPI_DMAR_STRUCTURE_HEADER > *)((UINTN)DmarHeader + > +DmarHeader->Length); > + } > + return (UINTN)-1; > +} > + > +/** > + Process DMAR RMRR table. > + > + @param[in] DmarRmrr The RMRR table. > +**/ > +VOID > +ProcessRmrr ( > + IN EFI_ACPI_DMAR_RMRR_HEADER *DmarRmrr > + ) > +{ > + EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER > *DmarDevScopeEntry; > + UINTN VTdIndex; > + UINT64 RmrrMask; > + UINTN LowBottom; > + UINTN LowTop; > + UINTN HighBottom; > + UINT64 HighTop; > + > + DEBUG ((DEBUG_INFO," RMRR (Base 0x%016lx, Limit 0x%016lx)\n", > + DmarRmrr->ReservedMemoryRegionBaseAddress, > + DmarRmrr->ReservedMemoryRegionLimitAddress)); > + > + if ((DmarRmrr->ReservedMemoryRegionBaseAddress =3D=3D 0) || > + (DmarRmrr->ReservedMemoryRegionLimitAddress =3D=3D 0)) { > + return ; > + } > + > + DmarDevScopeEntry =3D > (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER > + *)((UINTN)(DmarRmrr + 1)); while ((UINTN)DmarDevScopeEntry < > (UINTN)DmarRmrr + DmarRmrr->Header.Length) { > + ASSERT (DmarDevScopeEntry->Type =3D=3D > + EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_ENDPOINT); > + > + VTdIndex =3D GetVTdEngineFromDevScopeEntry > (DmarRmrr->SegmentNumber, DmarDevScopeEntry); > + if (VTdIndex !=3D (UINTN)-1) { > + RmrrMask =3D LShiftU64 (1, VTdIndex); > + > + LowBottom =3D 0; > + LowTop =3D (UINTN)DmarRmrr->ReservedMemoryRegionBaseAddress; > + HighBottom =3D > (UINTN)DmarRmrr->ReservedMemoryRegionLimitAddress + 1; > + HighTop =3D GetTopMemory (); > + > + SetDmaProtectedRange ( > + RmrrMask, > + 0, > + (UINT32)(LowTop - LowBottom), > + HighBottom, > + HighTop - HighBottom > + ); > + > + // > + // Remove the engine from the engine mask. > + // The assumption is that any other PEI driver does not access > + // the device covered by this engine. > + // > + mEngineMask =3D mEngineMask & (~RmrrMask); > + } > + > + DmarDevScopeEntry =3D > (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER > +*)((UINTN)DmarDevScopeEntry + DmarDevScopeEntry->Length); > + } > +} > + > +/** > + Parse DMAR DRHD table. > +**/ > +VOID > +ParseDmarAcpiTableRmrr ( > + VOID > + ) > +{ > + EFI_ACPI_DMAR_STRUCTURE_HEADER *DmarHeader; > + > + DmarHeader =3D (EFI_ACPI_DMAR_STRUCTURE_HEADER > +*)((UINTN)(mAcpiDmarTable + 1)); > + while ((UINTN)DmarHeader < (UINTN)mAcpiDmarTable + > mAcpiDmarTable->Header.Length) { > + switch (DmarHeader->Type) { > + case EFI_ACPI_DMAR_TYPE_RMRR: > + ProcessRmrr ((EFI_ACPI_DMAR_RMRR_HEADER *)DmarHeader); > + break; > + default: > + break; > + } > + DmarHeader =3D (EFI_ACPI_DMAR_STRUCTURE_HEADER > *)((UINTN)DmarHeader + > +DmarHeader->Length); > + } > +} > + > +/** > Initializes the Intel VTd PMR PEIM. >=20 > @param FileHandle Handle of the file being invoked. > @@ -585,10 +1131,25 @@ IntelVTdPmrInitialize ( > &gEdkiiVTdInfoPpiGuid, > 0, > NULL, > - (VOID **)&mVTdInfoPpi > + (VOID **)&mAcpiDmarTable > ); > ASSERT_EFI_ERROR(Status); >=20 > + DumpAcpiDMAR (mAcpiDmarTable); > + > + // > + // Get DMAR information to local VTdInfo // Status =3D > + ParseDmarAcpiTableDrhd (); if (EFI_ERROR(Status)) { > + return Status; > + } > + > + // > + // If there is RMRR memory, parse it here. > + // > + ParseDmarAcpiTableRmrr (); > + > // > // Find a pre-memory in resource hob as DMA buffer > // Mark PEI memory to be DMA protected. > diff --git a/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.h > b/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.h > index aa5926a7..720f5d4 100644 > --- a/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.h > +++ b/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.h > @@ -15,9 +15,16 @@ > #ifndef __DMA_ACCESS_LIB_H__ > #define __DMA_ACCESS_LIB_H__ >=20 > +typedef struct { > + UINT8 HostAddressWidth; > + UINTN VTdEngineCount; > + UINT64 VTdEngineAddress[1]; > +} VTD_INFO; > + > /** > Set DMA protected region. >=20 > + @param EngineMask The mask of the VTd engine to be accessed. > @param LowMemoryBase The protected low memory region base. > @param LowMemoryLength The protected low memory region length. > @param HighMemoryBase The protected high memory region base. > @@ -28,6 +35,7 @@ > **/ > EFI_STATUS > SetDmaProtectedRange ( > + IN UINT64 EngineMask, > IN UINT32 LowMemoryBase, > IN UINT32 LowMemoryLength, > IN UINT64 HighMemoryBase, > @@ -37,31 +45,37 @@ SetDmaProtectedRange ( > /** > Diable DMA protection. >=20 > + @param EngineMask The mask of the VTd engine to be accessed. > + > @retval DMA protection is disabled. > **/ > EFI_STATUS > DisableDmaProtection ( > - VOID > + IN UINT64 EngineMask > ); >=20 > /** > Get protected low memory alignment. >=20 > + @param EngineMask The mask of the VTd engine to be accessed. > + > @return protected low memory alignment. > **/ > UINT32 > GetLowMemoryAlignment ( > - VOID > + IN UINT64 EngineMask > ); >=20 > /** > Get protected high memory alignment. >=20 > + @param EngineMask The mask of the VTd engine to be accessed. > + > @return protected high memory alignment. > **/ > UINT64 > GetHighMemoryAlignment ( > - VOID > + IN UINT64 EngineMask > ); >=20 > #endif > -- > 2.7.4.windows.1