* [PATCH 01/11] MdeModulePkg/Include: Add IOMMU_PPI.
2017-09-08 15:03 [PATCH 00/11] Add IOMMU PEI support Jiewen Yao
@ 2017-09-08 15:03 ` Jiewen Yao
2017-09-08 15:03 ` [PATCH 02/11] MdeModulePkg/Dec: Add IOMMU_PPI GUID Jiewen Yao
` (10 subsequent siblings)
11 siblings, 0 replies; 19+ messages in thread
From: Jiewen Yao @ 2017-09-08 15:03 UTC (permalink / raw)
To: edk2-devel; +Cc: Star Zeng
This IOMMU_PPI is to provide IOMMU abstraction in PEI.
Cc: Star Zeng <star.zeng@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
---
MdeModulePkg/Include/Ppi/IoMmu.h | 196 ++++++++++++++++++++
1 file changed, 196 insertions(+)
diff --git a/MdeModulePkg/Include/Ppi/IoMmu.h b/MdeModulePkg/Include/Ppi/IoMmu.h
new file mode 100644
index 0000000..5303d68
--- /dev/null
+++ b/MdeModulePkg/Include/Ppi/IoMmu.h
@@ -0,0 +1,196 @@
+/** @file
+ PEI IOMMU PPI.
+
+Copyright (c) 2017, 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 that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+
+#ifndef __PEI_IOMMU_H__
+#define __PEI_IOMMU_H__
+
+//
+// for EFI_ALLOCATE_TYPE
+//
+#include <Uefi.h>
+
+//
+// Include protocol for common definition
+// EDKII_IOMMU_ACCESS_xxx
+// EDKII_IOMMU_OPERATION
+//
+#include <Protocol/IoMmu.h>
+
+//
+// IOMMU Ppi GUID value
+//
+#define EDKII_IOMMU_PPI_GUID \
+ { \
+ 0x70b0af26, 0xf847, 0x4bb6, { 0xaa, 0xb9, 0xcd, 0xe8, 0x4f, 0xc6, 0x14, 0x31 } \
+ }
+
+//
+// Forward reference for pure ANSI compatability
+//
+typedef struct _EDKII_IOMMU_PPI EDKII_IOMMU_PPI;
+
+//
+// Revision The revision to which the IOMMU interface adheres.
+// All future revisions must be backwards compatible.
+// If a future version is not back wards compatible it is not the same GUID.
+//
+#define EDKII_IOMMU_PPI_REVISION 0x00010000
+
+/**
+ Set IOMMU attribute for a system memory.
+
+ If the IOMMU PPI exists, the system memory cannot be used
+ for DMA by default.
+
+ When a device requests a DMA access for a system memory,
+ the device driver need use SetAttribute() to update the IOMMU
+ attribute to request DMA access (read and/or write).
+
+ @param[in] This The PPI instance pointer.
+ @param[in] Mapping The mapping value returned from Map().
+ @param[in] IoMmuAccess The IOMMU access.
+
+ @retval EFI_SUCCESS The IoMmuAccess is set for the memory range specified by DeviceAddress and Length.
+ @retval EFI_INVALID_PARAMETER Mapping is not a value that was returned by Map().
+ @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 Mapping.
+ @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.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EDKII_PEI_IOMMU_SET_ATTRIBUTE)(
+ IN EDKII_IOMMU_PPI *This,
+ IN VOID *Mapping,
+ IN UINT64 IoMmuAccess
+ );
+
+/**
+ Provides the controller-specific addresses required to access system memory from a
+ DMA bus master.
+
+ @param This The PPI instance pointer.
+ @param Operation Indicates if the bus master is going to read or write to system memory.
+ @param HostAddress The system memory address to map to the PCI controller.
+ @param NumberOfBytes On input the number of bytes to map. On output the number of bytes
+ that were mapped.
+ @param DeviceAddress The resulting map address for the bus master PCI controller to use to
+ access the hosts HostAddress.
+ @param Mapping A resulting value to pass to Unmap().
+
+ @retval EFI_SUCCESS The range was mapped for the returned NumberOfBytes.
+ @retval EFI_UNSUPPORTED The HostAddress cannot be mapped as a common buffer.
+ @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
+ @retval EFI_DEVICE_ERROR The system hardware could not map the requested address.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EDKII_PEI_IOMMU_MAP)(
+ IN EDKII_IOMMU_PPI *This,
+ IN EDKII_IOMMU_OPERATION Operation,
+ IN VOID *HostAddress,
+ IN OUT UINTN *NumberOfBytes,
+ OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,
+ OUT VOID **Mapping
+ );
+
+/**
+ Completes the Map() operation and releases any corresponding resources.
+
+ @param This The PPI instance pointer.
+ @param Mapping The mapping value returned from Map().
+
+ @retval EFI_SUCCESS The range was unmapped.
+ @retval EFI_INVALID_PARAMETER Mapping is not a value that was returned by Map().
+ @retval EFI_DEVICE_ERROR The data was not committed to the target system memory.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EDKII_PEI_IOMMU_UNMAP)(
+ IN EDKII_IOMMU_PPI *This,
+ IN VOID *Mapping
+ );
+
+/**
+ Allocates pages that are suitable for an OperationBusMasterCommonBuffer or
+ OperationBusMasterCommonBuffer64 mapping.
+
+ @param This The PPI instance pointer.
+ @param MemoryType The type of memory to allocate, EfiBootServicesData or
+ EfiRuntimeServicesData.
+ @param Pages The number of pages to allocate.
+ @param HostAddress A pointer to store the base system memory address of the
+ allocated range.
+ @param Attributes The requested bit mask of attributes for the allocated range.
+
+ @retval EFI_SUCCESS The requested memory pages were allocated.
+ @retval EFI_UNSUPPORTED Attributes is unsupported. The only legal attribute bits are
+ MEMORY_WRITE_COMBINE and MEMORY_CACHED.
+ @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
+ @retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EDKII_PEI_IOMMU_ALLOCATE_BUFFER)(
+ IN EDKII_IOMMU_PPI *This,
+ IN EFI_MEMORY_TYPE MemoryType,
+ IN UINTN Pages,
+ IN OUT VOID **HostAddress,
+ IN UINT64 Attributes
+ );
+
+/**
+ Frees memory that was allocated with AllocateBuffer().
+
+ @param This The protocol instance pointer.
+ @param Pages The number of pages to free.
+ @param HostAddress The base system memory address of the allocated range.
+
+ @retval EFI_SUCCESS The requested memory pages were freed.
+ @retval EFI_INVALID_PARAMETER The memory range specified by HostAddress and Pages
+ was not allocated with AllocateBuffer().
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EDKII_PEI_IOMMU_FREE_BUFFER)(
+ IN EDKII_IOMMU_PPI *This,
+ IN UINTN Pages,
+ IN VOID *HostAddress
+ );
+
+///
+/// IOMMU PPI structure.
+///
+struct _EDKII_IOMMU_PPI {
+ UINT64 Revision;
+ EDKII_PEI_IOMMU_SET_ATTRIBUTE SetAttribute;
+ EDKII_PEI_IOMMU_MAP Map;
+ EDKII_PEI_IOMMU_UNMAP Unmap;
+ EDKII_PEI_IOMMU_ALLOCATE_BUFFER AllocateBuffer;
+ EDKII_PEI_IOMMU_FREE_BUFFER FreeBuffer;
+};
+
+///
+/// IOMMU PPI GUID variable.
+///
+extern EFI_GUID gEdkiiIoMmuPpiGuid;
+
+#endif
--
2.7.4.windows.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 02/11] MdeModulePkg/Dec: Add IOMMU_PPI GUID.
2017-09-08 15:03 [PATCH 00/11] Add IOMMU PEI support Jiewen Yao
2017-09-08 15:03 ` [PATCH 01/11] MdeModulePkg/Include: Add IOMMU_PPI Jiewen Yao
@ 2017-09-08 15:03 ` Jiewen Yao
2017-09-08 15:03 ` [PATCH 03/11] IntelSiliconPkg/Vtd.h: Add definition for PMR Jiewen Yao
` (9 subsequent siblings)
11 siblings, 0 replies; 19+ messages in thread
From: Jiewen Yao @ 2017-09-08 15:03 UTC (permalink / raw)
To: edk2-devel; +Cc: Star Zeng
Cc: Star Zeng <star.zeng@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
---
MdeModulePkg/MdeModulePkg.dec | 3 +++
1 file changed, 3 insertions(+)
diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec
index 593bff3..403a66a 100644
--- a/MdeModulePkg/MdeModulePkg.dec
+++ b/MdeModulePkg/MdeModulePkg.dec
@@ -431,6 +431,9 @@
## Include/Ppi/SdMmcHostController.h
gEdkiiPeiSdMmcHostControllerPpiGuid = { 0xb30dfeed, 0x947f, 0x4396, { 0xb1, 0x5a, 0xdf, 0xbd, 0xb9, 0x16, 0xdc, 0x24 }}
+ ## Include/Ppi/IoMmu.h
+ gEdkiiIoMmuPpiGuid = { 0x70b0af26, 0xf847, 0x4bb6, { 0xaa, 0xb9, 0xcd, 0xe8, 0x4f, 0xc6, 0x14, 0x31 } }
+
[Protocols]
## Load File protocol provides capability to load and unload EFI image into memory and execute it.
# Include/Protocol/LoadPe32Image.h
--
2.7.4.windows.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 03/11] IntelSiliconPkg/Vtd.h: Add definition for PMR.
2017-09-08 15:03 [PATCH 00/11] Add IOMMU PEI support Jiewen Yao
2017-09-08 15:03 ` [PATCH 01/11] MdeModulePkg/Include: Add IOMMU_PPI Jiewen Yao
2017-09-08 15:03 ` [PATCH 02/11] MdeModulePkg/Dec: Add IOMMU_PPI GUID Jiewen Yao
@ 2017-09-08 15:03 ` Jiewen Yao
2017-09-08 15:03 ` [PATCH 04/11] IntelSiliconPkg/VTdDxe: Disable PMR Jiewen Yao
` (8 subsequent siblings)
11 siblings, 0 replies; 19+ messages in thread
From: Jiewen Yao @ 2017-09-08 15:03 UTC (permalink / raw)
To: edk2-devel; +Cc: Star Zeng
Add missing PMR definition in VTd spec.
Cc: Star Zeng <star.zeng@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
---
IntelSiliconPkg/Include/IndustryStandard/Vtd.h | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/IntelSiliconPkg/Include/IndustryStandard/Vtd.h b/IntelSiliconPkg/Include/IndustryStandard/Vtd.h
index 3b7012c..cfead61 100644
--- a/IntelSiliconPkg/Include/IndustryStandard/Vtd.h
+++ b/IntelSiliconPkg/Include/IndustryStandard/Vtd.h
@@ -247,6 +247,12 @@ typedef union {
#define R_FRCD_REG 0x00 // + FRO
+#define R_PMEN_ENABLE_REG 0x64
+#define R_PMEN_LOW_BASE_REG 0x68
+#define R_PMEN_LOW_LIMITE_REG 0x6C
+#define R_PMEN_HIGH_BASE_REG 0x70
+#define R_PMEN_HIGH_LIMITE_REG 0x78
+
typedef union {
struct {
UINT8 ND:3; // Number of domains supported
--
2.7.4.windows.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 04/11] IntelSiliconPkg/VTdDxe: Disable PMR
2017-09-08 15:03 [PATCH 00/11] Add IOMMU PEI support Jiewen Yao
` (2 preceding siblings ...)
2017-09-08 15:03 ` [PATCH 03/11] IntelSiliconPkg/Vtd.h: Add definition for PMR Jiewen Yao
@ 2017-09-08 15:03 ` Jiewen Yao
2017-09-14 5:35 ` Zeng, Star
2017-09-08 15:03 ` [PATCH 05/11] IntelSiliconPkg/include: Add VTD_INFO PPI Jiewen Yao
` (7 subsequent siblings)
11 siblings, 1 reply; 19+ messages in thread
From: Jiewen Yao @ 2017-09-08 15:03 UTC (permalink / raw)
To: edk2-devel; +Cc: Star Zeng
When VTd translation is enabled, PMR can be disable.
Or the DMA will be blocked by PMR.
Cc: Star Zeng <star.zeng@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
---
IntelSiliconPkg/IntelVTdDxe/VtdReg.c | 51 +++++++++++++++++++-
1 file changed, 50 insertions(+), 1 deletion(-)
diff --git a/IntelSiliconPkg/IntelVTdDxe/VtdReg.c b/IntelSiliconPkg/IntelVTdDxe/VtdReg.c
index 7402d81..1404af7 100644
--- a/IntelSiliconPkg/IntelVTdDxe/VtdReg.c
+++ b/IntelSiliconPkg/IntelVTdDxe/VtdReg.c
@@ -196,6 +196,39 @@ PrepareVtdConfig (
}
/**
+ Disable PMR in all VTd engine.
+**/
+VOID
+DisablePmr (
+ VOID
+ )
+{
+ UINT32 Reg32;
+ VTD_CAP_REG CapReg;
+ UINTN Index;
+
+ DEBUG ((DEBUG_INFO,"DisablePmr\n"));
+ for (Index = 0; Index < mVtdUnitNumber; Index++) {
+ CapReg.Uint64 = MmioRead64 (mVtdUnitInformation[Index].VtdUnitBaseAddress + R_CAP_REG);
+ if (CapReg.Bits.PLMR == 0 || CapReg.Bits.PHMR == 0) {
+ continue ;
+ }
+
+ Reg32 = MmioRead32 (mVtdUnitInformation[Index].VtdUnitBaseAddress + R_PMEN_ENABLE_REG);
+ if ((Reg32 & BIT0) != 0) {
+ MmioWrite32 (mVtdUnitInformation[Index].VtdUnitBaseAddress + R_PMEN_ENABLE_REG, 0x0);
+ do {
+ Reg32 = MmioRead32 (mVtdUnitInformation[Index].VtdUnitBaseAddress + R_PMEN_ENABLE_REG);
+ } while((Reg32 & BIT0) != 0);
+ DEBUG ((DEBUG_INFO,"Pmr(%d) disabled\n", Index));
+ } else {
+ DEBUG ((DEBUG_INFO,"Pmr(%d) not enabled\n", Index));
+ }
+ }
+ return ;
+}
+
+/**
Enable DMAR translation.
@retval EFI_SUCCESS DMAR translation is enabled.
@@ -259,6 +292,11 @@ EnableDmar (
DEBUG ((DEBUG_INFO,"VTD (%d) enabled!<<<<<<\n",Index));
}
+ //
+ // Need disable PMR, since we already setup translation table.
+ //
+ DisablePmr ();
+
mVtdEnabled = TRUE;
return EFI_SUCCESS;
@@ -502,7 +540,7 @@ DumpVtdIfError (
for (Index = 0; Index < (UINTN)CapReg.Bits.NFR + 1; Index++) {
FrcdReg.Uint64[0] = MmioRead64 (mVtdUnitInformation[Num].VtdUnitBaseAddress + ((CapReg.Bits.FRO * 16) + (Index * 16) + R_FRCD_REG));
FrcdReg.Uint64[1] = MmioRead64 (mVtdUnitInformation[Num].VtdUnitBaseAddress + ((CapReg.Bits.FRO * 16) + (Index * 16) + R_FRCD_REG + sizeof(UINT64)));
- if ((FrcdReg.Uint64[0] != 0) || (FrcdReg.Uint64[1] != 0)) {
+ if (FrcdReg.Bits.F != 0) {
HasError = TRUE;
}
}
@@ -511,6 +549,17 @@ DumpVtdIfError (
DEBUG((DEBUG_INFO, "\n#### ERROR ####\n"));
DumpVtdRegs (Num);
DEBUG((DEBUG_INFO, "#### ERROR ####\n\n"));
+ //
+ // Clear
+ //
+ for (Index = 0; Index < (UINTN)CapReg.Bits.NFR + 1; Index++) {
+ FrcdReg.Uint64[1] = MmioRead64 (mVtdUnitInformation[Num].VtdUnitBaseAddress + ((CapReg.Bits.FRO * 16) + (Index * 16) + R_FRCD_REG + sizeof(UINT64)));
+ if (FrcdReg.Bits.F != 0) {
+ FrcdReg.Bits.F = 0;
+ MmioWrite64 (mVtdUnitInformation[Num].VtdUnitBaseAddress + ((CapReg.Bits.FRO * 16) + (Index * 16) + R_FRCD_REG + sizeof(UINT64)), FrcdReg.Uint64[1]);
+ }
+ MmioWrite32 (mVtdUnitInformation[Num].VtdUnitBaseAddress + R_FSTS_REG, MmioRead32 (mVtdUnitInformation[Num].VtdUnitBaseAddress + R_FSTS_REG));
+ }
}
}
}
--
2.7.4.windows.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [PATCH 04/11] IntelSiliconPkg/VTdDxe: Disable PMR
2017-09-08 15:03 ` [PATCH 04/11] IntelSiliconPkg/VTdDxe: Disable PMR Jiewen Yao
@ 2017-09-14 5:35 ` Zeng, Star
2017-09-14 6:02 ` Yao, Jiewen
0 siblings, 1 reply; 19+ messages in thread
From: Zeng, Star @ 2017-09-14 5:35 UTC (permalink / raw)
To: Yao, Jiewen, edk2-devel@lists.01.org; +Cc: Zeng, Star
A minor comment.
Should or need IntelVTdPmrPei disable PMR at endofpei?
Thanks,
Star
-----Original Message-----
From: Yao, Jiewen
Sent: Friday, September 8, 2017 11:04 PM
To: edk2-devel@lists.01.org
Cc: Zeng, Star <star.zeng@intel.com>
Subject: [PATCH 04/11] IntelSiliconPkg/VTdDxe: Disable PMR
When VTd translation is enabled, PMR can be disable.
Or the DMA will be blocked by PMR.
Cc: Star Zeng <star.zeng@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
---
IntelSiliconPkg/IntelVTdDxe/VtdReg.c | 51 +++++++++++++++++++-
1 file changed, 50 insertions(+), 1 deletion(-)
diff --git a/IntelSiliconPkg/IntelVTdDxe/VtdReg.c b/IntelSiliconPkg/IntelVTdDxe/VtdReg.c
index 7402d81..1404af7 100644
--- a/IntelSiliconPkg/IntelVTdDxe/VtdReg.c
+++ b/IntelSiliconPkg/IntelVTdDxe/VtdReg.c
@@ -196,6 +196,39 @@ PrepareVtdConfig (
}
/**
+ Disable PMR in all VTd engine.
+**/
+VOID
+DisablePmr (
+ VOID
+ )
+{
+ UINT32 Reg32;
+ VTD_CAP_REG CapReg;
+ UINTN Index;
+
+ DEBUG ((DEBUG_INFO,"DisablePmr\n"));
+ for (Index = 0; Index < mVtdUnitNumber; Index++) {
+ CapReg.Uint64 = MmioRead64 (mVtdUnitInformation[Index].VtdUnitBaseAddress + R_CAP_REG);
+ if (CapReg.Bits.PLMR == 0 || CapReg.Bits.PHMR == 0) {
+ continue ;
+ }
+
+ Reg32 = MmioRead32 (mVtdUnitInformation[Index].VtdUnitBaseAddress + R_PMEN_ENABLE_REG);
+ if ((Reg32 & BIT0) != 0) {
+ MmioWrite32 (mVtdUnitInformation[Index].VtdUnitBaseAddress + R_PMEN_ENABLE_REG, 0x0);
+ do {
+ Reg32 = MmioRead32 (mVtdUnitInformation[Index].VtdUnitBaseAddress + R_PMEN_ENABLE_REG);
+ } while((Reg32 & BIT0) != 0);
+ DEBUG ((DEBUG_INFO,"Pmr(%d) disabled\n", Index));
+ } else {
+ DEBUG ((DEBUG_INFO,"Pmr(%d) not enabled\n", Index));
+ }
+ }
+ return ;
+}
+
+/**
Enable DMAR translation.
@retval EFI_SUCCESS DMAR translation is enabled.
@@ -259,6 +292,11 @@ EnableDmar (
DEBUG ((DEBUG_INFO,"VTD (%d) enabled!<<<<<<\n",Index));
}
+ //
+ // Need disable PMR, since we already setup translation table.
+ //
+ DisablePmr ();
+
mVtdEnabled = TRUE;
return EFI_SUCCESS;
@@ -502,7 +540,7 @@ DumpVtdIfError (
for (Index = 0; Index < (UINTN)CapReg.Bits.NFR + 1; Index++) {
FrcdReg.Uint64[0] = MmioRead64 (mVtdUnitInformation[Num].VtdUnitBaseAddress + ((CapReg.Bits.FRO * 16) + (Index * 16) + R_FRCD_REG));
FrcdReg.Uint64[1] = MmioRead64 (mVtdUnitInformation[Num].VtdUnitBaseAddress + ((CapReg.Bits.FRO * 16) + (Index * 16) + R_FRCD_REG + sizeof(UINT64)));
- if ((FrcdReg.Uint64[0] != 0) || (FrcdReg.Uint64[1] != 0)) {
+ if (FrcdReg.Bits.F != 0) {
HasError = TRUE;
}
}
@@ -511,6 +549,17 @@ DumpVtdIfError (
DEBUG((DEBUG_INFO, "\n#### ERROR ####\n"));
DumpVtdRegs (Num);
DEBUG((DEBUG_INFO, "#### ERROR ####\n\n"));
+ //
+ // Clear
+ //
+ for (Index = 0; Index < (UINTN)CapReg.Bits.NFR + 1; Index++) {
+ FrcdReg.Uint64[1] = MmioRead64 (mVtdUnitInformation[Num].VtdUnitBaseAddress + ((CapReg.Bits.FRO * 16) + (Index * 16) + R_FRCD_REG + sizeof(UINT64)));
+ if (FrcdReg.Bits.F != 0) {
+ FrcdReg.Bits.F = 0;
+ MmioWrite64 (mVtdUnitInformation[Num].VtdUnitBaseAddress + ((CapReg.Bits.FRO * 16) + (Index * 16) + R_FRCD_REG + sizeof(UINT64)), FrcdReg.Uint64[1]);
+ }
+ MmioWrite32 (mVtdUnitInformation[Num].VtdUnitBaseAddress + R_FSTS_REG, MmioRead32 (mVtdUnitInformation[Num].VtdUnitBaseAddress + R_FSTS_REG));
+ }
}
}
}
--
2.7.4.windows.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [PATCH 04/11] IntelSiliconPkg/VTdDxe: Disable PMR
2017-09-14 5:35 ` Zeng, Star
@ 2017-09-14 6:02 ` Yao, Jiewen
2017-09-14 6:10 ` Zeng, Star
0 siblings, 1 reply; 19+ messages in thread
From: Yao, Jiewen @ 2017-09-14 6:02 UTC (permalink / raw)
To: Zeng, Star, edk2-devel@lists.01.org
I did consider that before.
I do not disable at EndOfPei purposely that because I want to make sure that the DMA protect is still available in early DXE phase, just in case there is bug in other module which forgets disabling BME.
Later it is VTdDxe driver that disable PME, *after* it sets up translation table. As such, the DMA protection is always there.
Thank you
Yao Jiewen
> -----Original Message-----
> From: Zeng, Star
> Sent: Thursday, September 14, 2017 1:36 PM
> To: Yao, Jiewen <jiewen.yao@intel.com>; edk2-devel@lists.01.org
> Cc: Zeng, Star <star.zeng@intel.com>
> Subject: RE: [PATCH 04/11] IntelSiliconPkg/VTdDxe: Disable PMR
>
> A minor comment.
>
> Should or need IntelVTdPmrPei disable PMR at endofpei?
>
>
> Thanks,
> Star
> -----Original Message-----
> From: Yao, Jiewen
> Sent: Friday, September 8, 2017 11:04 PM
> To: edk2-devel@lists.01.org
> Cc: Zeng, Star <star.zeng@intel.com>
> Subject: [PATCH 04/11] IntelSiliconPkg/VTdDxe: Disable PMR
>
> When VTd translation is enabled, PMR can be disable.
> Or the DMA will be blocked by PMR.
>
> Cc: Star Zeng <star.zeng@intel.com>
> Contributed-under: TianoCore Contribution Agreement 1.1
> Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
> ---
> IntelSiliconPkg/IntelVTdDxe/VtdReg.c | 51 +++++++++++++++++++-
> 1 file changed, 50 insertions(+), 1 deletion(-)
>
> diff --git a/IntelSiliconPkg/IntelVTdDxe/VtdReg.c
> b/IntelSiliconPkg/IntelVTdDxe/VtdReg.c
> index 7402d81..1404af7 100644
> --- a/IntelSiliconPkg/IntelVTdDxe/VtdReg.c
> +++ b/IntelSiliconPkg/IntelVTdDxe/VtdReg.c
> @@ -196,6 +196,39 @@ PrepareVtdConfig (
> }
>
> /**
> + Disable PMR in all VTd engine.
> +**/
> +VOID
> +DisablePmr (
> + VOID
> + )
> +{
> + UINT32 Reg32;
> + VTD_CAP_REG CapReg;
> + UINTN Index;
> +
> + DEBUG ((DEBUG_INFO,"DisablePmr\n"));
> + for (Index = 0; Index < mVtdUnitNumber; Index++) {
> + CapReg.Uint64 = MmioRead64
> (mVtdUnitInformation[Index].VtdUnitBaseAddress + R_CAP_REG);
> + if (CapReg.Bits.PLMR == 0 || CapReg.Bits.PHMR == 0) {
> + continue ;
> + }
> +
> + Reg32 = MmioRead32 (mVtdUnitInformation[Index].VtdUnitBaseAddress +
> R_PMEN_ENABLE_REG);
> + if ((Reg32 & BIT0) != 0) {
> + MmioWrite32 (mVtdUnitInformation[Index].VtdUnitBaseAddress +
> R_PMEN_ENABLE_REG, 0x0);
> + do {
> + Reg32 = MmioRead32
> (mVtdUnitInformation[Index].VtdUnitBaseAddress + R_PMEN_ENABLE_REG);
> + } while((Reg32 & BIT0) != 0);
> + DEBUG ((DEBUG_INFO,"Pmr(%d) disabled\n", Index));
> + } else {
> + DEBUG ((DEBUG_INFO,"Pmr(%d) not enabled\n", Index));
> + }
> + }
> + return ;
> +}
> +
> +/**
> Enable DMAR translation.
>
> @retval EFI_SUCCESS DMAR translation is enabled.
> @@ -259,6 +292,11 @@ EnableDmar (
> DEBUG ((DEBUG_INFO,"VTD (%d) enabled!<<<<<<\n",Index));
> }
>
> + //
> + // Need disable PMR, since we already setup translation table.
> + //
> + DisablePmr ();
> +
> mVtdEnabled = TRUE;
>
> return EFI_SUCCESS;
> @@ -502,7 +540,7 @@ DumpVtdIfError (
> for (Index = 0; Index < (UINTN)CapReg.Bits.NFR + 1; Index++) {
> FrcdReg.Uint64[0] = MmioRead64
> (mVtdUnitInformation[Num].VtdUnitBaseAddress + ((CapReg.Bits.FRO * 16) +
> (Index * 16) + R_FRCD_REG));
> FrcdReg.Uint64[1] = MmioRead64
> (mVtdUnitInformation[Num].VtdUnitBaseAddress + ((CapReg.Bits.FRO * 16) +
> (Index * 16) + R_FRCD_REG + sizeof(UINT64)));
> - if ((FrcdReg.Uint64[0] != 0) || (FrcdReg.Uint64[1] != 0)) {
> + if (FrcdReg.Bits.F != 0) {
> HasError = TRUE;
> }
> }
> @@ -511,6 +549,17 @@ DumpVtdIfError (
> DEBUG((DEBUG_INFO, "\n#### ERROR ####\n"));
> DumpVtdRegs (Num);
> DEBUG((DEBUG_INFO, "#### ERROR ####\n\n"));
> + //
> + // Clear
> + //
> + for (Index = 0; Index < (UINTN)CapReg.Bits.NFR + 1; Index++) {
> + FrcdReg.Uint64[1] = MmioRead64
> (mVtdUnitInformation[Num].VtdUnitBaseAddress + ((CapReg.Bits.FRO * 16) +
> (Index * 16) + R_FRCD_REG + sizeof(UINT64)));
> + if (FrcdReg.Bits.F != 0) {
> + FrcdReg.Bits.F = 0;
> + MmioWrite64 (mVtdUnitInformation[Num].VtdUnitBaseAddress +
> ((CapReg.Bits.FRO * 16) + (Index * 16) + R_FRCD_REG + sizeof(UINT64)),
> FrcdReg.Uint64[1]);
> + }
> + MmioWrite32 (mVtdUnitInformation[Num].VtdUnitBaseAddress +
> R_FSTS_REG, MmioRead32 (mVtdUnitInformation[Num].VtdUnitBaseAddress +
> R_FSTS_REG));
> + }
> }
> }
> }
> --
> 2.7.4.windows.1
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 04/11] IntelSiliconPkg/VTdDxe: Disable PMR
2017-09-14 6:02 ` Yao, Jiewen
@ 2017-09-14 6:10 ` Zeng, Star
2017-09-14 6:15 ` Yao, Jiewen
0 siblings, 1 reply; 19+ messages in thread
From: Zeng, Star @ 2017-09-14 6:10 UTC (permalink / raw)
To: Yao, Jiewen, edk2-devel@lists.01.org; +Cc: Zeng, Star
Then, if there is a driver wants to do DMA at early DXE, it must need a PEIM to allocate the DMA buffers in PEI and transfer them to DXE by HOB.
Is that what we want? I want to confirm that.
Thanks,
Star
-----Original Message-----
From: Yao, Jiewen
Sent: Thursday, September 14, 2017 2:03 PM
To: Zeng, Star <star.zeng@intel.com>; edk2-devel@lists.01.org
Subject: RE: [PATCH 04/11] IntelSiliconPkg/VTdDxe: Disable PMR
I did consider that before.
I do not disable at EndOfPei purposely that because I want to make sure that the DMA protect is still available in early DXE phase, just in case there is bug in other module which forgets disabling BME.
Later it is VTdDxe driver that disable PME, *after* it sets up translation table. As such, the DMA protection is always there.
Thank you
Yao Jiewen
> -----Original Message-----
> From: Zeng, Star
> Sent: Thursday, September 14, 2017 1:36 PM
> To: Yao, Jiewen <jiewen.yao@intel.com>; edk2-devel@lists.01.org
> Cc: Zeng, Star <star.zeng@intel.com>
> Subject: RE: [PATCH 04/11] IntelSiliconPkg/VTdDxe: Disable PMR
>
> A minor comment.
>
> Should or need IntelVTdPmrPei disable PMR at endofpei?
>
>
> Thanks,
> Star
> -----Original Message-----
> From: Yao, Jiewen
> Sent: Friday, September 8, 2017 11:04 PM
> To: edk2-devel@lists.01.org
> Cc: Zeng, Star <star.zeng@intel.com>
> Subject: [PATCH 04/11] IntelSiliconPkg/VTdDxe: Disable PMR
>
> When VTd translation is enabled, PMR can be disable.
> Or the DMA will be blocked by PMR.
>
> Cc: Star Zeng <star.zeng@intel.com>
> Contributed-under: TianoCore Contribution Agreement 1.1
> Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
> ---
> IntelSiliconPkg/IntelVTdDxe/VtdReg.c | 51 +++++++++++++++++++-
> 1 file changed, 50 insertions(+), 1 deletion(-)
>
> diff --git a/IntelSiliconPkg/IntelVTdDxe/VtdReg.c
> b/IntelSiliconPkg/IntelVTdDxe/VtdReg.c
> index 7402d81..1404af7 100644
> --- a/IntelSiliconPkg/IntelVTdDxe/VtdReg.c
> +++ b/IntelSiliconPkg/IntelVTdDxe/VtdReg.c
> @@ -196,6 +196,39 @@ PrepareVtdConfig ( }
>
> /**
> + Disable PMR in all VTd engine.
> +**/
> +VOID
> +DisablePmr (
> + VOID
> + )
> +{
> + UINT32 Reg32;
> + VTD_CAP_REG CapReg;
> + UINTN Index;
> +
> + DEBUG ((DEBUG_INFO,"DisablePmr\n")); for (Index = 0; Index <
> + mVtdUnitNumber; Index++) {
> + CapReg.Uint64 = MmioRead64
> (mVtdUnitInformation[Index].VtdUnitBaseAddress + R_CAP_REG);
> + if (CapReg.Bits.PLMR == 0 || CapReg.Bits.PHMR == 0) {
> + continue ;
> + }
> +
> + Reg32 = MmioRead32 (mVtdUnitInformation[Index].VtdUnitBaseAddress
> + +
> R_PMEN_ENABLE_REG);
> + if ((Reg32 & BIT0) != 0) {
> + MmioWrite32 (mVtdUnitInformation[Index].VtdUnitBaseAddress +
> R_PMEN_ENABLE_REG, 0x0);
> + do {
> + Reg32 = MmioRead32
> (mVtdUnitInformation[Index].VtdUnitBaseAddress + R_PMEN_ENABLE_REG);
> + } while((Reg32 & BIT0) != 0);
> + DEBUG ((DEBUG_INFO,"Pmr(%d) disabled\n", Index));
> + } else {
> + DEBUG ((DEBUG_INFO,"Pmr(%d) not enabled\n", Index));
> + }
> + }
> + return ;
> +}
> +
> +/**
> Enable DMAR translation.
>
> @retval EFI_SUCCESS DMAR translation is enabled.
> @@ -259,6 +292,11 @@ EnableDmar (
> DEBUG ((DEBUG_INFO,"VTD (%d) enabled!<<<<<<\n",Index));
> }
>
> + //
> + // Need disable PMR, since we already setup translation table.
> + //
> + DisablePmr ();
> +
> mVtdEnabled = TRUE;
>
> return EFI_SUCCESS;
> @@ -502,7 +540,7 @@ DumpVtdIfError (
> for (Index = 0; Index < (UINTN)CapReg.Bits.NFR + 1; Index++) {
> FrcdReg.Uint64[0] = MmioRead64
> (mVtdUnitInformation[Num].VtdUnitBaseAddress + ((CapReg.Bits.FRO * 16)
> + (Index * 16) + R_FRCD_REG));
> FrcdReg.Uint64[1] = MmioRead64
> (mVtdUnitInformation[Num].VtdUnitBaseAddress + ((CapReg.Bits.FRO * 16)
> + (Index * 16) + R_FRCD_REG + sizeof(UINT64)));
> - if ((FrcdReg.Uint64[0] != 0) || (FrcdReg.Uint64[1] != 0)) {
> + if (FrcdReg.Bits.F != 0) {
> HasError = TRUE;
> }
> }
> @@ -511,6 +549,17 @@ DumpVtdIfError (
> DEBUG((DEBUG_INFO, "\n#### ERROR ####\n"));
> DumpVtdRegs (Num);
> DEBUG((DEBUG_INFO, "#### ERROR ####\n\n"));
> + //
> + // Clear
> + //
> + for (Index = 0; Index < (UINTN)CapReg.Bits.NFR + 1; Index++) {
> + FrcdReg.Uint64[1] = MmioRead64
> (mVtdUnitInformation[Num].VtdUnitBaseAddress + ((CapReg.Bits.FRO * 16)
> + (Index * 16) + R_FRCD_REG + sizeof(UINT64)));
> + if (FrcdReg.Bits.F != 0) {
> + FrcdReg.Bits.F = 0;
> + MmioWrite64 (mVtdUnitInformation[Num].VtdUnitBaseAddress +
> ((CapReg.Bits.FRO * 16) + (Index * 16) + R_FRCD_REG + sizeof(UINT64)),
> FrcdReg.Uint64[1]);
> + }
> + MmioWrite32 (mVtdUnitInformation[Num].VtdUnitBaseAddress +
> R_FSTS_REG, MmioRead32 (mVtdUnitInformation[Num].VtdUnitBaseAddress +
> R_FSTS_REG));
> + }
> }
> }
> }
> --
> 2.7.4.windows.1
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 04/11] IntelSiliconPkg/VTdDxe: Disable PMR
2017-09-14 6:10 ` Zeng, Star
@ 2017-09-14 6:15 ` Yao, Jiewen
0 siblings, 0 replies; 19+ messages in thread
From: Yao, Jiewen @ 2017-09-14 6:15 UTC (permalink / raw)
To: Zeng, Star, edk2-devel@lists.01.org
Yes, I think the usage model is: Any DMA buffer MUST be requested explicitly.
We do not want to allow a driver calling AllocatePage(), then start to use the memory as DMA.
It can help:
1) In case that the DMA buffer address is not identical.
2) DMA protection.
Thank you
Yao Jiewen
From: Zeng, Star
Sent: Thursday, September 14, 2017 2:10 PM
To: Yao, Jiewen <jiewen.yao@intel.com>; edk2-devel@lists.01.org
Cc: Zeng, Star <star.zeng@intel.com>
Subject: RE: [PATCH 04/11] IntelSiliconPkg/VTdDxe: Disable PMR
Then, if there is a driver wants to do DMA at early DXE, it must need a PEIM to allocate the DMA buffers in PEI and transfer them to DXE by HOB.
Is that what we want? I want to confirm that.
Thanks,
Star
-----Original Message-----
From: Yao, Jiewen
Sent: Thursday, September 14, 2017 2:03 PM
To: Zeng, Star <star.zeng@intel.com<mailto:star.zeng@intel.com>>; edk2-devel@lists.01.org<mailto:edk2-devel@lists.01.org>
Subject: RE: [PATCH 04/11] IntelSiliconPkg/VTdDxe: Disable PMR
I did consider that before.
I do not disable at EndOfPei purposely that because I want to make sure that the DMA protect is still available in early DXE phase, just in case there is bug in other module which forgets disabling BME.
Later it is VTdDxe driver that disable PME, *after* it sets up translation table. As such, the DMA protection is always there.
Thank you
Yao Jiewen
> -----Original Message-----
> From: Zeng, Star
> Sent: Thursday, September 14, 2017 1:36 PM
> To: Yao, Jiewen <jiewen.yao@intel.com<mailto:jiewen.yao@intel.com>>; edk2-devel@lists.01.org<mailto:edk2-devel@lists.01.org>
> Cc: Zeng, Star <star.zeng@intel.com<mailto:star.zeng@intel.com>>
> Subject: RE: [PATCH 04/11] IntelSiliconPkg/VTdDxe: Disable PMR
>
> A minor comment.
>
> Should or need IntelVTdPmrPei disable PMR at endofpei?
>
>
> Thanks,
> Star
> -----Original Message-----
> From: Yao, Jiewen
> Sent: Friday, September 8, 2017 11:04 PM
> To: edk2-devel@lists.01.org<mailto:edk2-devel@lists.01.org>
> Cc: Zeng, Star <star.zeng@intel.com<mailto:star.zeng@intel.com>>
> Subject: [PATCH 04/11] IntelSiliconPkg/VTdDxe: Disable PMR
>
> When VTd translation is enabled, PMR can be disable.
> Or the DMA will be blocked by PMR.
>
> Cc: Star Zeng <star.zeng@intel.com<mailto:star.zeng@intel.com>>
> Contributed-under: TianoCore Contribution Agreement 1.1
> Signed-off-by: Jiewen Yao <jiewen.yao@intel.com<mailto:jiewen.yao@intel.com>>
> ---
> IntelSiliconPkg/IntelVTdDxe/VtdReg.c | 51 +++++++++++++++++++-
> 1 file changed, 50 insertions(+), 1 deletion(-)
>
> diff --git a/IntelSiliconPkg/IntelVTdDxe/VtdReg.c
> b/IntelSiliconPkg/IntelVTdDxe/VtdReg.c
> index 7402d81..1404af7 100644
> --- a/IntelSiliconPkg/IntelVTdDxe/VtdReg.c
> +++ b/IntelSiliconPkg/IntelVTdDxe/VtdReg.c
> @@ -196,6 +196,39 @@ PrepareVtdConfig ( }
>
> /**
> + Disable PMR in all VTd engine.
> +**/
> +VOID
> +DisablePmr (
> + VOID
> + )
> +{
> + UINT32 Reg32;
> + VTD_CAP_REG CapReg;
> + UINTN Index;
> +
> + DEBUG ((DEBUG_INFO,"DisablePmr\n")); for (Index = 0; Index <
> + mVtdUnitNumber; Index++) {
> + CapReg.Uint64 = MmioRead64
> (mVtdUnitInformation[Index].VtdUnitBaseAddress + R_CAP_REG);
> + if (CapReg.Bits.PLMR == 0 || CapReg.Bits.PHMR == 0) {
> + continue ;
> + }
> +
> + Reg32 = MmioRead32 (mVtdUnitInformation[Index].VtdUnitBaseAddress
> + +
> R_PMEN_ENABLE_REG);
> + if ((Reg32 & BIT0) != 0) {
> + MmioWrite32 (mVtdUnitInformation[Index].VtdUnitBaseAddress +
> R_PMEN_ENABLE_REG, 0x0);
> + do {
> + Reg32 = MmioRead32
> (mVtdUnitInformation[Index].VtdUnitBaseAddress + R_PMEN_ENABLE_REG);
> + } while((Reg32 & BIT0) != 0);
> + DEBUG ((DEBUG_INFO,"Pmr(%d) disabled\n", Index));
> + } else {
> + DEBUG ((DEBUG_INFO,"Pmr(%d) not enabled\n", Index));
> + }
> + }
> + return ;
> +}
> +
> +/**
> Enable DMAR translation.
>
> @retval EFI_SUCCESS DMAR translation is enabled.
> @@ -259,6 +292,11 @@ EnableDmar (
> DEBUG ((DEBUG_INFO,"VTD (%d) enabled!<<<<<<\n",Index));
> }
>
> + //
> + // Need disable PMR, since we already setup translation table.
> + //
> + DisablePmr ();
> +
> mVtdEnabled = TRUE;
>
> return EFI_SUCCESS;
> @@ -502,7 +540,7 @@ DumpVtdIfError (
> for (Index = 0; Index < (UINTN)CapReg.Bits.NFR + 1; Index++) {
> FrcdReg.Uint64[0] = MmioRead64
> (mVtdUnitInformation[Num].VtdUnitBaseAddress + ((CapReg.Bits.FRO * 16)
> + (Index * 16) + R_FRCD_REG));
> FrcdReg.Uint64[1] = MmioRead64
> (mVtdUnitInformation[Num].VtdUnitBaseAddress + ((CapReg.Bits.FRO * 16)
> + (Index * 16) + R_FRCD_REG + sizeof(UINT64)));
> - if ((FrcdReg.Uint64[0] != 0) || (FrcdReg.Uint64[1] != 0)) {
> + if (FrcdReg.Bits.F != 0) {
> HasError = TRUE;
> }
> }
> @@ -511,6 +549,17 @@ DumpVtdIfError (
> DEBUG((DEBUG_INFO, "\n#### ERROR ####\n"));
> DumpVtdRegs (Num);
> DEBUG((DEBUG_INFO, "#### ERROR ####\n\n"));
> + //
> + // Clear
> + //
> + for (Index = 0; Index < (UINTN)CapReg.Bits.NFR + 1; Index++) {
> + FrcdReg.Uint64[1] = MmioRead64
> (mVtdUnitInformation[Num].VtdUnitBaseAddress + ((CapReg.Bits.FRO * 16)
> + (Index * 16) + R_FRCD_REG + sizeof(UINT64)));
> + if (FrcdReg.Bits.F != 0) {
> + FrcdReg.Bits.F = 0;
> + MmioWrite64 (mVtdUnitInformation[Num].VtdUnitBaseAddress +
> ((CapReg.Bits.FRO * 16) + (Index * 16) + R_FRCD_REG + sizeof(UINT64)),
> FrcdReg.Uint64[1]);
> + }
> + MmioWrite32 (mVtdUnitInformation[Num].VtdUnitBaseAddress +
> R_FSTS_REG, MmioRead32 (mVtdUnitInformation[Num].VtdUnitBaseAddress +
> R_FSTS_REG));
> + }
> }
> }
> }
> --
> 2.7.4.windows.1
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 05/11] IntelSiliconPkg/include: Add VTD_INFO PPI.
2017-09-08 15:03 [PATCH 00/11] Add IOMMU PEI support Jiewen Yao
` (3 preceding siblings ...)
2017-09-08 15:03 ` [PATCH 04/11] IntelSiliconPkg/VTdDxe: Disable PMR Jiewen Yao
@ 2017-09-08 15:03 ` Jiewen Yao
2017-09-08 15:03 ` [PATCH 06/11] IntelSiliconPkg/dec: Add VTD_INFO PPI GUID Jiewen Yao
` (6 subsequent siblings)
11 siblings, 0 replies; 19+ messages in thread
From: Jiewen Yao @ 2017-09-08 15:03 UTC (permalink / raw)
To: edk2-devel; +Cc: Star Zeng
This VTD_INFO_PPI is to provide VTD information in PEI.
As such, we can have a generic VTd driver.
It is a lightweight version DMAR table, but it does
not contain PCI device information.
Cc: Star Zeng <star.zeng@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
---
IntelSiliconPkg/Include/Ppi/VtdInfo.h | 40 ++++++++++++++++++++
1 file changed, 40 insertions(+)
diff --git a/IntelSiliconPkg/Include/Ppi/VtdInfo.h b/IntelSiliconPkg/Include/Ppi/VtdInfo.h
new file mode 100644
index 0000000..e8be63f
--- /dev/null
+++ b/IntelSiliconPkg/Include/Ppi/VtdInfo.h
@@ -0,0 +1,40 @@
+/** @file
+ The definition for VTD information PPI.
+
+ This is a lightweight VTd information report in PEI phase.
+
+ Copyright (c) 2017, 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
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __VTD_INFO_PPI_H__
+#define __VTD_INFO_PPI_H__
+
+#define EDKII_VTD_INFO_PPI_GUID \
+ { \
+ 0x8a59fcb3, 0xf191, 0x400c, { 0x97, 0x67, 0x67, 0xaf, 0x2b, 0x25, 0x68, 0x4a } \
+ }
+
+typedef struct _EDKII_VTD_INFO_PPI EDKII_VTD_INFO_PPI;
+
+#define EDKII_VTD_INFO_PPI_REVISION 0x00010000
+
+struct _EDKII_VTD_INFO_PPI {
+ UINT64 Revision;
+ UINT8 HostAddressWidth;
+ UINT8 Reserved[3];
+ UINT32 VTdEngineCount;
+ UINT64 VTdEngineAddress[1];
+};
+
+extern EFI_GUID gEdkiiVTdInfoPpiGuid;
+
+#endif
+
--
2.7.4.windows.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 06/11] IntelSiliconPkg/dec: Add VTD_INFO PPI GUID
2017-09-08 15:03 [PATCH 00/11] Add IOMMU PEI support Jiewen Yao
` (4 preceding siblings ...)
2017-09-08 15:03 ` [PATCH 05/11] IntelSiliconPkg/include: Add VTD_INFO PPI Jiewen Yao
@ 2017-09-08 15:03 ` Jiewen Yao
2017-09-08 15:03 ` [PATCH 07/11] IntelSiliconPkg: Add IntelVTdPmrPei Jiewen Yao
` (5 subsequent siblings)
11 siblings, 0 replies; 19+ messages in thread
From: Jiewen Yao @ 2017-09-08 15:03 UTC (permalink / raw)
To: edk2-devel; +Cc: Star Zeng
Cc: Star Zeng <star.zeng@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
---
IntelSiliconPkg/IntelSiliconPkg.dec | 3 +++
1 file changed, 3 insertions(+)
diff --git a/IntelSiliconPkg/IntelSiliconPkg.dec b/IntelSiliconPkg/IntelSiliconPkg.dec
index 2fc6379..941380a 100644
--- a/IntelSiliconPkg/IntelSiliconPkg.dec
+++ b/IntelSiliconPkg/IntelSiliconPkg.dec
@@ -33,6 +33,9 @@
# Generic DXE Library / Driver can locate HOB(s) and add SMBIOS records into SMBIOS table
gIntelSmbiosDataHobGuid = { 0x798e722e, 0x15b2, 0x4e13, { 0x8a, 0xe9, 0x6b, 0xa3, 0x0f, 0xf7, 0xf1, 0x67 }}
+[Ppis]
+ gEdkiiVTdInfoPpiGuid = { 0x8a59fcb3, 0xf191, 0x400c, { 0x97, 0x67, 0x67, 0xaf, 0x2b, 0x25, 0x68, 0x4a } }
+
[Protocols]
gEdkiiPlatformVTdPolicyProtocolGuid = { 0x3d17e448, 0x466, 0x4e20, { 0x99, 0x9f, 0xb2, 0xe1, 0x34, 0x88, 0xee, 0x22 }}
--
2.7.4.windows.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 07/11] IntelSiliconPkg: Add IntelVTdPmrPei.
2017-09-08 15:03 [PATCH 00/11] Add IOMMU PEI support Jiewen Yao
` (5 preceding siblings ...)
2017-09-08 15:03 ` [PATCH 06/11] IntelSiliconPkg/dec: Add VTD_INFO PPI GUID Jiewen Yao
@ 2017-09-08 15:03 ` Jiewen Yao
2017-09-08 15:03 ` [PATCH 08/11] IntelSiliconPkg/dsc: Add IntelVTdPmrPeim Jiewen Yao
` (4 subsequent siblings)
11 siblings, 0 replies; 19+ messages in thread
From: Jiewen Yao @ 2017-09-08 15:03 UTC (permalink / raw)
To: edk2-devel; +Cc: Star Zeng
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>
---
IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmr.c | 314 ++++++++++
IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmrPei.c | 615 ++++++++++++++++++++
IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmrPei.h | 68 +++
IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmrPei.inf | 59 ++
IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmrPei.uni | 20 +
| 20 +
6 files changed, 1096 insertions(+)
diff --git a/IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmr.c b/IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmr.c
new file mode 100644
index 0000000..ef08e29
--- /dev/null
+++ b/IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmr.c
@@ -0,0 +1,314 @@
+/** @file
+
+ Copyright (c) 2017, 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
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <PiPei.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <IndustryStandard/Vtd.h>
+#include <Ppi/VTdInfo.h>
+
+#include "IntelVTdPmrPei.h"
+
+extern EDKII_VTD_INFO_PPI *mVTdInfoPpi;
+
+/**
+ Get protected low memory alignment.
+
+ @param VtdUnitBaseAddress The base address of the VTd engine.
+
+ @return protected low memory alignment.
+**/
+UINT32
+GetPlmrAlignment (
+ IN UINTN VtdUnitBaseAddress
+ )
+{
+ UINT32 Data32;
+
+ MmioWrite32 (VtdUnitBaseAddress + R_PMEN_LOW_BASE_REG, 0xFFFFFFFF);
+ Data32 = MmioRead32 (VtdUnitBaseAddress + R_PMEN_LOW_BASE_REG);
+ Data32 = ~Data32 + 1;
+
+ return Data32;
+}
+
+/**
+ Get protected high memory alignment.
+
+ @param VtdUnitBaseAddress The base address of the VTd engine.
+
+ @return protected high memory alignment.
+**/
+UINT64
+GetPhmrAlignment (
+ IN UINTN VtdUnitBaseAddress
+ )
+{
+ UINT64 Data64;
+ UINT8 HostAddressWidth;
+
+ HostAddressWidth = mVTdInfoPpi->HostAddressWidth;
+
+ MmioWrite64 (VtdUnitBaseAddress + R_PMEN_HIGH_BASE_REG, 0xFFFFFFFFFFFFFFFF);
+ Data64 = MmioRead64 (VtdUnitBaseAddress + R_PMEN_HIGH_BASE_REG);
+ Data64 = ~Data64 + 1;
+ Data64 = Data64 & (LShiftU64 (1, HostAddressWidth) - 1);
+
+ return Data64;
+}
+
+/**
+ Get protected low memory alignment.
+
+ @return protected low memory alignment.
+**/
+UINT32
+GetLowMemoryAlignment (
+ VOID
+ )
+{
+ UINTN Index;
+ UINT32 Alignment;
+ UINT32 FinalAlignment;
+
+ FinalAlignment = 0;
+ for (Index = 0; Index < mVTdInfoPpi->VTdEngineCount; Index++) {
+ Alignment = GetPlmrAlignment ((UINTN)mVTdInfoPpi->VTdEngineAddress[Index]);
+ if (FinalAlignment < Alignment) {
+ FinalAlignment = Alignment;
+ }
+ }
+ return FinalAlignment;
+}
+
+/**
+ Get protected high memory alignment.
+
+ @return protected high memory alignment.
+**/
+UINT64
+GetHighMemoryAlignment (
+ VOID
+ )
+{
+ UINTN Index;
+ UINT64 Alignment;
+ UINT64 FinalAlignment;
+
+ FinalAlignment = 0;
+ for (Index = 0; Index < mVTdInfoPpi->VTdEngineCount; Index++) {
+ Alignment = GetPhmrAlignment ((UINTN)mVTdInfoPpi->VTdEngineAddress[Index]);
+ if (FinalAlignment < Alignment) {
+ FinalAlignment = Alignment;
+ }
+ }
+ return FinalAlignment;
+}
+
+/**
+ Enable PMR in the VTd engine.
+
+ @param VtdUnitBaseAddress The base address of the VTd engine.
+
+ @retval EFI_SUCCESS The PMR is enabled.
+ @retval EFI_UNSUPPORTED The PMR is not supported.
+**/
+EFI_STATUS
+EnablePmr (
+ IN UINTN VtdUnitBaseAddress
+ )
+{
+ UINT32 Reg32;
+ VTD_CAP_REG CapReg;
+
+ CapReg.Uint64 = MmioRead64 (VtdUnitBaseAddress + R_CAP_REG);
+ if (CapReg.Bits.PLMR == 0 || CapReg.Bits.PHMR == 0) {
+ return EFI_UNSUPPORTED;
+ }
+
+ Reg32 = MmioRead32 (VtdUnitBaseAddress + R_PMEN_ENABLE_REG);
+ if ((Reg32 & BIT0) == 0) {
+ MmioWrite32 (VtdUnitBaseAddress + R_PMEN_ENABLE_REG, BIT31);
+ do {
+ Reg32 = MmioRead32 (VtdUnitBaseAddress + R_PMEN_ENABLE_REG);
+ } while((Reg32 & BIT0) == 0);
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Disable PMR in the VTd engine.
+
+ @param VtdUnitBaseAddress The base address of the VTd engine.
+
+ @retval EFI_SUCCESS The PMR is disabled.
+ @retval EFI_UNSUPPORTED The PMR is not supported.
+**/
+EFI_STATUS
+DisablePmr (
+ IN UINTN VtdUnitBaseAddress
+ )
+{
+ UINT32 Reg32;
+ VTD_CAP_REG CapReg;
+
+ CapReg.Uint64 = MmioRead64 (VtdUnitBaseAddress + R_CAP_REG);
+ if (CapReg.Bits.PLMR == 0 || CapReg.Bits.PHMR == 0) {
+ return EFI_UNSUPPORTED;
+ }
+
+ Reg32 = MmioRead32 (VtdUnitBaseAddress + R_PMEN_ENABLE_REG);
+ if ((Reg32 & BIT0) != 0) {
+ MmioWrite32 (VtdUnitBaseAddress + R_PMEN_ENABLE_REG, 0x0);
+ do {
+ Reg32 = MmioRead32 (VtdUnitBaseAddress + R_PMEN_ENABLE_REG);
+ } while((Reg32 & BIT0) != 0);
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Set PMR region in the VTd engine.
+
+ @param VtdUnitBaseAddress The base address of the VTd engine.
+ @param LowMemoryBase The protected low memory region base.
+ @param LowMemoryLength The protected low memory region length.
+ @param HighMemoryBase The protected high memory region base.
+ @param HighMemoryLength The protected high memory region length.
+
+ @retval EFI_SUCCESS The PMR is set to protected region.
+ @retval EFI_UNSUPPORTED The PMR is not supported.
+**/
+EFI_STATUS
+SetPmrRegion (
+ IN UINTN VtdUnitBaseAddress,
+ IN UINT32 LowMemoryBase,
+ IN UINT32 LowMemoryLength,
+ IN UINT64 HighMemoryBase,
+ IN UINT64 HighMemoryLength
+ )
+{
+ VTD_CAP_REG CapReg;
+ UINT32 PlmrAlignment;
+ UINT64 PhmrAlignment;
+
+ DEBUG ((DEBUG_INFO, "VtdUnitBaseAddress - 0x%x\n", VtdUnitBaseAddress));
+
+ CapReg.Uint64 = MmioRead64 (VtdUnitBaseAddress + R_CAP_REG);
+ if (CapReg.Bits.PLMR == 0 || CapReg.Bits.PHMR == 0) {
+ DEBUG ((DEBUG_ERROR, "PLMR/PHMR unsupported\n"));
+ return EFI_UNSUPPORTED;
+ }
+
+ PlmrAlignment = GetPlmrAlignment (VtdUnitBaseAddress);
+ DEBUG ((DEBUG_INFO, "PlmrAlignment - 0x%x\n", PlmrAlignment));
+ PhmrAlignment = GetPhmrAlignment (VtdUnitBaseAddress);
+ DEBUG ((DEBUG_INFO, "PhmrAlignment - 0x%lx\n", PhmrAlignment));
+
+ if ((LowMemoryBase != ALIGN_VALUE(LowMemoryBase, PlmrAlignment)) ||
+ (LowMemoryLength != ALIGN_VALUE(LowMemoryLength, PlmrAlignment)) ||
+ (HighMemoryBase != ALIGN_VALUE(HighMemoryBase, PhmrAlignment)) ||
+ (HighMemoryLength != ALIGN_VALUE(HighMemoryLength, PhmrAlignment))) {
+ DEBUG ((DEBUG_ERROR, "PLMR/PHMR alignment issue\n"));
+ return EFI_UNSUPPORTED;
+ }
+
+ if (LowMemoryBase == 0 && LowMemoryLength == 0) {
+ LowMemoryBase = 0xFFFFFFFF;
+ }
+ if (HighMemoryBase == 0 && HighMemoryLength == 0) {
+ HighMemoryBase = 0xFFFFFFFFFFFFFFFF;
+ }
+
+ MmioWrite32 (VtdUnitBaseAddress + R_PMEN_LOW_BASE_REG, LowMemoryBase);
+ MmioWrite32 (VtdUnitBaseAddress + R_PMEN_LOW_LIMITE_REG, LowMemoryBase + LowMemoryLength - 1);
+ MmioWrite64 (VtdUnitBaseAddress + R_PMEN_HIGH_BASE_REG, HighMemoryBase);
+ MmioWrite64 (VtdUnitBaseAddress + R_PMEN_HIGH_LIMITE_REG, HighMemoryBase + HighMemoryLength - 1);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Set DMA protected region.
+
+ @param LowMemoryBase The protected low memory region base.
+ @param LowMemoryLength The protected low memory region length.
+ @param HighMemoryBase The protected high memory region base.
+ @param HighMemoryLength The protected high memory region length.
+
+ @retval EFI_SUCCESS The DMA protection is set.
+ @retval EFI_UNSUPPORTED The DMA protection is not set.
+**/
+EFI_STATUS
+SetDmaProtectedRange (
+ IN UINT32 LowMemoryBase,
+ IN UINT32 LowMemoryLength,
+ IN UINT64 HighMemoryBase,
+ IN UINT64 HighMemoryLength
+ )
+{
+ UINTN Index;
+ EFI_STATUS Status;
+
+ DEBUG ((DEBUG_INFO, "SetDmaProtectedRange - [0x%x, 0x%x] [0x%lx, 0x%lx]\n", LowMemoryBase, LowMemoryLength, HighMemoryBase, HighMemoryLength));
+
+ for (Index = 0; Index < mVTdInfoPpi->VTdEngineCount; Index++) {
+ DisablePmr ((UINTN)mVTdInfoPpi->VTdEngineAddress[Index]);
+ Status = SetPmrRegion (
+ (UINTN)mVTdInfoPpi->VTdEngineAddress[Index],
+ LowMemoryBase,
+ LowMemoryLength,
+ HighMemoryBase,
+ HighMemoryLength
+ );
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+ Status = EnablePmr ((UINTN)mVTdInfoPpi->VTdEngineAddress[Index]);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Diable DMA protection.
+
+ @retval DMA protection is disabled.
+**/
+EFI_STATUS
+DisableDmaProtection (
+ VOID
+ )
+{
+ UINTN Index;
+ EFI_STATUS Status;
+
+ DEBUG ((DEBUG_INFO, "DisableDmaProtection\n"));
+
+ for (Index = 0; Index < mVTdInfoPpi->VTdEngineCount; Index++) {
+ Status = DisablePmr ((UINTN)mVTdInfoPpi->VTdEngineAddress[Index]);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
diff --git a/IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmrPei.c b/IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmrPei.c
new file mode 100644
index 0000000..d118b7e
--- /dev/null
+++ b/IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmrPei.c
@@ -0,0 +1,615 @@
+/** @file
+
+ Copyright (c) 2017, 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
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Uefi.h>
+#include <PiPei.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/HobLib.h>
+#include <IndustryStandard/Vtd.h>
+#include <Ppi/IoMmu.h>
+#include <Ppi/VTdInfo.h>
+
+#include "IntelVTdPmrPei.h"
+
+#define TOTAL_DMA_BUFFER_SIZE SIZE_4MB
+
+EDKII_VTD_INFO_PPI *mVTdInfoPpi;
+UINTN mDmaBufferBase;
+UINTN mDmaBufferSize = TOTAL_DMA_BUFFER_SIZE;
+UINTN mDmaBufferCurrentTop;
+UINTN mDmaBufferCurrentBottom;
+
+#define MAP_INFO_SIGNATURE SIGNATURE_32 ('D', 'M', 'A', 'P')
+typedef struct {
+ UINT32 Signature;
+ EDKII_IOMMU_OPERATION Operation;
+ UINTN NumberOfBytes;
+ EFI_PHYSICAL_ADDRESS HostAddress;
+ EFI_PHYSICAL_ADDRESS DeviceAddress;
+} MAP_INFO;
+
+/**
+
+ PEI Memory Layout:
+
+ +------------------+ <------- EfiMemoryTop
+ | PEI allocated |
+ =========== +==================+
+ ^ | Commom Buf |
+ | | -------------- |
+ DMA Buffer | * DMA FREE * |
+ | | -------------- |
+ V | Read/Write Buf |
+ =========== +==================+
+ | PEI allocated |
+ | -------------- | <------- EfiFreeMemoryTop
+ | * PEI FREE * |
+ | -------------- | <------- EfiFreeMemoryBottom
+ | hob |
+ | -------------- |
+ | Stack |
+ +------------------+ <------- EfiMemoryBottom / Stack Bottom
+
+ +------------------+
+ | Mem Alloc Hob |
+ +------------------+
+
+**/
+
+
+/**
+ Set IOMMU attribute for a system memory.
+
+ If the IOMMU PPI exists, the system memory cannot be used
+ for DMA by default.
+
+ When a device requests a DMA access for a system memory,
+ the device driver need use SetAttribute() to update the IOMMU
+ attribute to request DMA access (read and/or write).
+
+ @param[in] This The PPI instance pointer.
+ @param[in] Mapping The mapping value returned from Map().
+ @param[in] IoMmuAccess The IOMMU access.
+
+ @retval EFI_SUCCESS The IoMmuAccess is set for the memory range specified by DeviceAddress and Length.
+ @retval EFI_INVALID_PARAMETER Mapping is not a value that was returned by Map().
+ @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 Mapping.
+ @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
+EFIAPI
+PeiIoMmuSetAttribute (
+ IN EDKII_IOMMU_PPI *This,
+ IN VOID *Mapping,
+ IN UINT64 IoMmuAccess
+ )
+{
+ return EFI_SUCCESS;
+}
+
+/**
+ Provides the controller-specific addresses required to access system memory from a
+ DMA bus master.
+
+ @param This The PPI instance pointer.
+ @param Operation Indicates if the bus master is going to read or write to system memory.
+ @param HostAddress The system memory address to map to the PCI controller.
+ @param NumberOfBytes On input the number of bytes to map. On output the number of bytes
+ that were mapped.
+ @param DeviceAddress The resulting map address for the bus master PCI controller to use to
+ access the hosts HostAddress.
+ @param Mapping A resulting value to pass to Unmap().
+
+ @retval EFI_SUCCESS The range was mapped for the returned NumberOfBytes.
+ @retval EFI_UNSUPPORTED The HostAddress cannot be mapped as a common buffer.
+ @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
+ @retval EFI_DEVICE_ERROR The system hardware could not map the requested address.
+
+**/
+EFI_STATUS
+EFIAPI
+PeiIoMmuMap (
+ IN EDKII_IOMMU_PPI *This,
+ IN EDKII_IOMMU_OPERATION Operation,
+ IN VOID *HostAddress,
+ IN OUT UINTN *NumberOfBytes,
+ OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,
+ OUT VOID **Mapping
+ )
+{
+ MAP_INFO *MapInfo;
+ UINTN Length;
+
+ if (Operation == EdkiiIoMmuOperationBusMasterCommonBuffer ||
+ Operation == EdkiiIoMmuOperationBusMasterCommonBuffer64) {
+ *DeviceAddress = (UINTN)HostAddress;
+ *Mapping = 0;
+ return EFI_SUCCESS;
+ }
+
+ DEBUG ((DEBUG_VERBOSE, "PeiIoMmuMap - HostAddress - 0x%x, NumberOfBytes - %x\n", HostAddress, *NumberOfBytes));
+ DEBUG ((DEBUG_VERBOSE, " mDmaBufferCurrentTop - %x\n", mDmaBufferCurrentTop));
+ DEBUG ((DEBUG_VERBOSE, " mDmaBufferCurrentBottom - %x\n", mDmaBufferCurrentBottom));
+
+ Length = *NumberOfBytes + sizeof(MAP_INFO);
+ if (Length > mDmaBufferCurrentTop - mDmaBufferCurrentBottom) {
+ DEBUG ((DEBUG_ERROR, "PeiIoMmuMap - OUT_OF_RESOURCE\n"));
+ ASSERT (FALSE);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ *DeviceAddress = mDmaBufferCurrentBottom;
+ mDmaBufferCurrentBottom += Length;
+
+ MapInfo = (VOID *)(UINTN)(*DeviceAddress + *NumberOfBytes);
+ MapInfo->Signature = MAP_INFO_SIGNATURE;
+ MapInfo->Operation = Operation;
+ MapInfo->NumberOfBytes = *NumberOfBytes;
+ MapInfo->HostAddress = (UINTN)HostAddress;
+ MapInfo->DeviceAddress = *DeviceAddress;
+ *Mapping = MapInfo;
+ DEBUG ((DEBUG_VERBOSE, " Op(%x):DeviceAddress - %x, Mapping - %x\n", Operation, (UINTN)*DeviceAddress, MapInfo));
+
+ //
+ // If this is a read operation from the Bus Master's point of view,
+ // then copy the contents of the real buffer into the mapped buffer
+ // so the Bus Master can read the contents of the real buffer.
+ //
+ if (Operation == EdkiiIoMmuOperationBusMasterRead ||
+ Operation == EdkiiIoMmuOperationBusMasterRead64) {
+ CopyMem (
+ (VOID *) (UINTN) MapInfo->DeviceAddress,
+ (VOID *) (UINTN) MapInfo->HostAddress,
+ MapInfo->NumberOfBytes
+ );
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Completes the Map() operation and releases any corresponding resources.
+
+ @param This The PPI instance pointer.
+ @param Mapping The mapping value returned from Map().
+
+ @retval EFI_SUCCESS The range was unmapped.
+ @retval EFI_INVALID_PARAMETER Mapping is not a value that was returned by Map().
+ @retval EFI_DEVICE_ERROR The data was not committed to the target system memory.
+**/
+EFI_STATUS
+EFIAPI
+PeiIoMmuUnmap (
+ IN EDKII_IOMMU_PPI *This,
+ IN VOID *Mapping
+ )
+{
+ MAP_INFO *MapInfo;
+ UINTN Length;
+
+ if (Mapping == NULL) {
+ return EFI_SUCCESS;
+ }
+
+ DEBUG ((DEBUG_VERBOSE, "PeiIoMmuUnmap - Mapping - %x\n", Mapping));
+ DEBUG ((DEBUG_VERBOSE, " mDmaBufferCurrentTop - %x\n", mDmaBufferCurrentTop));
+ DEBUG ((DEBUG_VERBOSE, " mDmaBufferCurrentBottom - %x\n", mDmaBufferCurrentBottom));
+
+ MapInfo = Mapping;
+ ASSERT (MapInfo->Signature == MAP_INFO_SIGNATURE);
+ DEBUG ((DEBUG_VERBOSE, " Op(%x):DeviceAddress - %x, NumberOfBytes - %x\n", MapInfo->Operation, (UINTN)MapInfo->DeviceAddress, MapInfo->NumberOfBytes));
+
+ //
+ // If this is a write operation from the Bus Master's point of view,
+ // then copy the contents of the mapped buffer into the real buffer
+ // so the processor can read the contents of the real buffer.
+ //
+ if (MapInfo->Operation == EdkiiIoMmuOperationBusMasterWrite ||
+ MapInfo->Operation == EdkiiIoMmuOperationBusMasterWrite64) {
+ CopyMem (
+ (VOID *) (UINTN) MapInfo->HostAddress,
+ (VOID *) (UINTN) MapInfo->DeviceAddress,
+ MapInfo->NumberOfBytes
+ );
+ }
+
+ Length = MapInfo->NumberOfBytes + sizeof(MAP_INFO);
+ if (mDmaBufferCurrentBottom == MapInfo->DeviceAddress + Length) {
+ mDmaBufferCurrentBottom -= Length;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Allocates pages that are suitable for an OperationBusMasterCommonBuffer or
+ OperationBusMasterCommonBuffer64 mapping.
+
+ @param This The PPI instance pointer.
+ @param MemoryType The type of memory to allocate, EfiBootServicesData or
+ EfiRuntimeServicesData.
+ @param Pages The number of pages to allocate.
+ @param HostAddress A pointer to store the base system memory address of the
+ allocated range.
+ @param Attributes The requested bit mask of attributes for the allocated range.
+
+ @retval EFI_SUCCESS The requested memory pages were allocated.
+ @retval EFI_UNSUPPORTED Attributes is unsupported. The only legal attribute bits are
+ MEMORY_WRITE_COMBINE and MEMORY_CACHED.
+ @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
+ @retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated.
+
+**/
+EFI_STATUS
+EFIAPI
+PeiIoMmuAllocateBuffer (
+ IN EDKII_IOMMU_PPI *This,
+ IN EFI_MEMORY_TYPE MemoryType,
+ IN UINTN Pages,
+ IN OUT VOID **HostAddress,
+ IN UINT64 Attributes
+ )
+{
+ UINTN Length;
+
+ DEBUG ((DEBUG_VERBOSE, "PeiIoMmuAllocateBuffer - page - %x\n", Pages));
+ DEBUG ((DEBUG_VERBOSE, " mDmaBufferCurrentTop - %x\n", mDmaBufferCurrentTop));
+ DEBUG ((DEBUG_VERBOSE, " mDmaBufferCurrentBottom - %x\n", mDmaBufferCurrentBottom));
+
+ Length = EFI_PAGES_TO_SIZE(Pages);
+ if (Length > mDmaBufferCurrentTop - mDmaBufferCurrentBottom) {
+ DEBUG ((DEBUG_ERROR, "PeiIoMmuAllocateBuffer - OUT_OF_RESOURCE\n"));
+ ASSERT (FALSE);
+ return EFI_OUT_OF_RESOURCES;
+ }
+ *HostAddress = (VOID *)(UINTN)(mDmaBufferCurrentTop - Length);
+ mDmaBufferCurrentTop -= Length;
+
+ DEBUG ((DEBUG_VERBOSE, "PeiIoMmuAllocateBuffer - allocate - %x\n", *HostAddress));
+ return EFI_SUCCESS;
+}
+
+/**
+ Frees memory that was allocated with AllocateBuffer().
+
+ @param This The PPI instance pointer.
+ @param Pages The number of pages to free.
+ @param HostAddress The base system memory address of the allocated range.
+
+ @retval EFI_SUCCESS The requested memory pages were freed.
+ @retval EFI_INVALID_PARAMETER The memory range specified by HostAddress and Pages
+ was not allocated with AllocateBuffer().
+
+**/
+EFI_STATUS
+EFIAPI
+PeiIoMmuFreeBuffer (
+ IN EDKII_IOMMU_PPI *This,
+ IN UINTN Pages,
+ IN VOID *HostAddress
+ )
+{
+ UINTN Length;
+
+ DEBUG ((DEBUG_VERBOSE, "PeiIoMmuFreeBuffer - page - %x, HostAddr - %x\n", Pages, HostAddress));
+ DEBUG ((DEBUG_VERBOSE, " mDmaBufferCurrentTop - %x\n", mDmaBufferCurrentTop));
+ DEBUG ((DEBUG_VERBOSE, " mDmaBufferCurrentBottom - %x\n", mDmaBufferCurrentBottom));
+
+ Length = EFI_PAGES_TO_SIZE(Pages);
+ if ((UINTN)HostAddress == mDmaBufferCurrentTop) {
+ mDmaBufferCurrentTop += Length;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EDKII_IOMMU_PPI mIoMmuPpi = {
+ EDKII_IOMMU_PPI_REVISION,
+ PeiIoMmuSetAttribute,
+ PeiIoMmuMap,
+ PeiIoMmuUnmap,
+ PeiIoMmuAllocateBuffer,
+ PeiIoMmuFreeBuffer,
+};
+
+CONST EFI_PEI_PPI_DESCRIPTOR mIoMmuPpiList = {
+ EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gEdkiiIoMmuPpiGuid,
+ (VOID *) &mIoMmuPpi
+};
+
+#define MEMORY_ATTRIBUTE_MASK (EFI_RESOURCE_ATTRIBUTE_PRESENT | \
+ EFI_RESOURCE_ATTRIBUTE_INITIALIZED | \
+ EFI_RESOURCE_ATTRIBUTE_TESTED | \
+ EFI_RESOURCE_ATTRIBUTE_16_BIT_IO | \
+ EFI_RESOURCE_ATTRIBUTE_32_BIT_IO | \
+ EFI_RESOURCE_ATTRIBUTE_64_BIT_IO \
+ )
+
+#define TESTED_MEMORY_ATTRIBUTES (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_TESTED)
+
+#define INITIALIZED_MEMORY_ATTRIBUTES (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED)
+
+#define PRESENT_MEMORY_ATTRIBUTES (EFI_RESOURCE_ATTRIBUTE_PRESENT)
+
+GLOBAL_REMOVE_IF_UNREFERENCED CHAR8 *mResourceTypeShortName[] = {
+ "Mem",
+ "MMIO",
+ "I/O",
+ "FD",
+ "MM Port I/O",
+ "Reserved Mem",
+ "Reserved I/O",
+};
+
+/**
+ Return the short name of resource type.
+
+ @param Type resource type.
+
+ @return the short name of resource type.
+**/
+CHAR8 *
+ShortNameOfResourceType (
+ IN UINT32 Type
+ )
+{
+ if (Type < sizeof(mResourceTypeShortName) / sizeof(mResourceTypeShortName[0])) {
+ return mResourceTypeShortName[Type];
+ } else {
+ return "Unknown";
+ }
+}
+
+/**
+ Dump resource hob.
+
+ @param HobList the HOB list.
+**/
+VOID
+DumpResourceHob (
+ IN VOID *HobList
+ )
+{
+ EFI_PEI_HOB_POINTERS Hob;
+ EFI_HOB_RESOURCE_DESCRIPTOR *ResourceHob;
+
+ DEBUG ((DEBUG_VERBOSE, "Resource Descriptor HOBs\n"));
+ 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) {
+ ResourceHob = Hob.ResourceDescriptor;
+ DEBUG ((DEBUG_VERBOSE,
+ " BA=%016lx L=%016lx Attr=%08x ",
+ ResourceHob->PhysicalStart,
+ ResourceHob->ResourceLength,
+ ResourceHob->ResourceAttribute
+ ));
+ DEBUG ((DEBUG_VERBOSE, ShortNameOfResourceType(ResourceHob->ResourceType)));
+ switch (ResourceHob->ResourceType) {
+ case EFI_RESOURCE_SYSTEM_MEMORY:
+ if ((ResourceHob->ResourceAttribute & EFI_RESOURCE_ATTRIBUTE_PERSISTENT) != 0) {
+ DEBUG ((DEBUG_VERBOSE, " (Persistent)"));
+ } else if ((ResourceHob->ResourceAttribute & EFI_RESOURCE_ATTRIBUTE_MORE_RELIABLE) != 0) {
+ DEBUG ((DEBUG_VERBOSE, " (MoreReliable)"));
+ } else if ((ResourceHob->ResourceAttribute & MEMORY_ATTRIBUTE_MASK) == TESTED_MEMORY_ATTRIBUTES) {
+ DEBUG ((DEBUG_VERBOSE, " (Tested)"));
+ } else if ((ResourceHob->ResourceAttribute & MEMORY_ATTRIBUTE_MASK) == INITIALIZED_MEMORY_ATTRIBUTES) {
+ DEBUG ((DEBUG_VERBOSE, " (Init)"));
+ } else if ((ResourceHob->ResourceAttribute & MEMORY_ATTRIBUTE_MASK) == PRESENT_MEMORY_ATTRIBUTES) {
+ DEBUG ((DEBUG_VERBOSE, " (Present)"));
+ } else {
+ DEBUG ((DEBUG_VERBOSE, " (Unknown)"));
+ }
+ break;
+ default:
+ break;
+ }
+ DEBUG ((DEBUG_VERBOSE, "\n"));
+ }
+ }
+}
+
+/**
+ Dump PHIT hob.
+
+ @param HobList the HOB list.
+**/
+VOID
+DumpPhitHob (
+ IN VOID *HobList
+ )
+{
+ EFI_HOB_HANDOFF_INFO_TABLE *PhitHob;
+
+ PhitHob = HobList;
+ ASSERT(GET_HOB_TYPE(HobList) == EFI_HOB_TYPE_HANDOFF);
+ DEBUG ((DEBUG_VERBOSE, "PHIT HOB\n"));
+ DEBUG ((DEBUG_VERBOSE, " PhitHob - 0x%x\n", PhitHob));
+ DEBUG ((DEBUG_VERBOSE, " BootMode - 0x%x\n", PhitHob->BootMode));
+ DEBUG ((DEBUG_VERBOSE, " EfiMemoryTop - 0x%016lx\n", PhitHob->EfiMemoryTop));
+ DEBUG ((DEBUG_VERBOSE, " EfiMemoryBottom - 0x%016lx\n", PhitHob->EfiMemoryBottom));
+ DEBUG ((DEBUG_VERBOSE, " EfiFreeMemoryTop - 0x%016lx\n", PhitHob->EfiFreeMemoryTop));
+ DEBUG ((DEBUG_VERBOSE, " EfiFreeMemoryBottom - 0x%016lx\n", PhitHob->EfiFreeMemoryBottom));
+ DEBUG ((DEBUG_VERBOSE, " EfiEndOfHobList - 0x%lx\n", PhitHob->EfiEndOfHobList));
+}
+
+/**
+ Get the highest memory.
+
+ @param HobList the HOB list.
+
+ @return the highest memory.
+**/
+UINT64
+GetTopMemory (
+ IN VOID *HobList
+ )
+{
+ EFI_PEI_HOB_POINTERS Hob;
+ EFI_HOB_RESOURCE_DESCRIPTOR *ResourceHob;
+ UINT64 TopMemory;
+ UINT64 ResourceTop;
+
+ 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) {
+ ResourceHob = Hob.ResourceDescriptor;
+ switch (ResourceHob->ResourceType) {
+ case EFI_RESOURCE_SYSTEM_MEMORY:
+ ResourceTop = ResourceHob->PhysicalStart + ResourceHob->ResourceLength;
+ if (TopMemory < ResourceTop) {
+ TopMemory = ResourceTop;
+ }
+ break;
+ default:
+ break;
+ }
+ DEBUG ((DEBUG_VERBOSE, "\n"));
+ }
+ }
+ return TopMemory;
+}
+
+/**
+ Initialize DMA protection.
+
+ @param DmaBufferSize the DMA buffer size
+ @param DmaBufferBase the DMA buffer base
+
+ @retval EFI_SUCCESS the DMA protection is initialized.
+ @retval EFI_OUT_OF_RESOURCES no enough resource to initialize DMA protection.
+**/
+EFI_STATUS
+InitDmaProtection (
+ IN UINTN DmaBufferSize,
+ OUT UINTN *DmaBufferBase
+ )
+{
+ EFI_STATUS Status;
+ VOID *HobList;
+ EFI_HOB_HANDOFF_INFO_TABLE *PhitHob;
+ UINT32 LowMemoryAlignment;
+ UINT64 HighMemoryAlignment;
+ UINTN MemoryAlignment;
+ UINTN LowBottom;
+ UINTN LowTop;
+ UINTN HighBottom;
+ UINT64 HighTop;
+
+ HobList = GetHobList ();
+ DumpPhitHob (HobList);
+ DumpResourceHob (HobList);
+
+ PhitHob = HobList;
+
+ ASSERT (PhitHob->EfiMemoryBottom < PhitHob->EfiMemoryTop);
+
+ LowMemoryAlignment = GetLowMemoryAlignment ();
+ HighMemoryAlignment = GetHighMemoryAlignment ();
+ if (LowMemoryAlignment < HighMemoryAlignment) {
+ MemoryAlignment = (UINTN)HighMemoryAlignment;
+ } else {
+ MemoryAlignment = LowMemoryAlignment;
+ }
+ ASSERT (DmaBufferSize == ALIGN_VALUE(DmaBufferSize, MemoryAlignment));
+ *DmaBufferBase = (UINTN)AllocateAlignedPages (EFI_SIZE_TO_PAGES(DmaBufferSize), MemoryAlignment);
+ if (*DmaBufferBase == 0) {
+ DEBUG ((DEBUG_INFO, " InitDmaProtection : OutOfResource\n"));
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ LowBottom = 0;
+ LowTop = *DmaBufferBase;
+ HighBottom = *DmaBufferBase + DmaBufferSize;
+ HighTop = GetTopMemory (HobList);
+
+ Status = SetDmaProtectedRange (
+ (UINT32)LowBottom,
+ (UINT32)(LowTop - LowBottom),
+ HighBottom,
+ HighTop - HighBottom
+ );
+
+ if (EFI_ERROR(Status)) {
+ FreePages ((VOID *)*DmaBufferBase, EFI_SIZE_TO_PAGES(DmaBufferSize));
+ }
+
+ return Status;
+}
+
+/**
+ Initializes the Intel VTd PMR PEIM.
+
+ @param FileHandle Handle of the file being invoked.
+ @param PeiServices Describes the list of possible PEI Services.
+
+ @retval EFI_SUCCESS Usb bot driver is successfully initialized.
+ @retval EFI_OUT_OF_RESOURCES Can't initialize the driver.
+
+**/
+EFI_STATUS
+EFIAPI
+IntelVTdPmrInitialize (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ )
+{
+ EFI_STATUS Status;
+
+ if ((PcdGet8(PcdVTdPolicyPropertyMask) & BIT0) == 0) {
+ return EFI_UNSUPPORTED;
+ }
+
+ Status = PeiServicesLocatePpi (
+ &gEdkiiVTdInfoPpiGuid,
+ 0,
+ NULL,
+ (VOID **)&mVTdInfoPpi
+ );
+ ASSERT_EFI_ERROR(Status);
+
+ //
+ // Find a pre-memory in resource hob as DMA buffer
+ // Mark PEI memory to be DMA protected.
+ //
+ Status = InitDmaProtection (mDmaBufferSize, &mDmaBufferBase);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ DEBUG ((DEBUG_INFO, " DmaBufferBase : 0x%x\n", mDmaBufferBase));
+ DEBUG ((DEBUG_INFO, " DmaBufferSize : 0x%x\n", mDmaBufferSize));
+
+ mDmaBufferCurrentTop = mDmaBufferBase + mDmaBufferSize;
+ mDmaBufferCurrentBottom = mDmaBufferBase;
+
+ //
+ // Install PPI.
+ //
+ Status = PeiServicesInstallPpi (&mIoMmuPpiList);
+ ASSERT_EFI_ERROR(Status);
+
+ return Status;
+}
+
diff --git a/IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmrPei.h b/IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmrPei.h
new file mode 100644
index 0000000..aa5926a7
--- /dev/null
+++ b/IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmrPei.h
@@ -0,0 +1,68 @@
+/** @file
+ The definition for DMA access Library.
+
+ Copyright (c) 2017, 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
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __DMA_ACCESS_LIB_H__
+#define __DMA_ACCESS_LIB_H__
+
+/**
+ Set DMA protected region.
+
+ @param LowMemoryBase The protected low memory region base.
+ @param LowMemoryLength The protected low memory region length.
+ @param HighMemoryBase The protected high memory region base.
+ @param HighMemoryLength The protected high memory region length.
+
+ @retval EFI_SUCCESS The DMA protection is set.
+ @retval EFI_UNSUPPORTED The DMA protection is not set.
+**/
+EFI_STATUS
+SetDmaProtectedRange (
+ IN UINT32 LowMemoryBase,
+ IN UINT32 LowMemoryLength,
+ IN UINT64 HighMemoryBase,
+ IN UINT64 HighMemoryLength
+ );
+
+/**
+ Diable DMA protection.
+
+ @retval DMA protection is disabled.
+**/
+EFI_STATUS
+DisableDmaProtection (
+ VOID
+ );
+
+/**
+ Get protected low memory alignment.
+
+ @return protected low memory alignment.
+**/
+UINT32
+GetLowMemoryAlignment (
+ VOID
+ );
+
+/**
+ Get protected high memory alignment.
+
+ @return protected high memory alignment.
+**/
+UINT64
+GetHighMemoryAlignment (
+ VOID
+ );
+
+#endif
+
diff --git a/IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmrPei.inf b/IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmrPei.inf
new file mode 100644
index 0000000..86cd7d1
--- /dev/null
+++ b/IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmrPei.inf
@@ -0,0 +1,59 @@
+## @file
+# Component INF file for the Intel VTd PMR PEIM.
+#
+# This driver initializes VTd engine based upon EDKII_VTD_INFO_PPI
+# and provide DMA protection in PEI.
+#
+# Copyright (c) 2017, 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
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010017
+ BASE_NAME = IntelVTdPmrPei
+ MODULE_UNI_FILE = IntelVTdPmrPei.uni
+ FILE_GUID = F906769F-4AED-4A0D-8C7C-FF21B9D1051A
+ MODULE_TYPE = PEIM
+ VERSION_STRING = 1.0
+ ENTRY_POINT = IntelVTdPmrInitialize
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ IntelSiliconPkg/IntelSiliconPkg.dec
+
+[Sources]
+ IntelVTdPmrPei.c
+ IntelVTdPmrPei.h
+ IntelVTdPmr.c
+
+[LibraryClasses]
+ DebugLib
+ BaseMemoryLib
+ BaseLib
+ PeimEntryPoint
+ PeiServicesLib
+ HobLib
+ IoLib
+
+[Ppis]
+ gEdkiiIoMmuPpiGuid ## PRODUCES
+ gEdkiiVTdInfoPpiGuid ## CONSUMES
+
+[Pcd]
+ gIntelSiliconPkgTokenSpaceGuid.PcdVTdPolicyPropertyMask ## CONSUMES
+
+[Depex]
+ gEfiPeiMemoryDiscoveredPpiGuid AND
+ gEdkiiVTdInfoPpiGuid
+
+[UserExtensions.TianoCore."ExtraFiles"]
+ IntelVTdPmrPeiExtra.uni
+
diff --git a/IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmrPei.uni b/IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmrPei.uni
new file mode 100644
index 0000000..11508a4
--- /dev/null
+++ b/IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmrPei.uni
@@ -0,0 +1,20 @@
+// /** @file
+// IntelVTdPmrPei Module Localized Abstract and Description Content
+//
+// Copyright (c) 2017, 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
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+// **/
+
+
+#string STR_MODULE_ABSTRACT #language en-US "Intel VTd PMR PEI Driver."
+
+#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."
+
--git a/IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmrPeiExtra.uni b/IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmrPeiExtra.uni
new file mode 100644
index 0000000..c6b2dec
--- /dev/null
+++ b/IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmrPeiExtra.uni
@@ -0,0 +1,20 @@
+// /** @file
+// IntelVTdPmrPei Localized Strings and Content
+//
+// Copyright (c) 2017, 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
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+// **/
+
+#string STR_PROPERTIES_MODULE_NAME
+#language en-US
+"Intel VTd PMR PEI Driver"
+
+
--
2.7.4.windows.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 08/11] IntelSiliconPkg/dsc: Add IntelVTdPmrPeim.
2017-09-08 15:03 [PATCH 00/11] Add IOMMU PEI support Jiewen Yao
` (6 preceding siblings ...)
2017-09-08 15:03 ` [PATCH 07/11] IntelSiliconPkg: Add IntelVTdPmrPei Jiewen Yao
@ 2017-09-08 15:03 ` Jiewen Yao
2017-09-08 15:03 ` [PATCH 09/11] IntelSiliconPkg: Add PlatformVTdInfoSamplePei Jiewen Yao
` (3 subsequent siblings)
11 siblings, 0 replies; 19+ messages in thread
From: Jiewen Yao @ 2017-09-08 15:03 UTC (permalink / raw)
To: edk2-devel; +Cc: Star Zeng
Cc: Star Zeng <star.zeng@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
---
IntelSiliconPkg/IntelSiliconPkg.dsc | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/IntelSiliconPkg/IntelSiliconPkg.dsc b/IntelSiliconPkg/IntelSiliconPkg.dsc
index 9a9920f..33e822f 100644
--- a/IntelSiliconPkg/IntelSiliconPkg.dsc
+++ b/IntelSiliconPkg/IntelSiliconPkg.dsc
@@ -40,6 +40,14 @@
SerialPortLib|MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.inf
CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf
+[LibraryClasses.common.PEIM]
+ PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf
+ PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf
+ PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
+
+ MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
+ HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
+
[LibraryClasses.common.DXE_DRIVER]
UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf
UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf
@@ -72,6 +80,7 @@
[Components]
IntelSiliconPkg/Library/DxeSmbiosDataHobLib/DxeSmbiosDataHobLib.inf
IntelSiliconPkg/IntelVTdDxe/IntelVTdDxe.inf
+ IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmrPei.inf
IntelSiliconPkg/PlatformVTdSampleDxe/PlatformVTdSampleDxe.inf
[BuildOptions]
--
2.7.4.windows.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 09/11] IntelSiliconPkg: Add PlatformVTdInfoSamplePei.
2017-09-08 15:03 [PATCH 00/11] Add IOMMU PEI support Jiewen Yao
` (7 preceding siblings ...)
2017-09-08 15:03 ` [PATCH 08/11] IntelSiliconPkg/dsc: Add IntelVTdPmrPeim Jiewen Yao
@ 2017-09-08 15:03 ` Jiewen Yao
2017-09-08 15:03 ` [PATCH 10/11] IntelSiliconPkg/dsc: " Jiewen Yao
` (2 subsequent siblings)
11 siblings, 0 replies; 19+ messages in thread
From: Jiewen Yao @ 2017-09-08 15:03 UTC (permalink / raw)
To: edk2-devel; +Cc: Star Zeng
This is a sample driver to produce VTD_INFO PPI.
Cc: Star Zeng <star.zeng@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
---
IntelSiliconPkg/PlatformVTdInfoSamplePei/PlatformVTdInfoSamplePei.c | 65 ++++++++++++++++++++
IntelSiliconPkg/PlatformVTdInfoSamplePei/PlatformVTdInfoSamplePei.inf | 51 +++++++++++++++
IntelSiliconPkg/PlatformVTdInfoSamplePei/PlatformVTdInfoSamplePei.uni | 20 ++++++
| 20 ++++++
4 files changed, 156 insertions(+)
diff --git a/IntelSiliconPkg/PlatformVTdInfoSamplePei/PlatformVTdInfoSamplePei.c b/IntelSiliconPkg/PlatformVTdInfoSamplePei/PlatformVTdInfoSamplePei.c
new file mode 100644
index 0000000..c79398f
--- /dev/null
+++ b/IntelSiliconPkg/PlatformVTdInfoSamplePei/PlatformVTdInfoSamplePei.c
@@ -0,0 +1,65 @@
+/** @file
+ Platform VTd Info Sample PEI driver.
+
+ Copyright (c) 2017, 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
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <PiPei.h>
+
+#include <Ppi/VTdInfo.h>
+
+#include <Library/PeiServicesLib.h>
+#include <Library/DebugLib.h>
+
+typedef struct {
+ UINT64 Revision;
+ UINT8 HostAddressWidth;
+ UINT8 Reserved[3];
+ UINT32 VTdEngineCount;
+ UINT64 VTdEngineAddress[2];
+} MY_VTD_INFO_PPI;
+
+MY_VTD_INFO_PPI mPlatformVTdSample = {
+ EDKII_VTD_INFO_PPI_REVISION,
+ 0x26,
+ {0},
+ 2,
+ {0xFED90000, 0xFED91000},
+};
+
+EFI_PEI_PPI_DESCRIPTOR mPlatformVTdInfoSampleDesc = {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gEdkiiVTdInfoPpiGuid,
+ &mPlatformVTdSample
+};
+
+/**
+ Platform VTd Info sample driver.
+
+ @param[in] FileHandle Handle of the file being invoked.
+ @param[in] PeiServices Describes the list of possible PEI Services.
+
+ @retval EFI_SUCCESS if it completed successfully.
+**/
+EFI_STATUS
+EFIAPI
+PlatformVTdInfoSampleInitialize (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ )
+{
+ EFI_STATUS Status;
+
+ Status = PeiServicesInstallPpi (&mPlatformVTdInfoSampleDesc);
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
diff --git a/IntelSiliconPkg/PlatformVTdInfoSamplePei/PlatformVTdInfoSamplePei.inf b/IntelSiliconPkg/PlatformVTdInfoSamplePei/PlatformVTdInfoSamplePei.inf
new file mode 100644
index 0000000..fe12821
--- /dev/null
+++ b/IntelSiliconPkg/PlatformVTdInfoSamplePei/PlatformVTdInfoSamplePei.inf
@@ -0,0 +1,51 @@
+## @file
+# Platform VTd Info Sample PEI driver.
+#
+# Copyright (c) 2017, 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
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = PlatformVTdInfoSamplePei
+ MODULE_UNI_FILE = PlatformVTdInfoSamplePei.uni
+ FILE_GUID = 839EB770-5C64-4EED-A6D5-EC515B2B2B23
+ MODULE_TYPE = PEIM
+ VERSION_STRING = 1.0
+ ENTRY_POINT = PlatformVTdInfoSampleInitialize
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+#
+
+[Sources]
+ PlatformVTdInfoSamplePei.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ IntelSiliconPkg/IntelSiliconPkg.dec
+
+[LibraryClasses]
+ PeimEntryPoint
+ PeiServicesLib
+
+[Ppis]
+ gEdkiiVTdInfoPpiGuid ## PRODUCES
+
+[Depex]
+ gEfiPeiMemoryDiscoveredPpiGuid
+
+[UserExtensions.TianoCore."ExtraFiles"]
+ PlatformVTdInfoSamplePeiExtra.uni
+
diff --git a/IntelSiliconPkg/PlatformVTdInfoSamplePei/PlatformVTdInfoSamplePei.uni b/IntelSiliconPkg/PlatformVTdInfoSamplePei/PlatformVTdInfoSamplePei.uni
new file mode 100644
index 0000000..36f9183
--- /dev/null
+++ b/IntelSiliconPkg/PlatformVTdInfoSamplePei/PlatformVTdInfoSamplePei.uni
@@ -0,0 +1,20 @@
+// /** @file
+// PlatformVTdInfoSamplePei Module Localized Abstract and Description Content
+//
+// Copyright (c) 2017, 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
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+// **/
+
+
+#string STR_MODULE_ABSTRACT #language en-US "Platform VTd Info PEI Driver."
+
+#string STR_MODULE_DESCRIPTION #language en-US "This driver provides sample on how to produce Platform VTd Info PPI."
+
--git a/IntelSiliconPkg/PlatformVTdInfoSamplePei/PlatformVTdInfoSamplePeiExtra.uni b/IntelSiliconPkg/PlatformVTdInfoSamplePei/PlatformVTdInfoSamplePeiExtra.uni
new file mode 100644
index 0000000..df6345f
--- /dev/null
+++ b/IntelSiliconPkg/PlatformVTdInfoSamplePei/PlatformVTdInfoSamplePeiExtra.uni
@@ -0,0 +1,20 @@
+// /** @file
+// PlatformVTdInfoSamplePei Localized Strings and Content
+//
+// Copyright (c) 2017, 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
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+// **/
+
+#string STR_PROPERTIES_MODULE_NAME
+#language en-US
+"Platform VTd Info Sample PEI Driver"
+
+
--
2.7.4.windows.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 10/11] IntelSiliconPkg/dsc: Add PlatformVTdInfoSamplePei.
2017-09-08 15:03 [PATCH 00/11] Add IOMMU PEI support Jiewen Yao
` (8 preceding siblings ...)
2017-09-08 15:03 ` [PATCH 09/11] IntelSiliconPkg: Add PlatformVTdInfoSamplePei Jiewen Yao
@ 2017-09-08 15:03 ` Jiewen Yao
2017-09-08 15:03 ` [PATCH 11/11] MdeModulePkg/XhciPei: Support IoMmu Jiewen Yao
2017-09-13 10:13 ` [PATCH 00/11] Add IOMMU PEI support Zeng, Star
11 siblings, 0 replies; 19+ messages in thread
From: Jiewen Yao @ 2017-09-08 15:03 UTC (permalink / raw)
To: edk2-devel; +Cc: Star Zeng
Cc: Star Zeng <star.zeng@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
---
IntelSiliconPkg/IntelSiliconPkg.dsc | 1 +
1 file changed, 1 insertion(+)
diff --git a/IntelSiliconPkg/IntelSiliconPkg.dsc b/IntelSiliconPkg/IntelSiliconPkg.dsc
index 33e822f..422e202 100644
--- a/IntelSiliconPkg/IntelSiliconPkg.dsc
+++ b/IntelSiliconPkg/IntelSiliconPkg.dsc
@@ -82,6 +82,7 @@
IntelSiliconPkg/IntelVTdDxe/IntelVTdDxe.inf
IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmrPei.inf
IntelSiliconPkg/PlatformVTdSampleDxe/PlatformVTdSampleDxe.inf
+ IntelSiliconPkg/PlatformVTdInfoSamplePei/PlatformVTdInfoSamplePei.inf
[BuildOptions]
*_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES
--
2.7.4.windows.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 11/11] MdeModulePkg/XhciPei: Support IoMmu.
2017-09-08 15:03 [PATCH 00/11] Add IOMMU PEI support Jiewen Yao
` (9 preceding siblings ...)
2017-09-08 15:03 ` [PATCH 10/11] IntelSiliconPkg/dsc: " Jiewen Yao
@ 2017-09-08 15:03 ` Jiewen Yao
2017-09-13 10:13 ` [PATCH 00/11] Add IOMMU PEI support Zeng, Star
11 siblings, 0 replies; 19+ messages in thread
From: Jiewen Yao @ 2017-09-08 15:03 UTC (permalink / raw)
To: edk2-devel; +Cc: Star Zeng
Update XHCI driver to consume IOMMU_PPI to allocate DMA buffer.
If no IOMMU_PPI exists, this driver still calls PEI service
to allocate DMA buffer, with assumption that DRAM==DMA.
This is a compatible change.
Cc: Star Zeng <star.zeng@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
---
MdeModulePkg/Bus/Pci/XhciPei/DmaMem.c | 249 ++++++++++++++++++++
MdeModulePkg/Bus/Pci/XhciPei/UsbHcMem.c | 55 +++--
MdeModulePkg/Bus/Pci/XhciPei/UsbHcMem.h | 9 +-
MdeModulePkg/Bus/Pci/XhciPei/XhcPeim.c | 55 ++++-
MdeModulePkg/Bus/Pci/XhciPei/XhcPeim.h | 107 +++++++++
MdeModulePkg/Bus/Pci/XhciPei/XhciPei.inf | 3 +
MdeModulePkg/Bus/Pci/XhciPei/XhciSched.c | 47 +++-
MdeModulePkg/Bus/Pci/XhciPei/XhciSched.h | 1 +
8 files changed, 492 insertions(+), 34 deletions(-)
diff --git a/MdeModulePkg/Bus/Pci/XhciPei/DmaMem.c b/MdeModulePkg/Bus/Pci/XhciPei/DmaMem.c
new file mode 100644
index 0000000..6e2c1b5
--- /dev/null
+++ b/MdeModulePkg/Bus/Pci/XhciPei/DmaMem.c
@@ -0,0 +1,249 @@
+/** @file
+The DMA memory help function.
+
+Copyright (c) 2017, 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
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "XhcPeim.h"
+
+EDKII_IOMMU_PPI *mIoMmu;
+
+/**
+ Provides the controller-specific addresses required to access system memory from a
+ DMA bus master.
+
+ @param Operation Indicates if the bus master is going to read or write to system memory.
+ @param HostAddress The system memory address to map to the PCI controller.
+ @param NumberOfBytes On input the number of bytes to map. On output the number of bytes
+ that were mapped.
+ @param DeviceAddress The resulting map address for the bus master PCI controller to use to
+ access the hosts HostAddress.
+ @param Mapping A resulting value to pass to Unmap().
+
+ @retval EFI_SUCCESS The range was mapped for the returned NumberOfBytes.
+ @retval EFI_UNSUPPORTED The HostAddress cannot be mapped as a common buffer.
+ @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
+ @retval EFI_DEVICE_ERROR The system hardware could not map the requested address.
+
+**/
+EFI_STATUS
+IoMmuMap (
+ IN EDKII_IOMMU_OPERATION Operation,
+ IN VOID *HostAddress,
+ IN OUT UINTN *NumberOfBytes,
+ OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,
+ OUT VOID **Mapping
+ )
+{
+ EFI_STATUS Status;
+ UINT64 Attribute;
+
+ if (mIoMmu != NULL) {
+ Status = mIoMmu->Map (
+ mIoMmu,
+ Operation,
+ HostAddress,
+ NumberOfBytes,
+ DeviceAddress,
+ Mapping
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ switch (Operation) {
+ case EdkiiIoMmuOperationBusMasterRead:
+ case EdkiiIoMmuOperationBusMasterRead64:
+ Attribute = EDKII_IOMMU_ACCESS_READ;
+ break;
+ case EdkiiIoMmuOperationBusMasterWrite:
+ case EdkiiIoMmuOperationBusMasterWrite64:
+ Attribute = EDKII_IOMMU_ACCESS_WRITE;
+ break;
+ case EdkiiIoMmuOperationBusMasterCommonBuffer:
+ case EdkiiIoMmuOperationBusMasterCommonBuffer64:
+ Attribute = EDKII_IOMMU_ACCESS_READ | EDKII_IOMMU_ACCESS_WRITE;
+ break;
+ default:
+ ASSERT(FALSE);
+ return EFI_INVALID_PARAMETER;
+ }
+ Status = mIoMmu->SetAttribute (
+ mIoMmu,
+ *Mapping,
+ Attribute
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ } else {
+ *DeviceAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)HostAddress;
+ *Mapping = NULL;
+ Status = EFI_SUCCESS;
+ }
+ return Status;
+}
+
+/**
+ Completes the Map() operation and releases any corresponding resources.
+
+ @param Mapping The mapping value returned from Map().
+
+ @retval EFI_SUCCESS The range was unmapped.
+ @retval EFI_INVALID_PARAMETER Mapping is not a value that was returned by Map().
+ @retval EFI_DEVICE_ERROR The data was not committed to the target system memory.
+**/
+EFI_STATUS
+IoMmuUnmap (
+ IN VOID *Mapping
+ )
+{
+ EFI_STATUS Status;
+
+ if (mIoMmu != NULL) {
+ Status = mIoMmu->SetAttribute (mIoMmu, Mapping, 0);
+ Status = mIoMmu->Unmap (mIoMmu, Mapping);
+ } else {
+ Status = EFI_SUCCESS;
+ }
+ return Status;
+}
+
+/**
+ Allocates pages that are suitable for an OperationBusMasterCommonBuffer or
+ OperationBusMasterCommonBuffer64 mapping.
+
+ @param Pages The number of pages to allocate.
+ @param HostAddress A pointer to store the base system memory address of the
+ allocated range.
+ @param DeviceAddress The resulting map address for the bus master PCI controller to use to
+ access the hosts HostAddress.
+ @param Mapping A resulting value to pass to Unmap().
+
+ @retval EFI_SUCCESS The requested memory pages were allocated.
+ @retval EFI_UNSUPPORTED Attributes is unsupported. The only legal attribute bits are
+ MEMORY_WRITE_COMBINE and MEMORY_CACHED.
+ @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
+ @retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated.
+
+**/
+EFI_STATUS
+IoMmuAllocateBuffer (
+ IN UINTN Pages,
+ OUT VOID **HostAddress,
+ OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,
+ OUT VOID **Mapping
+ )
+{
+ EFI_STATUS Status;
+ UINTN NumberOfBytes;
+ EFI_PHYSICAL_ADDRESS HostPhyAddress;
+
+ *HostAddress = NULL;
+ *DeviceAddress = 0;
+
+ if (mIoMmu != NULL) {
+ Status = mIoMmu->AllocateBuffer (
+ mIoMmu,
+ EfiBootServicesData,
+ Pages,
+ HostAddress,
+ 0
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ NumberOfBytes = EFI_PAGES_TO_SIZE(Pages);
+ Status = mIoMmu->Map (
+ mIoMmu,
+ EdkiiIoMmuOperationBusMasterCommonBuffer,
+ *HostAddress,
+ &NumberOfBytes,
+ DeviceAddress,
+ Mapping
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ Status = mIoMmu->SetAttribute (
+ mIoMmu,
+ *Mapping,
+ EDKII_IOMMU_ACCESS_READ | EDKII_IOMMU_ACCESS_WRITE
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ } else {
+ Status = PeiServicesAllocatePages (
+ EfiBootServicesData,
+ Pages,
+ &HostPhyAddress
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ *HostAddress = (VOID *)(UINTN)HostPhyAddress;
+ *DeviceAddress = HostPhyAddress;
+ *Mapping = NULL;
+ }
+ return Status;
+}
+
+/**
+ Frees memory that was allocated with AllocateBuffer().
+
+ @param Pages The number of pages to free.
+ @param HostAddress The base system memory address of the allocated range.
+ @param Mapping The mapping value returned from Map().
+
+ @retval EFI_SUCCESS The requested memory pages were freed.
+ @retval EFI_INVALID_PARAMETER The memory range specified by HostAddress and Pages
+ was not allocated with AllocateBuffer().
+
+**/
+EFI_STATUS
+IoMmuFreeBuffer (
+ IN UINTN Pages,
+ IN VOID *HostAddress,
+ IN VOID *Mapping
+ )
+{
+ EFI_STATUS Status;
+
+ if (mIoMmu != NULL) {
+ Status = mIoMmu->SetAttribute (mIoMmu, Mapping, 0);
+ Status = mIoMmu->Unmap (mIoMmu, Mapping);
+ Status = mIoMmu->FreeBuffer (mIoMmu, Pages, HostAddress);
+ } else {
+ Status = EFI_SUCCESS;
+ }
+ return Status;
+}
+
+/**
+ Initialize IOMMU.
+**/
+VOID
+IoMmuInit (
+ VOID
+ )
+{
+ PeiServicesLocatePpi (
+ &gEdkiiIoMmuPpiGuid,
+ 0,
+ NULL,
+ (VOID **)&mIoMmu
+ );
+}
+
diff --git a/MdeModulePkg/Bus/Pci/XhciPei/UsbHcMem.c b/MdeModulePkg/Bus/Pci/XhciPei/UsbHcMem.c
index 6a3f3a5..5d0232c 100644
--- a/MdeModulePkg/Bus/Pci/XhciPei/UsbHcMem.c
+++ b/MdeModulePkg/Bus/Pci/XhciPei/UsbHcMem.c
@@ -31,6 +31,9 @@ UsbHcAllocMemBlock (
)
{
USBHC_MEM_BLOCK *Block;
+ VOID *BufHost;
+ VOID *Mapping;
+ EFI_PHYSICAL_ADDRESS MappedAddr;
EFI_STATUS Status;
UINTN PageNumber;
EFI_PHYSICAL_ADDRESS TempPtr;
@@ -71,18 +74,20 @@ UsbHcAllocMemBlock (
Block->Bits = (UINT8 *) (UINTN) TempPtr;
- Status = PeiServicesAllocatePages (
- EfiBootServicesData,
+ Status = IoMmuAllocateBuffer (
Pages,
- &TempPtr
+ &BufHost,
+ &MappedAddr,
+ &Mapping
);
if (EFI_ERROR (Status)) {
return NULL;
}
- ZeroMem ((VOID *) (UINTN) TempPtr, EFI_PAGES_TO_SIZE (Pages));
+ ZeroMem ((VOID *) (UINTN) BufHost, EFI_PAGES_TO_SIZE (Pages));
- Block->BufHost = (UINT8 *) (UINTN) TempPtr;;
- Block->Buf = (UINT8 *) (UINTN) TempPtr;
+ Block->BufHost = (UINT8 *) (UINTN) BufHost;
+ Block->Buf = (UINT8 *) (UINTN) MappedAddr;
+ Block->Mapping = Mapping;
Block->Next = NULL;
return Block;
@@ -102,6 +107,9 @@ UsbHcFreeMemBlock (
)
{
ASSERT ((Pool != NULL) && (Block != NULL));
+
+ IoMmuFreeBuffer (EFI_SIZE_TO_PAGES (Block->BufLen), Block->BufHost, Block->Mapping);
+
//
// No free memory in PEI.
//
@@ -567,6 +575,7 @@ UsbHcFreeMem (
@param HostAddress The system memory address to map to the PCI controller.
@param DeviceAddress The resulting map address for the bus master PCI controller to
use to access the hosts HostAddress.
+ @param Mapping A resulting value to pass to Unmap().
@retval EFI_SUCCESS Success to allocate aligned pages.
@retval EFI_INVALID_PARAMETER Pages or Alignment is not valid.
@@ -578,13 +587,16 @@ UsbHcAllocateAlignedPages (
IN UINTN Pages,
IN UINTN Alignment,
OUT VOID **HostAddress,
- OUT EFI_PHYSICAL_ADDRESS *DeviceAddress
+ OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,
+ OUT VOID **Mapping
)
{
EFI_STATUS Status;
- EFI_PHYSICAL_ADDRESS Memory;
+ VOID *Memory;
UINTN AlignedMemory;
UINTN AlignmentMask;
+ EFI_PHYSICAL_ADDRESS DeviceMemory;
+ UINTN AlignedDeviceMemory;
UINTN RealPages;
//
@@ -611,32 +623,36 @@ UsbHcAllocateAlignedPages (
//
ASSERT (RealPages > Pages);
- Status = PeiServicesAllocatePages (
- EfiBootServicesData,
+ Status = IoMmuAllocateBuffer (
Pages,
- &Memory
+ &Memory,
+ &DeviceMemory,
+ Mapping
);
if (EFI_ERROR (Status)) {
return EFI_OUT_OF_RESOURCES;
}
AlignedMemory = ((UINTN) Memory + AlignmentMask) & ~AlignmentMask;
+ AlignedDeviceMemory = ((UINTN) DeviceMemory + AlignmentMask) & ~AlignmentMask;
} else {
//
// Do not over-allocate pages in this case.
//
- Status = PeiServicesAllocatePages (
- EfiBootServicesData,
+ Status = IoMmuAllocateBuffer (
Pages,
- &Memory
+ &Memory,
+ &DeviceMemory,
+ Mapping
);
if (EFI_ERROR (Status)) {
return EFI_OUT_OF_RESOURCES;
}
AlignedMemory = (UINTN) Memory;
+ AlignedDeviceMemory = (UINTN) DeviceMemory;
}
*HostAddress = (VOID *) AlignedMemory;
- *DeviceAddress = (EFI_PHYSICAL_ADDRESS) AlignedMemory;
+ *DeviceAddress = (EFI_PHYSICAL_ADDRESS) AlignedDeviceMemory;
return EFI_SUCCESS;
}
@@ -646,17 +662,18 @@ UsbHcAllocateAlignedPages (
@param HostAddress The system memory address to map to the PCI controller.
@param Pages The number of pages to free.
+ @param Mapping The mapping value returned from Map().
**/
VOID
UsbHcFreeAlignedPages (
IN VOID *HostAddress,
- IN UINTN Pages
+ IN UINTN Pages,
+ IN VOID *Mapping
)
{
ASSERT (Pages != 0);
- //
- // No free memory in PEI.
- //
+
+ IoMmuFreeBuffer (Pages, HostAddress, Mapping);
}
diff --git a/MdeModulePkg/Bus/Pci/XhciPei/UsbHcMem.h b/MdeModulePkg/Bus/Pci/XhciPei/UsbHcMem.h
index c314e92..c315e6e 100644
--- a/MdeModulePkg/Bus/Pci/XhciPei/UsbHcMem.h
+++ b/MdeModulePkg/Bus/Pci/XhciPei/UsbHcMem.h
@@ -29,6 +29,7 @@ struct _USBHC_MEM_BLOCK {
UINT8 *Buf;
UINT8 *BufHost;
UINTN BufLen; // Memory size in bytes
+ VOID *Mapping;
USBHC_MEM_BLOCK *Next;
};
@@ -112,6 +113,7 @@ UsbHcGetHostAddrForPciAddr (
@param HostAddress The system memory address to map to the PCI controller.
@param DeviceAddress The resulting map address for the bus master PCI controller to
use to access the hosts HostAddress.
+ @param Mapping A resulting value to pass to Unmap().
@retval EFI_SUCCESS Success to allocate aligned pages.
@retval EFI_INVALID_PARAMETER Pages or Alignment is not valid.
@@ -123,7 +125,8 @@ UsbHcAllocateAlignedPages (
IN UINTN Pages,
IN UINTN Alignment,
OUT VOID **HostAddress,
- OUT EFI_PHYSICAL_ADDRESS *DeviceAddress
+ OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,
+ OUT VOID **Mapping
);
/**
@@ -131,12 +134,14 @@ UsbHcAllocateAlignedPages (
@param HostAddress The system memory address to map to the PCI controller.
@param Pages The number of pages to free.
+ @param Mapping The mapping value returned from Map().
**/
VOID
UsbHcFreeAlignedPages (
IN VOID *HostAddress,
- IN UINTN Pages
+ IN UINTN Pages,
+ IN VOID *Mapping
);
#endif
diff --git a/MdeModulePkg/Bus/Pci/XhciPei/XhcPeim.c b/MdeModulePkg/Bus/Pci/XhciPei/XhcPeim.c
index 38f0d21..99f69f7 100644
--- a/MdeModulePkg/Bus/Pci/XhciPei/XhcPeim.c
+++ b/MdeModulePkg/Bus/Pci/XhciPei/XhcPeim.c
@@ -662,7 +662,8 @@ XhcPeiControlTransfer (
if (EFI_ERROR(RecoveryStatus)) {
DEBUG((EFI_D_ERROR, "XhcPeiControlTransfer: XhcPeiDequeueTrbFromEndpoint failed\n"));
}
- goto FREE_URB;
+ XhcPeiFreeUrb (Xhc, Urb);
+ goto ON_EXIT;
} else {
if (*TransferResult == EFI_USB_NOERROR) {
Status = EFI_SUCCESS;
@@ -672,11 +673,17 @@ XhcPeiControlTransfer (
DEBUG ((EFI_D_ERROR, "XhcPeiControlTransfer: XhcPeiRecoverHaltedEndpoint failed\n"));
}
Status = EFI_DEVICE_ERROR;
- goto FREE_URB;
+ XhcPeiFreeUrb (Xhc, Urb);
+ goto ON_EXIT;
} else {
- goto FREE_URB;
+ XhcPeiFreeUrb (Xhc, Urb);
+ goto ON_EXIT;
}
}
+ //
+ // Unmap data before consume.
+ //
+ XhcPeiFreeUrb (Xhc, Urb);
//
// Hook Get_Descriptor request from UsbBus as we need evaluate context and configure endpoint.
@@ -704,7 +711,7 @@ XhcPeiControlTransfer (
Xhc->UsbDevContext[SlotId].ConfDesc = AllocateZeroPool (Xhc->UsbDevContext[SlotId].DevDesc.NumConfigurations * sizeof (EFI_USB_CONFIG_DESCRIPTOR *));
if (Xhc->UsbDevContext[SlotId].ConfDesc == NULL) {
Status = EFI_OUT_OF_RESOURCES;
- goto FREE_URB;
+ goto ON_EXIT;
}
if (Xhc->HcCParams.Data.Csz == 0) {
Status = XhcPeiEvaluateContext (Xhc, SlotId, MaxPacket0);
@@ -722,7 +729,7 @@ XhcPeiControlTransfer (
Xhc->UsbDevContext[SlotId].ConfDesc[Index] = AllocateZeroPool (*DataLength);
if (Xhc->UsbDevContext[SlotId].ConfDesc[Index] == NULL) {
Status = EFI_OUT_OF_RESOURCES;
- goto FREE_URB;
+ goto ON_EXIT;
}
CopyMem (Xhc->UsbDevContext[SlotId].ConfDesc[Index], Data, *DataLength);
}
@@ -844,9 +851,6 @@ XhcPeiControlTransfer (
*(UINT32 *) Data = *(UINT32 *) &PortStatus;
}
-FREE_URB:
- XhcPeiFreeUrb (Xhc, Urb);
-
ON_EXIT:
if (EFI_ERROR (Status)) {
@@ -1399,6 +1403,34 @@ XhcPeiGetRootHubPortStatus (
}
/**
+ One notified function to stop the Host Controller at the end of PEI
+
+ @param[in] PeiServices Pointer to PEI Services Table.
+ @param[in] NotifyDescriptor Pointer to the descriptor for the Notification event that
+ caused this function to execute.
+ @param[in] Ppi Pointer to the PPI data associated with this function.
+
+ @retval EFI_SUCCESS The function completes successfully
+ @retval others
+**/
+EFI_STATUS
+EFIAPI
+XhcEndOfPei (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *Ppi
+ )
+{
+ PEI_XHC_DEV *Xhc;
+
+ Xhc = PEI_RECOVERY_USB_XHC_DEV_FROM_THIS_NOTIFY(NotifyDescriptor);
+
+ XhcPeiHaltHC (Xhc, XHC_GENERIC_TIMEOUT);
+
+ return EFI_SUCCESS;
+}
+
+/**
@param FileHandle Handle of the file being invoked.
@param PeiServices Describes the list of possible PEI Services.
@@ -1429,6 +1461,8 @@ XhcPeimEntry (
return EFI_SUCCESS;
}
+ IoMmuInit ();
+
Status = PeiServicesLocatePpi (
&gPeiUsbControllerPpiGuid,
0,
@@ -1530,7 +1564,12 @@ XhcPeimEntry (
XhcDev->PpiDescriptor.Guid = &gPeiUsb2HostControllerPpiGuid;
XhcDev->PpiDescriptor.Ppi = &XhcDev->Usb2HostControllerPpi;
+ XhcDev->EndOfPeiNotifyList.Flags = (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST);
+ XhcDev->EndOfPeiNotifyList.Guid = &gEfiEndOfPeiSignalPpiGuid;
+ XhcDev->EndOfPeiNotifyList.Notify = XhcEndOfPei;
+
PeiServicesInstallPpi (&XhcDev->PpiDescriptor);
+ PeiServicesNotifyPpi (&XhcDev->EndOfPeiNotifyList);
Index++;
}
diff --git a/MdeModulePkg/Bus/Pci/XhciPei/XhcPeim.h b/MdeModulePkg/Bus/Pci/XhciPei/XhcPeim.h
index 99f0396..e7a100f 100644
--- a/MdeModulePkg/Bus/Pci/XhciPei/XhcPeim.h
+++ b/MdeModulePkg/Bus/Pci/XhciPei/XhcPeim.h
@@ -21,6 +21,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Ppi/UsbController.h>
#include <Ppi/Usb2HostController.h>
+#include <Ppi/IoMmu.h>
+#include <Ppi/EndOfPeiPhase.h>
#include <Library/DebugLib.h>
#include <Library/PeimEntryPoint.h>
@@ -153,6 +155,12 @@ struct _PEI_XHC_DEV {
USBHC_MEM_POOL *MemPool;
//
+ // EndOfPei callback is used to stop the XHC DMA operation
+ // after exit PEI phase.
+ //
+ EFI_PEI_NOTIFY_DESCRIPTOR EndOfPeiNotifyList;
+
+ //
// XHCI configuration data
//
UINT8 CapLength; ///< Capability Register Length
@@ -164,7 +172,9 @@ struct _PEI_XHC_DEV {
UINT32 PageSize;
UINT32 MaxScratchpadBufs;
UINT64 *ScratchBuf;
+ VOID *ScratchMap;
UINT64 *ScratchEntry;
+ UINTN *ScratchEntryMap;
UINT64 *DCBAA;
UINT32 MaxSlotsEn;
//
@@ -184,6 +194,7 @@ struct _PEI_XHC_DEV {
};
#define PEI_RECOVERY_USB_XHC_DEV_FROM_THIS(a) CR (a, PEI_XHC_DEV, Usb2HostControllerPpi, USB_XHC_DEV_SIGNATURE)
+#define PEI_RECOVERY_USB_XHC_DEV_FROM_THIS_NOTIFY(a) CR (a, PEI_XHC_DEV, EndOfPeiNotifyList, USB_XHC_DEV_SIGNATURE)
/**
Initialize the memory management pool for the host controller.
@@ -242,4 +253,100 @@ UsbHcFreeMem (
)
;
+
+/**
+ Initialize IOMMU.
+**/
+VOID
+IoMmuInit (
+ VOID
+ );
+
+/**
+ Provides the controller-specific addresses required to access system memory from a
+ DMA bus master.
+
+ @param Operation Indicates if the bus master is going to read or write to system memory.
+ @param HostAddress The system memory address to map to the PCI controller.
+ @param NumberOfBytes On input the number of bytes to map. On output the number of bytes
+ that were mapped.
+ @param DeviceAddress The resulting map address for the bus master PCI controller to use to
+ access the hosts HostAddress.
+ @param Mapping A resulting value to pass to Unmap().
+
+ @retval EFI_SUCCESS The range was mapped for the returned NumberOfBytes.
+ @retval EFI_UNSUPPORTED The HostAddress cannot be mapped as a common buffer.
+ @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
+ @retval EFI_DEVICE_ERROR The system hardware could not map the requested address.
+
+**/
+EFI_STATUS
+IoMmuMap (
+ IN EDKII_IOMMU_OPERATION Operation,
+ IN VOID *HostAddress,
+ IN OUT UINTN *NumberOfBytes,
+ OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,
+ OUT VOID **Mapping
+ );
+
+/**
+ Completes the Map() operation and releases any corresponding resources.
+
+ @param Mapping The mapping value returned from Map().
+
+ @retval EFI_SUCCESS The range was unmapped.
+ @retval EFI_INVALID_PARAMETER Mapping is not a value that was returned by Map().
+ @retval EFI_DEVICE_ERROR The data was not committed to the target system memory.
+**/
+EFI_STATUS
+IoMmuUnmap (
+ IN VOID *Mapping
+ );
+
+/**
+ Allocates pages that are suitable for an OperationBusMasterCommonBuffer or
+ OperationBusMasterCommonBuffer64 mapping.
+
+ @param Pages The number of pages to allocate.
+ @param HostAddress A pointer to store the base system memory address of the
+ allocated range.
+ @param DeviceAddress The resulting map address for the bus master PCI controller to use to
+ access the hosts HostAddress.
+ @param Mapping A resulting value to pass to Unmap().
+
+ @retval EFI_SUCCESS The requested memory pages were allocated.
+ @retval EFI_UNSUPPORTED Attributes is unsupported. The only legal attribute bits are
+ MEMORY_WRITE_COMBINE and MEMORY_CACHED.
+ @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
+ @retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated.
+
+**/
+EFI_STATUS
+IoMmuAllocateBuffer (
+ IN UINTN Pages,
+ OUT VOID **HostAddress,
+ OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,
+ OUT VOID **Mapping
+ );
+
+/**
+ Frees memory that was allocated with AllocateBuffer().
+
+ @param Pages The number of pages to free.
+ @param HostAddress The base system memory address of the allocated range.
+ @param Mapping The mapping value returned from Map().
+
+ @retval EFI_SUCCESS The requested memory pages were freed.
+ @retval EFI_INVALID_PARAMETER The memory range specified by HostAddress and Pages
+ was not allocated with AllocateBuffer().
+
+**/
+EFI_STATUS
+IoMmuFreeBuffer (
+ IN UINTN Pages,
+ IN VOID *HostAddress,
+ IN VOID *Mapping
+ );
+
#endif
diff --git a/MdeModulePkg/Bus/Pci/XhciPei/XhciPei.inf b/MdeModulePkg/Bus/Pci/XhciPei/XhciPei.inf
index dc65f28..f307ea7 100644
--- a/MdeModulePkg/Bus/Pci/XhciPei/XhciPei.inf
+++ b/MdeModulePkg/Bus/Pci/XhciPei/XhciPei.inf
@@ -37,6 +37,7 @@
XhcPeim.h
XhciSched.c
UsbHcMem.c
+ DmaMem.c
XhciReg.h
XhciSched.h
UsbHcMem.h
@@ -56,6 +57,8 @@
[Ppis]
gPeiUsb2HostControllerPpiGuid ## PRODUCES
gPeiUsbControllerPpiGuid ## CONSUMES
+ gEdkiiIoMmuPpiGuid ## CONSUMES
+ gEfiEndOfPeiSignalPpiGuid ## CONSUMES
[Depex]
gEfiPeiMemoryDiscoveredPpiGuid AND gPeiUsbControllerPpiGuid AND gEfiPeiBootInRecoveryModePpiGuid
diff --git a/MdeModulePkg/Bus/Pci/XhciPei/XhciSched.c b/MdeModulePkg/Bus/Pci/XhciPei/XhciSched.c
index 3dd2b89..e5aee49 100644
--- a/MdeModulePkg/Bus/Pci/XhciPei/XhciSched.c
+++ b/MdeModulePkg/Bus/Pci/XhciPei/XhciSched.c
@@ -200,6 +200,8 @@ XhcPeiFreeUrb (
return;
}
+ IoMmuUnmap (Urb->DataMap);
+
FreePool (Urb);
}
@@ -227,6 +229,10 @@ XhcPeiCreateTransferTrb (
UINTN TotalLen;
UINTN Len;
UINTN TrbNum;
+ EDKII_IOMMU_OPERATION MapOp;
+ EFI_PHYSICAL_ADDRESS PhyAddr;
+ VOID *Map;
+ EFI_STATUS Status;
SlotId = XhcPeiBusDevAddrToSlotId (Xhc, Urb->Ep.BusAddr);
if (SlotId == 0) {
@@ -249,7 +255,27 @@ XhcPeiCreateTransferTrb (
EPType = (UINT8) ((DEVICE_CONTEXT_64 *)OutputContext)->EP[Dci-1].EPType;
}
- Urb->DataPhy = Urb->Data;
+ //
+ // No need to remap.
+ //
+ if ((Urb->Data != NULL) && (Urb->DataMap == NULL)) {
+ if (((UINT8) (Urb->Ep.Direction)) == EfiUsbDataIn) {
+ MapOp = EdkiiIoMmuOperationBusMasterWrite;
+ } else {
+ MapOp = EdkiiIoMmuOperationBusMasterRead;
+ }
+
+ Len = Urb->DataLen;
+ Status = IoMmuMap (MapOp, Urb->Data, &Len, &PhyAddr, &Map);
+
+ if (EFI_ERROR (Status) || (Len != Urb->DataLen)) {
+ DEBUG ((DEBUG_ERROR, "XhcCreateTransferTrb: Fail to map Urb->Data.\n"));
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Urb->DataPhy = (VOID *) ((UINTN) PhyAddr);
+ Urb->DataMap = Map;
+ }
//
// Construct the TRB
@@ -2812,6 +2838,7 @@ XhcPeiInitSched (
UINT64 *ScratchEntry;
EFI_PHYSICAL_ADDRESS ScratchEntryPhy;
UINT32 Index;
+ UINTN *ScratchEntryMap;
EFI_STATUS Status;
//
@@ -2848,6 +2875,13 @@ XhcPeiInitSched (
ASSERT (MaxScratchpadBufs <= 1023);
if (MaxScratchpadBufs != 0) {
//
+ // Allocate the buffer to record the Mapping for each scratch buffer in order to Unmap them
+ //
+ ScratchEntryMap = AllocateZeroPool (sizeof (UINTN) * MaxScratchpadBufs);
+ ASSERT (ScratchEntryMap != NULL);
+ Xhc->ScratchEntryMap = ScratchEntryMap;
+
+ //
// Allocate the buffer to record the host address for each entry
//
ScratchEntry = AllocateZeroPool (sizeof (UINT64) * MaxScratchpadBufs);
@@ -2859,7 +2893,8 @@ XhcPeiInitSched (
EFI_SIZE_TO_PAGES (MaxScratchpadBufs * sizeof (UINT64)),
Xhc->PageSize,
(VOID **) &ScratchBuf,
- &ScratchPhy
+ &ScratchPhy,
+ &Xhc->ScratchMap
);
ASSERT_EFI_ERROR (Status);
@@ -2875,7 +2910,8 @@ XhcPeiInitSched (
EFI_SIZE_TO_PAGES (Xhc->PageSize),
Xhc->PageSize,
(VOID **) &ScratchEntry[Index],
- &ScratchEntryPhy
+ &ScratchEntryPhy,
+ (VOID **) &ScratchEntryMap[Index]
);
ASSERT_EFI_ERROR (Status);
ZeroMem ((VOID *) (UINTN) ScratchEntry[Index], Xhc->PageSize);
@@ -2967,12 +3003,13 @@ XhcPeiFreeSched (
//
// Free Scratchpad Buffers
//
- UsbHcFreeAlignedPages ((VOID*) (UINTN) ScratchEntry[Index], EFI_SIZE_TO_PAGES (Xhc->PageSize));
+ UsbHcFreeAlignedPages ((VOID*) (UINTN) ScratchEntry[Index], EFI_SIZE_TO_PAGES (Xhc->PageSize), (VOID *) Xhc->ScratchEntryMap[Index]);
}
//
// Free Scratchpad Buffer Array
//
- UsbHcFreeAlignedPages (Xhc->ScratchBuf, EFI_SIZE_TO_PAGES (Xhc->MaxScratchpadBufs * sizeof (UINT64)));
+ UsbHcFreeAlignedPages (Xhc->ScratchBuf, EFI_SIZE_TO_PAGES (Xhc->MaxScratchpadBufs * sizeof (UINT64)), Xhc->ScratchMap);
+ FreePool (Xhc->ScratchEntryMap);
FreePool (Xhc->ScratchEntry);
}
diff --git a/MdeModulePkg/Bus/Pci/XhciPei/XhciSched.h b/MdeModulePkg/Bus/Pci/XhciPei/XhciSched.h
index b3d4c45..faf2e63 100644
--- a/MdeModulePkg/Bus/Pci/XhciPei/XhciSched.h
+++ b/MdeModulePkg/Bus/Pci/XhciPei/XhciSched.h
@@ -170,6 +170,7 @@ typedef struct _URB {
VOID *Data;
UINTN DataLen;
VOID *DataPhy;
+ VOID *DataMap;
EFI_ASYNC_USB_TRANSFER_CALLBACK Callback;
VOID *Context;
//
--
2.7.4.windows.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [PATCH 00/11] Add IOMMU PEI support.
2017-09-08 15:03 [PATCH 00/11] Add IOMMU PEI support Jiewen Yao
` (10 preceding siblings ...)
2017-09-08 15:03 ` [PATCH 11/11] MdeModulePkg/XhciPei: Support IoMmu Jiewen Yao
@ 2017-09-13 10:13 ` Zeng, Star
2017-09-13 10:19 ` Yao, Jiewen
11 siblings, 1 reply; 19+ messages in thread
From: Zeng, Star @ 2017-09-13 10:13 UTC (permalink / raw)
To: Yao, Jiewen, edk2-devel@lists.01.org; +Cc: Zeng, Star
I have been confused by where should new module be put for some time.
When should a new module be put at XXXPkg/Universal? For example, MdeModule/Universal, UefiCpuPkg/Universal, ....
When should a new module be put at XXXPkg/Feature? For example, UefiCpuPkg/Feature.
When should a new module be put at the root of a package folder? For example, UefiCpuPkg/PiSmmCpuDxeSmm, IntelSiliconPkg/IntelVTdDxe, ....
Is it better or not to put IntelVTdDxe, PlatformVTdSampleDxe and new IntelVTdPmrPei, PlatformVTdInfoSamplePei in IntelSiliconPkg/Feature/VTd together?
Thanks,
Star
-----Original Message-----
From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of Jiewen Yao
Sent: Friday, September 8, 2017 11:04 PM
To: edk2-devel@lists.01.org
Subject: [edk2] [PATCH 00/11] Add IOMMU PEI support.
This series patch added IOMMU PEI support.
It is also posted to https://github.com/jyao1/edk2/tree/IoMmuPpi.
1) Patch 1 and 2 add EDKII_IOMMU_PPI.
It is similar to EDKII_IOMMU_PROTOCOL.
2) Patch 3 and 4 add Intel VTD PMR register support for DXE phase IntelVTdDxe.
This is to prepare handle PMR usage in PEI phase.
3) Patch 5 and 6 add EDKII_VTD_INFO_PPI.
This PPI is to provide Intel VTD information in PEI.
In DXE, the VTd driver can get VTD info from ACPI DMAR table.
But in PEI, there is no way to get VTD info before.
VTD_INFO_PPI is added to resolve the problem.
4) Patch 7 and 8 add IntelVTdPmrPei driver.
This driver consumes EDKII_VTD_INFO_PPI and produces IOMMU_PPI.
It enables VTD PMR register to provide DMA protection.
The PMR based DMA protection is a simple solution to mark 2 regions can be DMA protected.
The IntelVTdPmrPei allocates a small chunk buffer for DMA and protect the rest memory.
5) Patch 9 and 10 add a sample VTdInfo PEI driver.
It provides a sample to show how to report VTd info in PEI phase.
6) Patch 11 updates XhciPei driver to consume IOMMU_PPI.
If the IOMMU_PPI is present, XhciPei will use IOMMU_PPI to allocate DMA buffer. Or the XhciPei will still use old way - PeiServiceAllocatePage to allocate DRAM as DMA buffer.
This is the first PEI device driver consuming IOMMU_PPI to show the concept. The rest PEI device drivers will be updated in separated patches.
This series patch is validated on Intel Kabylake Platform.
1) We can use XHCI to do file transfer in PEI phase,
2) We can still use XHCI in DXE phase, such as shell environment.
3) If the device driver does not consume IOMMU_PPI, the DMA fails.
Jiewen Yao (11):
MdeModulePkg/Include: Add IOMMU_PPI.
MdeModulePkg/Dec: Add IOMMU_PPI GUID.
IntelSiliconPkg/Vtd.h: Add definition for PMR.
IntelSiliconPkg/VTdDxe: Disable PMR
IntelSiliconPkg/include: Add VTD_INFO PPI.
IntelSiliconPkg/dec: Add VTD_INFO PPI GUID
IntelSiliconPkg: Add IntelVTdPmrPei.
IntelSiliconPkg/dsc: Add IntelVTdPmrPeim.
IntelSiliconPkg: Add PlatformVTdInfoSamplePei.
IntelSiliconPkg/dsc: Add PlatformVTdInfoSamplePei.
MdeModulePkg/XhciPei: Support IoMmu.
IntelSiliconPkg/Include/IndustryStandard/Vtd.h | 6 +
IntelSiliconPkg/Include/Ppi/VtdInfo.h | 40 ++
IntelSiliconPkg/IntelSiliconPkg.dec | 3 +
IntelSiliconPkg/IntelSiliconPkg.dsc | 10 +
IntelSiliconPkg/IntelVTdDxe/VtdReg.c | 51 +-
IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmr.c | 314 ++++++++++
IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmrPei.c | 615 ++++++++++++++++++++
IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmrPei.h | 68 +++
IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmrPei.inf | 59 ++
IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmrPei.uni | 20 +
IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmrPeiExtra.uni | 20 +
IntelSiliconPkg/PlatformVTdInfoSamplePei/PlatformVTdInfoSamplePei.c | 65 +++
IntelSiliconPkg/PlatformVTdInfoSamplePei/PlatformVTdInfoSamplePei.inf | 51 ++
IntelSiliconPkg/PlatformVTdInfoSamplePei/PlatformVTdInfoSamplePei.uni | 20 +
IntelSiliconPkg/PlatformVTdInfoSamplePei/PlatformVTdInfoSamplePeiExtra.uni | 20 +
MdeModulePkg/Bus/Pci/XhciPei/DmaMem.c | 249 ++++++++
MdeModulePkg/Bus/Pci/XhciPei/UsbHcMem.c | 55 +-
MdeModulePkg/Bus/Pci/XhciPei/UsbHcMem.h | 9 +-
MdeModulePkg/Bus/Pci/XhciPei/XhcPeim.c | 55 +-
MdeModulePkg/Bus/Pci/XhciPei/XhcPeim.h | 107 ++++
MdeModulePkg/Bus/Pci/XhciPei/XhciPei.inf | 3 +
MdeModulePkg/Bus/Pci/XhciPei/XhciSched.c | 47 +-
MdeModulePkg/Bus/Pci/XhciPei/XhciSched.h | 1 +
MdeModulePkg/Include/Ppi/IoMmu.h | 196 +++++++
MdeModulePkg/MdeModulePkg.dec | 3 +
25 files changed, 2052 insertions(+), 35 deletions(-) create mode 100644 IntelSiliconPkg/Include/Ppi/VtdInfo.h
create mode 100644 IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmr.c
create mode 100644 IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmrPei.c
create mode 100644 IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmrPei.h
create mode 100644 IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmrPei.inf
create mode 100644 IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmrPei.uni
create mode 100644 IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmrPeiExtra.uni
create mode 100644 IntelSiliconPkg/PlatformVTdInfoSamplePei/PlatformVTdInfoSamplePei.c
create mode 100644 IntelSiliconPkg/PlatformVTdInfoSamplePei/PlatformVTdInfoSamplePei.inf
create mode 100644 IntelSiliconPkg/PlatformVTdInfoSamplePei/PlatformVTdInfoSamplePei.uni
create mode 100644 IntelSiliconPkg/PlatformVTdInfoSamplePei/PlatformVTdInfoSamplePeiExtra.uni
create mode 100644 MdeModulePkg/Bus/Pci/XhciPei/DmaMem.c
create mode 100644 MdeModulePkg/Include/Ppi/IoMmu.h
--
2.7.4.windows.1
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 00/11] Add IOMMU PEI support.
2017-09-13 10:13 ` [PATCH 00/11] Add IOMMU PEI support Zeng, Star
@ 2017-09-13 10:19 ` Yao, Jiewen
2017-09-14 6:32 ` Zeng, Star
0 siblings, 1 reply; 19+ messages in thread
From: Yao, Jiewen @ 2017-09-13 10:19 UTC (permalink / raw)
To: Zeng, Star, edk2-devel@lists.01.org
Good question.
Yes, I think we can put all VTd related components to IntelSiliconPkg/Feature/VTd.
Once we finished the review, I would submit another patch to move all components to the new location.
Thank you
Yao Jiewen
> -----Original Message-----
> From: Zeng, Star
> Sent: Wednesday, September 13, 2017 6:14 PM
> To: Yao, Jiewen <jiewen.yao@intel.com>; edk2-devel@lists.01.org
> Cc: Zeng, Star <star.zeng@intel.com>
> Subject: RE: [edk2] [PATCH 00/11] Add IOMMU PEI support.
>
> I have been confused by where should new module be put for some time.
> When should a new module be put at XXXPkg/Universal? For example,
> MdeModule/Universal, UefiCpuPkg/Universal, ....
> When should a new module be put at XXXPkg/Feature? For example,
> UefiCpuPkg/Feature.
> When should a new module be put at the root of a package folder? For example,
> UefiCpuPkg/PiSmmCpuDxeSmm, IntelSiliconPkg/IntelVTdDxe, ....
>
> Is it better or not to put IntelVTdDxe, PlatformVTdSampleDxe and new
> IntelVTdPmrPei, PlatformVTdInfoSamplePei in IntelSiliconPkg/Feature/VTd
> together?
>
>
> Thanks,
> Star
> -----Original Message-----
> From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of Jiewen
> Yao
> Sent: Friday, September 8, 2017 11:04 PM
> To: edk2-devel@lists.01.org
> Subject: [edk2] [PATCH 00/11] Add IOMMU PEI support.
>
> This series patch added IOMMU PEI support.
> It is also posted to https://github.com/jyao1/edk2/tree/IoMmuPpi.
>
> 1) Patch 1 and 2 add EDKII_IOMMU_PPI.
> It is similar to EDKII_IOMMU_PROTOCOL.
>
> 2) Patch 3 and 4 add Intel VTD PMR register support for DXE phase IntelVTdDxe.
> This is to prepare handle PMR usage in PEI phase.
>
> 3) Patch 5 and 6 add EDKII_VTD_INFO_PPI.
> This PPI is to provide Intel VTD information in PEI.
> In DXE, the VTd driver can get VTD info from ACPI DMAR table.
> But in PEI, there is no way to get VTD info before.
> VTD_INFO_PPI is added to resolve the problem.
>
> 4) Patch 7 and 8 add IntelVTdPmrPei driver.
> This driver consumes EDKII_VTD_INFO_PPI and produces IOMMU_PPI.
> It enables VTD PMR register to provide DMA protection.
> The PMR based DMA protection is a simple solution to mark 2 regions can be
> DMA protected.
> The IntelVTdPmrPei allocates a small chunk buffer for DMA and protect the rest
> memory.
>
> 5) Patch 9 and 10 add a sample VTdInfo PEI driver.
> It provides a sample to show how to report VTd info in PEI phase.
>
> 6) Patch 11 updates XhciPei driver to consume IOMMU_PPI.
> If the IOMMU_PPI is present, XhciPei will use IOMMU_PPI to allocate DMA
> buffer. Or the XhciPei will still use old way - PeiServiceAllocatePage to allocate
> DRAM as DMA buffer.
> This is the first PEI device driver consuming IOMMU_PPI to show the concept.
> The rest PEI device drivers will be updated in separated patches.
>
>
> This series patch is validated on Intel Kabylake Platform.
> 1) We can use XHCI to do file transfer in PEI phase,
> 2) We can still use XHCI in DXE phase, such as shell environment.
> 3) If the device driver does not consume IOMMU_PPI, the DMA fails.
>
> Jiewen Yao (11):
> MdeModulePkg/Include: Add IOMMU_PPI.
> MdeModulePkg/Dec: Add IOMMU_PPI GUID.
> IntelSiliconPkg/Vtd.h: Add definition for PMR.
> IntelSiliconPkg/VTdDxe: Disable PMR
> IntelSiliconPkg/include: Add VTD_INFO PPI.
> IntelSiliconPkg/dec: Add VTD_INFO PPI GUID
> IntelSiliconPkg: Add IntelVTdPmrPei.
> IntelSiliconPkg/dsc: Add IntelVTdPmrPeim.
> IntelSiliconPkg: Add PlatformVTdInfoSamplePei.
> IntelSiliconPkg/dsc: Add PlatformVTdInfoSamplePei.
> MdeModulePkg/XhciPei: Support IoMmu.
>
> IntelSiliconPkg/Include/IndustryStandard/Vtd.h
> | 6 +
> IntelSiliconPkg/Include/Ppi/VtdInfo.h
> | 40 ++
> IntelSiliconPkg/IntelSiliconPkg.dec
> | 3 +
> IntelSiliconPkg/IntelSiliconPkg.dsc
> | 10 +
> IntelSiliconPkg/IntelVTdDxe/VtdReg.c
> | 51 +-
> IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmr.c
> | 314 ++++++++++
> IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmrPei.c
> | 615 ++++++++++++++++++++
> IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmrPei.h
> | 68 +++
> IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmrPei.inf
> | 59 ++
> IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmrPei.uni
> | 20 +
> IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmrPeiExtra.uni
> | 20 +
> IntelSiliconPkg/PlatformVTdInfoSamplePei/PlatformVTdInfoSamplePei.c
> | 65 +++
> IntelSiliconPkg/PlatformVTdInfoSamplePei/PlatformVTdInfoSamplePei.inf
> | 51 ++
> IntelSiliconPkg/PlatformVTdInfoSamplePei/PlatformVTdInfoSamplePei.uni
> | 20 +
> IntelSiliconPkg/PlatformVTdInfoSamplePei/PlatformVTdInfoSamplePeiExtra.uni
> | 20 +
> MdeModulePkg/Bus/Pci/XhciPei/DmaMem.c
> | 249 ++++++++
> MdeModulePkg/Bus/Pci/XhciPei/UsbHcMem.c
> | 55 +-
> MdeModulePkg/Bus/Pci/XhciPei/UsbHcMem.h
> | 9 +-
> MdeModulePkg/Bus/Pci/XhciPei/XhcPeim.c
> | 55 +-
> MdeModulePkg/Bus/Pci/XhciPei/XhcPeim.h
> | 107 ++++
> MdeModulePkg/Bus/Pci/XhciPei/XhciPei.inf
> | 3 +
> MdeModulePkg/Bus/Pci/XhciPei/XhciSched.c
> | 47 +-
> MdeModulePkg/Bus/Pci/XhciPei/XhciSched.h
> | 1 +
> MdeModulePkg/Include/Ppi/IoMmu.h
> | 196 +++++++
> MdeModulePkg/MdeModulePkg.dec
> | 3 +
> 25 files changed, 2052 insertions(+), 35 deletions(-) create mode 100644
> IntelSiliconPkg/Include/Ppi/VtdInfo.h
> create mode 100644 IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmr.c
> create mode 100644 IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmrPei.c
> create mode 100644 IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmrPei.h
> create mode 100644 IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmrPei.inf
> create mode 100644 IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmrPei.uni
> create mode 100644 IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmrPeiExtra.uni
> create mode 100644
> IntelSiliconPkg/PlatformVTdInfoSamplePei/PlatformVTdInfoSamplePei.c
> create mode 100644
> IntelSiliconPkg/PlatformVTdInfoSamplePei/PlatformVTdInfoSamplePei.inf
> create mode 100644
> IntelSiliconPkg/PlatformVTdInfoSamplePei/PlatformVTdInfoSamplePei.uni
> create mode 100644
> IntelSiliconPkg/PlatformVTdInfoSamplePei/PlatformVTdInfoSamplePeiExtra.uni
> create mode 100644 MdeModulePkg/Bus/Pci/XhciPei/DmaMem.c
> create mode 100644 MdeModulePkg/Include/Ppi/IoMmu.h
>
> --
> 2.7.4.windows.1
>
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org
> https://lists.01.org/mailman/listinfo/edk2-devel
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 00/11] Add IOMMU PEI support.
2017-09-13 10:19 ` Yao, Jiewen
@ 2017-09-14 6:32 ` Zeng, Star
0 siblings, 0 replies; 19+ messages in thread
From: Zeng, Star @ 2017-09-14 6:32 UTC (permalink / raw)
To: Yao, Jiewen, edk2-devel@lists.01.org; +Cc: Zeng, Star
Reviewed-by: Star Zeng <star.zeng@intel.com>
-----Original Message-----
From: Yao, Jiewen
Sent: Wednesday, September 13, 2017 6:19 PM
To: Zeng, Star <star.zeng@intel.com>; edk2-devel@lists.01.org
Subject: RE: [edk2] [PATCH 00/11] Add IOMMU PEI support.
Good question.
Yes, I think we can put all VTd related components to IntelSiliconPkg/Feature/VTd.
Once we finished the review, I would submit another patch to move all components to the new location.
Thank you
Yao Jiewen
> -----Original Message-----
> From: Zeng, Star
> Sent: Wednesday, September 13, 2017 6:14 PM
> To: Yao, Jiewen <jiewen.yao@intel.com>; edk2-devel@lists.01.org
> Cc: Zeng, Star <star.zeng@intel.com>
> Subject: RE: [edk2] [PATCH 00/11] Add IOMMU PEI support.
>
> I have been confused by where should new module be put for some time.
> When should a new module be put at XXXPkg/Universal? For example,
> MdeModule/Universal, UefiCpuPkg/Universal, ....
> When should a new module be put at XXXPkg/Feature? For example,
> UefiCpuPkg/Feature.
> When should a new module be put at the root of a package folder? For
> example, UefiCpuPkg/PiSmmCpuDxeSmm, IntelSiliconPkg/IntelVTdDxe, ....
>
> Is it better or not to put IntelVTdDxe, PlatformVTdSampleDxe and new
> IntelVTdPmrPei, PlatformVTdInfoSamplePei in
> IntelSiliconPkg/Feature/VTd together?
>
>
> Thanks,
> Star
> -----Original Message-----
> From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of
> Jiewen Yao
> Sent: Friday, September 8, 2017 11:04 PM
> To: edk2-devel@lists.01.org
> Subject: [edk2] [PATCH 00/11] Add IOMMU PEI support.
>
> This series patch added IOMMU PEI support.
> It is also posted to https://github.com/jyao1/edk2/tree/IoMmuPpi.
>
> 1) Patch 1 and 2 add EDKII_IOMMU_PPI.
> It is similar to EDKII_IOMMU_PROTOCOL.
>
> 2) Patch 3 and 4 add Intel VTD PMR register support for DXE phase IntelVTdDxe.
> This is to prepare handle PMR usage in PEI phase.
>
> 3) Patch 5 and 6 add EDKII_VTD_INFO_PPI.
> This PPI is to provide Intel VTD information in PEI.
> In DXE, the VTd driver can get VTD info from ACPI DMAR table.
> But in PEI, there is no way to get VTD info before.
> VTD_INFO_PPI is added to resolve the problem.
>
> 4) Patch 7 and 8 add IntelVTdPmrPei driver.
> This driver consumes EDKII_VTD_INFO_PPI and produces IOMMU_PPI.
> It enables VTD PMR register to provide DMA protection.
> The PMR based DMA protection is a simple solution to mark 2 regions
> can be DMA protected.
> The IntelVTdPmrPei allocates a small chunk buffer for DMA and protect
> the rest memory.
>
> 5) Patch 9 and 10 add a sample VTdInfo PEI driver.
> It provides a sample to show how to report VTd info in PEI phase.
>
> 6) Patch 11 updates XhciPei driver to consume IOMMU_PPI.
> If the IOMMU_PPI is present, XhciPei will use IOMMU_PPI to allocate
> DMA buffer. Or the XhciPei will still use old way -
> PeiServiceAllocatePage to allocate DRAM as DMA buffer.
> This is the first PEI device driver consuming IOMMU_PPI to show the concept.
> The rest PEI device drivers will be updated in separated patches.
>
>
> This series patch is validated on Intel Kabylake Platform.
> 1) We can use XHCI to do file transfer in PEI phase,
> 2) We can still use XHCI in DXE phase, such as shell environment.
> 3) If the device driver does not consume IOMMU_PPI, the DMA fails.
>
> Jiewen Yao (11):
> MdeModulePkg/Include: Add IOMMU_PPI.
> MdeModulePkg/Dec: Add IOMMU_PPI GUID.
> IntelSiliconPkg/Vtd.h: Add definition for PMR.
> IntelSiliconPkg/VTdDxe: Disable PMR
> IntelSiliconPkg/include: Add VTD_INFO PPI.
> IntelSiliconPkg/dec: Add VTD_INFO PPI GUID
> IntelSiliconPkg: Add IntelVTdPmrPei.
> IntelSiliconPkg/dsc: Add IntelVTdPmrPeim.
> IntelSiliconPkg: Add PlatformVTdInfoSamplePei.
> IntelSiliconPkg/dsc: Add PlatformVTdInfoSamplePei.
> MdeModulePkg/XhciPei: Support IoMmu.
>
> IntelSiliconPkg/Include/IndustryStandard/Vtd.h
> | 6 +
> IntelSiliconPkg/Include/Ppi/VtdInfo.h
> | 40 ++
> IntelSiliconPkg/IntelSiliconPkg.dec
> | 3 +
> IntelSiliconPkg/IntelSiliconPkg.dsc
> | 10 +
> IntelSiliconPkg/IntelVTdDxe/VtdReg.c
> | 51 +-
> IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmr.c
> | 314 ++++++++++
> IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmrPei.c
> | 615 ++++++++++++++++++++
> IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmrPei.h
> | 68 +++
> IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmrPei.inf
> | 59 ++
> IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmrPei.uni
> | 20 +
> IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmrPeiExtra.uni
> | 20 +
> IntelSiliconPkg/PlatformVTdInfoSamplePei/PlatformVTdInfoSamplePei.c
> | 65 +++
> IntelSiliconPkg/PlatformVTdInfoSamplePei/PlatformVTdInfoSamplePei.inf
> | 51 ++
> IntelSiliconPkg/PlatformVTdInfoSamplePei/PlatformVTdInfoSamplePei.uni
> | 20 +
>
> IntelSiliconPkg/PlatformVTdInfoSamplePei/PlatformVTdInfoSamplePeiExtra
> .uni
> | 20 +
> MdeModulePkg/Bus/Pci/XhciPei/DmaMem.c
> | 249 ++++++++
> MdeModulePkg/Bus/Pci/XhciPei/UsbHcMem.c
> | 55 +-
> MdeModulePkg/Bus/Pci/XhciPei/UsbHcMem.h
> | 9 +-
> MdeModulePkg/Bus/Pci/XhciPei/XhcPeim.c
> | 55 +-
> MdeModulePkg/Bus/Pci/XhciPei/XhcPeim.h
> | 107 ++++
> MdeModulePkg/Bus/Pci/XhciPei/XhciPei.inf
> | 3 +
> MdeModulePkg/Bus/Pci/XhciPei/XhciSched.c
> | 47 +-
> MdeModulePkg/Bus/Pci/XhciPei/XhciSched.h
> | 1 +
> MdeModulePkg/Include/Ppi/IoMmu.h
> | 196 +++++++
> MdeModulePkg/MdeModulePkg.dec
> | 3 +
> 25 files changed, 2052 insertions(+), 35 deletions(-) create mode
> 100644 IntelSiliconPkg/Include/Ppi/VtdInfo.h
> create mode 100644 IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmr.c
> create mode 100644 IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmrPei.c
> create mode 100644 IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmrPei.h
> create mode 100644 IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmrPei.inf
> create mode 100644 IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmrPei.uni
> create mode 100644
> IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmrPeiExtra.uni
> create mode 100644
> IntelSiliconPkg/PlatformVTdInfoSamplePei/PlatformVTdInfoSamplePei.c
> create mode 100644
> IntelSiliconPkg/PlatformVTdInfoSamplePei/PlatformVTdInfoSamplePei.inf
> create mode 100644
> IntelSiliconPkg/PlatformVTdInfoSamplePei/PlatformVTdInfoSamplePei.uni
> create mode 100644
> IntelSiliconPkg/PlatformVTdInfoSamplePei/PlatformVTdInfoSamplePeiExtra
> .uni create mode 100644 MdeModulePkg/Bus/Pci/XhciPei/DmaMem.c
> create mode 100644 MdeModulePkg/Include/Ppi/IoMmu.h
>
> --
> 2.7.4.windows.1
>
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org
> https://lists.01.org/mailman/listinfo/edk2-devel
^ permalink raw reply [flat|nested] 19+ messages in thread