* [PATCH] Extened PMR feature: allow silicon code to adjust PLMR/PHMR region base on the project needs
@ 2019-08-08 0:29 Evelyn Wang
2019-08-08 13:41 ` Yao, Jiewen
0 siblings, 1 reply; 4+ messages in thread
From: Evelyn Wang @ 2019-08-08 0:29 UTC (permalink / raw)
To: devel; +Cc: jenny.huang, jiewen.yao
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=1770
1) IOMMU PMR feature should be generic to support different hardware architecture.
Some platforms may request no overlap between PMR regions and system reserve memory regions. Create an interface to control PLMR/PHMR regions.
2) DisableDMAr Function Code Optimization
Currently, DisableDMAr flow functional-wise has no issues. However, it will be great if we can optimize the flow to follow the VT-d spec requirements.
3) Renamed InitDmar() to InitGlobalVtd()
The oringal function name is misleading
Change-Id: Ia80394183522f7a4a921a75a1fa6e3779053d4eb
Cc: jenny.huang@intel.com
Cc: jiewen.yao@intel.com
Cd: more.shih@intel.com
Signed-off-by: Evelyn Wang <iwen.evelyn.wang@intel.com>
---
IntelSiliconPkg/Feature/VTd/IntelVTdDxe/VtdReg.c | 28 ++++++++++++++++++++++++++--
IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------
IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.inf | 5 ++++-
IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/VtdReg.c | 27 +++++++++++++++++++++++++--
IntelSiliconPkg/Include/Library/GetVtdPmrAlignmentLib.h | 31 +++++++++++++++++++++++++++++++
IntelSiliconPkg/Include/SysMemInfoHob.h | 28 ++++++++++++++++++++++++++++
IntelSiliconPkg/IntelSiliconPkg.dec | 4 +++-
IntelSiliconPkg/IntelSiliconPkg.dsc | 3 ++-
IntelSiliconPkg/Library/GetVtdPmrAlignmentLib/GetVtdPmrAlignmentLib.c | 170 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
IntelSiliconPkg/Library/GetVtdPmrAlignmentLib/GetVtdPmrAlignmentLib.inf | 38 ++++++++++++++++++++++++++++++++++++++
10 files changed, 377 insertions(+), 33 deletions(-)
diff --git a/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/VtdReg.c b/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/VtdReg.c
index 8dbc83fa2d..6a66a860b4 100644
--- a/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/VtdReg.c
+++ b/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/VtdReg.c
@@ -1,6 +1,6 @@
/** @file
- Copyright (c) 2017 - 2018, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2017 - 2019, 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
@@ -315,6 +315,8 @@ DisableDmar (
UINTN Index;
UINTN SubIndex;
UINT32 Reg32;
+ UINT32 Status;
+ UINT32 Command;
for (Index = 0; Index < mVtdUnitNumber; Index++) {
DEBUG((DEBUG_INFO, ">>>>>>DisableDmar() for engine [%d] \n", Index));
@@ -327,7 +329,29 @@ DisableDmar (
//
// Disable VTd
//
- MmioWrite32 (mVtdUnitInformation[Index].VtdUnitBaseAddress + R_GCMD_REG, B_GMCD_REG_SRTP);
+ //
+ // Set TE (Translation Enable: BIT31) of Global command register to zero
+ //
+ Reg32 = MmioRead32 (mVtdUnitInformation[Index].VtdUnitBaseAddress + R_GSTS_REG);
+ Status = (Reg32 & 0x96FFFFFF); // Reset the one-shot bits
+ Command = (Status & ~B_GMCD_REG_TE);
+ MmioWrite32 (mVtdUnitInformation[Index].VtdUnitBaseAddress + R_GCMD_REG, Command);
+
+ //
+ // Poll on TE Status bit of Global status register to become zero
+ //
+ do {
+ Reg32 = MmioRead32 (mVtdUnitInformation[Index].VtdUnitBaseAddress + R_GSTS_REG);
+ } while ((Reg32 & B_GSTS_REG_TE) == B_GSTS_REG_TE);
+
+ //
+ // Set SRTP (Set Root Table Pointer: BIT30) of Global command register in order to update the root table pointerDisable VTd
+ //
+ Reg32 = MmioRead32 (mVtdUnitInformation[Index].VtdUnitBaseAddress + R_GSTS_REG);
+ Status = (Reg32 & 0x96FFFFFF); // Reset the one-shot bits
+ Command = (Status | B_GMCD_REG_SRTP);
+ MmioWrite32 (mVtdUnitInformation[Index].VtdUnitBaseAddress + R_GCMD_REG, Command);
+
do {
Reg32 = MmioRead32 (mVtdUnitInformation[Index].VtdUnitBaseAddress + R_GSTS_REG);
} while((Reg32 & B_GSTS_REG_RTPS) == 0);
diff --git a/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.c b/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.c
index 27847f4331..c8a2cae5ff 100644
--- a/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.c
+++ b/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.c
@@ -1,6 +1,6 @@
/** @file
- Copyright (c) 2017 - 2018, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2017 - 2019, 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.
@@ -26,7 +26,7 @@
#include <Ppi/VtdInfo.h>
#include <Ppi/MemoryDiscovered.h>
#include <Ppi/EndOfPeiPhase.h>
-
+#include <SysMemInfoHob.h>
#include "IntelVTdPmrPei.h"
EFI_GUID mVTdInfoGuid = {
@@ -430,38 +430,65 @@ InitDmaProtection (
UINTN MemoryAlignment;
UINTN LowBottom;
UINTN LowTop;
- UINTN HighBottom;
+ UINT64 HighBottom;
UINT64 HighTop;
DMA_BUFFER_INFO *DmaBufferInfo;
VOID *Hob;
EFI_PEI_PPI_DESCRIPTOR *OldDescriptor;
EDKII_IOMMU_PPI *OldIoMmuPpi;
+ SYSTEM_MEM_INFO_HOB *SysMemHob;
+ VOID *SysMemHobPtr;
Hob = GetFirstGuidHob (&mDmaBufferInfoGuid);
DmaBufferInfo = GET_GUID_HOB_DATA(Hob);
-
- DEBUG ((DEBUG_INFO, " DmaBufferSize : 0x%x\n", DmaBufferInfo->DmaBufferSize));
-
- LowMemoryAlignment = GetLowMemoryAlignment (VTdInfo, VTdInfo->EngineMask);
- HighMemoryAlignment = GetHighMemoryAlignment (VTdInfo, VTdInfo->EngineMask);
- if (LowMemoryAlignment < HighMemoryAlignment) {
- MemoryAlignment = (UINTN)HighMemoryAlignment;
+
+ SysMemHobPtr = GetFirstGuidHob (&gSysMemInfoDataHobGuid);
+
+ if (SysMemHobPtr == NULL) {
+ //
+ // Calcuate the PMR memory alignment
+ //
+ LowMemoryAlignment = GetLowMemoryAlignment (VTdInfo, VTdInfo->EngineMask);
+ HighMemoryAlignment = GetHighMemoryAlignment (VTdInfo, VTdInfo->EngineMask);
+ if (LowMemoryAlignment < HighMemoryAlignment) {
+ MemoryAlignment = (UINTN)HighMemoryAlignment;
+ } else {
+ MemoryAlignment = LowMemoryAlignment;
+ }
+ ASSERT (DmaBufferInfo->DmaBufferSize == ALIGN_VALUE(DmaBufferInfo->DmaBufferSize, MemoryAlignment));
+
+ //
+ // Allocate memory for DMA buffer
+ //
+ DmaBufferInfo->DmaBufferBase = (UINTN)AllocateAlignedPages (EFI_SIZE_TO_PAGES(DmaBufferInfo->DmaBufferSize), MemoryAlignment);
+ ASSERT (DmaBufferInfo->DmaBufferBase != 0);
+ if (DmaBufferInfo->DmaBufferBase == 0) {
+ DEBUG ((DEBUG_INFO, " InitDmaProtection : OutOfResource\n"));
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ DmaBufferInfo->DmaBufferCurrentTop = DmaBufferInfo->DmaBufferBase + DmaBufferInfo->DmaBufferSize;
+ DmaBufferInfo->DmaBufferCurrentBottom = DmaBufferInfo->DmaBufferBase;
+ LowBottom = 0;
+ LowTop = DmaBufferInfo->DmaBufferBase;
+ HighBottom = DmaBufferInfo->DmaBufferBase + DmaBufferInfo->DmaBufferSize;
+ HighTop = LShiftU64 (1, VTdInfo->HostAddressWidth + 1);
} else {
- MemoryAlignment = LowMemoryAlignment;
- }
- ASSERT (DmaBufferInfo->DmaBufferSize == ALIGN_VALUE(DmaBufferInfo->DmaBufferSize, MemoryAlignment));
- DmaBufferInfo->DmaBufferBase = (UINTN)AllocateAlignedPages (EFI_SIZE_TO_PAGES(DmaBufferInfo->DmaBufferSize), MemoryAlignment);
- ASSERT (DmaBufferInfo->DmaBufferBase != 0);
- if (DmaBufferInfo->DmaBufferBase == 0) {
- DEBUG ((DEBUG_INFO, " InitDmaProtection : OutOfResource\n"));
- return EFI_OUT_OF_RESOURCES;
- }
+ //
+ // Get the PMR ranges information for the hob
+ //
+ SysMemHob = GET_GUID_HOB_DATA (SysMemHobPtr);
+ DmaBufferInfo->DmaBufferBase = SysMemHob->ProtectedLowLimit << 20;
+ LowBottom = SysMemHob->ProtectedLowBase;
+ LowTop = SysMemHob->ProtectedLowLimit << 20;
+ HighBottom = (UINT64) BASE_4GB;
+ HighTop = (UINT64) SysMemHob->ProtectedHighLimit << 20;
+ }
+
+ DEBUG ((DEBUG_INFO, " DmaBufferSize : 0x%x\n", DmaBufferInfo->DmaBufferSize));
DEBUG ((DEBUG_INFO, " DmaBufferBase : 0x%x\n", DmaBufferInfo->DmaBufferBase));
- DmaBufferInfo->DmaBufferCurrentTop = DmaBufferInfo->DmaBufferBase + DmaBufferInfo->DmaBufferSize;
- DmaBufferInfo->DmaBufferCurrentBottom = DmaBufferInfo->DmaBufferBase;
-
//
// (Re)Install PPI.
//
@@ -478,10 +505,7 @@ InitDmaProtection (
}
ASSERT_EFI_ERROR (Status);
- LowBottom = 0;
- LowTop = DmaBufferInfo->DmaBufferBase;
- HighBottom = DmaBufferInfo->DmaBufferBase + DmaBufferInfo->DmaBufferSize;
- HighTop = LShiftU64 (1, VTdInfo->HostAddressWidth + 1);
+
Status = SetDmaProtectedRange (
VTdInfo,
diff --git a/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.inf b/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.inf
index 5b688d5cbf..427c9a830c 100644
--- a/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.inf
+++ b/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.inf
@@ -4,7 +4,7 @@
# This driver initializes VTd engine based upon EDKII_VTD_INFO_PPI
# and provide DMA protection in PEI.
#
-# Copyright (c) 2017 - 2018, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2017 - 2019, 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
@@ -46,6 +46,9 @@
IoLib
CacheMaintenanceLib
+[Guids]
+ gSysMemInfoDataHobGuid ## CONSUMES
+
[Ppis]
gEdkiiIoMmuPpiGuid ## PRODUCES
gEdkiiVTdInfoPpiGuid ## CONSUMES
diff --git a/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/VtdReg.c b/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/VtdReg.c
index 888905d40d..b6a3614e75 100644
--- a/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/VtdReg.c
+++ b/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/VtdReg.c
@@ -1,6 +1,6 @@
/** @file
- Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2017 - 2019, 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.
@@ -203,6 +203,8 @@ DisableDmar (
)
{
UINT32 Reg32;
+ UINT32 Status;
+ UINT32 Command;
DEBUG((DEBUG_INFO, ">>>>>>DisableDmar() for engine [%x] \n", VtdUnitBaseAddress));
@@ -214,7 +216,28 @@ DisableDmar (
//
// Disable VTd
//
- MmioWrite32 (VtdUnitBaseAddress + R_GCMD_REG, B_GMCD_REG_SRTP);
+ //
+ // Set TE (Translation Enable: BIT31) of Global command register to zero
+ //
+ Reg32 = MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG);
+ Status = (Reg32 & 0x96FFFFFF); // Reset the one-shot bits
+ Command = (Status & ~B_GMCD_REG_TE);
+ MmioWrite32 (VtdUnitBaseAddress + R_GCMD_REG, Command);
+
+ //
+ // Poll on TE Status bit of Global status register to become zero
+ //
+ do {
+ Reg32 = MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG);
+ } while ((Reg32 & B_GSTS_REG_TE) == B_GSTS_REG_TE);
+
+ //
+ // Set SRTP (Set Root Table Pointer: BIT30) of Global command register in order to update the root table pointerDisable VTd
+ //
+ Reg32 = MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG);
+ Status = (Reg32 & 0x96FFFFFF); // Reset the one-shot bits
+ Command = (Status | B_GMCD_REG_SRTP);
+ MmioWrite32 (VtdUnitBaseAddress + R_GCMD_REG, Command);
do {
Reg32 = MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG);
} while((Reg32 & B_GSTS_REG_RTPS) == 0);
diff --git a/IntelSiliconPkg/Include/Library/GetVtdPmrAlignmentLib.h b/IntelSiliconPkg/Include/Library/GetVtdPmrAlignmentLib.h
new file mode 100644
index 0000000000..537d013783
--- /dev/null
+++ b/IntelSiliconPkg/Include/Library/GetVtdPmrAlignmentLib.h
@@ -0,0 +1,31 @@
+/** @file
+ Get Global VTd PMR alignment information library.
+
+ Copyright (c) 2019, 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 __GET_VTD_PMR_ALIGN_LIB_H__
+#define __GET_VTD_PMR_ALIGN_LIB_H__
+#include <Library/BaseLib.h>
+
+/**
+ Get Global VT-d Protected Memory alignment.
+
+
+ @return protected high memory alignment.
+**/
+
+UINTN
+GetGlobalVtdPmrAlignment (
+);
+
+#endif // __GET_VTD_PMR_ALIGN_LIB_H__
diff --git a/IntelSiliconPkg/Include/SysMemInfoHob.h b/IntelSiliconPkg/Include/SysMemInfoHob.h
new file mode 100644
index 0000000000..d3045b2c7a
--- /dev/null
+++ b/IntelSiliconPkg/Include/SysMemInfoHob.h
@@ -0,0 +1,28 @@
+/** @file
+ The definition for VTD System information Hob.
+
+ This is a lightweight VTd information report in PEI phase.
+
+ Copyright (c) 2019, 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 _SYS_MEM_INFO_HOB_H_
+#define _SYS_MEM_INFO_HOB_H_
+
+typedef struct {
+ UINTN ProtectedLowBase;
+ UINTN ProtectedLowLimit;
+ UINTN ProtectedHighBase;
+ UINTN ProtectedHighLimit;
+} SYSTEM_MEM_INFO_HOB;
+
+#endif // _SYS_MEM_INFO_HOB_H_
+
diff --git a/IntelSiliconPkg/IntelSiliconPkg.dec b/IntelSiliconPkg/IntelSiliconPkg.dec
index c0cf58fa6c..d2efac71c0 100644
--- a/IntelSiliconPkg/IntelSiliconPkg.dec
+++ b/IntelSiliconPkg/IntelSiliconPkg.dec
@@ -3,7 +3,7 @@
#
# This package provides common open source Intel silicon modules.
#
-# Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2016 - 2019, 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
@@ -27,6 +27,7 @@
## @libraryclass Provides services to access Microcode region on flash device.
#
MicrocodeFlashAccessLib|Include/Library/MicrocodeFlashAccessLib.h
+ GetVtdPmrAlignmentLib|Include/Library/GetVtdPmrAlignmentLib.h
[Guids]
## GUID for Package token space
@@ -40,6 +41,7 @@
## Include/Guid/MicrocodeFmp.h
gMicrocodeFmpImageTypeIdGuid = { 0x96d4fdcd, 0x1502, 0x424d, { 0x9d, 0x4c, 0x9b, 0x12, 0xd2, 0xdc, 0xae, 0x5c } }
+ gSysMemInfoDataHobGuid = {0x6fb61645, 0xf168, 0x46be, { 0x80, 0xec, 0xb5, 0x02, 0x38, 0x5e, 0xe7, 0xe7 } }
[Ppis]
gEdkiiVTdInfoPpiGuid = { 0x8a59fcb3, 0xf191, 0x400c, { 0x97, 0x67, 0x67, 0xaf, 0x2b, 0x25, 0x68, 0x4a } }
diff --git a/IntelSiliconPkg/IntelSiliconPkg.dsc b/IntelSiliconPkg/IntelSiliconPkg.dsc
index 790870e2f1..99061e3715 100644
--- a/IntelSiliconPkg/IntelSiliconPkg.dsc
+++ b/IntelSiliconPkg/IntelSiliconPkg.dsc
@@ -1,7 +1,7 @@
## @file
# This package provides common open source Intel silicon modules.
#
-# Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2017 - 2019, 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
@@ -40,6 +40,7 @@
SerialPortLib|MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.inf
CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf
MicrocodeFlashAccessLib|IntelSiliconPkg/Feature/Capsule/Library/MicrocodeFlashAccessLibNull/MicrocodeFlashAccessLibNull.inf
+ GetVtdPmrAlignmentLib|IntelSiliconPkg/Library/GetVtdPmrAlignmentLib/GetVtdPmrAlignmentLib.inf
[LibraryClasses.common.PEIM]
PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf
diff --git a/IntelSiliconPkg/Library/GetVtdPmrAlignmentLib/GetVtdPmrAlignmentLib.c b/IntelSiliconPkg/Library/GetVtdPmrAlignmentLib/GetVtdPmrAlignmentLib.c
new file mode 100644
index 0000000000..28fb8d4978
--- /dev/null
+++ b/IntelSiliconPkg/Library/GetVtdPmrAlignmentLib/GetVtdPmrAlignmentLib.c
@@ -0,0 +1,170 @@
+/** @file
+ Library to get Global VTd PMR alignment information.
+ Copyright (c) 2019, 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 <Library/GetVtdPmrAlignmentLib.h>
+#include <Library/PeiServicesLib.h>
+#include <IndustryStandard/DmaRemappingReportingTable.h>
+#include <IndustryStandard/VTd.h>
+
+typedef union {
+ struct {
+ UINT32 Low;
+ UINT32 High;
+ } Data32;
+ UINT64 Data;
+} UINT64_STRUCT;
+
+/**
+ Get protected low memory alignment.
+
+ @param HostAddressWidth The host address width.
+ @param VtdUnitBaseAddress The base address of the VTd engine.
+
+ @return protected low memory alignment.
+**/
+UINT32
+GetGlobalVTdPlmrAlignment (
+ IN UINT8 HostAddressWidth,
+ 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 HostAddressWidth The host address width.
+ @param VtdUnitBaseAddress The base address of the VTd engine.
+
+ @return protected high memory alignment.
+**/
+UINT64_STRUCT
+GetGlobalVTdPhmrAlignment (
+ IN UINT8 HostAddressWidth,
+ IN UINTN VtdUnitBaseAddress
+ )
+{
+ UINT64_STRUCT Data64;
+
+ MmioWrite64 (VtdUnitBaseAddress + R_PMEN_HIGH_BASE_REG, 0xFFFFFFFFFFFFFFFF);
+ Data64.Data = MmioRead64 (VtdUnitBaseAddress + R_PMEN_HIGH_BASE_REG);
+ Data64.Data = ~Data64.Data + 1;
+ Data64.Data = Data64.Data & (LShiftU64 (1, HostAddressWidth) - 1);
+
+ return Data64;
+}
+
+/**
+ Get Global VT-d Protected Memory Aignment.
+
+ @return protected high memory alignment.
+**/
+UINTN
+GetGlobalVtdPmrAlignment (
+)
+{
+ UINT32 LowMemoryAlignment;
+ UINT64_STRUCT HighMemoryAlignment;
+ UINTN MemoryAlignment;
+ UINT32 GlobalVTdBaseAddress;
+ EFI_STATUS Status;
+ UINTN VtdIndex;
+ EFI_ACPI_DMAR_STRUCTURE_HEADER *DmarHeader;
+ EFI_ACPI_DMAR_DRHD_HEADER *DrhdHeader;
+ EFI_ACPI_DMAR_HEADER *AcpiDmarTable;
+
+ //
+ // Initialization
+ //
+ GlobalVTdBaseAddress = 0xFFFFFFFF;
+ LowMemoryAlignment = 0;
+ HighMemoryAlignment.Data = 0;
+ MemoryAlignment = 0;
+ Status = EFI_UNSUPPORTED;
+ VtdIndex = 0;
+ DmarHeader = NULL;
+ DrhdHeader = NULL;
+ AcpiDmarTable = NULL;
+
+ //
+ // Fatch the PEI DMAR ACPU Table that created and installed in PlatformVTdInfoSamplePei.c
+ //
+ Status = PeiServicesLocatePpi (
+ &gEdkiiVTdInfoPpiGuid,
+ 0,
+ NULL,
+ (VOID **)&AcpiDmarTable
+ );
+ if (EFI_ERROR (Status)) {
+
+ DEBUG ((DEBUG_ERROR, "PeiServicesLocatePpi gEdkiiVTdInfoPpiGuid failed\n"));
+ Status = EFI_NOT_FOUND;
+ MemoryAlignment = SIZE_1MB;
+
+ } else {
+
+ //
+ // Seatch the DRHD structure with INCLUDE_PCI_ALL flag Set -> Global VT-d
+ //
+ DmarHeader = (EFI_ACPI_DMAR_STRUCTURE_HEADER *)((UINTN)(AcpiDmarTable + 1));
+ while ((UINTN)DmarHeader < (UINTN)AcpiDmarTable + AcpiDmarTable->Header.Length) {
+ switch (DmarHeader->Type) {
+ case EFI_ACPI_DMAR_TYPE_DRHD:
+ DrhdHeader = (EFI_ACPI_DMAR_DRHD_HEADER *) DmarHeader;
+ if ((DrhdHeader->Flags & BIT0) == BIT0) {
+ GlobalVTdBaseAddress = (UINT32)DrhdHeader->RegisterBaseAddress;
+ DEBUG ((DEBUG_INFO," GlobalVTdBaseAddress: %x\n", GlobalVTdBaseAddress));
+ }
+ VtdIndex++;
+
+ break;
+
+ default:
+ break;
+ }
+ DmarHeader = (EFI_ACPI_DMAR_STRUCTURE_HEADER *)((UINTN)DmarHeader + DmarHeader->Length);
+ }
+
+ if (GlobalVTdBaseAddress == 0xFFFFFFFF) {
+
+ DEBUG ((DEBUG_ERROR, "Error! Please set INCLUDE_PCI_ALL flag to your Global VT-d\n"));
+ MemoryAlignment = SIZE_1MB;
+
+ } else {
+ //
+ // Get the alignment information from VT-d register
+ //
+ LowMemoryAlignment = GetGlobalVTdPlmrAlignment (AcpiDmarTable->HostAddressWidth, GlobalVTdBaseAddress);
+ HighMemoryAlignment = GetGlobalVTdPhmrAlignment (AcpiDmarTable->HostAddressWidth, GlobalVTdBaseAddress);
+ if (LowMemoryAlignment < HighMemoryAlignment.Data) {
+ MemoryAlignment = (UINTN)HighMemoryAlignment.Data;
+ } else {
+ MemoryAlignment = LowMemoryAlignment;
+ }
+ }
+ }
+
+ return MemoryAlignment;
+}
\ No newline at end of file
diff --git a/IntelSiliconPkg/Library/GetVtdPmrAlignmentLib/GetVtdPmrAlignmentLib.inf b/IntelSiliconPkg/Library/GetVtdPmrAlignmentLib/GetVtdPmrAlignmentLib.inf
new file mode 100644
index 0000000000..2ef199c92e
--- /dev/null
+++ b/IntelSiliconPkg/Library/GetVtdPmrAlignmentLib/GetVtdPmrAlignmentLib.inf
@@ -0,0 +1,38 @@
+## @file
+# Component INF file for the GetVtdPmrAlignment library.
+#
+# Copyright (c) 2019, 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 = GetVtdPmrAlignmentLib
+FILE_GUID = 0332BE93-0547-4D87-A7FA-0D9D76C53187
+MODULE_TYPE = BASE
+LIBRARY_CLASS = GetVtdPmrAlignmentLib
+
+[Packages]
+MdePkg/MdePkg.dec
+IntelSiliconPkg/IntelSiliconPkg.dec
+
+[Sources]
+GetVtdPmrAlignmentLib.c
+
+[LibraryClasses]
+DebugLib
+BaseMemoryLib
+MemoryAllocationLib
+BaseLib
+PeiServicesLib
+
+[Ppis]
+gEdkiiVTdInfoPpiGuid
--
2.16.2.windows.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH] Extened PMR feature: allow silicon code to adjust PLMR/PHMR region base on the project needs
2019-08-08 0:29 [PATCH] Extened PMR feature: allow silicon code to adjust PLMR/PHMR region base on the project needs Evelyn Wang
@ 2019-08-08 13:41 ` Yao, Jiewen
2019-08-08 18:04 ` Wang, Iwen Evelyn
0 siblings, 1 reply; 4+ messages in thread
From: Yao, Jiewen @ 2019-08-08 13:41 UTC (permalink / raw)
To: Wang, Iwen Evelyn, devel@edk2.groups.io; +Cc: Huang, Jenny
Hi Evelyn
Thanks for the enhancement.
However, I fail to apply the patch to the latest tree.
Please be aware that:
1) We updated the license header.
2) We moved the IntelSiliconPkg from edkii repo to edkii-platform repo.
Would you please pull the latest tree and apply the patch, then send it again?
Some format issue:
1) "Cd: more.shih@intel.com" should be "Cc: more.shih@intel.com", right?
2) Please also add the full name such as: Cc: Jiewen Yao <jiewen.yao@intel.com>
3) Please remove "Change-Id: Ia80394183522f7a4a921a75a1fa6e3779053d4eb"
4) Please add "PackageName/ModuleName:" in the title.
Thank you
Yao Jiewen
> -----Original Message-----
> From: Wang, Iwen Evelyn
> Sent: Thursday, August 8, 2019 8:29 AM
> To: devel@edk2.groups.io
> Cc: Huang, Jenny <jenny.huang@intel.com>; Yao, Jiewen
> <jiewen.yao@intel.com>
> Subject: [PATCH] Extened PMR feature: allow silicon code to adjust
> PLMR/PHMR region base on the project needs
>
> REF: https://bugzilla.tianocore.org/show_bug.cgi?id=1770
>
> 1) IOMMU PMR feature should be generic to support different hardware
> architecture.
> Some platforms may request no overlap between PMR regions and system
> reserve memory regions. Create an interface to control PLMR/PHMR
> regions.
>
> 2) DisableDMAr Function Code Optimization
> Currently, DisableDMAr flow functional-wise has no issues. However, it will
> be great if we can optimize the flow to follow the VT-d spec requirements.
>
> 3) Renamed InitDmar() to InitGlobalVtd()
> The oringal function name is misleading
>
> Change-Id: Ia80394183522f7a4a921a75a1fa6e3779053d4eb
> Cc: jenny.huang@intel.com
> Cc: jiewen.yao@intel.com
> Cd: more.shih@intel.com
> Signed-off-by: Evelyn Wang <iwen.evelyn.wang@intel.com>
> ---
> IntelSiliconPkg/Feature/VTd/IntelVTdDxe/VtdReg.c
> | 28 ++++++++++++++++++++++++++--
> IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.c
> | 76
> ++++++++++++++++++++++++++++++++++++++++++++++++++------------------
> --------
> IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.inf
> | 5 ++++-
> IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/VtdReg.c
> | 27 +++++++++++++++++++++++++--
> IntelSiliconPkg/Include/Library/GetVtdPmrAlignmentLib.h
> | 31 +++++++++++++++++++++++++++++++
> IntelSiliconPkg/Include/SysMemInfoHob.h
> | 28 ++++++++++++++++++++++++++++
> IntelSiliconPkg/IntelSiliconPkg.dec
> | 4 +++-
> IntelSiliconPkg/IntelSiliconPkg.dsc
> | 3 ++-
> IntelSiliconPkg/Library/GetVtdPmrAlignmentLib/GetVtdPmrAlignmentLib.c
> | 170
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++
> IntelSiliconPkg/Library/GetVtdPmrAlignmentLib/GetVtdPmrAlignmentLib.inf
> | 38 ++++++++++++++++++++++++++++++++++++++
> 10 files changed, 377 insertions(+), 33 deletions(-)
>
> diff --git a/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/VtdReg.c
> b/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/VtdReg.c
> index 8dbc83fa2d..6a66a860b4 100644
> --- a/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/VtdReg.c
> +++ b/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/VtdReg.c
> @@ -1,6 +1,6 @@
> /** @file
>
> - Copyright (c) 2017 - 2018, Intel Corporation. All rights reserved.<BR>
> + Copyright (c) 2017 - 2019, 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
> @@ -315,6 +315,8 @@ DisableDmar (
> UINTN Index;
> UINTN SubIndex;
> UINT32 Reg32;
> + UINT32 Status;
> + UINT32 Command;
>
> for (Index = 0; Index < mVtdUnitNumber; Index++) {
> DEBUG((DEBUG_INFO, ">>>>>>DisableDmar() for engine [%d] \n",
> Index));
> @@ -327,7 +329,29 @@ DisableDmar (
> //
> // Disable VTd
> //
> - MmioWrite32 (mVtdUnitInformation[Index].VtdUnitBaseAddress +
> R_GCMD_REG, B_GMCD_REG_SRTP);
> + //
> + // Set TE (Translation Enable: BIT31) of Global command register to
> zero
> + //
> + Reg32 = MmioRead32
> (mVtdUnitInformation[Index].VtdUnitBaseAddress + R_GSTS_REG);
> + Status = (Reg32 & 0x96FFFFFF); // Reset the one-shot bits
> + Command = (Status & ~B_GMCD_REG_TE);
> + MmioWrite32 (mVtdUnitInformation[Index].VtdUnitBaseAddress +
> R_GCMD_REG, Command);
> +
> + //
> + // Poll on TE Status bit of Global status register to become zero
> + //
> + do {
> + Reg32 = MmioRead32
> (mVtdUnitInformation[Index].VtdUnitBaseAddress + R_GSTS_REG);
> + } while ((Reg32 & B_GSTS_REG_TE) == B_GSTS_REG_TE);
> +
> + //
> + // Set SRTP (Set Root Table Pointer: BIT30) of Global command
> register in order to update the root table pointerDisable VTd
> + //
> + Reg32 = MmioRead32
> (mVtdUnitInformation[Index].VtdUnitBaseAddress + R_GSTS_REG);
> + Status = (Reg32 & 0x96FFFFFF); // Reset the one-shot bits
> + Command = (Status | B_GMCD_REG_SRTP);
> + MmioWrite32 (mVtdUnitInformation[Index].VtdUnitBaseAddress +
> R_GCMD_REG, Command);
> +
> do {
> Reg32 = MmioRead32
> (mVtdUnitInformation[Index].VtdUnitBaseAddress + R_GSTS_REG);
> } while((Reg32 & B_GSTS_REG_RTPS) == 0);
> diff --git a/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.c
> b/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.c
> index 27847f4331..c8a2cae5ff 100644
> --- a/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.c
> +++ b/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.c
> @@ -1,6 +1,6 @@
> /** @file
>
> - Copyright (c) 2017 - 2018, Intel Corporation. All rights reserved.<BR>
> + Copyright (c) 2017 - 2019, 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.
> @@ -26,7 +26,7 @@
> #include <Ppi/VtdInfo.h>
> #include <Ppi/MemoryDiscovered.h>
> #include <Ppi/EndOfPeiPhase.h>
> -
> +#include <SysMemInfoHob.h>
> #include "IntelVTdPmrPei.h"
>
> EFI_GUID mVTdInfoGuid = {
> @@ -430,38 +430,65 @@ InitDmaProtection (
> UINTN MemoryAlignment;
> UINTN LowBottom;
> UINTN LowTop;
> - UINTN HighBottom;
> + UINT64 HighBottom;
> UINT64 HighTop;
> DMA_BUFFER_INFO *DmaBufferInfo;
> VOID *Hob;
> EFI_PEI_PPI_DESCRIPTOR *OldDescriptor;
> EDKII_IOMMU_PPI *OldIoMmuPpi;
> + SYSTEM_MEM_INFO_HOB *SysMemHob;
> + VOID *SysMemHobPtr;
>
> Hob = GetFirstGuidHob (&mDmaBufferInfoGuid);
> DmaBufferInfo = GET_GUID_HOB_DATA(Hob);
> -
> - DEBUG ((DEBUG_INFO, " DmaBufferSize : 0x%x\n",
> DmaBufferInfo->DmaBufferSize));
> -
> - LowMemoryAlignment = GetLowMemoryAlignment (VTdInfo,
> VTdInfo->EngineMask);
> - HighMemoryAlignment = GetHighMemoryAlignment (VTdInfo,
> VTdInfo->EngineMask);
> - if (LowMemoryAlignment < HighMemoryAlignment) {
> - MemoryAlignment = (UINTN)HighMemoryAlignment;
> +
> + SysMemHobPtr = GetFirstGuidHob (&gSysMemInfoDataHobGuid);
> +
> + if (SysMemHobPtr == NULL) {
> + //
> + // Calcuate the PMR memory alignment
> + //
> + LowMemoryAlignment = GetLowMemoryAlignment (VTdInfo,
> VTdInfo->EngineMask);
> + HighMemoryAlignment = GetHighMemoryAlignment (VTdInfo,
> VTdInfo->EngineMask);
> + if (LowMemoryAlignment < HighMemoryAlignment) {
> + MemoryAlignment = (UINTN)HighMemoryAlignment;
> + } else {
> + MemoryAlignment = LowMemoryAlignment;
> + }
> + ASSERT (DmaBufferInfo->DmaBufferSize ==
> ALIGN_VALUE(DmaBufferInfo->DmaBufferSize, MemoryAlignment));
> +
> + //
> + // Allocate memory for DMA buffer
> + //
> + DmaBufferInfo->DmaBufferBase = (UINTN)AllocateAlignedPages
> (EFI_SIZE_TO_PAGES(DmaBufferInfo->DmaBufferSize), MemoryAlignment);
> + ASSERT (DmaBufferInfo->DmaBufferBase != 0);
> + if (DmaBufferInfo->DmaBufferBase == 0) {
> + DEBUG ((DEBUG_INFO, " InitDmaProtection :
> OutOfResource\n"));
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + DmaBufferInfo->DmaBufferCurrentTop =
> DmaBufferInfo->DmaBufferBase + DmaBufferInfo->DmaBufferSize;
> + DmaBufferInfo->DmaBufferCurrentBottom =
> DmaBufferInfo->DmaBufferBase;
> + LowBottom = 0;
> + LowTop = DmaBufferInfo->DmaBufferBase;
> + HighBottom = DmaBufferInfo->DmaBufferBase +
> DmaBufferInfo->DmaBufferSize;
> + HighTop = LShiftU64 (1, VTdInfo->HostAddressWidth + 1);
> } else {
> - MemoryAlignment = LowMemoryAlignment;
> - }
> - ASSERT (DmaBufferInfo->DmaBufferSize ==
> ALIGN_VALUE(DmaBufferInfo->DmaBufferSize, MemoryAlignment));
> - DmaBufferInfo->DmaBufferBase = (UINTN)AllocateAlignedPages
> (EFI_SIZE_TO_PAGES(DmaBufferInfo->DmaBufferSize), MemoryAlignment);
> - ASSERT (DmaBufferInfo->DmaBufferBase != 0);
> - if (DmaBufferInfo->DmaBufferBase == 0) {
> - DEBUG ((DEBUG_INFO, " InitDmaProtection : OutOfResource\n"));
> - return EFI_OUT_OF_RESOURCES;
> - }
>
> + //
> + // Get the PMR ranges information for the hob
> + //
> + SysMemHob = GET_GUID_HOB_DATA (SysMemHobPtr);
> + DmaBufferInfo->DmaBufferBase = SysMemHob->ProtectedLowLimit
> << 20;
> + LowBottom = SysMemHob->ProtectedLowBase;
> + LowTop = SysMemHob->ProtectedLowLimit << 20;
> + HighBottom = (UINT64) BASE_4GB;
> + HighTop = (UINT64) SysMemHob->ProtectedHighLimit << 20;
> + }
> +
> + DEBUG ((DEBUG_INFO, " DmaBufferSize : 0x%x\n",
> DmaBufferInfo->DmaBufferSize));
> DEBUG ((DEBUG_INFO, " DmaBufferBase : 0x%x\n",
> DmaBufferInfo->DmaBufferBase));
>
> - DmaBufferInfo->DmaBufferCurrentTop =
> DmaBufferInfo->DmaBufferBase + DmaBufferInfo->DmaBufferSize;
> - DmaBufferInfo->DmaBufferCurrentBottom =
> DmaBufferInfo->DmaBufferBase;
> -
> //
> // (Re)Install PPI.
> //
> @@ -478,10 +505,7 @@ InitDmaProtection (
> }
> ASSERT_EFI_ERROR (Status);
>
> - LowBottom = 0;
> - LowTop = DmaBufferInfo->DmaBufferBase;
> - HighBottom = DmaBufferInfo->DmaBufferBase +
> DmaBufferInfo->DmaBufferSize;
> - HighTop = LShiftU64 (1, VTdInfo->HostAddressWidth + 1);
> +
>
> Status = SetDmaProtectedRange (
> VTdInfo,
> diff --git a/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.inf
> b/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.inf
> index 5b688d5cbf..427c9a830c 100644
> --- a/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.inf
> +++ b/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.inf
> @@ -4,7 +4,7 @@
> # This driver initializes VTd engine based upon EDKII_VTD_INFO_PPI
> # and provide DMA protection in PEI.
> #
> -# Copyright (c) 2017 - 2018, Intel Corporation. All rights reserved.<BR>
> +# Copyright (c) 2017 - 2019, 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
> @@ -46,6 +46,9 @@
> IoLib
> CacheMaintenanceLib
>
> +[Guids]
> + gSysMemInfoDataHobGuid ## CONSUMES
> +
> [Ppis]
> gEdkiiIoMmuPpiGuid ## PRODUCES
> gEdkiiVTdInfoPpiGuid ## CONSUMES
> diff --git a/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/VtdReg.c
> b/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/VtdReg.c
> index 888905d40d..b6a3614e75 100644
> --- a/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/VtdReg.c
> +++ b/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/VtdReg.c
> @@ -1,6 +1,6 @@
> /** @file
>
> - Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
> + Copyright (c) 2017 - 2019, 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.
> @@ -203,6 +203,8 @@ DisableDmar (
> )
> {
> UINT32 Reg32;
> + UINT32 Status;
> + UINT32 Command;
>
> DEBUG((DEBUG_INFO, ">>>>>>DisableDmar() for engine [%x] \n",
> VtdUnitBaseAddress));
>
> @@ -214,7 +216,28 @@ DisableDmar (
> //
> // Disable VTd
> //
> - MmioWrite32 (VtdUnitBaseAddress + R_GCMD_REG,
> B_GMCD_REG_SRTP);
> + //
> + // Set TE (Translation Enable: BIT31) of Global command register to zero
> + //
> + Reg32 = MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG);
> + Status = (Reg32 & 0x96FFFFFF); // Reset the one-shot bits
> + Command = (Status & ~B_GMCD_REG_TE);
> + MmioWrite32 (VtdUnitBaseAddress + R_GCMD_REG, Command);
> +
> + //
> + // Poll on TE Status bit of Global status register to become zero
> + //
> + do {
> + Reg32 = MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG);
> + } while ((Reg32 & B_GSTS_REG_TE) == B_GSTS_REG_TE);
> +
> + //
> + // Set SRTP (Set Root Table Pointer: BIT30) of Global command register
> in order to update the root table pointerDisable VTd
> + //
> + Reg32 = MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG);
> + Status = (Reg32 & 0x96FFFFFF); // Reset the one-shot bits
> + Command = (Status | B_GMCD_REG_SRTP);
> + MmioWrite32 (VtdUnitBaseAddress + R_GCMD_REG, Command);
> do {
> Reg32 = MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG);
> } while((Reg32 & B_GSTS_REG_RTPS) == 0);
> diff --git a/IntelSiliconPkg/Include/Library/GetVtdPmrAlignmentLib.h
> b/IntelSiliconPkg/Include/Library/GetVtdPmrAlignmentLib.h
> new file mode 100644
> index 0000000000..537d013783
> --- /dev/null
> +++ b/IntelSiliconPkg/Include/Library/GetVtdPmrAlignmentLib.h
> @@ -0,0 +1,31 @@
> +/** @file
> + Get Global VTd PMR alignment information library.
> +
> + Copyright (c) 2019, 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 __GET_VTD_PMR_ALIGN_LIB_H__
> +#define __GET_VTD_PMR_ALIGN_LIB_H__
> +#include <Library/BaseLib.h>
> +
> +/**
> + Get Global VT-d Protected Memory alignment.
> +
> +
> + @return protected high memory alignment.
> +**/
> +
> +UINTN
> +GetGlobalVtdPmrAlignment (
> +);
> +
> +#endif // __GET_VTD_PMR_ALIGN_LIB_H__
> diff --git a/IntelSiliconPkg/Include/SysMemInfoHob.h
> b/IntelSiliconPkg/Include/SysMemInfoHob.h
> new file mode 100644
> index 0000000000..d3045b2c7a
> --- /dev/null
> +++ b/IntelSiliconPkg/Include/SysMemInfoHob.h
> @@ -0,0 +1,28 @@
> +/** @file
> + The definition for VTD System information Hob.
> +
> + This is a lightweight VTd information report in PEI phase.
> +
> + Copyright (c) 2019, 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 _SYS_MEM_INFO_HOB_H_
> +#define _SYS_MEM_INFO_HOB_H_
> +
> +typedef struct {
> + UINTN ProtectedLowBase;
> + UINTN ProtectedLowLimit;
> + UINTN ProtectedHighBase;
> + UINTN ProtectedHighLimit;
> +} SYSTEM_MEM_INFO_HOB;
> +
> +#endif // _SYS_MEM_INFO_HOB_H_
> +
> diff --git a/IntelSiliconPkg/IntelSiliconPkg.dec
> b/IntelSiliconPkg/IntelSiliconPkg.dec
> index c0cf58fa6c..d2efac71c0 100644
> --- a/IntelSiliconPkg/IntelSiliconPkg.dec
> +++ b/IntelSiliconPkg/IntelSiliconPkg.dec
> @@ -3,7 +3,7 @@
> #
> # This package provides common open source Intel silicon modules.
> #
> -# Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
> +# Copyright (c) 2016 - 2019, 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
> @@ -27,6 +27,7 @@
> ## @libraryclass Provides services to access Microcode region on flash
> device.
> #
> MicrocodeFlashAccessLib|Include/Library/MicrocodeFlashAccessLib.h
> + GetVtdPmrAlignmentLib|Include/Library/GetVtdPmrAlignmentLib.h
>
> [Guids]
> ## GUID for Package token space
> @@ -40,6 +41,7 @@
>
> ## Include/Guid/MicrocodeFmp.h
> gMicrocodeFmpImageTypeIdGuid = { 0x96d4fdcd, 0x1502, 0x424d,
> { 0x9d, 0x4c, 0x9b, 0x12, 0xd2, 0xdc, 0xae, 0x5c } }
> + gSysMemInfoDataHobGuid = {0x6fb61645, 0xf168, 0x46be, { 0x80, 0xec,
> 0xb5, 0x02, 0x38, 0x5e, 0xe7, 0xe7 } }
>
> [Ppis]
> gEdkiiVTdInfoPpiGuid = { 0x8a59fcb3, 0xf191, 0x400c, { 0x97, 0x67, 0x67,
> 0xaf, 0x2b, 0x25, 0x68, 0x4a } }
> diff --git a/IntelSiliconPkg/IntelSiliconPkg.dsc
> b/IntelSiliconPkg/IntelSiliconPkg.dsc
> index 790870e2f1..99061e3715 100644
> --- a/IntelSiliconPkg/IntelSiliconPkg.dsc
> +++ b/IntelSiliconPkg/IntelSiliconPkg.dsc
> @@ -1,7 +1,7 @@
> ## @file
> # This package provides common open source Intel silicon modules.
> #
> -# Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
> +# Copyright (c) 2017 - 2019, 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
> @@ -40,6 +40,7 @@
>
> SerialPortLib|MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.in
> f
>
> CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCac
> heMaintenanceLib.inf
>
> MicrocodeFlashAccessLib|IntelSiliconPkg/Feature/Capsule/Library/Microcod
> eFlashAccessLibNull/MicrocodeFlashAccessLibNull.inf
> +
> GetVtdPmrAlignmentLib|IntelSiliconPkg/Library/GetVtdPmrAlignmentLib/Get
> VtdPmrAlignmentLib.inf
>
> [LibraryClasses.common.PEIM]
> PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf
> diff --git
> a/IntelSiliconPkg/Library/GetVtdPmrAlignmentLib/GetVtdPmrAlignmentLib.c
> b/IntelSiliconPkg/Library/GetVtdPmrAlignmentLib/GetVtdPmrAlignmentLib.c
> new file mode 100644
> index 0000000000..28fb8d4978
> --- /dev/null
> +++
> b/IntelSiliconPkg/Library/GetVtdPmrAlignmentLib/GetVtdPmrAlignmentLib.c
> @@ -0,0 +1,170 @@
> +/** @file
> + Library to get Global VTd PMR alignment information.
> + Copyright (c) 2019, 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 <Library/GetVtdPmrAlignmentLib.h>
> +#include <Library/PeiServicesLib.h>
> +#include <IndustryStandard/DmaRemappingReportingTable.h>
> +#include <IndustryStandard/VTd.h>
> +
> +typedef union {
> + struct {
> + UINT32 Low;
> + UINT32 High;
> + } Data32;
> + UINT64 Data;
> +} UINT64_STRUCT;
> +
> +/**
> + Get protected low memory alignment.
> +
> + @param HostAddressWidth The host address width.
> + @param VtdUnitBaseAddress The base address of the VTd engine.
> +
> + @return protected low memory alignment.
> +**/
> +UINT32
> +GetGlobalVTdPlmrAlignment (
> + IN UINT8 HostAddressWidth,
> + 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 HostAddressWidth The host address width.
> + @param VtdUnitBaseAddress The base address of the VTd engine.
> +
> + @return protected high memory alignment.
> +**/
> +UINT64_STRUCT
> +GetGlobalVTdPhmrAlignment (
> + IN UINT8 HostAddressWidth,
> + IN UINTN VtdUnitBaseAddress
> + )
> +{
> + UINT64_STRUCT Data64;
> +
> + MmioWrite64 (VtdUnitBaseAddress + R_PMEN_HIGH_BASE_REG,
> 0xFFFFFFFFFFFFFFFF);
> + Data64.Data = MmioRead64 (VtdUnitBaseAddress +
> R_PMEN_HIGH_BASE_REG);
> + Data64.Data = ~Data64.Data + 1;
> + Data64.Data = Data64.Data & (LShiftU64 (1, HostAddressWidth) - 1);
> +
> + return Data64;
> +}
> +
> +/**
> + Get Global VT-d Protected Memory Aignment.
> +
> + @return protected high memory alignment.
> +**/
> +UINTN
> +GetGlobalVtdPmrAlignment (
> +)
> +{
> + UINT32 LowMemoryAlignment;
> + UINT64_STRUCT HighMemoryAlignment;
> + UINTN MemoryAlignment;
> + UINT32 GlobalVTdBaseAddress;
> + EFI_STATUS Status;
> + UINTN VtdIndex;
> + EFI_ACPI_DMAR_STRUCTURE_HEADER *DmarHeader;
> + EFI_ACPI_DMAR_DRHD_HEADER *DrhdHeader;
> + EFI_ACPI_DMAR_HEADER *AcpiDmarTable;
> +
> + //
> + // Initialization
> + //
> + GlobalVTdBaseAddress = 0xFFFFFFFF;
> + LowMemoryAlignment = 0;
> + HighMemoryAlignment.Data = 0;
> + MemoryAlignment = 0;
> + Status = EFI_UNSUPPORTED;
> + VtdIndex = 0;
> + DmarHeader = NULL;
> + DrhdHeader = NULL;
> + AcpiDmarTable = NULL;
> +
> + //
> + // Fatch the PEI DMAR ACPU Table that created and installed in
> PlatformVTdInfoSamplePei.c
> + //
> + Status = PeiServicesLocatePpi (
> + &gEdkiiVTdInfoPpiGuid,
> + 0,
> + NULL,
> + (VOID **)&AcpiDmarTable
> + );
> + if (EFI_ERROR (Status)) {
> +
> + DEBUG ((DEBUG_ERROR, "PeiServicesLocatePpi gEdkiiVTdInfoPpiGuid
> failed\n"));
> + Status = EFI_NOT_FOUND;
> + MemoryAlignment = SIZE_1MB;
> +
> + } else {
> +
> + //
> + // Seatch the DRHD structure with INCLUDE_PCI_ALL flag Set -> Global
> VT-d
> + //
> + DmarHeader = (EFI_ACPI_DMAR_STRUCTURE_HEADER
> *)((UINTN)(AcpiDmarTable + 1));
> + while ((UINTN)DmarHeader < (UINTN)AcpiDmarTable +
> AcpiDmarTable->Header.Length) {
> + switch (DmarHeader->Type) {
> + case EFI_ACPI_DMAR_TYPE_DRHD:
> + DrhdHeader = (EFI_ACPI_DMAR_DRHD_HEADER *) DmarHeader;
> + if ((DrhdHeader->Flags & BIT0) == BIT0) {
> + GlobalVTdBaseAddress =
> (UINT32)DrhdHeader->RegisterBaseAddress;
> + DEBUG ((DEBUG_INFO," GlobalVTdBaseAddress: %x\n",
> GlobalVTdBaseAddress));
> + }
> + VtdIndex++;
> +
> + break;
> +
> + default:
> + break;
> + }
> + DmarHeader = (EFI_ACPI_DMAR_STRUCTURE_HEADER
> *)((UINTN)DmarHeader + DmarHeader->Length);
> + }
> +
> + if (GlobalVTdBaseAddress == 0xFFFFFFFF) {
> +
> + DEBUG ((DEBUG_ERROR, "Error! Please set INCLUDE_PCI_ALL flag
> to your Global VT-d\n"));
> + MemoryAlignment = SIZE_1MB;
> +
> + } else {
> + //
> + // Get the alignment information from VT-d register
> + //
> + LowMemoryAlignment = GetGlobalVTdPlmrAlignment
> (AcpiDmarTable->HostAddressWidth, GlobalVTdBaseAddress);
> + HighMemoryAlignment = GetGlobalVTdPhmrAlignment
> (AcpiDmarTable->HostAddressWidth, GlobalVTdBaseAddress);
> + if (LowMemoryAlignment < HighMemoryAlignment.Data) {
> + MemoryAlignment = (UINTN)HighMemoryAlignment.Data;
> + } else {
> + MemoryAlignment = LowMemoryAlignment;
> + }
> + }
> + }
> +
> + return MemoryAlignment;
> +}
> \ No newline at end of file
> diff --git
> a/IntelSiliconPkg/Library/GetVtdPmrAlignmentLib/GetVtdPmrAlignmentLib.in
> f
> b/IntelSiliconPkg/Library/GetVtdPmrAlignmentLib/GetVtdPmrAlignmentLib.in
> f
> new file mode 100644
> index 0000000000..2ef199c92e
> --- /dev/null
> +++
> b/IntelSiliconPkg/Library/GetVtdPmrAlignmentLib/GetVtdPmrAlignmentLib.in
> f
> @@ -0,0 +1,38 @@
> +## @file
> +# Component INF file for the GetVtdPmrAlignment library.
> +#
> +# Copyright (c) 2019, 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 = GetVtdPmrAlignmentLib
> +FILE_GUID = 0332BE93-0547-4D87-A7FA-0D9D76C53187
> +MODULE_TYPE = BASE
> +LIBRARY_CLASS = GetVtdPmrAlignmentLib
> +
> +[Packages]
> +MdePkg/MdePkg.dec
> +IntelSiliconPkg/IntelSiliconPkg.dec
> +
> +[Sources]
> +GetVtdPmrAlignmentLib.c
> +
> +[LibraryClasses]
> +DebugLib
> +BaseMemoryLib
> +MemoryAllocationLib
> +BaseLib
> +PeiServicesLib
> +
> +[Ppis]
> +gEdkiiVTdInfoPpiGuid
> --
> 2.16.2.windows.1
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] Extened PMR feature: allow silicon code to adjust PLMR/PHMR region base on the project needs
2019-08-08 13:41 ` Yao, Jiewen
@ 2019-08-08 18:04 ` Wang, Iwen Evelyn
0 siblings, 0 replies; 4+ messages in thread
From: Wang, Iwen Evelyn @ 2019-08-08 18:04 UTC (permalink / raw)
To: Yao, Jiewen; +Cc: Huang, Jenny, devel@edk2.groups.io
Hi Jiewen,
1) We updated the license header.
Evelyn: I'm aware of this license header change, and I think I already follow the new format.
I will confirm it again.
2) We moved the IntelSiliconPkg from edkii repo to edkii-platform repo.
Evelyn: I'm aware of it as well, and before I submitted the code review, I did consult with Chasel and confirmed that my patch is in the right directory. (edkii-platform repo)
Would you please pull the latest tree and apply the patch, then send it again?
Evelyn: Sure! I will consult with other experienced people to fill the gap above, also fix the format issues. Thanks for reminder.
BR
Evelyn Wang
-----Original Message-----
From: Yao, Jiewen
Sent: Thursday, August 8, 2019 6:41 AM
To: Wang, Iwen Evelyn <iwen.evelyn.wang@intel.com>; devel@edk2.groups.io
Cc: Huang, Jenny <jenny.huang@intel.com>
Subject: RE: [PATCH] Extened PMR feature: allow silicon code to adjust PLMR/PHMR region base on the project needs
Hi Evelyn
Thanks for the enhancement.
However, I fail to apply the patch to the latest tree.
Please be aware that:
1) We updated the license header.
2) We moved the IntelSiliconPkg from edkii repo to edkii-platform repo.
Would you please pull the latest tree and apply the patch, then send it again?
Some format issue:
1) "Cd: more.shih@intel.com" should be "Cc: more.shih@intel.com", right?
2) Please also add the full name such as: Cc: Jiewen Yao <jiewen.yao@intel.com>
3) Please remove "Change-Id: Ia80394183522f7a4a921a75a1fa6e3779053d4eb"
4) Please add "PackageName/ModuleName:" in the title.
Thank you
Yao Jiewen
> -----Original Message-----
> From: Wang, Iwen Evelyn
> Sent: Thursday, August 8, 2019 8:29 AM
> To: devel@edk2.groups.io
> Cc: Huang, Jenny <jenny.huang@intel.com>; Yao, Jiewen
> <jiewen.yao@intel.com>
> Subject: [PATCH] Extened PMR feature: allow silicon code to adjust
> PLMR/PHMR region base on the project needs
>
> REF: https://bugzilla.tianocore.org/show_bug.cgi?id=1770
>
> 1) IOMMU PMR feature should be generic to support different hardware
> architecture.
> Some platforms may request no overlap between PMR regions and system
> reserve memory regions. Create an interface to control PLMR/PHMR
> regions.
>
> 2) DisableDMAr Function Code Optimization Currently, DisableDMAr flow
> functional-wise has no issues. However, it will be great if we can
> optimize the flow to follow the VT-d spec requirements.
>
> 3) Renamed InitDmar() to InitGlobalVtd() The oringal function name is
> misleading
>
> Change-Id: Ia80394183522f7a4a921a75a1fa6e3779053d4eb
> Cc: jenny.huang@intel.com
> Cc: jiewen.yao@intel.com
> Cd: more.shih@intel.com
> Signed-off-by: Evelyn Wang <iwen.evelyn.wang@intel.com>
> ---
> IntelSiliconPkg/Feature/VTd/IntelVTdDxe/VtdReg.c
> | 28 ++++++++++++++++++++++++++--
> IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.c
> | 76
> ++++++++++++++++++++++++++++++++++++++++++++++++++------------------
> --------
> IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.inf
> | 5 ++++-
> IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/VtdReg.c
> | 27 +++++++++++++++++++++++++--
> IntelSiliconPkg/Include/Library/GetVtdPmrAlignmentLib.h
> | 31 +++++++++++++++++++++++++++++++
> IntelSiliconPkg/Include/SysMemInfoHob.h
> | 28 ++++++++++++++++++++++++++++
> IntelSiliconPkg/IntelSiliconPkg.dec
> | 4 +++-
> IntelSiliconPkg/IntelSiliconPkg.dsc
> | 3 ++-
> IntelSiliconPkg/Library/GetVtdPmrAlignmentLib/GetVtdPmrAlignmentLib.c
> | 170
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++
>
> IntelSiliconPkg/Library/GetVtdPmrAlignmentLib/GetVtdPmrAlignmentLib.in
> f
> | 38 ++++++++++++++++++++++++++++++++++++++
> 10 files changed, 377 insertions(+), 33 deletions(-)
>
> diff --git a/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/VtdReg.c
> b/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/VtdReg.c
> index 8dbc83fa2d..6a66a860b4 100644
> --- a/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/VtdReg.c
> +++ b/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/VtdReg.c
> @@ -1,6 +1,6 @@
> /** @file
>
> - Copyright (c) 2017 - 2018, Intel Corporation. All rights
> reserved.<BR>
> + Copyright (c) 2017 - 2019, 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 @@ -315,6 +315,8 @@ DisableDmar (
> UINTN Index;
> UINTN SubIndex;
> UINT32 Reg32;
> + UINT32 Status;
> + UINT32 Command;
>
> for (Index = 0; Index < mVtdUnitNumber; Index++) {
> DEBUG((DEBUG_INFO, ">>>>>>DisableDmar() for engine [%d] \n",
> Index)); @@ -327,7 +329,29 @@ DisableDmar (
> //
> // Disable VTd
> //
> - MmioWrite32 (mVtdUnitInformation[Index].VtdUnitBaseAddress +
> R_GCMD_REG, B_GMCD_REG_SRTP);
> + //
> + // Set TE (Translation Enable: BIT31) of Global command register
> + to
> zero
> + //
> + Reg32 = MmioRead32
> (mVtdUnitInformation[Index].VtdUnitBaseAddress + R_GSTS_REG);
> + Status = (Reg32 & 0x96FFFFFF); // Reset the one-shot bits
> + Command = (Status & ~B_GMCD_REG_TE);
> + MmioWrite32 (mVtdUnitInformation[Index].VtdUnitBaseAddress +
> R_GCMD_REG, Command);
> +
> + //
> + // Poll on TE Status bit of Global status register to become zero
> + //
> + do {
> + Reg32 = MmioRead32
> (mVtdUnitInformation[Index].VtdUnitBaseAddress + R_GSTS_REG);
> + } while ((Reg32 & B_GSTS_REG_TE) == B_GSTS_REG_TE);
> +
> + //
> + // Set SRTP (Set Root Table Pointer: BIT30) of Global command
> register in order to update the root table pointerDisable VTd
> + //
> + Reg32 = MmioRead32
> (mVtdUnitInformation[Index].VtdUnitBaseAddress + R_GSTS_REG);
> + Status = (Reg32 & 0x96FFFFFF); // Reset the one-shot bits
> + Command = (Status | B_GMCD_REG_SRTP);
> + MmioWrite32 (mVtdUnitInformation[Index].VtdUnitBaseAddress +
> R_GCMD_REG, Command);
> +
> do {
> Reg32 = MmioRead32
> (mVtdUnitInformation[Index].VtdUnitBaseAddress + R_GSTS_REG);
> } while((Reg32 & B_GSTS_REG_RTPS) == 0); diff --git
> a/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.c
> b/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.c
> index 27847f4331..c8a2cae5ff 100644
> --- a/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.c
> +++ b/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.c
> @@ -1,6 +1,6 @@
> /** @file
>
> - Copyright (c) 2017 - 2018, Intel Corporation. All rights
> reserved.<BR>
> + Copyright (c) 2017 - 2019, 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.
> @@ -26,7 +26,7 @@
> #include <Ppi/VtdInfo.h>
> #include <Ppi/MemoryDiscovered.h>
> #include <Ppi/EndOfPeiPhase.h>
> -
> +#include <SysMemInfoHob.h>
> #include "IntelVTdPmrPei.h"
>
> EFI_GUID mVTdInfoGuid = {
> @@ -430,38 +430,65 @@ InitDmaProtection (
> UINTN MemoryAlignment;
> UINTN LowBottom;
> UINTN LowTop;
> - UINTN HighBottom;
> + UINT64 HighBottom;
> UINT64 HighTop;
> DMA_BUFFER_INFO *DmaBufferInfo;
> VOID *Hob;
> EFI_PEI_PPI_DESCRIPTOR *OldDescriptor;
> EDKII_IOMMU_PPI *OldIoMmuPpi;
> + SYSTEM_MEM_INFO_HOB *SysMemHob;
> + VOID *SysMemHobPtr;
>
> Hob = GetFirstGuidHob (&mDmaBufferInfoGuid);
> DmaBufferInfo = GET_GUID_HOB_DATA(Hob);
> -
> - DEBUG ((DEBUG_INFO, " DmaBufferSize : 0x%x\n",
> DmaBufferInfo->DmaBufferSize));
> -
> - LowMemoryAlignment = GetLowMemoryAlignment (VTdInfo,
> VTdInfo->EngineMask);
> - HighMemoryAlignment = GetHighMemoryAlignment (VTdInfo,
> VTdInfo->EngineMask);
> - if (LowMemoryAlignment < HighMemoryAlignment) {
> - MemoryAlignment = (UINTN)HighMemoryAlignment;
> +
> + SysMemHobPtr = GetFirstGuidHob (&gSysMemInfoDataHobGuid);
> +
> + if (SysMemHobPtr == NULL) {
> + //
> + // Calcuate the PMR memory alignment
> + //
> + LowMemoryAlignment = GetLowMemoryAlignment (VTdInfo,
> VTdInfo->EngineMask);
> + HighMemoryAlignment = GetHighMemoryAlignment (VTdInfo,
> VTdInfo->EngineMask);
> + if (LowMemoryAlignment < HighMemoryAlignment) {
> + MemoryAlignment = (UINTN)HighMemoryAlignment;
> + } else {
> + MemoryAlignment = LowMemoryAlignment;
> + }
> + ASSERT (DmaBufferInfo->DmaBufferSize ==
> ALIGN_VALUE(DmaBufferInfo->DmaBufferSize, MemoryAlignment));
> +
> + //
> + // Allocate memory for DMA buffer
> + //
> + DmaBufferInfo->DmaBufferBase = (UINTN)AllocateAlignedPages
> (EFI_SIZE_TO_PAGES(DmaBufferInfo->DmaBufferSize), MemoryAlignment);
> + ASSERT (DmaBufferInfo->DmaBufferBase != 0);
> + if (DmaBufferInfo->DmaBufferBase == 0) {
> + DEBUG ((DEBUG_INFO, " InitDmaProtection :
> OutOfResource\n"));
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + DmaBufferInfo->DmaBufferCurrentTop =
> DmaBufferInfo->DmaBufferBase + DmaBufferInfo->DmaBufferSize;
> + DmaBufferInfo->DmaBufferCurrentBottom =
> DmaBufferInfo->DmaBufferBase;
> + LowBottom = 0;
> + LowTop = DmaBufferInfo->DmaBufferBase;
> + HighBottom = DmaBufferInfo->DmaBufferBase +
> DmaBufferInfo->DmaBufferSize;
> + HighTop = LShiftU64 (1, VTdInfo->HostAddressWidth + 1);
> } else {
> - MemoryAlignment = LowMemoryAlignment;
> - }
> - ASSERT (DmaBufferInfo->DmaBufferSize ==
> ALIGN_VALUE(DmaBufferInfo->DmaBufferSize, MemoryAlignment));
> - DmaBufferInfo->DmaBufferBase = (UINTN)AllocateAlignedPages
> (EFI_SIZE_TO_PAGES(DmaBufferInfo->DmaBufferSize), MemoryAlignment);
> - ASSERT (DmaBufferInfo->DmaBufferBase != 0);
> - if (DmaBufferInfo->DmaBufferBase == 0) {
> - DEBUG ((DEBUG_INFO, " InitDmaProtection : OutOfResource\n"));
> - return EFI_OUT_OF_RESOURCES;
> - }
>
> + //
> + // Get the PMR ranges information for the hob
> + //
> + SysMemHob = GET_GUID_HOB_DATA (SysMemHobPtr);
> + DmaBufferInfo->DmaBufferBase = SysMemHob->ProtectedLowLimit
> << 20;
> + LowBottom = SysMemHob->ProtectedLowBase;
> + LowTop = SysMemHob->ProtectedLowLimit << 20;
> + HighBottom = (UINT64) BASE_4GB;
> + HighTop = (UINT64) SysMemHob->ProtectedHighLimit << 20; }
> +
> + DEBUG ((DEBUG_INFO, " DmaBufferSize : 0x%x\n",
> DmaBufferInfo->DmaBufferSize));
> DEBUG ((DEBUG_INFO, " DmaBufferBase : 0x%x\n",
> DmaBufferInfo->DmaBufferBase));
>
> - DmaBufferInfo->DmaBufferCurrentTop =
> DmaBufferInfo->DmaBufferBase + DmaBufferInfo->DmaBufferSize;
> - DmaBufferInfo->DmaBufferCurrentBottom =
> DmaBufferInfo->DmaBufferBase;
> -
> //
> // (Re)Install PPI.
> //
> @@ -478,10 +505,7 @@ InitDmaProtection (
> }
> ASSERT_EFI_ERROR (Status);
>
> - LowBottom = 0;
> - LowTop = DmaBufferInfo->DmaBufferBase;
> - HighBottom = DmaBufferInfo->DmaBufferBase +
> DmaBufferInfo->DmaBufferSize;
> - HighTop = LShiftU64 (1, VTdInfo->HostAddressWidth + 1);
> +
>
> Status = SetDmaProtectedRange (
> VTdInfo,
> diff --git
> a/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.inf
> b/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.inf
> index 5b688d5cbf..427c9a830c 100644
> --- a/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.inf
> +++ b/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.inf
> @@ -4,7 +4,7 @@
> # This driver initializes VTd engine based upon EDKII_VTD_INFO_PPI #
> and provide DMA protection in PEI.
> #
> -# Copyright (c) 2017 - 2018, Intel Corporation. All rights
> reserved.<BR>
> +# Copyright (c) 2017 - 2019, 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 @@ -46,6 +46,9 @@
> IoLib
> CacheMaintenanceLib
>
> +[Guids]
> + gSysMemInfoDataHobGuid ## CONSUMES
> +
> [Ppis]
> gEdkiiIoMmuPpiGuid ## PRODUCES
> gEdkiiVTdInfoPpiGuid ## CONSUMES
> diff --git a/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/VtdReg.c
> b/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/VtdReg.c
> index 888905d40d..b6a3614e75 100644
> --- a/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/VtdReg.c
> +++ b/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/VtdReg.c
> @@ -1,6 +1,6 @@
> /** @file
>
> - Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
> + Copyright (c) 2017 - 2019, 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.
> @@ -203,6 +203,8 @@ DisableDmar (
> )
> {
> UINT32 Reg32;
> + UINT32 Status;
> + UINT32 Command;
>
> DEBUG((DEBUG_INFO, ">>>>>>DisableDmar() for engine [%x] \n",
> VtdUnitBaseAddress));
>
> @@ -214,7 +216,28 @@ DisableDmar (
> //
> // Disable VTd
> //
> - MmioWrite32 (VtdUnitBaseAddress + R_GCMD_REG, B_GMCD_REG_SRTP);
> + //
> + // Set TE (Translation Enable: BIT31) of Global command register to
> + zero //
> + Reg32 = MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG);
> + Status = (Reg32 & 0x96FFFFFF); // Reset the one-shot bits
> + Command = (Status & ~B_GMCD_REG_TE);
> + MmioWrite32 (VtdUnitBaseAddress + R_GCMD_REG, Command);
> +
> + //
> + // Poll on TE Status bit of Global status register to become zero
> + //
> + do {
> + Reg32 = MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG);
> + } while ((Reg32 & B_GSTS_REG_TE) == B_GSTS_REG_TE);
> +
> + //
> + // Set SRTP (Set Root Table Pointer: BIT30) of Global command
> + register
> in order to update the root table pointerDisable VTd
> + //
> + Reg32 = MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG);
> + Status = (Reg32 & 0x96FFFFFF); // Reset the one-shot bits
> + Command = (Status | B_GMCD_REG_SRTP);
> + MmioWrite32 (VtdUnitBaseAddress + R_GCMD_REG, Command);
> do {
> Reg32 = MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG);
> } while((Reg32 & B_GSTS_REG_RTPS) == 0); diff --git
> a/IntelSiliconPkg/Include/Library/GetVtdPmrAlignmentLib.h
> b/IntelSiliconPkg/Include/Library/GetVtdPmrAlignmentLib.h
> new file mode 100644
> index 0000000000..537d013783
> --- /dev/null
> +++ b/IntelSiliconPkg/Include/Library/GetVtdPmrAlignmentLib.h
> @@ -0,0 +1,31 @@
> +/** @file
> + Get Global VTd PMR alignment information library.
> +
> + Copyright (c) 2019, 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 __GET_VTD_PMR_ALIGN_LIB_H__
> +#define __GET_VTD_PMR_ALIGN_LIB_H__
> +#include <Library/BaseLib.h>
> +
> +/**
> + Get Global VT-d Protected Memory alignment.
> +
> +
> + @return protected high memory alignment.
> +**/
> +
> +UINTN
> +GetGlobalVtdPmrAlignment (
> +);
> +
> +#endif // __GET_VTD_PMR_ALIGN_LIB_H__
> diff --git a/IntelSiliconPkg/Include/SysMemInfoHob.h
> b/IntelSiliconPkg/Include/SysMemInfoHob.h
> new file mode 100644
> index 0000000000..d3045b2c7a
> --- /dev/null
> +++ b/IntelSiliconPkg/Include/SysMemInfoHob.h
> @@ -0,0 +1,28 @@
> +/** @file
> + The definition for VTD System information Hob.
> +
> + This is a lightweight VTd information report in PEI phase.
> +
> + Copyright (c) 2019, 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 _SYS_MEM_INFO_HOB_H_
> +#define _SYS_MEM_INFO_HOB_H_
> +
> +typedef struct {
> + UINTN ProtectedLowBase;
> + UINTN ProtectedLowLimit;
> + UINTN ProtectedHighBase;
> + UINTN ProtectedHighLimit;
> +} SYSTEM_MEM_INFO_HOB;
> +
> +#endif // _SYS_MEM_INFO_HOB_H_
> +
> diff --git a/IntelSiliconPkg/IntelSiliconPkg.dec
> b/IntelSiliconPkg/IntelSiliconPkg.dec
> index c0cf58fa6c..d2efac71c0 100644
> --- a/IntelSiliconPkg/IntelSiliconPkg.dec
> +++ b/IntelSiliconPkg/IntelSiliconPkg.dec
> @@ -3,7 +3,7 @@
> #
> # This package provides common open source Intel silicon modules.
> #
> -# Copyright (c) 2016 - 2018, Intel Corporation. All rights
> reserved.<BR>
> +# Copyright (c) 2016 - 2019, 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 @@ -27,6 +27,7 @@
> ## @libraryclass Provides services to access Microcode region on
> flash device.
> #
> MicrocodeFlashAccessLib|Include/Library/MicrocodeFlashAccessLib.h
> + GetVtdPmrAlignmentLib|Include/Library/GetVtdPmrAlignmentLib.h
>
> [Guids]
> ## GUID for Package token space
> @@ -40,6 +41,7 @@
>
> ## Include/Guid/MicrocodeFmp.h
> gMicrocodeFmpImageTypeIdGuid = { 0x96d4fdcd, 0x1502, 0x424d,
> { 0x9d, 0x4c, 0x9b, 0x12, 0xd2, 0xdc, 0xae, 0x5c } }
> + gSysMemInfoDataHobGuid = {0x6fb61645, 0xf168, 0x46be, { 0x80, 0xec,
> 0xb5, 0x02, 0x38, 0x5e, 0xe7, 0xe7 } }
>
> [Ppis]
> gEdkiiVTdInfoPpiGuid = { 0x8a59fcb3, 0xf191, 0x400c, { 0x97, 0x67,
> 0x67, 0xaf, 0x2b, 0x25, 0x68, 0x4a } } diff --git
> a/IntelSiliconPkg/IntelSiliconPkg.dsc
> b/IntelSiliconPkg/IntelSiliconPkg.dsc
> index 790870e2f1..99061e3715 100644
> --- a/IntelSiliconPkg/IntelSiliconPkg.dsc
> +++ b/IntelSiliconPkg/IntelSiliconPkg.dsc
> @@ -1,7 +1,7 @@
> ## @file
> # This package provides common open source Intel silicon modules.
> #
> -# Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
> +# Copyright (c) 2017 - 2019, 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
> @@ -40,6 +40,7 @@
>
> SerialPortLib|MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNu
> SerialPortLib|ll.in
> f
>
> CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCac
> heMaintenanceLib.inf
>
> MicrocodeFlashAccessLib|IntelSiliconPkg/Feature/Capsule/Library/Microc
> MicrocodeFlashAccessLib|od
> eFlashAccessLibNull/MicrocodeFlashAccessLibNull.inf
> +
> GetVtdPmrAlignmentLib|IntelSiliconPkg/Library/GetVtdPmrAlignmentLib/Ge
> GetVtdPmrAlignmentLib|t
> VtdPmrAlignmentLib.inf
>
> [LibraryClasses.common.PEIM]
> PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf
> diff --git
> a/IntelSiliconPkg/Library/GetVtdPmrAlignmentLib/GetVtdPmrAlignmentLib.
> c
> b/IntelSiliconPkg/Library/GetVtdPmrAlignmentLib/GetVtdPmrAlignmentLib.
> c
> new file mode 100644
> index 0000000000..28fb8d4978
> --- /dev/null
> +++
> b/IntelSiliconPkg/Library/GetVtdPmrAlignmentLib/GetVtdPmrAlignmentLib.
> c
> @@ -0,0 +1,170 @@
> +/** @file
> + Library to get Global VTd PMR alignment information.
> + Copyright (c) 2019, 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 <Library/GetVtdPmrAlignmentLib.h> #include
> +<Library/PeiServicesLib.h> #include
> +<IndustryStandard/DmaRemappingReportingTable.h>
> +#include <IndustryStandard/VTd.h>
> +
> +typedef union {
> + struct {
> + UINT32 Low;
> + UINT32 High;
> + } Data32;
> + UINT64 Data;
> +} UINT64_STRUCT;
> +
> +/**
> + Get protected low memory alignment.
> +
> + @param HostAddressWidth The host address width.
> + @param VtdUnitBaseAddress The base address of the VTd engine.
> +
> + @return protected low memory alignment.
> +**/
> +UINT32
> +GetGlobalVTdPlmrAlignment (
> + IN UINT8 HostAddressWidth,
> + 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 HostAddressWidth The host address width.
> + @param VtdUnitBaseAddress The base address of the VTd engine.
> +
> + @return protected high memory alignment.
> +**/
> +UINT64_STRUCT
> +GetGlobalVTdPhmrAlignment (
> + IN UINT8 HostAddressWidth,
> + IN UINTN VtdUnitBaseAddress
> + )
> +{
> + UINT64_STRUCT Data64;
> +
> + MmioWrite64 (VtdUnitBaseAddress + R_PMEN_HIGH_BASE_REG,
> 0xFFFFFFFFFFFFFFFF);
> + Data64.Data = MmioRead64 (VtdUnitBaseAddress +
> R_PMEN_HIGH_BASE_REG);
> + Data64.Data = ~Data64.Data + 1;
> + Data64.Data = Data64.Data & (LShiftU64 (1, HostAddressWidth) - 1);
> +
> + return Data64;
> +}
> +
> +/**
> + Get Global VT-d Protected Memory Aignment.
> +
> + @return protected high memory alignment.
> +**/
> +UINTN
> +GetGlobalVtdPmrAlignment (
> +)
> +{
> + UINT32 LowMemoryAlignment;
> + UINT64_STRUCT HighMemoryAlignment;
> + UINTN MemoryAlignment;
> + UINT32 GlobalVTdBaseAddress;
> + EFI_STATUS Status;
> + UINTN VtdIndex;
> + EFI_ACPI_DMAR_STRUCTURE_HEADER *DmarHeader;
> + EFI_ACPI_DMAR_DRHD_HEADER *DrhdHeader;
> + EFI_ACPI_DMAR_HEADER *AcpiDmarTable;
> +
> + //
> + // Initialization
> + //
> + GlobalVTdBaseAddress = 0xFFFFFFFF;
> + LowMemoryAlignment = 0;
> + HighMemoryAlignment.Data = 0;
> + MemoryAlignment = 0;
> + Status = EFI_UNSUPPORTED;
> + VtdIndex = 0;
> + DmarHeader = NULL;
> + DrhdHeader = NULL;
> + AcpiDmarTable = NULL;
> +
> + //
> + // Fatch the PEI DMAR ACPU Table that created and installed in
> PlatformVTdInfoSamplePei.c
> + //
> + Status = PeiServicesLocatePpi (
> + &gEdkiiVTdInfoPpiGuid,
> + 0,
> + NULL,
> + (VOID **)&AcpiDmarTable
> + );
> + if (EFI_ERROR (Status)) {
> +
> + DEBUG ((DEBUG_ERROR, "PeiServicesLocatePpi gEdkiiVTdInfoPpiGuid
> failed\n"));
> + Status = EFI_NOT_FOUND;
> + MemoryAlignment = SIZE_1MB;
> +
> + } else {
> +
> + //
> + // Seatch the DRHD structure with INCLUDE_PCI_ALL flag Set ->
> + Global
> VT-d
> + //
> + DmarHeader = (EFI_ACPI_DMAR_STRUCTURE_HEADER
> *)((UINTN)(AcpiDmarTable + 1));
> + while ((UINTN)DmarHeader < (UINTN)AcpiDmarTable +
> AcpiDmarTable->Header.Length) {
> + switch (DmarHeader->Type) {
> + case EFI_ACPI_DMAR_TYPE_DRHD:
> + DrhdHeader = (EFI_ACPI_DMAR_DRHD_HEADER *) DmarHeader;
> + if ((DrhdHeader->Flags & BIT0) == BIT0) {
> + GlobalVTdBaseAddress =
> (UINT32)DrhdHeader->RegisterBaseAddress;
> + DEBUG ((DEBUG_INFO," GlobalVTdBaseAddress: %x\n",
> GlobalVTdBaseAddress));
> + }
> + VtdIndex++;
> +
> + break;
> +
> + default:
> + break;
> + }
> + DmarHeader = (EFI_ACPI_DMAR_STRUCTURE_HEADER
> *)((UINTN)DmarHeader + DmarHeader->Length);
> + }
> +
> + if (GlobalVTdBaseAddress == 0xFFFFFFFF) {
> +
> + DEBUG ((DEBUG_ERROR, "Error! Please set INCLUDE_PCI_ALL flag
> to your Global VT-d\n"));
> + MemoryAlignment = SIZE_1MB;
> +
> + } else {
> + //
> + // Get the alignment information from VT-d register
> + //
> + LowMemoryAlignment = GetGlobalVTdPlmrAlignment
> (AcpiDmarTable->HostAddressWidth, GlobalVTdBaseAddress);
> + HighMemoryAlignment = GetGlobalVTdPhmrAlignment
> (AcpiDmarTable->HostAddressWidth, GlobalVTdBaseAddress);
> + if (LowMemoryAlignment < HighMemoryAlignment.Data) {
> + MemoryAlignment = (UINTN)HighMemoryAlignment.Data;
> + } else {
> + MemoryAlignment = LowMemoryAlignment;
> + }
> + }
> + }
> +
> + return MemoryAlignment;
> +}
> \ No newline at end of file
> diff --git
> a/IntelSiliconPkg/Library/GetVtdPmrAlignmentLib/GetVtdPmrAlignmentLib.
> in
> f
> b/IntelSiliconPkg/Library/GetVtdPmrAlignmentLib/GetVtdPmrAlignmentLib.
> in
> f
> new file mode 100644
> index 0000000000..2ef199c92e
> --- /dev/null
> +++
> b/IntelSiliconPkg/Library/GetVtdPmrAlignmentLib/GetVtdPmrAlignmentLib.
> in
> f
> @@ -0,0 +1,38 @@
> +## @file
> +# Component INF file for the GetVtdPmrAlignment library.
> +#
> +# Copyright (c) 2019, 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 = GetVtdPmrAlignmentLib
> +FILE_GUID = 0332BE93-0547-4D87-A7FA-0D9D76C53187
> +MODULE_TYPE = BASE
> +LIBRARY_CLASS = GetVtdPmrAlignmentLib
> +
> +[Packages]
> +MdePkg/MdePkg.dec
> +IntelSiliconPkg/IntelSiliconPkg.dec
> +
> +[Sources]
> +GetVtdPmrAlignmentLib.c
> +
> +[LibraryClasses]
> +DebugLib
> +BaseMemoryLib
> +MemoryAllocationLib
> +BaseLib
> +PeiServicesLib
> +
> +[Ppis]
> +gEdkiiVTdInfoPpiGuid
> --
> 2.16.2.windows.1
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH] Extened PMR feature: allow silicon code to adjust PLMR/PHMR region base on the project needs
@ 2019-08-07 21:48 Evelyn Wang
0 siblings, 0 replies; 4+ messages in thread
From: Evelyn Wang @ 2019-08-07 21:48 UTC (permalink / raw)
To: devel
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=1770
1) IOMMU PMR feature should be generic to support different hardware architecture.
Some platforms may request no overlap between PMR regions and system reserve memory regions. Create an interface to control PLMR/PHMR regions.
2) DisableDMAr Function Code Optimization
Currently, DisableDMAr flow functional-wise has no issues. However, it will be great if we can optimize the flow to follow the VT-d spec requirements.
3) Renamed InitDmar() to InitGlobalVtd()
The oringal function name is misleading
Change-Id: Ia80394183522f7a4a921a75a1fa6e3779053d4eb
Cc:
Cc:
Signed-off-by:
Reviewed-by:
---
IntelSiliconPkg/Feature/VTd/IntelVTdDxe/VtdReg.c | 28 ++++++++++++++++++++++++++--
IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------
IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.inf | 5 ++++-
IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/VtdReg.c | 27 +++++++++++++++++++++++++--
IntelSiliconPkg/Include/Library/GetVtdPmrAlignmentLib.h | 31 +++++++++++++++++++++++++++++++
IntelSiliconPkg/Include/SysMemInfoHob.h | 28 ++++++++++++++++++++++++++++
IntelSiliconPkg/IntelSiliconPkg.dec | 4 +++-
IntelSiliconPkg/IntelSiliconPkg.dsc | 3 ++-
IntelSiliconPkg/Library/GetVtdPmrAlignmentLib/GetVtdPmrAlignmentLib.c | 170 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
IntelSiliconPkg/Library/GetVtdPmrAlignmentLib/GetVtdPmrAlignmentLib.inf | 38 ++++++++++++++++++++++++++++++++++++++
10 files changed, 377 insertions(+), 33 deletions(-)
diff --git a/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/VtdReg.c b/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/VtdReg.c
index 8dbc83fa2d..6a66a860b4 100644
--- a/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/VtdReg.c
+++ b/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/VtdReg.c
@@ -1,6 +1,6 @@
/** @file
- Copyright (c) 2017 - 2018, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2017 - 2019, 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
@@ -315,6 +315,8 @@ DisableDmar (
UINTN Index;
UINTN SubIndex;
UINT32 Reg32;
+ UINT32 Status;
+ UINT32 Command;
for (Index = 0; Index < mVtdUnitNumber; Index++) {
DEBUG((DEBUG_INFO, ">>>>>>DisableDmar() for engine [%d] \n", Index));
@@ -327,7 +329,29 @@ DisableDmar (
//
// Disable VTd
//
- MmioWrite32 (mVtdUnitInformation[Index].VtdUnitBaseAddress + R_GCMD_REG, B_GMCD_REG_SRTP);
+ //
+ // Set TE (Translation Enable: BIT31) of Global command register to zero
+ //
+ Reg32 = MmioRead32 (mVtdUnitInformation[Index].VtdUnitBaseAddress + R_GSTS_REG);
+ Status = (Reg32 & 0x96FFFFFF); // Reset the one-shot bits
+ Command = (Status & ~B_GMCD_REG_TE);
+ MmioWrite32 (mVtdUnitInformation[Index].VtdUnitBaseAddress + R_GCMD_REG, Command);
+
+ //
+ // Poll on TE Status bit of Global status register to become zero
+ //
+ do {
+ Reg32 = MmioRead32 (mVtdUnitInformation[Index].VtdUnitBaseAddress + R_GSTS_REG);
+ } while ((Reg32 & B_GSTS_REG_TE) == B_GSTS_REG_TE);
+
+ //
+ // Set SRTP (Set Root Table Pointer: BIT30) of Global command register in order to update the root table pointerDisable VTd
+ //
+ Reg32 = MmioRead32 (mVtdUnitInformation[Index].VtdUnitBaseAddress + R_GSTS_REG);
+ Status = (Reg32 & 0x96FFFFFF); // Reset the one-shot bits
+ Command = (Status | B_GMCD_REG_SRTP);
+ MmioWrite32 (mVtdUnitInformation[Index].VtdUnitBaseAddress + R_GCMD_REG, Command);
+
do {
Reg32 = MmioRead32 (mVtdUnitInformation[Index].VtdUnitBaseAddress + R_GSTS_REG);
} while((Reg32 & B_GSTS_REG_RTPS) == 0);
diff --git a/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.c b/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.c
index 27847f4331..c8a2cae5ff 100644
--- a/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.c
+++ b/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.c
@@ -1,6 +1,6 @@
/** @file
- Copyright (c) 2017 - 2018, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2017 - 2019, 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.
@@ -26,7 +26,7 @@
#include <Ppi/VtdInfo.h>
#include <Ppi/MemoryDiscovered.h>
#include <Ppi/EndOfPeiPhase.h>
-
+#include <SysMemInfoHob.h>
#include "IntelVTdPmrPei.h"
EFI_GUID mVTdInfoGuid = {
@@ -430,38 +430,65 @@ InitDmaProtection (
UINTN MemoryAlignment;
UINTN LowBottom;
UINTN LowTop;
- UINTN HighBottom;
+ UINT64 HighBottom;
UINT64 HighTop;
DMA_BUFFER_INFO *DmaBufferInfo;
VOID *Hob;
EFI_PEI_PPI_DESCRIPTOR *OldDescriptor;
EDKII_IOMMU_PPI *OldIoMmuPpi;
+ SYSTEM_MEM_INFO_HOB *SysMemHob;
+ VOID *SysMemHobPtr;
Hob = GetFirstGuidHob (&mDmaBufferInfoGuid);
DmaBufferInfo = GET_GUID_HOB_DATA(Hob);
-
- DEBUG ((DEBUG_INFO, " DmaBufferSize : 0x%x\n", DmaBufferInfo->DmaBufferSize));
-
- LowMemoryAlignment = GetLowMemoryAlignment (VTdInfo, VTdInfo->EngineMask);
- HighMemoryAlignment = GetHighMemoryAlignment (VTdInfo, VTdInfo->EngineMask);
- if (LowMemoryAlignment < HighMemoryAlignment) {
- MemoryAlignment = (UINTN)HighMemoryAlignment;
+
+ SysMemHobPtr = GetFirstGuidHob (&gSysMemInfoDataHobGuid);
+
+ if (SysMemHobPtr == NULL) {
+ //
+ // Calcuate the PMR memory alignment
+ //
+ LowMemoryAlignment = GetLowMemoryAlignment (VTdInfo, VTdInfo->EngineMask);
+ HighMemoryAlignment = GetHighMemoryAlignment (VTdInfo, VTdInfo->EngineMask);
+ if (LowMemoryAlignment < HighMemoryAlignment) {
+ MemoryAlignment = (UINTN)HighMemoryAlignment;
+ } else {
+ MemoryAlignment = LowMemoryAlignment;
+ }
+ ASSERT (DmaBufferInfo->DmaBufferSize == ALIGN_VALUE(DmaBufferInfo->DmaBufferSize, MemoryAlignment));
+
+ //
+ // Allocate memory for DMA buffer
+ //
+ DmaBufferInfo->DmaBufferBase = (UINTN)AllocateAlignedPages (EFI_SIZE_TO_PAGES(DmaBufferInfo->DmaBufferSize), MemoryAlignment);
+ ASSERT (DmaBufferInfo->DmaBufferBase != 0);
+ if (DmaBufferInfo->DmaBufferBase == 0) {
+ DEBUG ((DEBUG_INFO, " InitDmaProtection : OutOfResource\n"));
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ DmaBufferInfo->DmaBufferCurrentTop = DmaBufferInfo->DmaBufferBase + DmaBufferInfo->DmaBufferSize;
+ DmaBufferInfo->DmaBufferCurrentBottom = DmaBufferInfo->DmaBufferBase;
+ LowBottom = 0;
+ LowTop = DmaBufferInfo->DmaBufferBase;
+ HighBottom = DmaBufferInfo->DmaBufferBase + DmaBufferInfo->DmaBufferSize;
+ HighTop = LShiftU64 (1, VTdInfo->HostAddressWidth + 1);
} else {
- MemoryAlignment = LowMemoryAlignment;
- }
- ASSERT (DmaBufferInfo->DmaBufferSize == ALIGN_VALUE(DmaBufferInfo->DmaBufferSize, MemoryAlignment));
- DmaBufferInfo->DmaBufferBase = (UINTN)AllocateAlignedPages (EFI_SIZE_TO_PAGES(DmaBufferInfo->DmaBufferSize), MemoryAlignment);
- ASSERT (DmaBufferInfo->DmaBufferBase != 0);
- if (DmaBufferInfo->DmaBufferBase == 0) {
- DEBUG ((DEBUG_INFO, " InitDmaProtection : OutOfResource\n"));
- return EFI_OUT_OF_RESOURCES;
- }
+ //
+ // Get the PMR ranges information for the hob
+ //
+ SysMemHob = GET_GUID_HOB_DATA (SysMemHobPtr);
+ DmaBufferInfo->DmaBufferBase = SysMemHob->ProtectedLowLimit << 20;
+ LowBottom = SysMemHob->ProtectedLowBase;
+ LowTop = SysMemHob->ProtectedLowLimit << 20;
+ HighBottom = (UINT64) BASE_4GB;
+ HighTop = (UINT64) SysMemHob->ProtectedHighLimit << 20;
+ }
+
+ DEBUG ((DEBUG_INFO, " DmaBufferSize : 0x%x\n", DmaBufferInfo->DmaBufferSize));
DEBUG ((DEBUG_INFO, " DmaBufferBase : 0x%x\n", DmaBufferInfo->DmaBufferBase));
- DmaBufferInfo->DmaBufferCurrentTop = DmaBufferInfo->DmaBufferBase + DmaBufferInfo->DmaBufferSize;
- DmaBufferInfo->DmaBufferCurrentBottom = DmaBufferInfo->DmaBufferBase;
-
//
// (Re)Install PPI.
//
@@ -478,10 +505,7 @@ InitDmaProtection (
}
ASSERT_EFI_ERROR (Status);
- LowBottom = 0;
- LowTop = DmaBufferInfo->DmaBufferBase;
- HighBottom = DmaBufferInfo->DmaBufferBase + DmaBufferInfo->DmaBufferSize;
- HighTop = LShiftU64 (1, VTdInfo->HostAddressWidth + 1);
+
Status = SetDmaProtectedRange (
VTdInfo,
diff --git a/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.inf b/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.inf
index 5b688d5cbf..427c9a830c 100644
--- a/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.inf
+++ b/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.inf
@@ -4,7 +4,7 @@
# This driver initializes VTd engine based upon EDKII_VTD_INFO_PPI
# and provide DMA protection in PEI.
#
-# Copyright (c) 2017 - 2018, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2017 - 2019, 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
@@ -46,6 +46,9 @@
IoLib
CacheMaintenanceLib
+[Guids]
+ gSysMemInfoDataHobGuid ## CONSUMES
+
[Ppis]
gEdkiiIoMmuPpiGuid ## PRODUCES
gEdkiiVTdInfoPpiGuid ## CONSUMES
diff --git a/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/VtdReg.c b/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/VtdReg.c
index 888905d40d..b6a3614e75 100644
--- a/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/VtdReg.c
+++ b/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/VtdReg.c
@@ -1,6 +1,6 @@
/** @file
- Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2017 - 2019, 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.
@@ -203,6 +203,8 @@ DisableDmar (
)
{
UINT32 Reg32;
+ UINT32 Status;
+ UINT32 Command;
DEBUG((DEBUG_INFO, ">>>>>>DisableDmar() for engine [%x] \n", VtdUnitBaseAddress));
@@ -214,7 +216,28 @@ DisableDmar (
//
// Disable VTd
//
- MmioWrite32 (VtdUnitBaseAddress + R_GCMD_REG, B_GMCD_REG_SRTP);
+ //
+ // Set TE (Translation Enable: BIT31) of Global command register to zero
+ //
+ Reg32 = MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG);
+ Status = (Reg32 & 0x96FFFFFF); // Reset the one-shot bits
+ Command = (Status & ~B_GMCD_REG_TE);
+ MmioWrite32 (VtdUnitBaseAddress + R_GCMD_REG, Command);
+
+ //
+ // Poll on TE Status bit of Global status register to become zero
+ //
+ do {
+ Reg32 = MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG);
+ } while ((Reg32 & B_GSTS_REG_TE) == B_GSTS_REG_TE);
+
+ //
+ // Set SRTP (Set Root Table Pointer: BIT30) of Global command register in order to update the root table pointerDisable VTd
+ //
+ Reg32 = MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG);
+ Status = (Reg32 & 0x96FFFFFF); // Reset the one-shot bits
+ Command = (Status | B_GMCD_REG_SRTP);
+ MmioWrite32 (VtdUnitBaseAddress + R_GCMD_REG, Command);
do {
Reg32 = MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG);
} while((Reg32 & B_GSTS_REG_RTPS) == 0);
diff --git a/IntelSiliconPkg/Include/Library/GetVtdPmrAlignmentLib.h b/IntelSiliconPkg/Include/Library/GetVtdPmrAlignmentLib.h
new file mode 100644
index 0000000000..537d013783
--- /dev/null
+++ b/IntelSiliconPkg/Include/Library/GetVtdPmrAlignmentLib.h
@@ -0,0 +1,31 @@
+/** @file
+ Get Global VTd PMR alignment information library.
+
+ Copyright (c) 2019, 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 __GET_VTD_PMR_ALIGN_LIB_H__
+#define __GET_VTD_PMR_ALIGN_LIB_H__
+#include <Library/BaseLib.h>
+
+/**
+ Get Global VT-d Protected Memory alignment.
+
+
+ @return protected high memory alignment.
+**/
+
+UINTN
+GetGlobalVtdPmrAlignment (
+);
+
+#endif // __GET_VTD_PMR_ALIGN_LIB_H__
diff --git a/IntelSiliconPkg/Include/SysMemInfoHob.h b/IntelSiliconPkg/Include/SysMemInfoHob.h
new file mode 100644
index 0000000000..d3045b2c7a
--- /dev/null
+++ b/IntelSiliconPkg/Include/SysMemInfoHob.h
@@ -0,0 +1,28 @@
+/** @file
+ The definition for VTD System information Hob.
+
+ This is a lightweight VTd information report in PEI phase.
+
+ Copyright (c) 2019, 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 _SYS_MEM_INFO_HOB_H_
+#define _SYS_MEM_INFO_HOB_H_
+
+typedef struct {
+ UINTN ProtectedLowBase;
+ UINTN ProtectedLowLimit;
+ UINTN ProtectedHighBase;
+ UINTN ProtectedHighLimit;
+} SYSTEM_MEM_INFO_HOB;
+
+#endif // _SYS_MEM_INFO_HOB_H_
+
diff --git a/IntelSiliconPkg/IntelSiliconPkg.dec b/IntelSiliconPkg/IntelSiliconPkg.dec
index c0cf58fa6c..d2efac71c0 100644
--- a/IntelSiliconPkg/IntelSiliconPkg.dec
+++ b/IntelSiliconPkg/IntelSiliconPkg.dec
@@ -3,7 +3,7 @@
#
# This package provides common open source Intel silicon modules.
#
-# Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2016 - 2019, 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
@@ -27,6 +27,7 @@
## @libraryclass Provides services to access Microcode region on flash device.
#
MicrocodeFlashAccessLib|Include/Library/MicrocodeFlashAccessLib.h
+ GetVtdPmrAlignmentLib|Include/Library/GetVtdPmrAlignmentLib.h
[Guids]
## GUID for Package token space
@@ -40,6 +41,7 @@
## Include/Guid/MicrocodeFmp.h
gMicrocodeFmpImageTypeIdGuid = { 0x96d4fdcd, 0x1502, 0x424d, { 0x9d, 0x4c, 0x9b, 0x12, 0xd2, 0xdc, 0xae, 0x5c } }
+ gSysMemInfoDataHobGuid = {0x6fb61645, 0xf168, 0x46be, { 0x80, 0xec, 0xb5, 0x02, 0x38, 0x5e, 0xe7, 0xe7 } }
[Ppis]
gEdkiiVTdInfoPpiGuid = { 0x8a59fcb3, 0xf191, 0x400c, { 0x97, 0x67, 0x67, 0xaf, 0x2b, 0x25, 0x68, 0x4a } }
diff --git a/IntelSiliconPkg/IntelSiliconPkg.dsc b/IntelSiliconPkg/IntelSiliconPkg.dsc
index 790870e2f1..99061e3715 100644
--- a/IntelSiliconPkg/IntelSiliconPkg.dsc
+++ b/IntelSiliconPkg/IntelSiliconPkg.dsc
@@ -1,7 +1,7 @@
## @file
# This package provides common open source Intel silicon modules.
#
-# Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2017 - 2019, 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
@@ -40,6 +40,7 @@
SerialPortLib|MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.inf
CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf
MicrocodeFlashAccessLib|IntelSiliconPkg/Feature/Capsule/Library/MicrocodeFlashAccessLibNull/MicrocodeFlashAccessLibNull.inf
+ GetVtdPmrAlignmentLib|IntelSiliconPkg/Library/GetVtdPmrAlignmentLib/GetVtdPmrAlignmentLib.inf
[LibraryClasses.common.PEIM]
PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf
diff --git a/IntelSiliconPkg/Library/GetVtdPmrAlignmentLib/GetVtdPmrAlignmentLib.c b/IntelSiliconPkg/Library/GetVtdPmrAlignmentLib/GetVtdPmrAlignmentLib.c
new file mode 100644
index 0000000000..28fb8d4978
--- /dev/null
+++ b/IntelSiliconPkg/Library/GetVtdPmrAlignmentLib/GetVtdPmrAlignmentLib.c
@@ -0,0 +1,170 @@
+/** @file
+ Library to get Global VTd PMR alignment information.
+ Copyright (c) 2019, 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 <Library/GetVtdPmrAlignmentLib.h>
+#include <Library/PeiServicesLib.h>
+#include <IndustryStandard/DmaRemappingReportingTable.h>
+#include <IndustryStandard/VTd.h>
+
+typedef union {
+ struct {
+ UINT32 Low;
+ UINT32 High;
+ } Data32;
+ UINT64 Data;
+} UINT64_STRUCT;
+
+/**
+ Get protected low memory alignment.
+
+ @param HostAddressWidth The host address width.
+ @param VtdUnitBaseAddress The base address of the VTd engine.
+
+ @return protected low memory alignment.
+**/
+UINT32
+GetGlobalVTdPlmrAlignment (
+ IN UINT8 HostAddressWidth,
+ 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 HostAddressWidth The host address width.
+ @param VtdUnitBaseAddress The base address of the VTd engine.
+
+ @return protected high memory alignment.
+**/
+UINT64_STRUCT
+GetGlobalVTdPhmrAlignment (
+ IN UINT8 HostAddressWidth,
+ IN UINTN VtdUnitBaseAddress
+ )
+{
+ UINT64_STRUCT Data64;
+
+ MmioWrite64 (VtdUnitBaseAddress + R_PMEN_HIGH_BASE_REG, 0xFFFFFFFFFFFFFFFF);
+ Data64.Data = MmioRead64 (VtdUnitBaseAddress + R_PMEN_HIGH_BASE_REG);
+ Data64.Data = ~Data64.Data + 1;
+ Data64.Data = Data64.Data & (LShiftU64 (1, HostAddressWidth) - 1);
+
+ return Data64;
+}
+
+/**
+ Get Global VT-d Protected Memory Aignment.
+
+ @return protected high memory alignment.
+**/
+UINTN
+GetGlobalVtdPmrAlignment (
+)
+{
+ UINT32 LowMemoryAlignment;
+ UINT64_STRUCT HighMemoryAlignment;
+ UINTN MemoryAlignment;
+ UINT32 GlobalVTdBaseAddress;
+ EFI_STATUS Status;
+ UINTN VtdIndex;
+ EFI_ACPI_DMAR_STRUCTURE_HEADER *DmarHeader;
+ EFI_ACPI_DMAR_DRHD_HEADER *DrhdHeader;
+ EFI_ACPI_DMAR_HEADER *AcpiDmarTable;
+
+ //
+ // Initialization
+ //
+ GlobalVTdBaseAddress = 0xFFFFFFFF;
+ LowMemoryAlignment = 0;
+ HighMemoryAlignment.Data = 0;
+ MemoryAlignment = 0;
+ Status = EFI_UNSUPPORTED;
+ VtdIndex = 0;
+ DmarHeader = NULL;
+ DrhdHeader = NULL;
+ AcpiDmarTable = NULL;
+
+ //
+ // Fatch the PEI DMAR ACPU Table that created and installed in PlatformVTdInfoSamplePei.c
+ //
+ Status = PeiServicesLocatePpi (
+ &gEdkiiVTdInfoPpiGuid,
+ 0,
+ NULL,
+ (VOID **)&AcpiDmarTable
+ );
+ if (EFI_ERROR (Status)) {
+
+ DEBUG ((DEBUG_ERROR, "PeiServicesLocatePpi gEdkiiVTdInfoPpiGuid failed\n"));
+ Status = EFI_NOT_FOUND;
+ MemoryAlignment = SIZE_1MB;
+
+ } else {
+
+ //
+ // Seatch the DRHD structure with INCLUDE_PCI_ALL flag Set -> Global VT-d
+ //
+ DmarHeader = (EFI_ACPI_DMAR_STRUCTURE_HEADER *)((UINTN)(AcpiDmarTable + 1));
+ while ((UINTN)DmarHeader < (UINTN)AcpiDmarTable + AcpiDmarTable->Header.Length) {
+ switch (DmarHeader->Type) {
+ case EFI_ACPI_DMAR_TYPE_DRHD:
+ DrhdHeader = (EFI_ACPI_DMAR_DRHD_HEADER *) DmarHeader;
+ if ((DrhdHeader->Flags & BIT0) == BIT0) {
+ GlobalVTdBaseAddress = (UINT32)DrhdHeader->RegisterBaseAddress;
+ DEBUG ((DEBUG_INFO," GlobalVTdBaseAddress: %x\n", GlobalVTdBaseAddress));
+ }
+ VtdIndex++;
+
+ break;
+
+ default:
+ break;
+ }
+ DmarHeader = (EFI_ACPI_DMAR_STRUCTURE_HEADER *)((UINTN)DmarHeader + DmarHeader->Length);
+ }
+
+ if (GlobalVTdBaseAddress == 0xFFFFFFFF) {
+
+ DEBUG ((DEBUG_ERROR, "Error! Please set INCLUDE_PCI_ALL flag to your Global VT-d\n"));
+ MemoryAlignment = SIZE_1MB;
+
+ } else {
+ //
+ // Get the alignment information from VT-d register
+ //
+ LowMemoryAlignment = GetGlobalVTdPlmrAlignment (AcpiDmarTable->HostAddressWidth, GlobalVTdBaseAddress);
+ HighMemoryAlignment = GetGlobalVTdPhmrAlignment (AcpiDmarTable->HostAddressWidth, GlobalVTdBaseAddress);
+ if (LowMemoryAlignment < HighMemoryAlignment.Data) {
+ MemoryAlignment = (UINTN)HighMemoryAlignment.Data;
+ } else {
+ MemoryAlignment = LowMemoryAlignment;
+ }
+ }
+ }
+
+ return MemoryAlignment;
+}
\ No newline at end of file
diff --git a/IntelSiliconPkg/Library/GetVtdPmrAlignmentLib/GetVtdPmrAlignmentLib.inf b/IntelSiliconPkg/Library/GetVtdPmrAlignmentLib/GetVtdPmrAlignmentLib.inf
new file mode 100644
index 0000000000..2ef199c92e
--- /dev/null
+++ b/IntelSiliconPkg/Library/GetVtdPmrAlignmentLib/GetVtdPmrAlignmentLib.inf
@@ -0,0 +1,38 @@
+## @file
+# Component INF file for the GetVtdPmrAlignment library.
+#
+# Copyright (c) 2019, 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 = GetVtdPmrAlignmentLib
+FILE_GUID = 0332BE93-0547-4D87-A7FA-0D9D76C53187
+MODULE_TYPE = BASE
+LIBRARY_CLASS = GetVtdPmrAlignmentLib
+
+[Packages]
+MdePkg/MdePkg.dec
+IntelSiliconPkg/IntelSiliconPkg.dec
+
+[Sources]
+GetVtdPmrAlignmentLib.c
+
+[LibraryClasses]
+DebugLib
+BaseMemoryLib
+MemoryAllocationLib
+BaseLib
+PeiServicesLib
+
+[Ppis]
+gEdkiiVTdInfoPpiGuid
--
2.16.2.windows.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
end of thread, other threads:[~2019-08-08 18:04 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-08-08 0:29 [PATCH] Extened PMR feature: allow silicon code to adjust PLMR/PHMR region base on the project needs Evelyn Wang
2019-08-08 13:41 ` Yao, Jiewen
2019-08-08 18:04 ` Wang, Iwen Evelyn
-- strict thread matches above, loose matches on Subject: below --
2019-08-07 21:48 Evelyn Wang
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox