]> git.proxmox.com Git - mirror_edk2.git/commitdiff
IntelSiliconPkg: Add IntelVTdPmrPei.
authorJiewen Yao <jiewen.yao@intel.com>
Fri, 1 Sep 2017 08:30:46 +0000 (16:30 +0800)
committerJiewen Yao <jiewen.yao@intel.com>
Sat, 16 Sep 2017 01:18:07 +0000 (09:18 +0800)
This PEIM is to produce IOMMU_PPI, so that PEI device
driver can have better DAM management.

This PEIM will setup VTD PMR register to protect
most DRAM. It allocates a big chunk DMA buffer in
the entrypoint, and only use this buffer for DMA.
Any other region is DMA protected.

Cc: Star Zeng <star.zeng@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
Reviewed-by: Star Zeng <star.zeng@intel.com>
IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmr.c [new file with mode: 0644]
IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmrPei.c [new file with mode: 0644]
IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmrPei.h [new file with mode: 0644]
IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmrPei.inf [new file with mode: 0644]
IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmrPei.uni [new file with mode: 0644]
IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmrPeiExtra.uni [new file with mode: 0644]

diff --git a/IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmr.c b/IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmr.c
new file mode 100644 (file)
index 0000000..ef08e29
--- /dev/null
@@ -0,0 +1,314 @@
+/** @file\r
+\r
+  Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>\r
+\r
+  This program and the accompanying materials are licensed and made available under\r
+  the terms and conditions of the BSD License which accompanies this distribution.\r
+  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <PiPei.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/IoLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <IndustryStandard/Vtd.h>\r
+#include <Ppi/VTdInfo.h>\r
+\r
+#include "IntelVTdPmrPei.h"\r
+\r
+extern EDKII_VTD_INFO_PPI                *mVTdInfoPpi;\r
+\r
+/**\r
+  Get protected low memory alignment.\r
+\r
+  @param VtdUnitBaseAddress The base address of the VTd engine.\r
+\r
+  @return protected low memory alignment.\r
+**/\r
+UINT32\r
+GetPlmrAlignment (\r
+  IN UINTN         VtdUnitBaseAddress\r
+  )\r
+{\r
+  UINT32        Data32;\r
+\r
+  MmioWrite32 (VtdUnitBaseAddress + R_PMEN_LOW_BASE_REG, 0xFFFFFFFF);\r
+  Data32 = MmioRead32 (VtdUnitBaseAddress + R_PMEN_LOW_BASE_REG);\r
+  Data32 = ~Data32 + 1;\r
+\r
+  return Data32;\r
+}\r
+\r
+/**\r
+  Get protected high memory alignment.\r
+\r
+  @param VtdUnitBaseAddress The base address of the VTd engine.\r
+\r
+  @return protected high memory alignment.\r
+**/\r
+UINT64\r
+GetPhmrAlignment (\r
+  IN UINTN         VtdUnitBaseAddress\r
+  )\r
+{\r
+  UINT64        Data64;\r
+  UINT8         HostAddressWidth;\r
+\r
+  HostAddressWidth = mVTdInfoPpi->HostAddressWidth;\r
+\r
+  MmioWrite64 (VtdUnitBaseAddress + R_PMEN_HIGH_BASE_REG, 0xFFFFFFFFFFFFFFFF);\r
+  Data64 = MmioRead64 (VtdUnitBaseAddress + R_PMEN_HIGH_BASE_REG);\r
+  Data64 = ~Data64 + 1;\r
+  Data64 = Data64 & (LShiftU64 (1, HostAddressWidth) - 1);\r
+\r
+  return Data64;\r
+}\r
+\r
+/**\r
+  Get protected low memory alignment.\r
+\r
+  @return protected low memory alignment.\r
+**/\r
+UINT32\r
+GetLowMemoryAlignment (\r
+  VOID\r
+  )\r
+{\r
+  UINTN         Index;\r
+  UINT32        Alignment;\r
+  UINT32        FinalAlignment;\r
+\r
+  FinalAlignment = 0;\r
+  for (Index = 0; Index < mVTdInfoPpi->VTdEngineCount; Index++) {\r
+    Alignment = GetPlmrAlignment ((UINTN)mVTdInfoPpi->VTdEngineAddress[Index]);\r
+    if (FinalAlignment < Alignment) {\r
+      FinalAlignment = Alignment;\r
+    }\r
+  }\r
+  return FinalAlignment;\r
+}\r
+\r
+/**\r
+  Get protected high memory alignment.\r
+\r
+  @return protected high memory alignment.\r
+**/\r
+UINT64\r
+GetHighMemoryAlignment (\r
+  VOID\r
+  )\r
+{\r
+  UINTN         Index;\r
+  UINT64        Alignment;\r
+  UINT64        FinalAlignment;\r
+\r
+  FinalAlignment = 0;\r
+  for (Index = 0; Index < mVTdInfoPpi->VTdEngineCount; Index++) {\r
+    Alignment = GetPhmrAlignment ((UINTN)mVTdInfoPpi->VTdEngineAddress[Index]);\r
+    if (FinalAlignment < Alignment) {\r
+      FinalAlignment = Alignment;\r
+    }\r
+  }\r
+  return FinalAlignment;\r
+}\r
+\r
+/**\r
+  Enable PMR in the VTd engine.\r
+\r
+  @param VtdUnitBaseAddress The base address of the VTd engine.\r
+\r
+  @retval EFI_SUCCESS      The PMR is enabled.\r
+  @retval EFI_UNSUPPORTED  The PMR is not supported.\r
+**/\r
+EFI_STATUS\r
+EnablePmr (\r
+  IN UINTN         VtdUnitBaseAddress\r
+  )\r
+{\r
+  UINT32        Reg32;\r
+  VTD_CAP_REG   CapReg;\r
+\r
+  CapReg.Uint64 = MmioRead64 (VtdUnitBaseAddress + R_CAP_REG);\r
+  if (CapReg.Bits.PLMR == 0 || CapReg.Bits.PHMR == 0) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  Reg32 = MmioRead32 (VtdUnitBaseAddress + R_PMEN_ENABLE_REG);\r
+  if ((Reg32 & BIT0) == 0) {\r
+    MmioWrite32 (VtdUnitBaseAddress + R_PMEN_ENABLE_REG, BIT31);\r
+    do {\r
+      Reg32 = MmioRead32 (VtdUnitBaseAddress + R_PMEN_ENABLE_REG);\r
+    } while((Reg32 & BIT0) == 0);\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Disable PMR in the VTd engine.\r
+\r
+  @param VtdUnitBaseAddress The base address of the VTd engine.\r
+\r
+  @retval EFI_SUCCESS      The PMR is disabled.\r
+  @retval EFI_UNSUPPORTED  The PMR is not supported.\r
+**/\r
+EFI_STATUS\r
+DisablePmr (\r
+  IN UINTN         VtdUnitBaseAddress\r
+  )\r
+{\r
+  UINT32        Reg32;\r
+  VTD_CAP_REG   CapReg;\r
+\r
+  CapReg.Uint64 = MmioRead64 (VtdUnitBaseAddress + R_CAP_REG);\r
+  if (CapReg.Bits.PLMR == 0 || CapReg.Bits.PHMR == 0) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  Reg32 = MmioRead32 (VtdUnitBaseAddress + R_PMEN_ENABLE_REG);\r
+  if ((Reg32 & BIT0) != 0) {\r
+    MmioWrite32 (VtdUnitBaseAddress + R_PMEN_ENABLE_REG, 0x0);\r
+    do {\r
+      Reg32 = MmioRead32 (VtdUnitBaseAddress + R_PMEN_ENABLE_REG);\r
+    } while((Reg32 & BIT0) != 0);\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Set PMR region in the VTd engine.\r
+\r
+  @param VtdUnitBaseAddress The base address of the VTd engine.\r
+  @param LowMemoryBase      The protected low memory region base.\r
+  @param LowMemoryLength    The protected low memory region length.\r
+  @param HighMemoryBase     The protected high memory region base.\r
+  @param HighMemoryLength   The protected high memory region length.\r
+\r
+  @retval EFI_SUCCESS      The PMR is set to protected region.\r
+  @retval EFI_UNSUPPORTED  The PMR is not supported.\r
+**/\r
+EFI_STATUS\r
+SetPmrRegion (\r
+  IN UINTN         VtdUnitBaseAddress,\r
+  IN UINT32        LowMemoryBase,\r
+  IN UINT32        LowMemoryLength,\r
+  IN UINT64        HighMemoryBase,\r
+  IN UINT64        HighMemoryLength\r
+  )\r
+{\r
+  VTD_CAP_REG   CapReg;\r
+  UINT32        PlmrAlignment;\r
+  UINT64        PhmrAlignment;\r
+\r
+  DEBUG ((DEBUG_INFO, "VtdUnitBaseAddress - 0x%x\n", VtdUnitBaseAddress));\r
+\r
+  CapReg.Uint64 = MmioRead64 (VtdUnitBaseAddress + R_CAP_REG);\r
+  if (CapReg.Bits.PLMR == 0 || CapReg.Bits.PHMR == 0) {\r
+    DEBUG ((DEBUG_ERROR, "PLMR/PHMR unsupported\n"));\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  PlmrAlignment = GetPlmrAlignment (VtdUnitBaseAddress);\r
+  DEBUG ((DEBUG_INFO, "PlmrAlignment - 0x%x\n", PlmrAlignment));\r
+  PhmrAlignment = GetPhmrAlignment (VtdUnitBaseAddress);\r
+  DEBUG ((DEBUG_INFO, "PhmrAlignment - 0x%lx\n", PhmrAlignment));\r
+\r
+  if ((LowMemoryBase    != ALIGN_VALUE(LowMemoryBase, PlmrAlignment)) ||\r
+      (LowMemoryLength  != ALIGN_VALUE(LowMemoryLength, PlmrAlignment)) ||\r
+      (HighMemoryBase   != ALIGN_VALUE(HighMemoryBase, PhmrAlignment)) ||\r
+      (HighMemoryLength != ALIGN_VALUE(HighMemoryLength, PhmrAlignment))) {\r
+    DEBUG ((DEBUG_ERROR, "PLMR/PHMR alignment issue\n"));\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  if (LowMemoryBase == 0 && LowMemoryLength == 0) {\r
+    LowMemoryBase = 0xFFFFFFFF;\r
+  }\r
+  if (HighMemoryBase == 0 && HighMemoryLength == 0) {\r
+    HighMemoryBase = 0xFFFFFFFFFFFFFFFF;\r
+  }\r
+\r
+  MmioWrite32 (VtdUnitBaseAddress + R_PMEN_LOW_BASE_REG,    LowMemoryBase);\r
+  MmioWrite32 (VtdUnitBaseAddress + R_PMEN_LOW_LIMITE_REG,  LowMemoryBase + LowMemoryLength - 1);\r
+  MmioWrite64 (VtdUnitBaseAddress + R_PMEN_HIGH_BASE_REG,   HighMemoryBase);\r
+  MmioWrite64 (VtdUnitBaseAddress + R_PMEN_HIGH_LIMITE_REG, HighMemoryBase + HighMemoryLength - 1);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Set DMA protected region.\r
+\r
+  @param LowMemoryBase      The protected low memory region base.\r
+  @param LowMemoryLength    The protected low memory region length.\r
+  @param HighMemoryBase     The protected high memory region base.\r
+  @param HighMemoryLength   The protected high memory region length.\r
+\r
+  @retval EFI_SUCCESS      The DMA protection is set.\r
+  @retval EFI_UNSUPPORTED  The DMA protection is not set.\r
+**/\r
+EFI_STATUS\r
+SetDmaProtectedRange (\r
+  IN UINT32        LowMemoryBase,\r
+  IN UINT32        LowMemoryLength,\r
+  IN UINT64        HighMemoryBase,\r
+  IN UINT64        HighMemoryLength\r
+  )\r
+{\r
+  UINTN       Index;\r
+  EFI_STATUS  Status;\r
+\r
+  DEBUG ((DEBUG_INFO, "SetDmaProtectedRange - [0x%x, 0x%x] [0x%lx, 0x%lx]\n", LowMemoryBase, LowMemoryLength, HighMemoryBase, HighMemoryLength));\r
+\r
+  for (Index = 0; Index < mVTdInfoPpi->VTdEngineCount; Index++) {\r
+    DisablePmr ((UINTN)mVTdInfoPpi->VTdEngineAddress[Index]);\r
+    Status = SetPmrRegion (\r
+               (UINTN)mVTdInfoPpi->VTdEngineAddress[Index],\r
+               LowMemoryBase,\r
+               LowMemoryLength,\r
+               HighMemoryBase,\r
+               HighMemoryLength\r
+               );\r
+    if (EFI_ERROR(Status)) {\r
+      return Status;\r
+    }\r
+    Status = EnablePmr ((UINTN)mVTdInfoPpi->VTdEngineAddress[Index]);\r
+    if (EFI_ERROR(Status)) {\r
+      return Status;\r
+    }\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Diable DMA protection.\r
+\r
+  @retval DMA protection is disabled.\r
+**/\r
+EFI_STATUS\r
+DisableDmaProtection (\r
+  VOID\r
+  )\r
+{\r
+  UINTN       Index;\r
+  EFI_STATUS  Status;\r
+\r
+  DEBUG ((DEBUG_INFO, "DisableDmaProtection\n"));\r
+\r
+  for (Index = 0; Index < mVTdInfoPpi->VTdEngineCount; Index++) {\r
+    Status = DisablePmr ((UINTN)mVTdInfoPpi->VTdEngineAddress[Index]);\r
+    if (EFI_ERROR(Status)) {\r
+      return Status;\r
+    }\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
diff --git a/IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmrPei.c b/IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmrPei.c
new file mode 100644 (file)
index 0000000..d118b7e
--- /dev/null
@@ -0,0 +1,615 @@
+/** @file\r
+\r
+  Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>\r
+\r
+  This program and the accompanying materials are licensed and made available under\r
+  the terms and conditions of the BSD License which accompanies this distribution.\r
+  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <Uefi.h>\r
+#include <PiPei.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/IoLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/PeiServicesLib.h>\r
+#include <Library/HobLib.h>\r
+#include <IndustryStandard/Vtd.h>\r
+#include <Ppi/IoMmu.h>\r
+#include <Ppi/VTdInfo.h>\r
+\r
+#include "IntelVTdPmrPei.h"\r
+\r
+#define  TOTAL_DMA_BUFFER_SIZE    SIZE_4MB\r
+\r
+EDKII_VTD_INFO_PPI                *mVTdInfoPpi;\r
+UINTN                             mDmaBufferBase;\r
+UINTN                             mDmaBufferSize = TOTAL_DMA_BUFFER_SIZE;\r
+UINTN                             mDmaBufferCurrentTop;\r
+UINTN                             mDmaBufferCurrentBottom;\r
+\r
+#define MAP_INFO_SIGNATURE  SIGNATURE_32 ('D', 'M', 'A', 'P')\r
+typedef struct {\r
+  UINT32                                    Signature;\r
+  EDKII_IOMMU_OPERATION                     Operation;\r
+  UINTN                                     NumberOfBytes;\r
+  EFI_PHYSICAL_ADDRESS                      HostAddress;\r
+  EFI_PHYSICAL_ADDRESS                      DeviceAddress;\r
+} MAP_INFO;\r
+\r
+/**\r
+\r
+  PEI Memory Layout:\r
+\r
+              +------------------+ <------- EfiMemoryTop\r
+              |   PEI allocated  |\r
+  =========== +==================+\r
+       ^      |    Commom Buf    |\r
+       |      |  --------------  |\r
+  DMA Buffer  |   * DMA FREE *   |\r
+       |      |  --------------  |\r
+       V      |  Read/Write Buf  |\r
+  =========== +==================+\r
+              |   PEI allocated  |\r
+              |  --------------  | <------- EfiFreeMemoryTop\r
+              |   * PEI FREE *   |\r
+              |  --------------  | <------- EfiFreeMemoryBottom\r
+              |       hob        |\r
+              |  --------------  |\r
+              |      Stack       |\r
+              +------------------+ <------- EfiMemoryBottom / Stack Bottom\r
+\r
+              +------------------+\r
+              |   Mem Alloc Hob  |\r
+              +------------------+\r
+\r
+**/\r
+\r
+\r
+/**\r
+  Set IOMMU attribute for a system memory.\r
+\r
+  If the IOMMU PPI exists, the system memory cannot be used\r
+  for DMA by default.\r
+\r
+  When a device requests a DMA access for a system memory,\r
+  the device driver need use SetAttribute() to update the IOMMU\r
+  attribute to request DMA access (read and/or write).\r
+\r
+  @param[in]  This              The PPI instance pointer.\r
+  @param[in]  Mapping           The mapping value returned from Map().\r
+  @param[in]  IoMmuAccess       The IOMMU access.\r
+\r
+  @retval EFI_SUCCESS            The IoMmuAccess is set for the memory range specified by DeviceAddress and Length.\r
+  @retval EFI_INVALID_PARAMETER  Mapping is not a value that was returned by Map().\r
+  @retval EFI_INVALID_PARAMETER  IoMmuAccess specified an illegal combination of access.\r
+  @retval EFI_UNSUPPORTED        The bit mask of IoMmuAccess is not supported by the IOMMU.\r
+  @retval EFI_UNSUPPORTED        The IOMMU does not support the memory range specified by Mapping.\r
+  @retval EFI_OUT_OF_RESOURCES   There are not enough resources available to modify the IOMMU access.\r
+  @retval EFI_DEVICE_ERROR       The IOMMU device reported an error while attempting the operation.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+PeiIoMmuSetAttribute (\r
+  IN EDKII_IOMMU_PPI       *This,\r
+  IN VOID                  *Mapping,\r
+  IN UINT64                IoMmuAccess\r
+  )\r
+{\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Provides the controller-specific addresses required to access system memory from a\r
+  DMA bus master.\r
+\r
+  @param  This                  The PPI instance pointer.\r
+  @param  Operation             Indicates if the bus master is going to read or write to system memory.\r
+  @param  HostAddress           The system memory address to map to the PCI controller.\r
+  @param  NumberOfBytes         On input the number of bytes to map. On output the number of bytes\r
+                                that were mapped.\r
+  @param  DeviceAddress         The resulting map address for the bus master PCI controller to use to\r
+                                access the hosts HostAddress.\r
+  @param  Mapping               A resulting value to pass to Unmap().\r
+\r
+  @retval EFI_SUCCESS           The range was mapped for the returned NumberOfBytes.\r
+  @retval EFI_UNSUPPORTED       The HostAddress cannot be mapped as a common buffer.\r
+  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.\r
+  @retval EFI_OUT_OF_RESOURCES  The request could not be completed due to a lack of resources.\r
+  @retval EFI_DEVICE_ERROR      The system hardware could not map the requested address.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+PeiIoMmuMap (\r
+  IN     EDKII_IOMMU_PPI                            *This,\r
+  IN     EDKII_IOMMU_OPERATION                      Operation,\r
+  IN     VOID                                       *HostAddress,\r
+  IN OUT UINTN                                      *NumberOfBytes,\r
+  OUT    EFI_PHYSICAL_ADDRESS                       *DeviceAddress,\r
+  OUT    VOID                                       **Mapping\r
+  )\r
+{\r
+  MAP_INFO   *MapInfo;\r
+  UINTN      Length;\r
+\r
+  if (Operation == EdkiiIoMmuOperationBusMasterCommonBuffer ||\r
+      Operation == EdkiiIoMmuOperationBusMasterCommonBuffer64) {\r
+    *DeviceAddress = (UINTN)HostAddress;\r
+    *Mapping = 0;\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  DEBUG ((DEBUG_VERBOSE, "PeiIoMmuMap - HostAddress - 0x%x, NumberOfBytes - %x\n", HostAddress, *NumberOfBytes));\r
+  DEBUG ((DEBUG_VERBOSE, "  mDmaBufferCurrentTop - %x\n", mDmaBufferCurrentTop));\r
+  DEBUG ((DEBUG_VERBOSE, "  mDmaBufferCurrentBottom - %x\n", mDmaBufferCurrentBottom));\r
+\r
+  Length = *NumberOfBytes + sizeof(MAP_INFO);\r
+  if (Length > mDmaBufferCurrentTop - mDmaBufferCurrentBottom) {\r
+    DEBUG ((DEBUG_ERROR, "PeiIoMmuMap - OUT_OF_RESOURCE\n"));\r
+    ASSERT (FALSE);\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  *DeviceAddress = mDmaBufferCurrentBottom;\r
+  mDmaBufferCurrentBottom += Length;\r
+\r
+  MapInfo = (VOID *)(UINTN)(*DeviceAddress + *NumberOfBytes);\r
+  MapInfo->Signature     = MAP_INFO_SIGNATURE;\r
+  MapInfo->Operation     = Operation;\r
+  MapInfo->NumberOfBytes = *NumberOfBytes;\r
+  MapInfo->HostAddress   = (UINTN)HostAddress;\r
+  MapInfo->DeviceAddress = *DeviceAddress;\r
+  *Mapping = MapInfo;\r
+  DEBUG ((DEBUG_VERBOSE, "  Op(%x):DeviceAddress - %x, Mapping - %x\n", Operation, (UINTN)*DeviceAddress, MapInfo));\r
+\r
+  //\r
+  // If this is a read operation from the Bus Master's point of view,\r
+  // then copy the contents of the real buffer into the mapped buffer\r
+  // so the Bus Master can read the contents of the real buffer.\r
+  //\r
+  if (Operation == EdkiiIoMmuOperationBusMasterRead ||\r
+      Operation == EdkiiIoMmuOperationBusMasterRead64) {\r
+    CopyMem (\r
+      (VOID *) (UINTN) MapInfo->DeviceAddress,\r
+      (VOID *) (UINTN) MapInfo->HostAddress,\r
+      MapInfo->NumberOfBytes\r
+      );\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Completes the Map() operation and releases any corresponding resources.\r
+\r
+  @param  This                  The PPI instance pointer.\r
+  @param  Mapping               The mapping value returned from Map().\r
+\r
+  @retval EFI_SUCCESS           The range was unmapped.\r
+  @retval EFI_INVALID_PARAMETER Mapping is not a value that was returned by Map().\r
+  @retval EFI_DEVICE_ERROR      The data was not committed to the target system memory.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+PeiIoMmuUnmap (\r
+  IN  EDKII_IOMMU_PPI                          *This,\r
+  IN  VOID                                     *Mapping\r
+  )\r
+{\r
+  MAP_INFO   *MapInfo;\r
+  UINTN      Length;\r
+\r
+  if (Mapping == NULL) {\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  DEBUG ((DEBUG_VERBOSE, "PeiIoMmuUnmap - Mapping - %x\n", Mapping));\r
+  DEBUG ((DEBUG_VERBOSE, "  mDmaBufferCurrentTop - %x\n", mDmaBufferCurrentTop));\r
+  DEBUG ((DEBUG_VERBOSE, "  mDmaBufferCurrentBottom - %x\n", mDmaBufferCurrentBottom));\r
+\r
+  MapInfo = Mapping;\r
+  ASSERT (MapInfo->Signature == MAP_INFO_SIGNATURE);\r
+  DEBUG ((DEBUG_VERBOSE, "  Op(%x):DeviceAddress - %x, NumberOfBytes - %x\n", MapInfo->Operation, (UINTN)MapInfo->DeviceAddress, MapInfo->NumberOfBytes));\r
+\r
+  //\r
+  // If this is a write operation from the Bus Master's point of view,\r
+  // then copy the contents of the mapped buffer into the real buffer\r
+  // so the processor can read the contents of the real buffer.\r
+  //\r
+  if (MapInfo->Operation == EdkiiIoMmuOperationBusMasterWrite ||\r
+      MapInfo->Operation == EdkiiIoMmuOperationBusMasterWrite64) {\r
+    CopyMem (\r
+      (VOID *) (UINTN) MapInfo->HostAddress,\r
+      (VOID *) (UINTN) MapInfo->DeviceAddress,\r
+      MapInfo->NumberOfBytes\r
+      );\r
+  }\r
+\r
+  Length = MapInfo->NumberOfBytes + sizeof(MAP_INFO);\r
+  if (mDmaBufferCurrentBottom == MapInfo->DeviceAddress + Length) {\r
+    mDmaBufferCurrentBottom -= Length;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Allocates pages that are suitable for an OperationBusMasterCommonBuffer or\r
+  OperationBusMasterCommonBuffer64 mapping.\r
+\r
+  @param  This                  The PPI instance pointer.\r
+  @param  MemoryType            The type of memory to allocate, EfiBootServicesData or\r
+                                EfiRuntimeServicesData.\r
+  @param  Pages                 The number of pages to allocate.\r
+  @param  HostAddress           A pointer to store the base system memory address of the\r
+                                allocated range.\r
+  @param  Attributes            The requested bit mask of attributes for the allocated range.\r
+\r
+  @retval EFI_SUCCESS           The requested memory pages were allocated.\r
+  @retval EFI_UNSUPPORTED       Attributes is unsupported. The only legal attribute bits are\r
+                                MEMORY_WRITE_COMBINE and MEMORY_CACHED.\r
+  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.\r
+  @retval EFI_OUT_OF_RESOURCES  The memory pages could not be allocated.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+PeiIoMmuAllocateBuffer (\r
+  IN     EDKII_IOMMU_PPI                          *This,\r
+  IN     EFI_MEMORY_TYPE                          MemoryType,\r
+  IN     UINTN                                    Pages,\r
+  IN OUT VOID                                     **HostAddress,\r
+  IN     UINT64                                   Attributes\r
+  )\r
+{\r
+  UINTN  Length;\r
+\r
+  DEBUG ((DEBUG_VERBOSE, "PeiIoMmuAllocateBuffer - page - %x\n", Pages));\r
+  DEBUG ((DEBUG_VERBOSE, "  mDmaBufferCurrentTop - %x\n", mDmaBufferCurrentTop));\r
+  DEBUG ((DEBUG_VERBOSE, "  mDmaBufferCurrentBottom - %x\n", mDmaBufferCurrentBottom));\r
+\r
+  Length = EFI_PAGES_TO_SIZE(Pages);\r
+  if (Length > mDmaBufferCurrentTop - mDmaBufferCurrentBottom) {\r
+    DEBUG ((DEBUG_ERROR, "PeiIoMmuAllocateBuffer - OUT_OF_RESOURCE\n"));\r
+    ASSERT (FALSE);\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+  *HostAddress = (VOID *)(UINTN)(mDmaBufferCurrentTop - Length);\r
+  mDmaBufferCurrentTop -= Length;\r
+\r
+  DEBUG ((DEBUG_VERBOSE, "PeiIoMmuAllocateBuffer - allocate - %x\n", *HostAddress));\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Frees memory that was allocated with AllocateBuffer().\r
+\r
+  @param  This                  The PPI instance pointer.\r
+  @param  Pages                 The number of pages to free.\r
+  @param  HostAddress           The base system memory address of the allocated range.\r
+\r
+  @retval EFI_SUCCESS           The requested memory pages were freed.\r
+  @retval EFI_INVALID_PARAMETER The memory range specified by HostAddress and Pages\r
+                                was not allocated with AllocateBuffer().\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+PeiIoMmuFreeBuffer (\r
+  IN  EDKII_IOMMU_PPI                          *This,\r
+  IN  UINTN                                    Pages,\r
+  IN  VOID                                     *HostAddress\r
+  )\r
+{\r
+  UINTN  Length;\r
+\r
+  DEBUG ((DEBUG_VERBOSE, "PeiIoMmuFreeBuffer - page - %x, HostAddr - %x\n", Pages, HostAddress));\r
+  DEBUG ((DEBUG_VERBOSE, "  mDmaBufferCurrentTop - %x\n", mDmaBufferCurrentTop));\r
+  DEBUG ((DEBUG_VERBOSE, "  mDmaBufferCurrentBottom - %x\n", mDmaBufferCurrentBottom));\r
+\r
+  Length = EFI_PAGES_TO_SIZE(Pages);\r
+  if ((UINTN)HostAddress == mDmaBufferCurrentTop) {\r
+    mDmaBufferCurrentTop += Length;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+EDKII_IOMMU_PPI mIoMmuPpi = {\r
+  EDKII_IOMMU_PPI_REVISION,\r
+  PeiIoMmuSetAttribute,\r
+  PeiIoMmuMap,\r
+  PeiIoMmuUnmap,\r
+  PeiIoMmuAllocateBuffer,\r
+  PeiIoMmuFreeBuffer,\r
+};\r
+\r
+CONST EFI_PEI_PPI_DESCRIPTOR mIoMmuPpiList = {\r
+  EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,\r
+  &gEdkiiIoMmuPpiGuid,\r
+  (VOID *) &mIoMmuPpi\r
+};\r
+\r
+#define MEMORY_ATTRIBUTE_MASK (EFI_RESOURCE_ATTRIBUTE_PRESENT | \\r
+                               EFI_RESOURCE_ATTRIBUTE_INITIALIZED | \\r
+                               EFI_RESOURCE_ATTRIBUTE_TESTED | \\r
+                               EFI_RESOURCE_ATTRIBUTE_16_BIT_IO | \\r
+                               EFI_RESOURCE_ATTRIBUTE_32_BIT_IO | \\r
+                               EFI_RESOURCE_ATTRIBUTE_64_BIT_IO \\r
+                               )\r
+\r
+#define TESTED_MEMORY_ATTRIBUTES      (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_TESTED)\r
+\r
+#define INITIALIZED_MEMORY_ATTRIBUTES (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED)\r
+\r
+#define PRESENT_MEMORY_ATTRIBUTES     (EFI_RESOURCE_ATTRIBUTE_PRESENT)\r
+\r
+GLOBAL_REMOVE_IF_UNREFERENCED CHAR8 *mResourceTypeShortName[] = {\r
+  "Mem",\r
+  "MMIO",\r
+  "I/O",\r
+  "FD",\r
+  "MM Port I/O",\r
+  "Reserved Mem",\r
+  "Reserved I/O",\r
+};\r
+\r
+/**\r
+  Return the short name of resource type.\r
+\r
+  @param Type  resource type.\r
+\r
+  @return the short name of resource type.\r
+**/\r
+CHAR8 *\r
+ShortNameOfResourceType (\r
+  IN UINT32 Type\r
+  )\r
+{\r
+  if (Type < sizeof(mResourceTypeShortName) / sizeof(mResourceTypeShortName[0])) {\r
+    return mResourceTypeShortName[Type];\r
+  } else {\r
+    return "Unknown";\r
+  }\r
+}\r
+\r
+/**\r
+  Dump resource hob.\r
+\r
+  @param HobList  the HOB list.\r
+**/\r
+VOID\r
+DumpResourceHob (\r
+  IN VOID                        *HobList\r
+  )\r
+{\r
+  EFI_PEI_HOB_POINTERS        Hob;\r
+  EFI_HOB_RESOURCE_DESCRIPTOR *ResourceHob;\r
+\r
+  DEBUG ((DEBUG_VERBOSE, "Resource Descriptor HOBs\n"));\r
+  for (Hob.Raw = HobList; !END_OF_HOB_LIST (Hob); Hob.Raw = GET_NEXT_HOB (Hob)) {\r
+    if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {\r
+      ResourceHob = Hob.ResourceDescriptor;\r
+      DEBUG ((DEBUG_VERBOSE,\r
+        "  BA=%016lx  L=%016lx  Attr=%08x  ",\r
+        ResourceHob->PhysicalStart,\r
+        ResourceHob->ResourceLength,\r
+        ResourceHob->ResourceAttribute\r
+        ));\r
+      DEBUG ((DEBUG_VERBOSE, ShortNameOfResourceType(ResourceHob->ResourceType)));\r
+      switch (ResourceHob->ResourceType) {\r
+      case EFI_RESOURCE_SYSTEM_MEMORY:\r
+        if ((ResourceHob->ResourceAttribute & EFI_RESOURCE_ATTRIBUTE_PERSISTENT) != 0) {\r
+          DEBUG ((DEBUG_VERBOSE, " (Persistent)"));\r
+        } else if ((ResourceHob->ResourceAttribute & EFI_RESOURCE_ATTRIBUTE_MORE_RELIABLE) != 0) {\r
+          DEBUG ((DEBUG_VERBOSE, " (MoreReliable)"));\r
+        } else if ((ResourceHob->ResourceAttribute & MEMORY_ATTRIBUTE_MASK) == TESTED_MEMORY_ATTRIBUTES) {\r
+          DEBUG ((DEBUG_VERBOSE, " (Tested)"));\r
+        } else if ((ResourceHob->ResourceAttribute & MEMORY_ATTRIBUTE_MASK) == INITIALIZED_MEMORY_ATTRIBUTES) {\r
+          DEBUG ((DEBUG_VERBOSE, " (Init)"));\r
+        } else if ((ResourceHob->ResourceAttribute & MEMORY_ATTRIBUTE_MASK) == PRESENT_MEMORY_ATTRIBUTES) {\r
+          DEBUG ((DEBUG_VERBOSE, " (Present)"));\r
+        } else {\r
+          DEBUG ((DEBUG_VERBOSE, " (Unknown)"));\r
+        }\r
+        break;\r
+      default:\r
+        break;\r
+      }\r
+      DEBUG ((DEBUG_VERBOSE, "\n"));\r
+    }\r
+  }\r
+}\r
+\r
+/**\r
+  Dump PHIT hob.\r
+\r
+  @param HobList  the HOB list.\r
+**/\r
+VOID\r
+DumpPhitHob (\r
+  IN VOID                        *HobList\r
+  )\r
+{\r
+  EFI_HOB_HANDOFF_INFO_TABLE  *PhitHob;\r
+\r
+  PhitHob = HobList;\r
+  ASSERT(GET_HOB_TYPE(HobList) == EFI_HOB_TYPE_HANDOFF);\r
+  DEBUG ((DEBUG_VERBOSE, "PHIT HOB\n"));\r
+  DEBUG ((DEBUG_VERBOSE, "  PhitHob             - 0x%x\n", PhitHob));\r
+  DEBUG ((DEBUG_VERBOSE, "  BootMode            - 0x%x\n", PhitHob->BootMode));\r
+  DEBUG ((DEBUG_VERBOSE, "  EfiMemoryTop        - 0x%016lx\n", PhitHob->EfiMemoryTop));\r
+  DEBUG ((DEBUG_VERBOSE, "  EfiMemoryBottom     - 0x%016lx\n", PhitHob->EfiMemoryBottom));\r
+  DEBUG ((DEBUG_VERBOSE, "  EfiFreeMemoryTop    - 0x%016lx\n", PhitHob->EfiFreeMemoryTop));\r
+  DEBUG ((DEBUG_VERBOSE, "  EfiFreeMemoryBottom - 0x%016lx\n", PhitHob->EfiFreeMemoryBottom));\r
+  DEBUG ((DEBUG_VERBOSE, "  EfiEndOfHobList     - 0x%lx\n", PhitHob->EfiEndOfHobList));\r
+}\r
+\r
+/**\r
+  Get the highest memory.\r
+\r
+  @param HobList  the HOB list.\r
+\r
+  @return the highest memory.\r
+**/\r
+UINT64\r
+GetTopMemory (\r
+  IN VOID                        *HobList\r
+  )\r
+{\r
+  EFI_PEI_HOB_POINTERS        Hob;\r
+  EFI_HOB_RESOURCE_DESCRIPTOR *ResourceHob;\r
+  UINT64                      TopMemory;\r
+  UINT64                      ResourceTop;\r
+\r
+  TopMemory = 0;\r
+  for (Hob.Raw = HobList; !END_OF_HOB_LIST (Hob); Hob.Raw = GET_NEXT_HOB (Hob)) {\r
+    if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {\r
+      ResourceHob = Hob.ResourceDescriptor;\r
+      switch (ResourceHob->ResourceType) {\r
+      case EFI_RESOURCE_SYSTEM_MEMORY:\r
+        ResourceTop = ResourceHob->PhysicalStart + ResourceHob->ResourceLength;\r
+        if (TopMemory < ResourceTop) {\r
+          TopMemory = ResourceTop;\r
+        }\r
+        break;\r
+      default:\r
+        break;\r
+      }\r
+      DEBUG ((DEBUG_VERBOSE, "\n"));\r
+    }\r
+  }\r
+  return TopMemory;\r
+}\r
+\r
+/**\r
+  Initialize DMA protection.\r
+\r
+  @param DmaBufferSize  the DMA buffer size\r
+  @param DmaBufferBase  the DMA buffer base\r
+\r
+  @retval EFI_SUCCESS           the DMA protection is initialized.\r
+  @retval EFI_OUT_OF_RESOURCES  no enough resource to initialize DMA protection.\r
+**/\r
+EFI_STATUS\r
+InitDmaProtection (\r
+  IN   UINTN  DmaBufferSize,\r
+  OUT  UINTN  *DmaBufferBase\r
+  )\r
+{\r
+  EFI_STATUS                  Status;\r
+  VOID                        *HobList;\r
+  EFI_HOB_HANDOFF_INFO_TABLE  *PhitHob;\r
+  UINT32                      LowMemoryAlignment;\r
+  UINT64                      HighMemoryAlignment;\r
+  UINTN                       MemoryAlignment;\r
+  UINTN                       LowBottom;\r
+  UINTN                       LowTop;\r
+  UINTN                       HighBottom;\r
+  UINT64                      HighTop;\r
+\r
+  HobList = GetHobList ();\r
+  DumpPhitHob (HobList);\r
+  DumpResourceHob (HobList);\r
+\r
+  PhitHob = HobList;\r
+\r
+  ASSERT (PhitHob->EfiMemoryBottom < PhitHob->EfiMemoryTop);\r
+\r
+  LowMemoryAlignment = GetLowMemoryAlignment ();\r
+  HighMemoryAlignment = GetHighMemoryAlignment ();\r
+  if (LowMemoryAlignment < HighMemoryAlignment) {\r
+    MemoryAlignment = (UINTN)HighMemoryAlignment;\r
+  } else {\r
+    MemoryAlignment = LowMemoryAlignment;\r
+  }\r
+  ASSERT (DmaBufferSize == ALIGN_VALUE(DmaBufferSize, MemoryAlignment));\r
+  *DmaBufferBase = (UINTN)AllocateAlignedPages (EFI_SIZE_TO_PAGES(DmaBufferSize), MemoryAlignment);\r
+  if (*DmaBufferBase == 0) {\r
+    DEBUG ((DEBUG_INFO, " InitDmaProtection : OutOfResource\n"));\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  LowBottom = 0;\r
+  LowTop = *DmaBufferBase;\r
+  HighBottom = *DmaBufferBase + DmaBufferSize;\r
+  HighTop = GetTopMemory (HobList);\r
+\r
+  Status = SetDmaProtectedRange (\r
+               (UINT32)LowBottom,\r
+               (UINT32)(LowTop - LowBottom),\r
+               HighBottom,\r
+               HighTop - HighBottom\r
+               );\r
+\r
+  if (EFI_ERROR(Status)) {\r
+    FreePages ((VOID *)*DmaBufferBase, EFI_SIZE_TO_PAGES(DmaBufferSize));\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Initializes the Intel VTd PMR PEIM.\r
+\r
+  @param  FileHandle  Handle of the file being invoked.\r
+  @param  PeiServices Describes the list of possible PEI Services.\r
+\r
+  @retval EFI_SUCCESS            Usb bot driver is successfully initialized.\r
+  @retval EFI_OUT_OF_RESOURCES   Can't initialize the driver.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IntelVTdPmrInitialize (\r
+  IN EFI_PEI_FILE_HANDLE       FileHandle,\r
+  IN CONST EFI_PEI_SERVICES    **PeiServices\r
+  )\r
+{\r
+  EFI_STATUS                  Status;\r
+\r
+  if ((PcdGet8(PcdVTdPolicyPropertyMask) & BIT0) == 0) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  Status = PeiServicesLocatePpi (\r
+             &gEdkiiVTdInfoPpiGuid,\r
+             0,\r
+             NULL,\r
+             (VOID **)&mVTdInfoPpi\r
+             );\r
+  ASSERT_EFI_ERROR(Status);\r
+\r
+  //\r
+  // Find a pre-memory in resource hob as DMA buffer\r
+  // Mark PEI memory to be DMA protected.\r
+  //\r
+  Status = InitDmaProtection (mDmaBufferSize, &mDmaBufferBase);\r
+  if (EFI_ERROR(Status)) {\r
+    return Status;\r
+  }\r
+\r
+  DEBUG ((DEBUG_INFO, " DmaBufferBase : 0x%x\n", mDmaBufferBase));\r
+  DEBUG ((DEBUG_INFO, " DmaBufferSize : 0x%x\n", mDmaBufferSize));\r
+\r
+  mDmaBufferCurrentTop = mDmaBufferBase + mDmaBufferSize;\r
+  mDmaBufferCurrentBottom = mDmaBufferBase;\r
+\r
+  //\r
+  // Install PPI.\r
+  //\r
+  Status = PeiServicesInstallPpi (&mIoMmuPpiList);\r
+  ASSERT_EFI_ERROR(Status);\r
+\r
+  return Status;\r
+}\r
+\r
diff --git a/IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmrPei.h b/IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmrPei.h
new file mode 100644 (file)
index 0000000..aa5926a
--- /dev/null
@@ -0,0 +1,68 @@
+/** @file\r
+  The definition for DMA access Library.\r
+\r
+  Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php.\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef __DMA_ACCESS_LIB_H__\r
+#define __DMA_ACCESS_LIB_H__\r
+\r
+/**\r
+  Set DMA protected region.\r
+\r
+  @param LowMemoryBase      The protected low memory region base.\r
+  @param LowMemoryLength    The protected low memory region length.\r
+  @param HighMemoryBase     The protected high memory region base.\r
+  @param HighMemoryLength   The protected high memory region length.\r
+\r
+  @retval EFI_SUCCESS      The DMA protection is set.\r
+  @retval EFI_UNSUPPORTED  The DMA protection is not set.\r
+**/\r
+EFI_STATUS\r
+SetDmaProtectedRange (\r
+  IN UINT32        LowMemoryBase,\r
+  IN UINT32        LowMemoryLength,\r
+  IN UINT64        HighMemoryBase,\r
+  IN UINT64        HighMemoryLength\r
+  );\r
+\r
+/**\r
+  Diable DMA protection.\r
+\r
+  @retval DMA protection is disabled.\r
+**/\r
+EFI_STATUS\r
+DisableDmaProtection (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Get protected low memory alignment.\r
+\r
+  @return protected low memory alignment.\r
+**/\r
+UINT32\r
+GetLowMemoryAlignment (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Get protected high memory alignment.\r
+\r
+  @return protected high memory alignment.\r
+**/\r
+UINT64\r
+GetHighMemoryAlignment (\r
+  VOID\r
+  );\r
+\r
+#endif\r
+\r
diff --git a/IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmrPei.inf b/IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmrPei.inf
new file mode 100644 (file)
index 0000000..86cd7d1
--- /dev/null
@@ -0,0 +1,59 @@
+## @file\r
+# Component INF file for the Intel VTd PMR PEIM.\r
+#\r
+# This driver initializes VTd engine based upon EDKII_VTD_INFO_PPI\r
+# and provide DMA protection in PEI.\r
+#\r
+# Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>\r
+# This program and the accompanying materials\r
+# are licensed and made available under the terms and conditions of the BSD License\r
+# which accompanies this distribution.  The full text of the license may be found at\r
+# http://opensource.org/licenses/bsd-license.php\r
+#\r
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+##\r
+\r
+[Defines]\r
+  INF_VERSION     = 0x00010017\r
+  BASE_NAME       = IntelVTdPmrPei\r
+  MODULE_UNI_FILE = IntelVTdPmrPei.uni\r
+  FILE_GUID       = F906769F-4AED-4A0D-8C7C-FF21B9D1051A\r
+  MODULE_TYPE     = PEIM\r
+  VERSION_STRING  = 1.0\r
+  ENTRY_POINT     = IntelVTdPmrInitialize\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec\r
+  IntelSiliconPkg/IntelSiliconPkg.dec\r
+\r
+[Sources]\r
+  IntelVTdPmrPei.c\r
+  IntelVTdPmrPei.h\r
+  IntelVTdPmr.c\r
+\r
+[LibraryClasses]\r
+  DebugLib\r
+  BaseMemoryLib\r
+  BaseLib\r
+  PeimEntryPoint\r
+  PeiServicesLib\r
+  HobLib\r
+  IoLib\r
+\r
+[Ppis]\r
+  gEdkiiIoMmuPpiGuid            ## PRODUCES\r
+  gEdkiiVTdInfoPpiGuid          ## CONSUMES\r
+\r
+[Pcd]\r
+  gIntelSiliconPkgTokenSpaceGuid.PcdVTdPolicyPropertyMask   ## CONSUMES\r
+\r
+[Depex]\r
+  gEfiPeiMemoryDiscoveredPpiGuid AND\r
+  gEdkiiVTdInfoPpiGuid\r
+\r
+[UserExtensions.TianoCore."ExtraFiles"]\r
+  IntelVTdPmrPeiExtra.uni\r
+\r
diff --git a/IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmrPei.uni b/IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmrPei.uni
new file mode 100644 (file)
index 0000000..11508a4
--- /dev/null
@@ -0,0 +1,20 @@
+// /** @file\r
+// IntelVTdPmrPei Module Localized Abstract and Description Content\r
+//\r
+// Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>\r
+//\r
+// This program and the accompanying materials are\r
+// licensed and made available under the terms and conditions of the BSD License\r
+// which accompanies this distribution.  The full text of the license may be found at\r
+// http://opensource.org/licenses/bsd-license.php\r
+//\r
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+//\r
+// **/\r
+\r
+\r
+#string STR_MODULE_ABSTRACT             #language en-US "Intel VTd PMR PEI Driver."\r
+\r
+#string STR_MODULE_DESCRIPTION          #language en-US "This driver initializes VTd engine based upon EDKII_VTD_INFO_PPI and provide DMA protection to device in PEI."\r
+\r
diff --git a/IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmrPeiExtra.uni b/IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmrPeiExtra.uni
new file mode 100644 (file)
index 0000000..c6b2dec
--- /dev/null
@@ -0,0 +1,20 @@
+// /** @file\r
+// IntelVTdPmrPei Localized Strings and Content\r
+//\r
+// Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>\r
+//\r
+// This program and the accompanying materials are\r
+// licensed and made available under the terms and conditions of the BSD License\r
+// which accompanies this distribution.  The full text of the license may be found at\r
+// http://opensource.org/licenses/bsd-license.php\r
+//\r
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+//\r
+// **/\r
+\r
+#string STR_PROPERTIES_MODULE_NAME\r
+#language en-US\r
+"Intel VTd PMR PEI Driver"\r
+\r
+\r