From: "Yao, Jiewen" <jiewen.yao@intel.com>
To: "Zeng, Star" <star.zeng@intel.com>,
"edk2-devel@lists.01.org" <edk2-devel@lists.01.org>
Subject: Re: [PATCH 2/3] IntelSiliconPkg/IntelVTdPmrPei: Parse RMRR table.
Date: Wed, 20 Sep 2017 06:33:36 +0000 [thread overview]
Message-ID: <74D8A39837DF1E4DA445A8C0B3885C503A9BF4B5@shsmsx102.ccr.corp.intel.com> (raw)
In-Reply-To: <0C09AFA07DD0434D9E2A0C6AEB0483103B97691F@shsmsx102.ccr.corp.intel.com>
Yes, Typo. will be fixed.
> -----Original Message-----
> From: Zeng, Star
> Sent: Wednesday, September 20, 2017 2:30 PM
> To: Yao, Jiewen <jiewen.yao@intel.com>; edk2-devel@lists.01.org
> Cc: Zeng, Star <star.zeng@intel.com>
> Subject: RE: [PATCH 2/3] IntelSiliconPkg/IntelVTdPmrPei: Parse RMRR table.
>
> Sorry, should it be "rest"?
>
> -----Original Message-----
> From: Zeng, Star
> Sent: Wednesday, September 20, 2017 2:29 PM
> To: Yao, Jiewen <jiewen.yao@intel.com>; edk2-devel@lists.01.org
> Cc: Zeng, Star <star.zeng@intel.com>
> Subject: RE: [PATCH 2/3] IntelSiliconPkg/IntelVTdPmrPei: Parse RMRR table.
>
> The typo "reset" in commit log? Should it be "reset"?
>
> Thanks,
> Star
> -----Original Message-----
> From: Yao, Jiewen
> Sent: Sunday, September 17, 2017 2:07 PM
> To: edk2-devel@lists.01.org
> Cc: Zeng, Star <star.zeng@intel.com>
> Subject: [PATCH 2/3] IntelSiliconPkg/IntelVTdPmrPei: Parse RMRR table.
>
> In order to support PEI graphic, we let VTdPmrPei driver parse DMAR table RMRR
> entry and allow the UMA access.
>
> If a system has no PEI IGD, no RMRR is needed. The behavior is unchanged.
>
> 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, and
> program the reset PCI VTd engine to skip the another DMA buffer allocated in PEI
> phase for other device driver.
>
> Cc: Star Zeng <star.zeng@intel.com>
> Contributed-under: TianoCore Contribution Agreement 1.1
> Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
> ---
> 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(-)
>
> 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 @@
>
> #include "IntelVTdPmrPei.h"
>
> -extern EDKII_VTD_INFO_PPI *mVTdInfoPpi;
> +extern VTD_INFO *mVTdInfo;
>
> /**
> Get protected low memory alignment.
> @@ -60,7 +60,7 @@ GetPhmrAlignment (
> UINT64 Data64;
> UINT8 HostAddressWidth;
>
> - HostAddressWidth = mVTdInfoPpi->HostAddressWidth;
> + HostAddressWidth = mVTdInfo->HostAddressWidth;
>
> MmioWrite64 (VtdUnitBaseAddress + R_PMEN_HIGH_BASE_REG,
> 0xFFFFFFFFFFFFFFFF);
> Data64 = MmioRead64 (VtdUnitBaseAddress + R_PMEN_HIGH_BASE_REG);
> @@ -73,11 +73,13 @@ GetPhmrAlignment (
> /**
> Get protected low memory alignment.
>
> + @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;
>
> FinalAlignment = 0;
> - for (Index = 0; Index < mVTdInfoPpi->VTdEngineCount; Index++) {
> - Alignment = GetPlmrAlignment
> ((UINTN)mVTdInfoPpi->VTdEngineAddress[Index]);
> + for (Index = 0; Index < mVTdInfo->VTdEngineCount; Index++) {
> + if ((EngineMask & LShiftU64(1, Index)) == 0) {
> + continue;
> + }
> + Alignment = GetPlmrAlignment
> + ((UINTN)mVTdInfo->VTdEngineAddress[Index]);
> if (FinalAlignment < Alignment) {
> FinalAlignment = Alignment;
> }
> @@ -97,11 +102,13 @@ GetLowMemoryAlignment (
> /**
> Get protected high memory alignment.
>
> + @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;
>
> FinalAlignment = 0;
> - for (Index = 0; Index < mVTdInfoPpi->VTdEngineCount; Index++) {
> - Alignment = GetPhmrAlignment
> ((UINTN)mVTdInfoPpi->VTdEngineAddress[Index]);
> + for (Index = 0; Index < mVTdInfo->VTdEngineCount; Index++) {
> + if ((EngineMask & LShiftU64(1, Index)) == 0) {
> + continue;
> + }
> + Alignment = GetPhmrAlignment
> + ((UINTN)mVTdInfo->VTdEngineAddress[Index]);
> if (FinalAlignment < Alignment) {
> FinalAlignment = Alignment;
> }
> @@ -246,6 +256,7 @@ SetPmrRegion (
> /**
> Set DMA protected region.
>
> + @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;
>
> - 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));
>
> - for (Index = 0; Index < mVTdInfoPpi->VTdEngineCount; Index++) {
> - DisablePmr ((UINTN)mVTdInfoPpi->VTdEngineAddress[Index]);
> + for (Index = 0; Index < mVTdInfo->VTdEngineCount; Index++) {
> + if ((EngineMask & LShiftU64(1, Index)) == 0) {
> + continue;
> + }
> + DisablePmr ((UINTN)mVTdInfo->VTdEngineAddress[Index]);
> Status = SetPmrRegion (
> - (UINTN)mVTdInfoPpi->VTdEngineAddress[Index],
> + (UINTN)mVTdInfo->VTdEngineAddress[Index],
> LowMemoryBase,
> LowMemoryLength,
> HighMemoryBase,
> @@ -279,7 +294,7 @@ SetDmaProtectedRange (
> if (EFI_ERROR(Status)) {
> return Status;
> }
> - Status = EnablePmr ((UINTN)mVTdInfoPpi->VTdEngineAddress[Index]);
> + Status = EnablePmr ((UINTN)mVTdInfo->VTdEngineAddress[Index]);
> if (EFI_ERROR(Status)) {
> return Status;
> }
> @@ -291,11 +306,13 @@ SetDmaProtectedRange (
> /**
> Diable DMA protection.
>
> + @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 (
>
> DEBUG ((DEBUG_INFO, "DisableDmaProtection\n"));
>
> - for (Index = 0; Index < mVTdInfoPpi->VTdEngineCount; Index++) {
> - Status = DisablePmr ((UINTN)mVTdInfoPpi->VTdEngineAddress[Index]);
> + for (Index = 0; Index < mVTdInfo->VTdEngineCount; Index++) {
> + if ((EngineMask & LShiftU64(1, Index)) == 0) {
> + continue;
> + }
> + Status = 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 @@
>
> #define TOTAL_DMA_BUFFER_SIZE SIZE_4MB
>
> -EDKII_VTD_INFO_PPI *mVTdInfoPpi;
> +EFI_ACPI_DMAR_HEADER *mAcpiDmarTable;
> +VTD_INFO *mVTdInfo;
> +UINT64 mEngineMask;
> UINTN mDmaBufferBase;
> UINTN mDmaBufferSize =
> TOTAL_DMA_BUFFER_SIZE;
> UINTN mDmaBufferCurrentTop;
> @@ -48,15 +50,19 @@ typedef struct {
>
> PEI Memory Layout:
>
> + +------------------+ <=============== PHMR.Limit (Top of
> memory)
> + | Mem Resource |
> + | |
> +
> +------------------+ <------- EfiMemoryTop
> | PEI allocated |
> - =========== +==================+
> + =========== +==================+ <=============== PHMR.Base
> ^ | Commom Buf |
> | | -------------- |
> DMA Buffer | * DMA FREE * |
> | | -------------- |
> V | Read/Write Buf |
> - =========== +==================+
> + =========== +==================+ <=============== PLMR.Limit
> | PEI allocated |
> | -------------- | <------- EfiFreeMemoryTop
> | * PEI FREE * |
> @@ -70,6 +76,9 @@ typedef struct {
> | Mem Alloc Hob |
> +------------------+
>
> + | |
> + | Mem Resource |
> + +------------------+ <=============== PLMR.Base (0)
> **/
>
>
> @@ -457,20 +466,21 @@ DumpPhitHob (
> /**
> Get the highest memory.
>
> - @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;
>
> + HobList = GetHobList ();
> +
> TopMemory = 0;
> for (Hob.Raw = HobList; !END_OF_HOB_LIST (Hob); Hob.Raw =
> GET_NEXT_HOB (Hob)) {
> if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR)
> { @@ -525,8 +535,8 @@ InitDmaProtection (
>
> ASSERT (PhitHob->EfiMemoryBottom < PhitHob->EfiMemoryTop);
>
> - LowMemoryAlignment = GetLowMemoryAlignment ();
> - HighMemoryAlignment = GetHighMemoryAlignment ();
> + LowMemoryAlignment = GetLowMemoryAlignment (mEngineMask);
> + HighMemoryAlignment = GetHighMemoryAlignment (mEngineMask);
> if (LowMemoryAlignment < HighMemoryAlignment) {
> MemoryAlignment = (UINTN)HighMemoryAlignment;
> } else {
> @@ -542,9 +552,10 @@ InitDmaProtection (
> LowBottom = 0;
> LowTop = *DmaBufferBase;
> HighBottom = *DmaBufferBase + DmaBufferSize;
> - HighTop = GetTopMemory (HobList);
> + HighTop = GetTopMemory ();
>
> Status = SetDmaProtectedRange (
> + mEngineMask,
> (UINT32)LowBottom,
> (UINT32)(LowTop - LowBottom),
> HighBottom,
> @@ -559,6 +570,541 @@ InitDmaProtection ( }
>
> /**
> + 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 == 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) == 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 = (DmarDeviceScopeEntry->Length -
> + sizeof(EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER)) /
> + sizeof(EFI_ACPI_DMAR_PCI_PATH); PciPath = (EFI_ACPI_DMAR_PCI_PATH
> *)(DmarDeviceScopeEntry + 1); for (PciPathIndex = 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 == NULL) {
> + return;
> + }
> +
> + DEBUG ((DEBUG_INFO,
> + "
> *************************************************************
> **************\n"
> + ));
> + DEBUG ((DEBUG_INFO,
> + " * Reserved Memory Region Reporting Structure
> *\n"
> + ));
> + DEBUG ((DEBUG_INFO,
> + "
> *************************************************************
> **************\n"
> + ));
> + DEBUG ((DEBUG_INFO,
> + (sizeof(UINTN) == 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 = Rmrr->Header.Length -
> sizeof(EFI_ACPI_DMAR_RMRR_HEADER);
> + DmarDeviceScopeEntry =
> (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER
> + *)(Rmrr + 1); while (RmrrLen > 0) {
> + DumpDmarDeviceScopeEntry (DmarDeviceScopeEntry);
> + RmrrLen -= DmarDeviceScopeEntry->Length;
> + DmarDeviceScopeEntry =
> (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 == NULL) {
> + return;
> + }
> +
> + DEBUG ((DEBUG_INFO,
> + "
> *************************************************************
> **************\n"
> + ));
> + DEBUG ((DEBUG_INFO,
> + " * DMA-Remapping Hardware Definition Structure
> *\n"
> + ));
> + DEBUG ((DEBUG_INFO,
> + "
> *************************************************************
> **************\n"
> + ));
> + DEBUG ((DEBUG_INFO,
> + (sizeof(UINTN) == 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 = Drhd->Header.Length - sizeof(EFI_ACPI_DMAR_DRHD_HEADER);
> + DmarDeviceScopeEntry =
> (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER
> + *)(Drhd + 1); while (DrhdLen > 0) {
> + DumpDmarDeviceScopeEntry (DmarDeviceScopeEntry);
> + DrhdLen -= DmarDeviceScopeEntry->Length;
> + DmarDeviceScopeEntry =
> (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 == NULL) {
> + return;
> + }
> +
> + //
> + // Dump Dmar table
> + //
> + DEBUG ((DEBUG_INFO,
> +
> "*************************************************************
> ****************\n"
> + ));
> + DEBUG ((DEBUG_INFO,
> + "* DMAR Table
> *\n"
> + ));
> + DEBUG ((DEBUG_INFO,
> +
> "*************************************************************
> ****************\n"
> + ));
> +
> + DEBUG ((DEBUG_INFO,
> + (sizeof(UINTN) == 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 = Dmar->Header.Length - sizeof(EFI_ACPI_DMAR_HEADER);
> + DmarHeader = (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 -= DmarHeader->Length;
> + DmarHeader = (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 = 0;
> + DmarHeader = (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 = (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] =
> 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 = GetVtdEngineNumber (); if (VtdUnitNumber == 0) {
> + return EFI_UNSUPPORTED;
> + }
> +
> + mVTdInfo = AllocateZeroPool (sizeof(VTD_INFO) + (VtdUnitNumber - 1) *
> + sizeof(UINT64)); if (mVTdInfo == NULL) {
> + return EFI_OUT_OF_RESOURCES;
> + }
> + mVTdInfo->HostAddressWidth = mAcpiDmarTable->HostAddressWidth;
> + mVTdInfo->VTdEngineCount = VtdUnitNumber;
> +
> + VtdIndex = 0;
> + DmarHeader = (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 = (EFI_ACPI_DMAR_STRUCTURE_HEADER
> *)((UINTN)DmarHeader +
> + DmarHeader->Length); } ASSERT (VtdIndex == VtdUnitNumber);
> +
> + //
> + // Initialize the engine mask to all.
> + //
> + mEngineMask = 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 DevScopeEntry.
> + @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 = 0;
> + DmarHeader = (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 = (EFI_ACPI_DMAR_DRHD_HEADER *)DmarHeader;
> + if (DmarDrhd->SegmentNumber != Segment) {
> + // Mismatch
> + break;
> + }
> + if ((DmarDrhd->Header.Length ==
> sizeof(EFI_ACPI_DMAR_DRHD_HEADER)) ||
> + ((DmarDrhd->Flags &
> EFI_ACPI_DMAR_DRHD_FLAGS_INCLUDE_PCI_ALL) != 0)) {
> + // No DevScopeEntry
> + // Do not handle PCI_ALL
> + break;
> + }
> + ThisDevScopeEntry =
> (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *)((UINTN)(DmarDrhd +
> 1));
> + while ((UINTN)ThisDevScopeEntry < (UINTN)DmarDrhd +
> DmarDrhd->Header.Length) {
> + if ((ThisDevScopeEntry->Length == DevScopeEntry->Length) &&
> + (CompareMem (ThisDevScopeEntry, DevScopeEntry,
> DevScopeEntry->Length) == 0)) {
> + return VtdIndex;
> + }
> + ThisDevScopeEntry =
> (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER
> *)((UINTN)ThisDevScopeEntry + ThisDevScopeEntry->Length);
> + }
> + break;
> + default:
> + break;
> + }
> + DmarHeader = (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 == 0) ||
> + (DmarRmrr->ReservedMemoryRegionLimitAddress == 0)) {
> + return ;
> + }
> +
> + DmarDevScopeEntry =
> (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER
> + *)((UINTN)(DmarRmrr + 1)); while ((UINTN)DmarDevScopeEntry <
> (UINTN)DmarRmrr + DmarRmrr->Header.Length) {
> + ASSERT (DmarDevScopeEntry->Type ==
> + EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_ENDPOINT);
> +
> + VTdIndex = GetVTdEngineFromDevScopeEntry
> (DmarRmrr->SegmentNumber, DmarDevScopeEntry);
> + if (VTdIndex != (UINTN)-1) {
> + RmrrMask = LShiftU64 (1, VTdIndex);
> +
> + LowBottom = 0;
> + LowTop = (UINTN)DmarRmrr->ReservedMemoryRegionBaseAddress;
> + HighBottom =
> (UINTN)DmarRmrr->ReservedMemoryRegionLimitAddress + 1;
> + HighTop = 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 = mEngineMask & (~RmrrMask);
> + }
> +
> + DmarDevScopeEntry =
> (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 = (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 = (EFI_ACPI_DMAR_STRUCTURE_HEADER
> *)((UINTN)DmarHeader +
> +DmarHeader->Length);
> + }
> +}
> +
> +/**
> Initializes the Intel VTd PMR PEIM.
>
> @param FileHandle Handle of the file being invoked.
> @@ -585,10 +1131,25 @@ IntelVTdPmrInitialize (
> &gEdkiiVTdInfoPpiGuid,
> 0,
> NULL,
> - (VOID **)&mVTdInfoPpi
> + (VOID **)&mAcpiDmarTable
> );
> ASSERT_EFI_ERROR(Status);
>
> + DumpAcpiDMAR (mAcpiDmarTable);
> +
> + //
> + // Get DMAR information to local VTdInfo // Status =
> + 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__
>
> +typedef struct {
> + UINT8 HostAddressWidth;
> + UINTN VTdEngineCount;
> + UINT64 VTdEngineAddress[1];
> +} VTD_INFO;
> +
> /**
> Set DMA protected region.
>
> + @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.
>
> + @param EngineMask The mask of the VTd engine to be accessed.
> +
> @retval DMA protection is disabled.
> **/
> EFI_STATUS
> DisableDmaProtection (
> - VOID
> + IN UINT64 EngineMask
> );
>
> /**
> Get protected low memory alignment.
>
> + @param EngineMask The mask of the VTd engine to be accessed.
> +
> @return protected low memory alignment.
> **/
> UINT32
> GetLowMemoryAlignment (
> - VOID
> + IN UINT64 EngineMask
> );
>
> /**
> Get protected high memory alignment.
>
> + @param EngineMask The mask of the VTd engine to be accessed.
> +
> @return protected high memory alignment.
> **/
> UINT64
> GetHighMemoryAlignment (
> - VOID
> + IN UINT64 EngineMask
> );
>
> #endif
> --
> 2.7.4.windows.1
next prev parent reply other threads:[~2017-09-20 6:30 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-09-17 6:06 [PATCH 0/3] IntelSiliconPkg/InteVTdPei: Add RMRR support in PEI Jiewen Yao
2017-09-17 6:06 ` [PATCH 1/3] IntelSiliconPkg/VTdInfoPpi: Let it follow DMAR table Jiewen Yao
2017-09-20 6:30 ` Zeng, Star
2017-09-20 6:33 ` Yao, Jiewen
2017-09-17 6:06 ` [PATCH 2/3] IntelSiliconPkg/IntelVTdPmrPei: Parse RMRR table Jiewen Yao
2017-09-20 6:29 ` Zeng, Star
2017-09-20 6:29 ` Zeng, Star
2017-09-20 6:33 ` Yao, Jiewen [this message]
2017-09-17 6:06 ` [PATCH 3/3] IntelSiliconPkg/VTdInfoSample: Add " Jiewen Yao
2017-09-20 6:30 ` [PATCH 0/3] IntelSiliconPkg/InteVTdPei: Add RMRR support in PEI Zeng, Star
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=74D8A39837DF1E4DA445A8C0B3885C503A9BF4B5@shsmsx102.ccr.corp.intel.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox