[edk2] [PATCH] IntelSiliconPkg IntelVTdDxe: Support early SetAttributes()

Star Zeng posted 1 patch 6 years, 3 months ago
Failed in applying to current master (apply log)
.../Feature/VTd/IntelVTdDxe/DmaProtection.c        | 147 +++++++++++++++++++++
.../Feature/VTd/IntelVTdDxe/DmaProtection.h        |  46 ++++++-
.../Feature/VTd/IntelVTdDxe/DmarAcpiTable.c        |   2 +-
.../Feature/VTd/IntelVTdDxe/IntelVTdDxe.c          |  10 +-
4 files changed, 202 insertions(+), 3 deletions(-)
[edk2] [PATCH] IntelSiliconPkg IntelVTdDxe: Support early SetAttributes()
Posted by Star Zeng 6 years, 3 months ago
Support early SetAttributes() before DMAR table is installed.

Cc: Jiewen Yao <jiewen.yao@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Star Zeng <star.zeng@intel.com>
---
 .../Feature/VTd/IntelVTdDxe/DmaProtection.c        | 147 +++++++++++++++++++++
 .../Feature/VTd/IntelVTdDxe/DmaProtection.h        |  46 ++++++-
 .../Feature/VTd/IntelVTdDxe/DmarAcpiTable.c        |   2 +-
 .../Feature/VTd/IntelVTdDxe/IntelVTdDxe.c          |  10 +-
 4 files changed, 202 insertions(+), 3 deletions(-)

diff --git a/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmaProtection.c b/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmaProtection.c
index 013823cc161f..665afe71703d 100644
--- a/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmaProtection.c
+++ b/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmaProtection.c
@@ -18,6 +18,151 @@ UINT64                                  mAbove4GMemoryLimit;
 
 EDKII_PLATFORM_VTD_POLICY_PROTOCOL      *mPlatformVTdPolicy;
 
