public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
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



  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