Re: [edk2] [PATCH 2/3] OvmfPkg: introduce FD_SIZE_4MB (mainly) for Windows HCK

2017-04-29 Thread Jordan Justen
On 2017-04-29 13:14:59, Laszlo Ersek wrote:
> The "Confirm64KilobytesOfUnauthenticatedVariableStorage" test case of the
> Secure Boot Logo Test ("Microsoft.UefiSecureBootLogo.Tests") suite in the
> Microsoft Hardware Certification Kit expects to be able to populate the
> variable store up to roughly 64 KB, with a series of 1 KB sized,
> unauthenticated variables. OVMF's current live varstore area is too small
> for this: 56 KB.
> 
> Introduce the FD_SIZE_4MB build macro, which
> 
> - enlarges the full flash image to 4MB -- QEMU supports up to 8MB, see
>   FLASH_MAP_BASE_MIN in "hw/i386/pc_sysfw.c" --,
> 
> - inside that, grows the varstore area / pflash chip to 512 KB, and within
>   it, the live area from 56 KB to 248 KB.
> 
> (For the latter, Hyper-V considers 128 KB generous:

Today, we give 128k to non-volatile storage, which due to various
reasons results in 56k of variable storage. Personally I already
consider this generous, especially when I look at the 128k size of the
seabios bios.bin. :)

>   Re: [edk2] Secure Boot & NV storage size
>   
> http://mid.mail-archive.com/24f63595e68c476eb98cf87e7abfa1bc@BL2PR03MB242.namprd03.prod.outlook.com
> 
> so we should be larger than that, for future proofing.)

I don't want to try to predict the future of Microsoft requirements,
nor be overly generous in the meantime. :) As pointed out by a
colleague, as of Fall 2016, Microsoft expects 120 KB as the current
requirement:

http://www.uefi.org/sites/default/files/resources/UEFI_Plugfest_Security_Microsoft_Fall_2016.pdf

I tested a 2MB RELEASE build of OvmfIa32X64 on GCC 4.9 with:

 * SECURE_BOOT_ENABLE=1
 * SMM_REQUIRE=1

There was > 600k available.

I also tested a 2MB RELEASE build of OvmfIa32X64 on GCC 4.9 with:

 * SECURE_BOOT_ENABLE=1
 * NETWORK_IP6_ENABLE=1
 * HTTP_BOOT_ENABLE=1
 * SMM_REQUIRE=1
 * TLS_ENABLE=1

I don't think we consider those network items as standard
requirements, yet there was still ~373k available. In order to bump
the variables to 120k, we need to use 2 * (120 - 56) => 128k.

So, what about adjusting our 2MB image to this?

Regarding how to 'upgrade' a system from using the smaller storage
size, I don't think there are any good answers. (Which also applies to
the 4MB case.) Does fw-cfg tell us the rom/flash regions?

-Jordan

> Importantly, a firmware binary built with -D FD_SIZE_4MB will *not* be
> compatible with a variable store that originates from a variable store
> template built *without* -D FD_SIZE_4MB. This is the reason for the large
> increase, as every such change breaks compatibility between a new firmware
> binary and old varstore files.
> 
> Enlarging the varstore should not impact the performance of normal
> operations, as we keep the varstore block size 4KB. The performance of
> reclaim is affected, but that is expected (since reclaim has to rework the
> full live area). And, reclaim should occur proportionally less frequently.
> 
> While at it, the FVMAIN_COMPACT volume (with the compressed FFS file in
> it) is also enlarged significantly, so that we have plenty of room for
> future DXEFV (and perhaps PEIFV) increments -- DXEFV has been growing
> steadily, and that increase shows through compression too. Right now the
> PEIFV and DXEFV volumes need no resizing.
> 
> Here's a summary:
> 
>   DescriptionCompression typeSize [KB]
>   -  -  --
>   Non-volatile data storage  open-coded binary128 ->   512 ( +384)
>data
> Variable store 56 ->   248 ( +192)
> Event log   4 -> 4 (   +0)
> Working block   4 -> 4 (   +0)
> Spare area 64 ->   256 ( +192)
> 
>   FVMAIN_COMPACT uncompressed1712 ->  3376 (+1664)
> FV FFS file  LZMA compressed
>   PEIFV  uncompressed 896 ->   896 (   +0)
> individual PEI   uncompressed
>   modules
>   DXEFV  uncompressed   10240 -> 10240 (   +0)
> individual DXE   uncompressed
>   modules
> 
>   SECFV  uncompressed 208 ->   208 (   +0)
> SEC driver
> reset vector code
> 
> Cc: Gary Ching-Pang Lin 
> Cc: Jordan Justen 
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Laszlo Ersek 
> ---
>  OvmfPkg/OvmfPkg.fdf.inc  | 29 
>  OvmfPkg/VarStore.fdf.inc | 46 +++-
>  2 files changed, 73 insertions(+), 2 deletions(-)
> 
> diff --git a/OvmfPkg/OvmfPkg.fdf.inc b/OvmfPkg/OvmfPkg.fdf.inc
> index fce6c7b8ce64..a1eb2d380167 100644
> --- a/OvmfPkg/OvmfPkg.fdf.inc
> +++ b/OvmfPkg/OvmfPkg.fdf.inc
> @@ -20,8 +20,35 @@
>  #
>  # Defining FD_SIZE_1MB on the build command line can override this.
>  #
> +# A 

[edk2] [PATCH 2/3] OvmfPkg: introduce FD_SIZE_4MB (mainly) for Windows HCK

2017-04-29 Thread Laszlo Ersek
The "Confirm64KilobytesOfUnauthenticatedVariableStorage" test case of the
Secure Boot Logo Test ("Microsoft.UefiSecureBootLogo.Tests") suite in the
Microsoft Hardware Certification Kit expects to be able to populate the
variable store up to roughly 64 KB, with a series of 1 KB sized,
unauthenticated variables. OVMF's current live varstore area is too small
for this: 56 KB.

Introduce the FD_SIZE_4MB build macro, which

- enlarges the full flash image to 4MB -- QEMU supports up to 8MB, see
  FLASH_MAP_BASE_MIN in "hw/i386/pc_sysfw.c" --,

- inside that, grows the varstore area / pflash chip to 512 KB, and within
  it, the live area from 56 KB to 248 KB.

(For the latter, Hyper-V considers 128 KB generous:

  Re: [edk2] Secure Boot & NV storage size
  
http://mid.mail-archive.com/24f63595e68c476eb98cf87e7abfa1bc@BL2PR03MB242.namprd03.prod.outlook.com

so we should be larger than that, for future proofing.)

Importantly, a firmware binary built with -D FD_SIZE_4MB will *not* be
compatible with a variable store that originates from a variable store
template built *without* -D FD_SIZE_4MB. This is the reason for the large
increase, as every such change breaks compatibility between a new firmware
binary and old varstore files.

Enlarging the varstore should not impact the performance of normal
operations, as we keep the varstore block size 4KB. The performance of
reclaim is affected, but that is expected (since reclaim has to rework the
full live area). And, reclaim should occur proportionally less frequently.

While at it, the FVMAIN_COMPACT volume (with the compressed FFS file in
it) is also enlarged significantly, so that we have plenty of room for
future DXEFV (and perhaps PEIFV) increments -- DXEFV has been growing
steadily, and that increase shows through compression too. Right now the
PEIFV and DXEFV volumes need no resizing.

Here's a summary:

  DescriptionCompression typeSize [KB]
  -  -  --
  Non-volatile data storage  open-coded binary128 ->   512 ( +384)
   data
Variable store 56 ->   248 ( +192)
Event log   4 -> 4 (   +0)
Working block   4 -> 4 (   +0)
Spare area 64 ->   256 ( +192)

  FVMAIN_COMPACT uncompressed1712 ->  3376 (+1664)
FV FFS file  LZMA compressed
  PEIFV  uncompressed 896 ->   896 (   +0)
individual PEI   uncompressed
  modules
  DXEFV  uncompressed   10240 -> 10240 (   +0)
individual DXE   uncompressed
  modules

  SECFV  uncompressed 208 ->   208 (   +0)
SEC driver
reset vector code

Cc: Gary Ching-Pang Lin 
Cc: Jordan Justen 
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek 
---
 OvmfPkg/OvmfPkg.fdf.inc  | 29 
 OvmfPkg/VarStore.fdf.inc | 46 +++-
 2 files changed, 73 insertions(+), 2 deletions(-)

diff --git a/OvmfPkg/OvmfPkg.fdf.inc b/OvmfPkg/OvmfPkg.fdf.inc
index fce6c7b8ce64..a1eb2d380167 100644
--- a/OvmfPkg/OvmfPkg.fdf.inc
+++ b/OvmfPkg/OvmfPkg.fdf.inc
@@ -20,8 +20,35 @@
 #
 # Defining FD_SIZE_1MB on the build command line can override this.
 #
+# A firmware binary built for the default 2MB flash size, and a firmware binary
+# built with FD_SIZE_1MB defined, use the same variable store layout.
+#
+# Defining FD_SIZE_4MB results in a different (much larger) variable store
+# structure that is incompatible with both the default and the FD_SIZE_1MB
+# firmware binaries.
+#
 
 DEFINE BLOCK_SIZE= 0x1000
+
+!ifdef $(FD_SIZE_4MB)
+
+DEFINE VARS_SIZE = 0x8
+DEFINE VARS_BLOCKS   = 0x80
+DEFINE VARS_LIVE_SIZE= 0x3E000
+DEFINE VARS_SPARE_SIZE   = 0x4
+
+DEFINE FW_BASE_ADDRESS   = 0xFFC0
+DEFINE FW_SIZE   = 0x0040
+DEFINE FW_BLOCKS = 0x400
+DEFINE CODE_BASE_ADDRESS = 0xFFC8
+DEFINE CODE_SIZE = 0x0038
+DEFINE CODE_BLOCKS   = 0x380
+DEFINE FVMAIN_SIZE   = 0x0034C000
+DEFINE SECFV_OFFSET  = 0x003CC000
+DEFINE SECFV_SIZE= 0x34000
+
+!else
+
 DEFINE VARS_SIZE = 0x2
 DEFINE VARS_BLOCKS   = 0x20
 DEFINE VARS_LIVE_SIZE= 0xE000
@@ -53,6 +80,8 @@
 
 !endif
 
+!endif
+
 SET gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFdBaseAddress = $(FW_BASE_ADDRESS)
 SET gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFirmwareFdSize= $(FW_SIZE)
 SET gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFirmwareBlockSize = $(BLOCK_SIZE)
diff --git a/OvmfPkg/VarStore.fdf.inc b/OvmfPkg/VarStore.fdf.inc
index ce901c0109b1..7325b698157d 100644
--- a/OvmfPkg/VarStore.fdf.inc
+++ b/OvmfPkg/VarStore.fdf.inc
@@ -15,7 +15,11 @@
 #
 ##
 
+!ifdef $(FD_SIZE_4MB)
+0x|0x0003e000

[edk2] [PATCH 3/3] OvmfPkg: raise max variable size (auth & non-auth) to 33KB for FD_SIZE_4MB

2017-04-29 Thread Laszlo Ersek
The "ConfirmSetOfLargeVariable" test case of the Secure Boot Logo Test
("Microsoft.UefiSecureBootLogo.Tests") suite in the Microsoft Hardware
Certification Kit sets a 32 KB large non-authenticated variable.

In the FD_SIZE_4MB build, our live varstore is now 248 KB big, so we can
accommodate this. Set both PcdMaxVariableSize and PcdMaxAuthVariableSize
to 0x8400 -- beyond DataSize=0x8000 from the HCK test, we need some room
for the variable name and attributes as well.

Cc: Gary Ching-Pang Lin 
Cc: Jordan Justen 
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek 
---
 OvmfPkg/OvmfPkgIa32.dsc| 5 +
 OvmfPkg/OvmfPkgIa32X64.dsc | 5 +
 OvmfPkg/OvmfPkgX64.dsc | 5 +
 3 files changed, 15 insertions(+)

diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc
index 0796b0db816b..a87aa669b907 100644
--- a/OvmfPkg/OvmfPkgIa32.dsc
+++ b/OvmfPkg/OvmfPkgIa32.dsc
@@ -395,8 +395,13 @@ [PcdsFixedAtBuild]
   gEfiMdePkgTokenSpaceGuid.PcdMaximumGuidedExtractHandler|0x10
   gEfiMdeModulePkgTokenSpaceGuid.PcdPeiCoreMaxFvSupported|6
   gEfiMdeModulePkgTokenSpaceGuid.PcdPeiCoreMaxPeimPerFv|32
+!ifdef $(FD_SIZE_4MB)
+  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x8400
+  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxAuthVariableSize|0x8400
+!else
   gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x2000
   gEfiMdeModulePkgTokenSpaceGuid.PcdMaxAuthVariableSize|0x2800
+!endif
   gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize|0xe000
 
   gEfiMdeModulePkgTokenSpaceGuid.PcdVpdBaseAddress|0x0
diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc
index 71ac62f023b5..c1e9faf0ef88 100644
--- a/OvmfPkg/OvmfPkgIa32X64.dsc
+++ b/OvmfPkg/OvmfPkgIa32X64.dsc
@@ -400,8 +400,13 @@ [PcdsFixedAtBuild]
   gEfiMdePkgTokenSpaceGuid.PcdMaximumGuidedExtractHandler|0x10
   gEfiMdeModulePkgTokenSpaceGuid.PcdPeiCoreMaxFvSupported|6
   gEfiMdeModulePkgTokenSpaceGuid.PcdPeiCoreMaxPeimPerFv|32
+!ifdef $(FD_SIZE_4MB)
+  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x8400
+  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxAuthVariableSize|0x8400
+!else
   gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x2000
   gEfiMdeModulePkgTokenSpaceGuid.PcdMaxAuthVariableSize|0x2800
+!endif
   gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize|0xe000
 
   gEfiMdeModulePkgTokenSpaceGuid.PcdVpdBaseAddress|0x0
diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
index 2ceb31d7ffd5..81e06056226f 100644
--- a/OvmfPkg/OvmfPkgX64.dsc
+++ b/OvmfPkg/OvmfPkgX64.dsc
@@ -400,8 +400,13 @@ [PcdsFixedAtBuild]
   gEfiMdePkgTokenSpaceGuid.PcdMaximumGuidedExtractHandler|0x10
   gEfiMdeModulePkgTokenSpaceGuid.PcdPeiCoreMaxFvSupported|6
   gEfiMdeModulePkgTokenSpaceGuid.PcdPeiCoreMaxPeimPerFv|32
+!ifdef $(FD_SIZE_4MB)
+  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x8400
+  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxAuthVariableSize|0x8400
+!else
   gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x2000
   gEfiMdeModulePkgTokenSpaceGuid.PcdMaxAuthVariableSize|0x2800
+!endif
   gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize|0xe000
 
   gEfiMdeModulePkgTokenSpaceGuid.PcdVpdBaseAddress|0x0
-- 
2.9.3

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


[edk2] [PATCH 0/3] OvmfPkg: add FD_SIZE_4MB for Windows HCK SB tests, and for future proofing

2017-04-29 Thread Laszlo Ersek
The patches come with detailed commit messages; for the blurb, the
subject says it all. For (a whole bunch of) details, please refer to
.

Repo:   https://github.com/lersek/edk2.git
Branch: fd_size_4mb

Cc: Gary Ching-Pang Lin 
Cc: Jordan Justen 

Thanks,
Laszlo

Laszlo Ersek (3):
  OvmfPkg/OvmfPkg.fdf.inc: extract VARS_LIVE_SIZE and VARS_SPARE_SIZE
macros
  OvmfPkg: introduce FD_SIZE_4MB (mainly) for Windows HCK
  OvmfPkg: raise max variable size (auth & non-auth) to 33KB for
FD_SIZE_4MB

 OvmfPkg/OvmfPkgIa32.dsc|  5 +++
 OvmfPkg/OvmfPkgIa32X64.dsc |  5 +++
 OvmfPkg/OvmfPkgX64.dsc |  5 +++
 OvmfPkg/OvmfPkg.fdf.inc| 35 ++-
 OvmfPkg/VarStore.fdf.inc   | 46 +++-
 5 files changed, 92 insertions(+), 4 deletions(-)

-- 
2.9.3

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


[edk2] [PATCH 1/3] OvmfPkg/OvmfPkg.fdf.inc: extract VARS_LIVE_SIZE and VARS_SPARE_SIZE macros

2017-04-29 Thread Laszlo Ersek
Cc: Gary Ching-Pang Lin 
Cc: Jordan Justen 
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek 
---
 OvmfPkg/OvmfPkg.fdf.inc | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/OvmfPkg/OvmfPkg.fdf.inc b/OvmfPkg/OvmfPkg.fdf.inc
index 9cc0578d6430..fce6c7b8ce64 100644
--- a/OvmfPkg/OvmfPkg.fdf.inc
+++ b/OvmfPkg/OvmfPkg.fdf.inc
@@ -24,6 +24,8 @@
 DEFINE BLOCK_SIZE= 0x1000
 DEFINE VARS_SIZE = 0x2
 DEFINE VARS_BLOCKS   = 0x20
+DEFINE VARS_LIVE_SIZE= 0xE000
+DEFINE VARS_SPARE_SIZE   = 0x1
 
 !ifdef $(FD_SIZE_1MB)
 
@@ -56,7 +58,7 @@
 SET gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFirmwareBlockSize = $(BLOCK_SIZE)
 
 SET gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageVariableBase = 
$(FW_BASE_ADDRESS)
-SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize = 0xE000
+SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize = 
$(VARS_LIVE_SIZE)
 
 SET gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageEventLogBase = 
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageVariableBase + 
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
 SET gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageEventLogSize = 
$(BLOCK_SIZE)
@@ -65,6 +67,6 @@
 SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize = 
$(BLOCK_SIZE)
 
 SET gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageFtwSpareBase = 
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageFtwWorkingBase + 
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
-SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize = 0x1
+SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize = 
$(VARS_SPARE_SIZE)
 
 DEFINE MEMFD_BASE_ADDRESS = 0x80
-- 
2.9.3


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


[edk2] [RFC] [PATCH V4 2/3] MdeModulePkg/PciHostBridge: Add IOMMU support.

2017-04-29 Thread Jiewen Yao
If IOMMU protocol is installed, PciHostBridge just calls
IOMMU AllocateBuffer/FreeBuffer/Map/Unmap.

PciHostBridge does not set IOMMU access attribute,
because it does not know which device request the DMA.
This work is done by PciBus driver.

Cc: Ruiyu Ni 
Cc: Leo Duran 
Cc: Brijesh Singh 
Cc: Ard Biesheuvel 
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jiewen Yao 
---
 MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.c  | 37 
 MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf |  2 +
 MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridge.h  |  2 +
 MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c| 61 

 4 files changed, 102 insertions(+)

diff --git a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.c 
b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.c
index 9005dee..70726a6 100644
--- a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.c
+++ b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.c
@@ -28,6 +28,10 @@ GLOBAL_REMOVE_IF_UNREFERENCED CHAR16 *mPciResourceTypeStr[] 
= {
   L"I/O", L"Mem", L"PMem", L"Mem64", L"PMem64", L"Bus"
 };
 
+EDKII_IOMMU_PROTOCOL*mIoMmuProtocol;
+EFI_EVENT   mIoMmuEvent;
+VOID*mIoMmuRegistration;
+
 /**
   Ensure the compatibility of an IO space descriptor with the IO aperture.
 
@@ -313,6 +317,28 @@ FreeMemorySpaceMap:
 }
 
 /**
+  Event notification that is fired when IOMMU protocol is installed.
+
+  @param  Event The Event that is being processed.
+  @param  Context   Event Context.
+
+**/
+VOID
+EFIAPI
+IoMmuProtocolCallback (
+  IN  EFI_EVENT   Event,
+  IN  VOID*Context
+  )
+{
+  EFI_STATUS   Status;
+
+  Status = gBS->LocateProtocol (, NULL, (VOID 
**));
+  if (!EFI_ERROR(Status)) {
+gBS->CloseEvent (mIoMmuEvent);
+  }
+}
+
+/**
 
   Entry point of this driver.
 
@@ -489,6 +515,17 @@ InitializePciHostBridge (
 ASSERT_EFI_ERROR (Status);
   }
   PciHostBridgeFreeRootBridges (RootBridges, RootBridgeCount);
+
+  if (!EFI_ERROR (Status)) {
+mIoMmuEvent = EfiCreateProtocolNotifyEvent (
+,
+TPL_CALLBACK,
+IoMmuProtocolCallback,
+NULL,
+
+);
+  }
+
   return Status;
 }
 
diff --git a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf 
b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
index d8b0439..42bd8a2 100644
--- a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
+++ b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
@@ -41,6 +41,7 @@
   BaseMemoryLib
   BaseLib
   PciSegmentLib
+  UefiLib
   PciHostBridgeLib
 
 [Protocols]
@@ -49,6 +50,7 @@
   gEfiDevicePathProtocolGuid  ## BY_START
   gEfiPciRootBridgeIoProtocolGuid ## BY_START
   gEfiPciHostBridgeResourceAllocationProtocolGuid ## BY_START
+  gEdkiiIoMmuProtocolGuid ## SOMETIMES_CONSUMES
 
 [Depex]
   gEfiCpuIo2ProtocolGuid AND
diff --git a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridge.h 
b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridge.h
index 13185b4..1fec88b 100644
--- a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridge.h
+++ b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridge.h
@@ -27,6 +27,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER 
EXPRESS OR IMPLIED.
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -34,6 +35,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER 
EXPRESS OR IMPLIED.
 #include 
 #include 
 #include 
+#include 
 #include "PciHostResource.h"
 
 
diff --git a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c 
b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c
index 8af131b..068295b 100644
--- a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c
+++ b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c
@@ -17,6 +17,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER 
EXPRESS OR IMPLIED.
 #include "PciRootBridge.h"
 #include "PciHostResource.h"
 
+extern EDKII_IOMMU_PROTOCOL*mIoMmuProtocol;
+
 #define NO_MAPPING  (VOID *) (UINTN) -1
 
 //
@@ -1072,6 +1074,26 @@ RootBridgeIoMap (
 
   RootBridge = ROOT_BRIDGE_FROM_THIS (This);
 
+  if (mIoMmuProtocol != NULL) {
+if (!RootBridge->DmaAbove4G) {
+  //
+  // Clear 64bit support
+  //
+  if (Operation > EfiPciOperationBusMasterCommonBuffer) {
+Operation = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION) (Operation - 
EfiPciOperationBusMasterRead64);
+  }
+}
+Status = mIoMmuProtocol->Map (
+   mIoMmuProtocol,
+   Operation,
+   HostAddress,
+   NumberOfBytes,
+

[edk2] [RFC] [PATCH V4 0/3] Add IOMMU support.

2017-04-29 Thread Jiewen Yao
 V4 ==
Refine the EDKII_IOMMU_PROTOCOL.

1) Add AllocateBuffer/FreeBuffer/Map/Unmap() API.
They are similar to DmaLib in EmbeddedPkg and
similar to the previous BmDmaLib (by leo.du...@amd.com).

These APIs are invoked by PciHostBridge driver
to allocate DMA memory.

The PciHostBridge driver (IOMMU consumer) is simplified:
It uses IOMMU, if IOMMU protocol is present.
Else it uses original logic.

2) Add SetMappingAttribute() API.
It is similar to SetAttribute() API in V1.

This API is invoked by PciBus driver to set DMA
access attribute (read/write) for device.

The PciBus driver (IOMMU consumer) is simplified:
It sets access attribute in Map/Unmap,
if IOMMU protocol is present.

3) Remove SetRemapAddress/GetRemapAddress() API.
Because PciHostBridge/PciBus can call the APIs defined
above, there is no need to provide remap capability.

-- Sample producer drivers:
1) The sample VTd driver (IOMMU producer)
is at https://github.com/jyao1/edk2/tree/dma_v4/IntelSiliconPkg/IntelVTdDxe

It is added to show the concept. It is not fully implemented yet.
It will not be checked in in this patch.

2) The sample AMD SEV driver (IOMMU producer)
is at https://github.com/jyao1/edk2/tree/dma_v4/IntelSiliconPkg/SampleAmdSevDxe
(code is borrowed from leo.du...@amd.com and brijesh.si...@amd.com)

This is not a right place to put this driver.

It is added to show the concept.
It is not fully implemented. It will not be checked in.
Please do not use it directly.

3) The sample STYX driver (IOMMU producer)
is at https://github.com/jyao1/edk2/tree/dma_v4/IntelSiliconPkg/SampleStyxDxe
(code is borrowed from ard.biesheu...@linaro.org)

This is not a right place to put this driver.

It is added to show the concept.
It is not fully implemented. It will not be checked in.
Please do not use it directly.


 V3 ==
1) Add Remap capability (from Ard Biesheuvel)
Add EDKII_IOMMU_REMAP_ADDRESS API in IOMMU_PROTOCOL.

NOTE: The code is not fully validated yet.
The purpose is to collect feedback to decide the next step.

 V2 ==
1) Enhance Unmap() in PciIo (From Ruiyu Ni)
Maintain a local list of MapInfo and match it in Unmap.

2) CopyMem for ReadOperation in PciIo after SetAttribute (Leo Duran)
Fix a bug in V1 that copy mem for read happen before SetAttribute,
which will break AMD SEV solution.

 V1 ==

This patch series adds IOMMU protocol and updates the consumer
to support IOMMU based DMA access in UEFI.

This patch series can support the BmDmaLib request for AMD SEV.
submitted by Duran, Leo  and Brijesh Singh 
.
https://lists.01.org/pipermail/edk2-devel/2017-March/008109.html, and
https://lists.01.org/pipermail/edk2-devel/2017-March/008820.html.
We can have an AMD SEV specific IOMMU driver to produce IOMMU protocol,
and clear SEV in IOMMU->SetAttribute().

This patch series can also support Intel VTd based DMA protection,
requested by Jiewen Yao , discussed in
https://lists.01.org/pipermail/edk2-devel/2017-March/008157.html.
We can have an Intel VTd specific IOMMU driver to produce IOMMU protocol,
and update VTd engine to grant or deny access in IOMMU->SetAttribute().

This patch series does not provide a full Intel VTd driver, which
will be provide in other patch in the future.

The purpose of this patch series to review if this IOMMU protocol design
can meet all DMA access and management requirement.

Cc: Ruiyu Ni 
Cc: Leo Duran 
Cc: Brijesh Singh 
Cc: Ard Biesheuvel 
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jiewen Yao 

Jiewen Yao (3):
  MdeModulePkg/Include: Add IOMMU protocol definition.
  MdeModulePkg/PciHostBridge: Add IOMMU support.
  MdeModulePkg/PciBus: Add IOMMU support.

 MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.c|   9 +
 MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h|   1 +
 MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf   |   1 +
 MdeModulePkg/Bus/Pci/PciBusDxe/PciIo.c |  37 +++
 MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.c  |  37 +++
 MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf |   2 +
 MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridge.h  |   2 +
 MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c|  61 
 MdeModulePkg/Include/Protocol/IoMmu.h  | 310 

 MdeModulePkg/MdeModulePkg.dec  |   3 +
 10 files changed, 463 insertions(+)
 create mode 100644 MdeModulePkg/Include/Protocol/IoMmu.h

-- 
2.7.4.windows.1

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


[edk2] [RFC] [PATCH V4 1/3] MdeModulePkg/Include: Add IOMMU protocol definition.

2017-04-29 Thread Jiewen Yao
This protocol is to abstract DMA access from IOMMU.
1) Intel "DMAR" ACPI table.
2) AMD "IVRS" ACPI table
3) ARM "IORT" ACPI table.

There might be multiple IOMMU engines on one platform.
For example, one for graphic and one for rest PCI devices
(such as ATA/USB).
All IOMMU engines are reported by one ACPI table.

All IOMMU protocol provider should be based upon ACPI table.
This single IOMMU protocol can handle multiple IOMMU engines on one system.

This IOMMU protocol provider can use UEFI device path to distinguish
if the device is graphic or ATA/USB, and find out corresponding
IOMMU engine.

The IOMMU protocol provides 2 capabilities:
A) Set DMA access attribute - such as write/read control.
B) Remap DMA memory - such as remap above 4GiB system memory address
to below 4GiB device address.
It provides AllocateBuffer/FreeBuffer/Map/Unmap for DMA memory.
The remapping can be static (fixed at build time) or dynamic (allocate
at runtime).

4) AMD "SEV" feature.
We can have an AMD SEV specific IOMMU driver to produce IOMMU protocol,
and manage SEV bit.

Cc: Ruiyu Ni 
Cc: Leo Duran 
Cc: Brijesh Singh 
Cc: Ard Biesheuvel 
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jiewen Yao 
---
 MdeModulePkg/Include/Protocol/IoMmu.h | 310 
 MdeModulePkg/MdeModulePkg.dec |   3 +
 2 files changed, 313 insertions(+)

diff --git a/MdeModulePkg/Include/Protocol/IoMmu.h 
b/MdeModulePkg/Include/Protocol/IoMmu.h
new file mode 100644
index 000..3f62f46
--- /dev/null
+++ b/MdeModulePkg/Include/Protocol/IoMmu.h
@@ -0,0 +1,310 @@
+/** @file
+  EFI IOMMU Protocol.
+
+Copyright (c) 2017, Intel Corporation. All rights reserved.
+This program and the accompanying materials are licensed and made available 
under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+
+#ifndef __IOMMU_H__
+#define __IOMMU_H__
+
+//
+// IOMMU Protocol GUID value
+//
+#define EDKII_IOMMU_PROTOCOL_GUID \
+{ \
+  0x4e939de9, 0xd948, 0x4b0f, { 0x88, 0xed, 0xe6, 0xe1, 0xce, 0x51, 0x7c, 
0x1e } \
+}
+
+//
+// Forward reference for pure ANSI compatability
+//
+typedef struct _EDKII_IOMMU_PROTOCOL  EDKII_IOMMU_PROTOCOL;
+
+//
+// Revision The revision to which the IOMMU interface adheres.
+//  All future revisions must be backwards compatible.
+//  If a future version is not back wards compatible it is not the 
same GUID.
+//
+#define EDKII_IOMMU_PROTOCOL_REVISION 0x0001
+
+//
+// IOMMU Access for SetAttribute
+//
+// These types can be "ORed" together as needed.
+// Any undefined bits are reserved and must be zero.
+//
+#define EDKII_IOMMU_ACCESS_READ   0x1
+#define EDKII_IOMMU_ACCESS_WRITE  0x2
+
+//
+// IOMMU Operation for Map
+//
+typedef enum {
+  ///
+  /// A read operation from system memory by a bus master that is not capable 
of producing
+  /// PCI dual address cycles.
+  ///
+  EdkiiIoMmuOperationBusMasterRead,
+  ///
+  /// A write operation from system memory by a bus master that is not capable 
of producing
+  /// PCI dual address cycles.
+  ///
+  EdkiiIoMmuOperationBusMasterWrite,
+  ///
+  /// Provides both read and write access to system memory by both the 
processor and a bus
+  /// master that is not capable of producing PCI dual address cycles.
+  ///
+  EdkiiIoMmuOperationBusMasterCommonBuffer,
+  ///
+  /// A read operation from system memory by a bus master that is capable of 
producing PCI
+  /// dual address cycles.
+  ///
+  EdkiiIoMmuOperationBusMasterRead64,
+  ///
+  /// A write operation to system memory by a bus master that is capable of 
producing PCI
+  /// dual address cycles.
+  ///
+  EdkiiIoMmuOperationBusMasterWrite64,
+  ///
+  /// Provides both read and write access to system memory by both the 
processor and a bus
+  /// master that is capable of producing PCI dual address cycles.
+  ///
+  EdkiiIoMmuOperationBusMasterCommonBuffer64,
+  EdkiiIoMmuOperationMaximum
+} EDKII_IOMMU_OPERATION;
+
+//
+// IOMMU attribute for AllocateBuffer
+// Any undefined bits are reserved and must be zero.
+//
+#define EDKII_IOMMU_ATTRIBUTE_MEMORY_WRITE_COMBINE0x0080
+#define EDKII_IOMMU_ATTRIBUTE_MEMORY_CACHED   0x0800
+#define EDKII_IOMMU_ATTRIBUTE_DUAL_ADDRESS_CYCLE  0x8000
+
+#define EDKII_IOMMU_ATTRIBUTE_VALID_FOR_ALLOCATE_BUFFER   
(EDKII_IOMMU_ATTRIBUTE_MEMORY_WRITE_COMBINE | 
EDKII_IOMMU_ATTRIBUTE_MEMORY_CACHED | EDKII_IOMMU_ATTRIBUTE_DUAL_ADDRESS_CYCLE)
+
+#define EDKII_IOMMU_ATTRIBUTE_INVALID_FOR_ALLOCATE_BUFFER 
(~EDKII_IOMMU_ATTRIBUTE_VALID_FOR_ALLOCATE_BUFFER)
+
+/**
+  Set IOMMU attribute for a system memory.
+
+  If the IOMMU 

[edk2] [RFC] [PATCH V4 3/3] MdeModulePkg/PciBus: Add IOMMU support.

2017-04-29 Thread Jiewen Yao
If IOMMU protocol is installed, PciBus need call IOMMU
to set access attribute for the PCI device in Map/Ummap.

Only after the access attribute is set, the PCI device can
access the DMA memory.

Cc: Ruiyu Ni 
Cc: Leo Duran 
Cc: Brijesh Singh 
Cc: Ard Biesheuvel 
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jiewen Yao 
---
 MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.c  |  9 +
 MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h  |  1 +
 MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf |  1 +
 MdeModulePkg/Bus/Pci/PciBusDxe/PciIo.c   | 37 
 4 files changed, 48 insertions(+)

diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.c 
b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.c
index f3be47a..950cacc 100644
--- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.c
+++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.c
@@ -42,6 +42,7 @@ UINT64gAllZero
 = 0;
 
 EFI_PCI_PLATFORM_PROTOCOL *gPciPlatformProtocol;
 EFI_PCI_OVERRIDE_PROTOCOL *gPciOverrideProtocol;
+EDKII_IOMMU_PROTOCOL  *mIoMmuProtocol;
 
 
 GLOBAL_REMOVE_IF_UNREFERENCED EFI_PCI_HOTPLUG_REQUEST_PROTOCOL 
mPciHotPlugRequest = {
@@ -284,6 +285,14 @@ PciBusDriverBindingStart (
   );
   }  
 
+  if (mIoMmuProtocol == NULL) {
+gBS->LocateProtocol (
+  ,
+  NULL,
+  (VOID **) 
+  );
+  }
+
   if (PcdGetBool (PcdPciDisableBusEnumeration)) {
 gFullEnumeration = FALSE;
   } else {
diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h 
b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h
index 39ba8b9..3bcc134 100644
--- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h
+++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h
@@ -32,6 +32,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER 
EXPRESS OR IMPLIED.
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf 
b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
index a3ab11f..5da094f 100644
--- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
+++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
@@ -95,6 +95,7 @@
   gEfiPciRootBridgeIoProtocolGuid ## TO_START
   gEfiIncompatiblePciDeviceSupportProtocolGuid## SOMETIMES_CONSUMES
   gEfiLoadFile2ProtocolGuid   ## SOMETIMES_PRODUCES
+  gEdkiiIoMmuProtocolGuid ## SOMETIMES_CONSUMES
 
 [FeaturePcd]
   gEfiMdeModulePkgTokenSpaceGuid.PcdPciBusHotplugDeviceSupport  ## CONSUMES
diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciIo.c 
b/MdeModulePkg/Bus/Pci/PciBusDxe/PciIo.c
index f72598d..c0251c0 100644
--- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciIo.c
+++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciIo.c
@@ -14,6 +14,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER 
EXPRESS OR IMPLIED.
 
 #include "PciBus.h"
 
+extern EDKII_IOMMU_PROTOCOL  *mIoMmuProtocol;
+
 //
 // Pci Io Protocol Interface
 //
@@ -967,6 +969,7 @@ PciIoMap (
 {
   EFI_STATUSStatus;
   PCI_IO_DEVICE *PciIoDevice;
+  UINT64IoMmuAttribute;
 
   PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);
 
@@ -999,6 +1002,31 @@ PciIoMap (
   );
   }
 
+  if (mIoMmuProtocol != NULL) {
+if (!EFI_ERROR (Status)) {
+  switch (Operation) {
+  case EfiPciIoOperationBusMasterRead:
+IoMmuAttribute = EDKII_IOMMU_ACCESS_READ;
+break;
+  case EfiPciIoOperationBusMasterWrite:
+IoMmuAttribute = EDKII_IOMMU_ACCESS_WRITE;
+break;
+  case EfiPciIoOperationBusMasterCommonBuffer:
+IoMmuAttribute = EDKII_IOMMU_ACCESS_READ | EDKII_IOMMU_ACCESS_WRITE;
+break;
+  default:
+ASSERT(FALSE);
+return EFI_INVALID_PARAMETER;
+  }
+  mIoMmuProtocol->SetMappingAttribute (
+mIoMmuProtocol,
+PciIoDevice->Handle,
+*Mapping,
+IoMmuAttribute
+);
+}
+  }
+
   return Status;
 }
 
@@ -1024,6 +1052,15 @@ PciIoUnmap (
 
   PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);
 
+  if (mIoMmuProtocol != NULL) {
+mIoMmuProtocol->SetMappingAttribute (
+  mIoMmuProtocol,
+  PciIoDevice->Handle,
+  Mapping,
+  0
+  );
+  }
+
   Status = PciIoDevice->PciRootBridgeIo->Unmap (
   PciIoDevice->PciRootBridgeIo,
   Mapping
-- 
2.7.4.windows.1

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


[edk2] [PATCH 3/3] MdeModulePkg/PciBus: Add IOMMU support.

2017-04-29 Thread Jiewen Yao
If IOMMU protocol is installed, PciBus need call IOMMU
to set access attribute for the PCI device in Map/Ummap.

Only after the access attribute is set, the PCI device can
access the DMA memory.

Cc: Ruiyu Ni 
Cc: Leo Duran 
Cc: Brijesh Singh 
Cc: Ard Biesheuvel 
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jiewen Yao 
---
 MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.c  |  9 +
 MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h  |  1 +
 MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf |  1 +
 MdeModulePkg/Bus/Pci/PciBusDxe/PciIo.c   | 37 
 4 files changed, 48 insertions(+)

diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.c 
b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.c
index f3be47a..950cacc 100644
--- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.c
+++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.c
@@ -42,6 +42,7 @@ UINT64gAllZero
 = 0;
 
 EFI_PCI_PLATFORM_PROTOCOL *gPciPlatformProtocol;
 EFI_PCI_OVERRIDE_PROTOCOL *gPciOverrideProtocol;
+EDKII_IOMMU_PROTOCOL  *mIoMmuProtocol;
 
 
 GLOBAL_REMOVE_IF_UNREFERENCED EFI_PCI_HOTPLUG_REQUEST_PROTOCOL 
mPciHotPlugRequest = {
@@ -284,6 +285,14 @@ PciBusDriverBindingStart (
   );
   }  
 
+  if (mIoMmuProtocol == NULL) {
+gBS->LocateProtocol (
+  ,
+  NULL,
+  (VOID **) 
+  );
+  }
+
   if (PcdGetBool (PcdPciDisableBusEnumeration)) {
 gFullEnumeration = FALSE;
   } else {
diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h 
b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h
index 39ba8b9..3bcc134 100644
--- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h
+++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h
@@ -32,6 +32,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER 
EXPRESS OR IMPLIED.
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf 
b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
index a3ab11f..5da094f 100644
--- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
+++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
@@ -95,6 +95,7 @@
   gEfiPciRootBridgeIoProtocolGuid ## TO_START
   gEfiIncompatiblePciDeviceSupportProtocolGuid## SOMETIMES_CONSUMES
   gEfiLoadFile2ProtocolGuid   ## SOMETIMES_PRODUCES
+  gEdkiiIoMmuProtocolGuid ## SOMETIMES_CONSUMES
 
 [FeaturePcd]
   gEfiMdeModulePkgTokenSpaceGuid.PcdPciBusHotplugDeviceSupport  ## CONSUMES
diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciIo.c 
b/MdeModulePkg/Bus/Pci/PciBusDxe/PciIo.c
index f72598d..c0251c0 100644
--- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciIo.c
+++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciIo.c
@@ -14,6 +14,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER 
EXPRESS OR IMPLIED.
 
 #include "PciBus.h"
 
+extern EDKII_IOMMU_PROTOCOL  *mIoMmuProtocol;
+
 //
 // Pci Io Protocol Interface
 //
@@ -967,6 +969,7 @@ PciIoMap (
 {
   EFI_STATUSStatus;
   PCI_IO_DEVICE *PciIoDevice;
+  UINT64IoMmuAttribute;
 
   PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);
 
@@ -999,6 +1002,31 @@ PciIoMap (
   );
   }
 
+  if (mIoMmuProtocol != NULL) {
+if (!EFI_ERROR (Status)) {
+  switch (Operation) {
+  case EfiPciIoOperationBusMasterRead:
+IoMmuAttribute = EDKII_IOMMU_ACCESS_READ;
+break;
+  case EfiPciIoOperationBusMasterWrite:
+IoMmuAttribute = EDKII_IOMMU_ACCESS_WRITE;
+break;
+  case EfiPciIoOperationBusMasterCommonBuffer:
+IoMmuAttribute = EDKII_IOMMU_ACCESS_READ | EDKII_IOMMU_ACCESS_WRITE;
+break;
+  default:
+ASSERT(FALSE);
+return EFI_INVALID_PARAMETER;
+  }
+  mIoMmuProtocol->SetMappingAttribute (
+mIoMmuProtocol,
+PciIoDevice->Handle,
+*Mapping,
+IoMmuAttribute
+);
+}
+  }
+
   return Status;
 }
 
@@ -1024,6 +1052,15 @@ PciIoUnmap (
 
   PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);
 
+  if (mIoMmuProtocol != NULL) {
+mIoMmuProtocol->SetMappingAttribute (
+  mIoMmuProtocol,
+  PciIoDevice->Handle,
+  Mapping,
+  0
+  );
+  }
+
   Status = PciIoDevice->PciRootBridgeIo->Unmap (
   PciIoDevice->PciRootBridgeIo,
   Mapping
-- 
2.7.4.windows.1

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


[edk2] [PATCH 2/3] MdeModulePkg/PciHostBridge: Add IOMMU support.

2017-04-29 Thread Jiewen Yao
If IOMMU protocol is installed, PciHostBridge just calls
IOMMU AllocateBuffer/FreeBuffer/Map/Unmap.

PciHostBridge does not set IOMMU access attribute,
because it does not know which device request the DMA.
This work is done by PciBus driver.

Cc: Ruiyu Ni 
Cc: Leo Duran 
Cc: Brijesh Singh 
Cc: Ard Biesheuvel 
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jiewen Yao 
---
 MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.c  | 37 
 MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf |  2 +
 MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridge.h  |  2 +
 MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c| 61 

 4 files changed, 102 insertions(+)

diff --git a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.c 
b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.c
index 9005dee..70726a6 100644
--- a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.c
+++ b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.c
@@ -28,6 +28,10 @@ GLOBAL_REMOVE_IF_UNREFERENCED CHAR16 *mPciResourceTypeStr[] 
= {
   L"I/O", L"Mem", L"PMem", L"Mem64", L"PMem64", L"Bus"
 };
 
+EDKII_IOMMU_PROTOCOL*mIoMmuProtocol;
+EFI_EVENT   mIoMmuEvent;
+VOID*mIoMmuRegistration;
+
 /**
   Ensure the compatibility of an IO space descriptor with the IO aperture.
 
@@ -313,6 +317,28 @@ FreeMemorySpaceMap:
 }
 
 /**
+  Event notification that is fired when IOMMU protocol is installed.
+
+  @param  Event The Event that is being processed.
+  @param  Context   Event Context.
+
+**/
+VOID
+EFIAPI
+IoMmuProtocolCallback (
+  IN  EFI_EVENT   Event,
+  IN  VOID*Context
+  )
+{
+  EFI_STATUS   Status;
+
+  Status = gBS->LocateProtocol (, NULL, (VOID 
**));
+  if (!EFI_ERROR(Status)) {
+gBS->CloseEvent (mIoMmuEvent);
+  }
+}
+
+/**
 
   Entry point of this driver.
 
@@ -489,6 +515,17 @@ InitializePciHostBridge (
 ASSERT_EFI_ERROR (Status);
   }
   PciHostBridgeFreeRootBridges (RootBridges, RootBridgeCount);
+
+  if (!EFI_ERROR (Status)) {
+mIoMmuEvent = EfiCreateProtocolNotifyEvent (
+,
+TPL_CALLBACK,
+IoMmuProtocolCallback,
+NULL,
+
+);
+  }
+
   return Status;
 }
 
diff --git a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf 
b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
index d8b0439..42bd8a2 100644
--- a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
+++ b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
@@ -41,6 +41,7 @@
   BaseMemoryLib
   BaseLib
   PciSegmentLib
+  UefiLib
   PciHostBridgeLib
 
 [Protocols]
@@ -49,6 +50,7 @@
   gEfiDevicePathProtocolGuid  ## BY_START
   gEfiPciRootBridgeIoProtocolGuid ## BY_START
   gEfiPciHostBridgeResourceAllocationProtocolGuid ## BY_START
+  gEdkiiIoMmuProtocolGuid ## SOMETIMES_CONSUMES
 
 [Depex]
   gEfiCpuIo2ProtocolGuid AND
diff --git a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridge.h 
b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridge.h
index 13185b4..1fec88b 100644
--- a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridge.h
+++ b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridge.h
@@ -27,6 +27,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER 
EXPRESS OR IMPLIED.
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -34,6 +35,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER 
EXPRESS OR IMPLIED.
 #include 
 #include 
 #include 
+#include 
 #include "PciHostResource.h"
 
 
diff --git a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c 
b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c
index 8af131b..068295b 100644
--- a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c
+++ b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c
@@ -17,6 +17,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER 
EXPRESS OR IMPLIED.
 #include "PciRootBridge.h"
 #include "PciHostResource.h"
 
+extern EDKII_IOMMU_PROTOCOL*mIoMmuProtocol;
+
 #define NO_MAPPING  (VOID *) (UINTN) -1
 
 //
@@ -1072,6 +1074,26 @@ RootBridgeIoMap (
 
   RootBridge = ROOT_BRIDGE_FROM_THIS (This);
 
+  if (mIoMmuProtocol != NULL) {
+if (!RootBridge->DmaAbove4G) {
+  //
+  // Clear 64bit support
+  //
+  if (Operation > EfiPciOperationBusMasterCommonBuffer) {
+Operation = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION) (Operation - 
EfiPciOperationBusMasterRead64);
+  }
+}
+Status = mIoMmuProtocol->Map (
+   mIoMmuProtocol,
+   Operation,
+   HostAddress,
+   NumberOfBytes,
+

[edk2] [PATCH 1/3] MdeModulePkg/Include: Add IOMMU protocol definition.

2017-04-29 Thread Jiewen Yao
This protocol is to abstract DMA access from IOMMU.
1) Intel "DMAR" ACPI table.
2) AMD "IVRS" ACPI table
3) ARM "IORT" ACPI table.

There might be multiple IOMMU engines on one platform.
For example, one for graphic and one for rest PCI devices
(such as ATA/USB).
All IOMMU engines are reported by one ACPI table.

All IOMMU protocol provider should be based upon ACPI table.
This single IOMMU protocol can handle multiple IOMMU engines on one system.

This IOMMU protocol provider can use UEFI device path to distinguish
if the device is graphic or ATA/USB, and find out corresponding
IOMMU engine.

The IOMMU protocol provides 2 capabilities:
A) Set DMA access attribute - such as write/read control.
B) Remap DMA memory - such as remap above 4GiB system memory address
to below 4GiB device address.
It provides AllocateBuffer/FreeBuffer/Map/Unmap for DMA memory.
The remapping can be static (fixed at build time) or dynamic (allocate
at runtime).

4) AMD "SEV" feature.
We can have an AMD SEV specific IOMMU driver to produce IOMMU protocol,
and manage SEV bit.

Cc: Ruiyu Ni 
Cc: Leo Duran 
Cc: Brijesh Singh 
Cc: Ard Biesheuvel 
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jiewen Yao 
---
 MdeModulePkg/Include/Protocol/IoMmu.h | 310 
 MdeModulePkg/MdeModulePkg.dec |   3 +
 2 files changed, 313 insertions(+)

diff --git a/MdeModulePkg/Include/Protocol/IoMmu.h 
b/MdeModulePkg/Include/Protocol/IoMmu.h
new file mode 100644
index 000..3f62f46
--- /dev/null
+++ b/MdeModulePkg/Include/Protocol/IoMmu.h
@@ -0,0 +1,310 @@
+/** @file
+  EFI IOMMU Protocol.
+
+Copyright (c) 2017, Intel Corporation. All rights reserved.
+This program and the accompanying materials are licensed and made available 
under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+
+#ifndef __IOMMU_H__
+#define __IOMMU_H__
+
+//
+// IOMMU Protocol GUID value
+//
+#define EDKII_IOMMU_PROTOCOL_GUID \
+{ \
+  0x4e939de9, 0xd948, 0x4b0f, { 0x88, 0xed, 0xe6, 0xe1, 0xce, 0x51, 0x7c, 
0x1e } \
+}
+
+//
+// Forward reference for pure ANSI compatability
+//
+typedef struct _EDKII_IOMMU_PROTOCOL  EDKII_IOMMU_PROTOCOL;
+
+//
+// Revision The revision to which the IOMMU interface adheres.
+//  All future revisions must be backwards compatible.
+//  If a future version is not back wards compatible it is not the 
same GUID.
+//
+#define EDKII_IOMMU_PROTOCOL_REVISION 0x0001
+
+//
+// IOMMU Access for SetAttribute
+//
+// These types can be "ORed" together as needed.
+// Any undefined bits are reserved and must be zero.
+//
+#define EDKII_IOMMU_ACCESS_READ   0x1
+#define EDKII_IOMMU_ACCESS_WRITE  0x2
+
+//
+// IOMMU Operation for Map
+//
+typedef enum {
+  ///
+  /// A read operation from system memory by a bus master that is not capable 
of producing
+  /// PCI dual address cycles.
+  ///
+  EdkiiIoMmuOperationBusMasterRead,
+  ///
+  /// A write operation from system memory by a bus master that is not capable 
of producing
+  /// PCI dual address cycles.
+  ///
+  EdkiiIoMmuOperationBusMasterWrite,
+  ///
+  /// Provides both read and write access to system memory by both the 
processor and a bus
+  /// master that is not capable of producing PCI dual address cycles.
+  ///
+  EdkiiIoMmuOperationBusMasterCommonBuffer,
+  ///
+  /// A read operation from system memory by a bus master that is capable of 
producing PCI
+  /// dual address cycles.
+  ///
+  EdkiiIoMmuOperationBusMasterRead64,
+  ///
+  /// A write operation to system memory by a bus master that is capable of 
producing PCI
+  /// dual address cycles.
+  ///
+  EdkiiIoMmuOperationBusMasterWrite64,
+  ///
+  /// Provides both read and write access to system memory by both the 
processor and a bus
+  /// master that is capable of producing PCI dual address cycles.
+  ///
+  EdkiiIoMmuOperationBusMasterCommonBuffer64,
+  EdkiiIoMmuOperationMaximum
+} EDKII_IOMMU_OPERATION;
+
+//
+// IOMMU attribute for AllocateBuffer
+// Any undefined bits are reserved and must be zero.
+//
+#define EDKII_IOMMU_ATTRIBUTE_MEMORY_WRITE_COMBINE0x0080
+#define EDKII_IOMMU_ATTRIBUTE_MEMORY_CACHED   0x0800
+#define EDKII_IOMMU_ATTRIBUTE_DUAL_ADDRESS_CYCLE  0x8000
+
+#define EDKII_IOMMU_ATTRIBUTE_VALID_FOR_ALLOCATE_BUFFER   
(EDKII_IOMMU_ATTRIBUTE_MEMORY_WRITE_COMBINE | 
EDKII_IOMMU_ATTRIBUTE_MEMORY_CACHED | EDKII_IOMMU_ATTRIBUTE_DUAL_ADDRESS_CYCLE)
+
+#define EDKII_IOMMU_ATTRIBUTE_INVALID_FOR_ALLOCATE_BUFFER 
(~EDKII_IOMMU_ATTRIBUTE_VALID_FOR_ALLOCATE_BUFFER)
+
+/**
+  Set IOMMU attribute for a system memory.
+
+  If the IOMMU 

[edk2] [RFC] [PATCH V4 0/3] Add IOMMU support.

2017-04-29 Thread Jiewen Yao
 V4 ==
Refine the EDKII_IOMMU_PROTOCOL.

1) Add AllocateBuffer/FreeBuffer/Map/Unmap() API.
They are similar to DmaLib in EmbeddedPkg and
similar to the previous BmDmaLib (by leo.du...@amd.com).

These APIs are invoked by PciHostBridge driver
to allocate DMA memory.

The PciHostBridge driver (IOMMU consumer) is simplified:
It uses IOMMU, if IOMMU protocol is present.
Else it uses original logic.

2) Add SetMappingAttribute() API.
It is similar to SetAttribute() API in V1.

This API is invoked by PciBus driver to set DMA
access attribute (read/write) for device.

The PciBus driver (IOMMU consumer) is simplified:
It sets access attribute in Map/Unmap,
if IOMMU protocol is present.

3) Remove SetRemapAddress/GetRemapAddress() API.
Because PciHostBridge/PciBus can call the APIs defined
above, there is no need to provide remap capability.

-- Sample producer drivers:
1) The sample VTd driver (IOMMU producer)
is at https://github.com/jyao1/edk2/tree/dma_v4/IntelSiliconPkg/IntelVTdDxe

It is added to show the concept. It is not fully implemented yet.
It will not be checked in in this patch.

2) The sample AMD SEV driver (IOMMU producer)
is at https://github.com/jyao1/edk2/tree/dma_v4/IntelSiliconPkg/SampleAmdSevDxe
(code is borrowed from leo.du...@amd.com and brijesh.si...@amd.com)

This is not a right place to put this driver.

It is added to show the concept.
It is not fully implemented. It will not be checked in.
Please do not use it directly.

3) The sample STYX driver (IOMMU producer)
is at https://github.com/jyao1/edk2/tree/dma_v4/IntelSiliconPkg/SampleStyxDxe
(code is borrowed from ard.biesheu...@linaro.org)

This is not a right place to put this driver.

It is added to show the concept.
It is not fully implemented. It will not be checked in.
Please do not use it directly.


 V3 ==
1) Add Remap capability (from Ard Biesheuvel)
Add EDKII_IOMMU_REMAP_ADDRESS API in IOMMU_PROTOCOL.

NOTE: The code is not fully validated yet.
The purpose is to collect feedback to decide the next step.

 V2 ==
1) Enhance Unmap() in PciIo (From Ruiyu Ni)
Maintain a local list of MapInfo and match it in Unmap.

2) CopyMem for ReadOperation in PciIo after SetAttribute (Leo Duran)
Fix a bug in V1 that copy mem for read happen before SetAttribute,
which will break AMD SEV solution.

 V1 ==

This patch series adds IOMMU protocol and updates the consumer
to support IOMMU based DMA access in UEFI.

This patch series can support the BmDmaLib request for AMD SEV.
submitted by Duran, Leo  and Brijesh Singh 
.
https://lists.01.org/pipermail/edk2-devel/2017-March/008109.html, and
https://lists.01.org/pipermail/edk2-devel/2017-March/008820.html.
We can have an AMD SEV specific IOMMU driver to produce IOMMU protocol,
and clear SEV in IOMMU->SetAttribute().

This patch series can also support Intel VTd based DMA protection,
requested by Jiewen Yao , discussed in
https://lists.01.org/pipermail/edk2-devel/2017-March/008157.html.
We can have an Intel VTd specific IOMMU driver to produce IOMMU protocol,
and update VTd engine to grant or deny access in IOMMU->SetAttribute().

This patch series does not provide a full Intel VTd driver, which
will be provide in other patch in the future.

The purpose of this patch series to review if this IOMMU protocol design
can meet all DMA access and management requirement.

Cc: Ruiyu Ni 
Cc: Leo Duran 
Cc: Brijesh Singh 
Cc: Ard Biesheuvel 
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jiewen Yao 

Jiewen Yao (3):
  MdeModulePkg/Include: Add IOMMU protocol definition.
  MdeModulePkg/PciHostBridge: Add IOMMU support.
  MdeModulePkg/PciBus: Add IOMMU support.

 MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.c|   9 +
 MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h|   1 +
 MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf   |   1 +
 MdeModulePkg/Bus/Pci/PciBusDxe/PciIo.c |  37 +++
 MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.c  |  37 +++
 MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf |   2 +
 MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridge.h  |   2 +
 MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c|  61 
 MdeModulePkg/Include/Protocol/IoMmu.h  | 310 

 MdeModulePkg/MdeModulePkg.dec  |   3 +
 10 files changed, 463 insertions(+)
 create mode 100644 MdeModulePkg/Include/Protocol/IoMmu.h

-- 
2.7.4.windows.1

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