+VTD_ACCESS_REQUEST                      *mAccessRequest = NULL;
+UINTN                                   mAccessRequestCount = 0;
+UINTN                                   mAccessRequestMaxCount = 0;
+
+/**
+  Append VTd Access Request to global.
+
+  @param[in]  Segment           The Segment used to identify a VTd engine.
+  @param[in]  SourceId          The SourceId used to identify a VTd engine and table entry.
+  @param[in]  BaseAddress       The base of device memory address to be used as the DMA memory.
+  @param[in]  Length            The length of device memory address to be used as the DMA memory.
+  @param[in]  IoMmuAccess       The IOMMU access.
+
+  @retval EFI_SUCCESS           The IoMmuAccess is set for the memory range specified by BaseAddress and Length.
+  @retval EFI_INVALID_PARAMETER BaseAddress is not IoMmu Page size aligned.
+  @retval EFI_INVALID_PARAMETER Length is not IoMmu Page size aligned.
+  @retval EFI_INVALID_PARAMETER Length is 0.
+  @retval EFI_INVALID_PARAMETER IoMmuAccess specified an illegal combination of access.
+  @retval EFI_UNSUPPORTED       The bit mask of IoMmuAccess is not supported by the IOMMU.
+  @retval EFI_UNSUPPORTED       The IOMMU does not support the memory range specified by BaseAddress and Length.
+  @retval EFI_OUT_OF_RESOURCES  There are not enough resources available to modify the IOMMU access.
+  @retval EFI_DEVICE_ERROR      The IOMMU device reported an error while attempting the operation.
+
+**/
+EFI_STATUS
+RequestAccessAttribute (
+  IN UINT16                 Segment,
+  IN VTD_SOURCE_ID          SourceId,
+  IN UINT64                 BaseAddress,
+  IN UINT64                 Length,
+  IN UINT64                 IoMmuAccess
+  )
+{
+  VTD_ACCESS_REQUEST        *NewAccessRequest;
+  UINTN                     Index;
+
+  //
+  // Optimization for memory.
+  //
+  // If the last record is to IoMmuAccess=0,
+  // Check previous records and remove the matched entry.
+  //
+  if (IoMmuAccess == 0) {
+    for (Index = 0; Index < mAccessRequestCount; Index++) {
+      if ((mAccessRequest[Index].Segment == Segment) &&
+          (mAccessRequest[Index].SourceId.Uint16 == SourceId.Uint16) &&
+          (mAccessRequest[Index].BaseAddress == BaseAddress) &&
+          (mAccessRequest[Index].Length == Length) &&
+          (mAccessRequest[Index].IoMmuAccess != 0)) {
+        //
+        // Remove this record [Index].
+        // No need to add the new record.
+        //
+        if (Index != mAccessRequestCount - 1) {
+          CopyMem (
+            &mAccessRequest[Index],
+            &mAccessRequest[Index + 1],
+            sizeof (VTD_ACCESS_REQUEST) * (mAccessRequestCount - 1 - Index)
+            );
+        }
+        ZeroMem (&mAccessRequest[mAccessRequestCount - 1], sizeof(VTD_ACCESS_REQUEST));
+        mAccessRequestCount--;
+        return EFI_SUCCESS;
+      }
+    }
+  }
+
+  if (mAccessRequestCount >= mAccessRequestMaxCount) {
+    NewAccessRequest = AllocateZeroPool (sizeof(*NewAccessRequest) * (mAccessRequestMaxCount + MAX_VTD_ACCESS_REQUEST));
+    if (NewAccessRequest == NULL) {
+      return EFI_OUT_OF_RESOURCES;
+    }
+    mAccessRequestMaxCount += MAX_VTD_ACCESS_REQUEST;
+    if (mAccessRequest != NULL) {
+      CopyMem (NewAccessRequest, mAccessRequest, sizeof(*NewAccessRequest) * mAccessRequestCount);
+      FreePool (mAccessRequest);
+      mAccessRequest = NewAccessRequest;
+    }
+  }
+
+  ASSERT (mAccessRequestCount < mAccessRequestMaxCount);
+
+  mAccessRequest[mAccessRequestCount].Segment = Segment;
+  mAccessRequest[mAccessRequestCount].SourceId = SourceId;
+  mAccessRequest[mAccessRequestCount].BaseAddress = BaseAddress;
+  mAccessRequest[mAccessRequestCount].Length = Length;
+  mAccessRequest[mAccessRequestCount].IoMmuAccess = IoMmuAccess;
+
+  mAccessRequestCount++;
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Process Access Requests from before DMAR table is installed.
+
+**/
+VOID
+ProcessRequestedAccessAttribute (
+  VOID
+  )
+{
+  UINTN       Index;
+  EFI_STATUS  Status;
+
+  DEBUG ((DEBUG_INFO, "ProcessRequestedAccessAttribute ...\n"));
+
+  for (Index = 0; Index < mAccessRequestCount; Index++) {
+    DEBUG ((
+      DEBUG_INFO,
+      "PCI(S%x.B%x.D%x.F%x) ",
+      mAccessRequest[Index].Segment,
+      mAccessRequest[Index].SourceId.Bits.Bus,
+      mAccessRequest[Index].SourceId.Bits.Device,
+      mAccessRequest[Index].SourceId.Bits.Function
+      ));
+    DEBUG ((
+      DEBUG_INFO,
+      "(0x%lx~0x%lx) - %lx\n",
+      mAccessRequest[Index].BaseAddress,
+      mAccessRequest[Index].Length,
+      mAccessRequest[Index].IoMmuAccess
+      ));
+    Status = SetAccessAttribute (
+               mAccessRequest[Index].Segment,
+               mAccessRequest[Index].SourceId,
+               mAccessRequest[Index].BaseAddress,
+               mAccessRequest[Index].Length,
+               mAccessRequest[Index].IoMmuAccess
+               );
+    if (EFI_ERROR (Status)) {
+      DEBUG ((DEBUG_ERROR, "SetAccessAttribute %r: ", Status));
+    }
+  }
+
+  if (mAccessRequest != NULL) {
+    FreePool (mAccessRequest);
+  }
+  mAccessRequest = NULL;
+  mAccessRequestCount = 0;
+  mAccessRequestMaxCount = 0;
+
+  DEBUG ((DEBUG_INFO, "ProcessRequestedAccessAttribute Done\n"));
+}
+
 /**
   return the UEFI memory information.
 
@@ -370,6 +515,8 @@ SetupVtd (
 
   ParseDmarAcpiTableRmrr ();
 
+  ProcessRequestedAccessAttribute ();
+
   for (Index = 0; Index < mVtdUnitNumber; Index++) {
     DEBUG ((DEBUG_INFO,"VTD Unit %d (Segment: %04x)\n", Index, mVtdUnitInformation[Index].Segment));
     if (mVtdUnitInformation[Index].ExtRootEntryTable != NULL) {
diff --git a/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmaProtection.h b/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmaProtection.h
index bc14ff9a6631..767531e4a93f 100644
--- a/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmaProtection.h
+++ b/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmaProtection.h
@@ -1,6 +1,6 @@
 /** @file
 
-  Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2017 - 2018, Intel Corporation. All rights reserved.<BR>
   This program and the accompanying materials
   are licensed and made available under the terms and conditions of the BSD License
   which accompanies this distribution.  The full text of the license may be found at
@@ -84,6 +84,21 @@ typedef struct {
   PCI_DEVICE_INFORMATION           PciDeviceInfo;
 } VTD_UNIT_INFORMATION;
 
+//
+// This is the initial max ACCESS request.
+// The number may be enlarged later.
+//
+#define MAX_VTD_ACCESS_REQUEST      0x100
+
+typedef struct {
+  UINT16                Segment;
+  VTD_SOURCE_ID         SourceId;
+  UINT64                BaseAddress;
+  UINT64                Length;
+  UINT64                IoMmuAccess;
+} VTD_ACCESS_REQUEST;
+
+
 /**
   The scan bus callback function.
 
@@ -561,4 +576,33 @@ GetPciBusDeviceFunction (
   OUT UINT8                                       *Function
   );
 
+/**
+  Append VTd Access Request to global.
+
+  @param[in]  Segment           The Segment used to identify a VTd engine.
+  @param[in]  SourceId          The SourceId used to identify a VTd engine and table entry.
+  @param[in]  BaseAddress       The base of device memory address to be used as the DMA memory.
+  @param[in]  Length            The length of device memory address to be used as the DMA memory.
+  @param[in]  IoMmuAccess       The IOMMU access.
+
+  @retval EFI_SUCCESS           The IoMmuAccess is set for the memory range specified by BaseAddress and Length.
+  @retval EFI_INVALID_PARAMETER BaseAddress is not IoMmu Page size aligned.
+  @retval EFI_INVALID_PARAMETER Length is not IoMmu Page size aligned.
+  @retval EFI_INVALID_PARAMETER Length is 0.
+  @retval EFI_INVALID_PARAMETER IoMmuAccess specified an illegal combination of access.
+  @retval EFI_UNSUPPORTED       The bit mask of IoMmuAccess is not supported by the IOMMU.
+  @retval EFI_UNSUPPORTED       The IOMMU does not support the memory range specified by BaseAddress and Length.
+  @retval EFI_OUT_OF_RESOURCES  There are not enough resources available to modify the IOMMU access.
+  @retval EFI_DEVICE_ERROR      The IOMMU device reported an error while attempting the operation.
+
+**/
+EFI_STATUS
+RequestAccessAttribute (
+  IN UINT16                 Segment,
+  IN VTD_SOURCE_ID          SourceId,
+  IN UINT64                 BaseAddress,
+  IN UINT64                 Length,
+  IN UINT64                 IoMmuAccess
+  );
+
 #endif
diff --git a/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmarAcpiTable.c b/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmarAcpiTable.c
index b16bd93d53f1..b981bcdb3aa0 100644
--- a/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmarAcpiTable.c
+++ b/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmarAcpiTable.c
@@ -27,7 +27,7 @@ typedef struct {
 
 #pragma pack()
 
-EFI_ACPI_DMAR_HEADER  *mAcpiDmarTable;
+EFI_ACPI_DMAR_HEADER  *mAcpiDmarTable = NULL;
 
 /**
   Dump DMAR DeviceScopeEntry.
diff --git a/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/IntelVTdDxe.c b/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/IntelVTdDxe.c
index 570b47cf7364..841a5a9264aa 100644
--- a/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/IntelVTdDxe.c
+++ b/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/IntelVTdDxe.c
@@ -1,7 +1,7 @@
 /** @file
   Intel VTd driver.
 
-  Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2017 - 2018, Intel Corporation. All rights reserved.<BR>
   This program and the accompanying materials
   are licensed and made available under the terms and conditions of the BSD License
   which accompanies this distribution.  The full text of the license may be found at
@@ -231,6 +231,14 @@ VTdSetAttribute (
   DEBUG ((DEBUG_VERBOSE, "PCI(S%x.B%x.D%x.F%x) ", Segment, SourceId.Bits.Bus, SourceId.Bits.Device, SourceId.Bits.Function));
   DEBUG ((DEBUG_VERBOSE, "(0x%lx~0x%lx) - %lx\n", DeviceAddress, Length, IoMmuAccess));
 
+  if (mAcpiDmarTable == NULL) {
+    //
+    // Record the entry to driver global variable.
+    // As such once VTd is activated, the setting can be adopted.
+    //
+    return RequestAccessAttribute (Segment, SourceId, DeviceAddress, Length, IoMmuAccess);
+  }
+
   PERF_CODE (
     AsciiSPrint (PerfToken, sizeof(PerfToken), "S%04xB%02xD%02xF%01x", Segment, SourceId.Bits.Bus, SourceId.Bits.Device, SourceId.Bits.Function);
     Identifier = (Segment << 16) | SourceId.Uint16;
-- 
2.7.0.windows.1

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel
Re: [edk2] [PATCH] IntelSiliconPkg IntelVTdDxe: Support early SetAttributes()
Posted by Yao, Jiewen 6 years, 3 months ago
Reviewed-by: Jiewen.yao@intel.com

> -----Original Message-----
> From: Zeng, Star
> Sent: Thursday, January 4, 2018 11:34 AM
> To: edk2-devel@lists.01.org
> Cc: Zeng, Star <star.zeng@intel.com>; Yao, Jiewen <jiewen.yao@intel.com>
> Subject: [PATCH] IntelSiliconPkg IntelVTdDxe: Support early SetAttributes()
> 
> Support early SetAttributes() before DMAR table is installed.
> 
> Cc: Jiewen Yao <jiewen.yao@intel.com>
> Contributed-under: TianoCore Contribution Agreement 1.1
> Signed-off-by: Star Zeng <star.zeng@intel.com>
> ---
>  .../Feature/VTd/IntelVTdDxe/DmaProtection.c        | 147
> +++++++++++++++++++++
>  .../Feature/VTd/IntelVTdDxe/DmaProtection.h        |  46 ++++++-
>  .../Feature/VTd/IntelVTdDxe/DmarAcpiTable.c        |   2 +-
>  .../Feature/VTd/IntelVTdDxe/IntelVTdDxe.c          |  10 +-
>  4 files changed, 202 insertions(+), 3 deletions(-)
> 
> diff --git a/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmaProtection.c
> b/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmaProtection.c
> index 013823cc161f..665afe71703d 100644
> --- a/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmaProtection.c
> +++ b/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmaProtection.c
> @@ -18,6 +18,151 @@ UINT64
> mAbove4GMemoryLimit;
> 
>  EDKII_PLATFORM_VTD_POLICY_PROTOCOL      *mPlatformVTdPolicy;
> 
> +VTD_ACCESS_REQUEST                      *mAccessRequest = NULL;
> +UINTN                                   mAccessRequestCount = 0;
> +UINTN                                   mAccessRequestMaxCount = 0;
> +
> +/**
> +  Append VTd Access Request to global.
> +
> +  @param[in]  Segment           The Segment used to identify a VTd
> engine.
> +  @param[in]  SourceId          The SourceId used to identify a VTd
> engine and table entry.
> +  @param[in]  BaseAddress       The base of device memory address to be
> used as the DMA memory.
> +  @param[in]  Length            The length of device memory address to
> be used as the DMA memory.
> +  @param[in]  IoMmuAccess       The IOMMU access.
> +
> +  @retval EFI_SUCCESS           The IoMmuAccess is set for the memory
> range specified by BaseAddress and Length.
> +  @retval EFI_INVALID_PARAMETER BaseAddress is not IoMmu Page size
> aligned.
> +  @retval EFI_INVALID_PARAMETER Length is not IoMmu Page size aligned.
> +  @retval EFI_INVALID_PARAMETER Length is 0.
> +  @retval EFI_INVALID_PARAMETER IoMmuAccess specified an illegal
> combination of access.
> +  @retval EFI_UNSUPPORTED       The bit mask of IoMmuAccess is not
> supported by the IOMMU.
> +  @retval EFI_UNSUPPORTED       The IOMMU does not support the
> memory range specified by BaseAddress and Length.
> +  @retval EFI_OUT_OF_RESOURCES  There are not enough resources
> available to modify the IOMMU access.
> +  @retval EFI_DEVICE_ERROR      The IOMMU device reported an error
> while attempting the operation.
> +
> +**/
> +EFI_STATUS
> +RequestAccessAttribute (
> +  IN UINT16                 Segment,
> +  IN VTD_SOURCE_ID          SourceId,
> +  IN UINT64                 BaseAddress,
> +  IN UINT64                 Length,
> +  IN UINT64                 IoMmuAccess
> +  )
> +{
> +  VTD_ACCESS_REQUEST        *NewAccessRequest;
> +  UINTN                     Index;
> +
> +  //
> +  // Optimization for memory.
> +  //
> +  // If the last record is to IoMmuAccess=0,
> +  // Check previous records and remove the matched entry.
> +  //
> +  if (IoMmuAccess == 0) {
> +    for (Index = 0; Index < mAccessRequestCount; Index++) {
> +      if ((mAccessRequest[Index].Segment == Segment) &&
> +          (mAccessRequest[Index].SourceId.Uint16 == SourceId.Uint16) &&
> +          (mAccessRequest[Index].BaseAddress == BaseAddress) &&
> +          (mAccessRequest[Index].Length == Length) &&
> +          (mAccessRequest[Index].IoMmuAccess != 0)) {
> +        //
> +        // Remove this record [Index].
> +        // No need to add the new record.
> +        //
> +        if (Index != mAccessRequestCount - 1) {
> +          CopyMem (
> +            &mAccessRequest[Index],
> +            &mAccessRequest[Index + 1],
> +            sizeof (VTD_ACCESS_REQUEST) * (mAccessRequestCount - 1 -
> Index)
> +            );
> +        }
> +        ZeroMem (&mAccessRequest[mAccessRequestCount - 1],
> sizeof(VTD_ACCESS_REQUEST));
> +        mAccessRequestCount--;
> +        return EFI_SUCCESS;
> +      }
> +    }
> +  }
> +
> +  if (mAccessRequestCount >= mAccessRequestMaxCount) {
> +    NewAccessRequest = AllocateZeroPool (sizeof(*NewAccessRequest) *
> (mAccessRequestMaxCount + MAX_VTD_ACCESS_REQUEST));
> +    if (NewAccessRequest == NULL) {
> +      return EFI_OUT_OF_RESOURCES;
> +    }
> +    mAccessRequestMaxCount += MAX_VTD_ACCESS_REQUEST;
> +    if (mAccessRequest != NULL) {
> +      CopyMem (NewAccessRequest, mAccessRequest,
> sizeof(*NewAccessRequest) * mAccessRequestCount);
> +      FreePool (mAccessRequest);
> +      mAccessRequest = NewAccessRequest;
> +    }
> +  }
> +
> +  ASSERT (mAccessRequestCount < mAccessRequestMaxCount);
> +
> +  mAccessRequest[mAccessRequestCount].Segment = Segment;
> +  mAccessRequest[mAccessRequestCount].SourceId = SourceId;
> +  mAccessRequest[mAccessRequestCount].BaseAddress = BaseAddress;
> +  mAccessRequest[mAccessRequestCount].Length = Length;
> +  mAccessRequest[mAccessRequestCount].IoMmuAccess = IoMmuAccess;
> +
> +  mAccessRequestCount++;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Process Access Requests from before DMAR table is installed.
> +
> +**/
> +VOID
> +ProcessRequestedAccessAttribute (
> +  VOID
> +  )
> +{
> +  UINTN       Index;
> +  EFI_STATUS  Status;
> +
> +  DEBUG ((DEBUG_INFO, "ProcessRequestedAccessAttribute ...\n"));
> +
> +  for (Index = 0; Index < mAccessRequestCount; Index++) {
> +    DEBUG ((
> +      DEBUG_INFO,
> +      "PCI(S%x.B%x.D%x.F%x) ",
> +      mAccessRequest[Index].Segment,
> +      mAccessRequest[Index].SourceId.Bits.Bus,
> +      mAccessRequest[Index].SourceId.Bits.Device,
> +      mAccessRequest[Index].SourceId.Bits.Function
> +      ));
> +    DEBUG ((
> +      DEBUG_INFO,
> +      "(0x%lx~0x%lx) - %lx\n",
> +      mAccessRequest[Index].BaseAddress,
> +      mAccessRequest[Index].Length,
> +      mAccessRequest[Index].IoMmuAccess
> +      ));
> +    Status = SetAccessAttribute (
> +               mAccessRequest[Index].Segment,
> +               mAccessRequest[Index].SourceId,
> +               mAccessRequest[Index].BaseAddress,
> +               mAccessRequest[Index].Length,
> +               mAccessRequest[Index].IoMmuAccess
> +               );
> +    if (EFI_ERROR (Status)) {
> +      DEBUG ((DEBUG_ERROR, "SetAccessAttribute %r: ", Status));
> +    }
> +  }
> +
> +  if (mAccessRequest != NULL) {
> +    FreePool (mAccessRequest);
> +  }
> +  mAccessRequest = NULL;
> +  mAccessRequestCount = 0;
> +  mAccessRequestMaxCount = 0;
> +
> +  DEBUG ((DEBUG_INFO, "ProcessRequestedAccessAttribute Done\n"));
> +}
> +
>  /**
>    return the UEFI memory information.
> 
> @@ -370,6 +515,8 @@ SetupVtd (
> 
>    ParseDmarAcpiTableRmrr ();
> 
> +  ProcessRequestedAccessAttribute ();
> +
>    for (Index = 0; Index < mVtdUnitNumber; Index++) {
>      DEBUG ((DEBUG_INFO,"VTD Unit %d (Segment: %04x)\n", Index,
> mVtdUnitInformation[Index].Segment));
>      if (mVtdUnitInformation[Index].ExtRootEntryTable != NULL) {
> diff --git a/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmaProtection.h
> b/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmaProtection.h
> index bc14ff9a6631..767531e4a93f 100644
> --- a/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmaProtection.h
> +++ b/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmaProtection.h
> @@ -1,6 +1,6 @@
>  /** @file
> 
> -  Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
> +  Copyright (c) 2017 - 2018, Intel Corporation. All rights reserved.<BR>
>    This program and the accompanying materials
>    are licensed and made available under the terms and conditions of the BSD
> License
>    which accompanies this distribution.  The full text of the license may be
> found at
> @@ -84,6 +84,21 @@ typedef struct {
>    PCI_DEVICE_INFORMATION           PciDeviceInfo;
>  } VTD_UNIT_INFORMATION;
> 
> +//
> +// This is the initial max ACCESS request.
> +// The number may be enlarged later.
> +//
> +#define MAX_VTD_ACCESS_REQUEST      0x100
> +
> +typedef struct {
> +  UINT16                Segment;
> +  VTD_SOURCE_ID         SourceId;
> +  UINT64                BaseAddress;
> +  UINT64                Length;
> +  UINT64                IoMmuAccess;
> +} VTD_ACCESS_REQUEST;
> +
> +
>  /**
>    The scan bus callback function.
> 
> @@ -561,4 +576,33 @@ GetPciBusDeviceFunction (
>    OUT UINT8                                       *Function
>    );
> 
> +/**
> +  Append VTd Access Request to global.
> +
> +  @param[in]  Segment           The Segment used to identify a VTd
> engine.
> +  @param[in]  SourceId          The SourceId used to identify a VTd
> engine and table entry.
> +  @param[in]  BaseAddress       The base of device memory address to be
> used as the DMA memory.
> +  @param[in]  Length            The length of device memory address to
> be used as the DMA memory.
> +  @param[in]  IoMmuAccess       The IOMMU access.
> +
> +  @retval EFI_SUCCESS           The IoMmuAccess is set for the memory
> range specified by BaseAddress and Length.
> +  @retval EFI_INVALID_PARAMETER BaseAddress is not IoMmu Page size
> aligned.
> +  @retval EFI_INVALID_PARAMETER Length is not IoMmu Page size aligned.
> +  @retval EFI_INVALID_PARAMETER Length is 0.
> +  @retval EFI_INVALID_PARAMETER IoMmuAccess specified an illegal
> combination of access.
> +  @retval EFI_UNSUPPORTED       The bit mask of IoMmuAccess is not
> supported by the IOMMU.
> +  @retval EFI_UNSUPPORTED       The IOMMU does not support the
> memory range specified by BaseAddress and Length.
> +  @retval EFI_OUT_OF_RESOURCES  There are not enough resources
> available to modify the IOMMU access.
> +  @retval EFI_DEVICE_ERROR      The IOMMU device reported an error
> while attempting the operation.
> +
> +**/
> +EFI_STATUS
> +RequestAccessAttribute (
> +  IN UINT16                 Segment,
> +  IN VTD_SOURCE_ID          SourceId,
> +  IN UINT64                 BaseAddress,
> +  IN UINT64                 Length,
> +  IN UINT64                 IoMmuAccess
> +  );
> +
>  #endif
> diff --git a/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmarAcpiTable.c
> b/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmarAcpiTable.c
> index b16bd93d53f1..b981bcdb3aa0 100644
> --- a/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmarAcpiTable.c
> +++ b/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmarAcpiTable.c
> @@ -27,7 +27,7 @@ typedef struct {
> 
>  #pragma pack()
> 
> -EFI_ACPI_DMAR_HEADER  *mAcpiDmarTable;
> +EFI_ACPI_DMAR_HEADER  *mAcpiDmarTable = NULL;
> 
>  /**
>    Dump DMAR DeviceScopeEntry.
> diff --git a/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/IntelVTdDxe.c
> b/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/IntelVTdDxe.c
> index 570b47cf7364..841a5a9264aa 100644
> --- a/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/IntelVTdDxe.c
> +++ b/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/IntelVTdDxe.c
> @@ -1,7 +1,7 @@
>  /** @file
>    Intel VTd driver.
> 
> -  Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
> +  Copyright (c) 2017 - 2018, Intel Corporation. All rights reserved.<BR>
>    This program and the accompanying materials
>    are licensed and made available under the terms and conditions of the BSD
> License
>    which accompanies this distribution.  The full text of the license may be
> found at
> @@ -231,6 +231,14 @@ VTdSetAttribute (
>    DEBUG ((DEBUG_VERBOSE, "PCI(S%x.B%x.D%x.F%x) ", Segment,
> SourceId.Bits.Bus, SourceId.Bits.Device, SourceId.Bits.Function));
>    DEBUG ((DEBUG_VERBOSE, "(0x%lx~0x%lx) - %lx\n", DeviceAddress, Length,
> IoMmuAccess));
> 
> +  if (mAcpiDmarTable == NULL) {
> +    //
> +    // Record the entry to driver global variable.
> +    // As such once VTd is activated, the setting can be adopted.
> +    //
> +    return RequestAccessAttribute (Segment, SourceId, DeviceAddress, Length,
> IoMmuAccess);
> +  }
> +
>    PERF_CODE (
>      AsciiSPrint (PerfToken, sizeof(PerfToken), "S%04xB%02xD%02xF%01x",
> Segment, SourceId.Bits.Bus, SourceId.Bits.Device, SourceId.Bits.Function);
>      Identifier = (Segment << 16) | SourceId.Uint16;
> --
> 2.7.0.windows.1

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel