public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [PATCH] MdeModulePkg/NvmExpressPei: Produce NVM Express PassThru PPI
@ 2019-06-17  2:11 Maggie Chu
  2019-06-18 12:34 ` [edk2-devel] " Wu, Hao A
  0 siblings, 1 reply; 3+ messages in thread
From: Maggie Chu @ 2019-06-17  2:11 UTC (permalink / raw)
  To: devel; +Cc: Hao A Wu, Jian J Wang, Ray Ni, Star Zeng

https://bugzilla.tianocore.org/show_bug.cgi?id=1879
This commit will add codes to produce the NVM Express PassThru PPI.

Signed-off-by: Maggie Chu <maggie.chu@intel.com>
Cc: Hao A Wu <hao.a.wu@intel.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Star Zeng <star.zeng@intel.com>
---
 MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.c |  26 +++
 MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.h |   8 +
 .../Bus/Pci/NvmExpressPei/NvmExpressPei.inf        |   1 +
 .../Bus/Pci/NvmExpressPei/NvmExpressPeiBlockIo.c   |  27 +--
 .../Bus/Pci/NvmExpressPei/NvmExpressPeiHci.c       |  74 ++++---
 .../Bus/Pci/NvmExpressPei/NvmExpressPeiPassThru.c  | 218 ++++++++++++++++++++-
 .../Bus/Pci/NvmExpressPei/NvmExpressPeiPassThru.h  | 159 ++++++++++-----
 .../NvmExpressPei/NvmExpressPeiStorageSecurity.c   |  24 +--
 8 files changed, 420 insertions(+), 117 deletions(-)

diff --git a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.c b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.c
index 0e79b29f82..987eed420e 100644
--- a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.c
+++ b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.c
@@ -28,6 +28,12 @@ EFI_PEI_PPI_DESCRIPTOR  mNvmeStorageSecurityPpiListTemplate = {
   NULL
 };
 
+EFI_PEI_PPI_DESCRIPTOR  mNvmePassThruPpiListTemplate = {
+  (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+  &gEdkiiPeiNvmExpressPassThruPpiGuid,
+  NULL
+};
+
 EFI_PEI_NOTIFY_DESCRIPTOR  mNvmeEndOfPeiNotifyListTemplate = {
   (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
   &gEfiEndOfPeiSignalPpiGuid,
@@ -392,6 +398,26 @@ NvmExpressPeimEntry (
     Private->BlkIo2PpiList.Ppi                 = &Private->BlkIo2Ppi;
     PeiServicesInstallPpi (&Private->BlkIoPpiList);
 
+    //
+    // Nvm Express Pass Thru PPI
+    //
+    Private->PassThruMode.Attributes            = EFI_NVM_EXPRESS_PASS_THRU_ATTRIBUTES_PHYSICAL |
+                                                  EFI_NVM_EXPRESS_PASS_THRU_ATTRIBUTES_LOGICAL |
+                                                  EFI_NVM_EXPRESS_PASS_THRU_ATTRIBUTES_CMD_SET_NVM;
+    Private->PassThruMode.IoAlign               = sizeof (UINTN);
+    Private->PassThruMode.NvmeVersion           = EDKII_PEI_NVM_EXPRESS_PASS_THRU_PPI_REVISION;
+    Private->NvmePassThruPpi.Mode               = &Private->PassThruMode;
+    Private->NvmePassThruPpi.GetDevicePath      = NvmePassThruGetDevicePath;
+    Private->NvmePassThruPpi.GetNextNameSpace   = NvmePassThruGetNextNameSpace;
+    Private->NvmePassThruPpi.PassThru           = NvmePassThru;
+    CopyMem (
+      &Private->NvmePassThruPpiList,
+      &mNvmePassThruPpiListTemplate,
+      sizeof (EFI_PEI_PPI_DESCRIPTOR)
+      );
+    Private->NvmePassThruPpiList.Ppi            = &Private->NvmePassThruPpi;
+    PeiServicesInstallPpi (&Private->NvmePassThruPpiList);
+
     //
     // Check if the NVME controller supports the Security Receive/Send commands
     //
diff --git a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.h b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.h
index 6b2e2f0326..8cd905191b 100644
--- a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.h
+++ b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.h
@@ -19,6 +19,7 @@
 #include <Ppi/BlockIo.h>
 #include <Ppi/BlockIo2.h>
 #include <Ppi/StorageSecurityCommand.h>
+#include <Ppi/NvmExpressPassThru.h>
 #include <Ppi/IoMmu.h>
 #include <Ppi/EndOfPeiPhase.h>
 
@@ -74,6 +75,8 @@ struct _PEI_NVME_NAMESPACE_INFO {
   PEI_NVME_CONTROLLER_PRIVATE_DATA          *Controller;
 };
 
+#define NVME_CONTROLLER_NSID        0
+
 //
 // Unique signature for private data structure.
 //
@@ -85,15 +88,18 @@ struct _PEI_NVME_NAMESPACE_INFO {
 struct _PEI_NVME_CONTROLLER_PRIVATE_DATA {
   UINT32                                    Signature;
   UINTN                                     MmioBase;
+  EFI_NVM_EXPRESS_PASS_THRU_MODE            PassThruMode;
   UINTN                                     DevicePathLength;
   EFI_DEVICE_PATH_PROTOCOL                  *DevicePath;
 
   EFI_PEI_RECOVERY_BLOCK_IO_PPI             BlkIoPpi;
   EFI_PEI_RECOVERY_BLOCK_IO2_PPI            BlkIo2Ppi;
   EDKII_PEI_STORAGE_SECURITY_CMD_PPI        StorageSecurityPpi;
+  EDKII_PEI_NVM_EXPRESS_PASS_THRU_PPI       NvmePassThruPpi;
   EFI_PEI_PPI_DESCRIPTOR                    BlkIoPpiList;
   EFI_PEI_PPI_DESCRIPTOR                    BlkIo2PpiList;
   EFI_PEI_PPI_DESCRIPTOR                    StorageSecurityPpiList;
+  EFI_PEI_PPI_DESCRIPTOR                    NvmePassThruPpiList;
   EFI_PEI_NOTIFY_DESCRIPTOR                 EndOfPeiNotifyList;
 
   //
@@ -145,6 +151,8 @@ struct _PEI_NVME_CONTROLLER_PRIVATE_DATA {
   CR (a, PEI_NVME_CONTROLLER_PRIVATE_DATA, BlkIo2Ppi, NVME_PEI_CONTROLLER_PRIVATE_DATA_SIGNATURE)
 #define GET_NVME_PEIM_HC_PRIVATE_DATA_FROM_THIS_STROAGE_SECURITY(a)    \
   CR (a, PEI_NVME_CONTROLLER_PRIVATE_DATA, StorageSecurityPpi, NVME_PEI_CONTROLLER_PRIVATE_DATA_SIGNATURE)
+#define GET_NVME_PEIM_HC_PRIVATE_DATA_FROM_THIS_NVME_PASSTHRU(a)       \
+  CR (a, PEI_NVME_CONTROLLER_PRIVATE_DATA, NvmePassThruPpi, NVME_PEI_CONTROLLER_PRIVATE_DATA_SIGNATURE)
 #define GET_NVME_PEIM_HC_PRIVATE_DATA_FROM_THIS_NOTIFY(a)              \
   CR (a, PEI_NVME_CONTROLLER_PRIVATE_DATA, EndOfPeiNotifyList, NVME_PEI_CONTROLLER_PRIVATE_DATA_SIGNATURE)
 
diff --git a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.inf b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.inf
index a8e4808e6b..4dd6c5704f 100644
--- a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.inf
+++ b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.inf
@@ -56,6 +56,7 @@
   gEdkiiPeiNvmExpressHostControllerPpiGuid       ## CONSUMES
   gEdkiiIoMmuPpiGuid                             ## CONSUMES
   gEfiEndOfPeiSignalPpiGuid                      ## CONSUMES
+  gEdkiiPeiNvmExpressPassThruPpiGuid             ## SOMETIMES_PRODUCES
   gEfiPeiVirtualBlockIoPpiGuid                   ## SOMETIMES_PRODUCES
   gEfiPeiVirtualBlockIo2PpiGuid                  ## SOMETIMES_PRODUCES
   gEdkiiPeiStorageSecurityCommandPpiGuid         ## SOMETIMES_PRODUCES
diff --git a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiBlockIo.c b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiBlockIo.c
index 94cdd05f33..a9bf4f8190 100644
--- a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiBlockIo.c
+++ b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiBlockIo.c
@@ -2,7 +2,7 @@
   The NvmExpressPei driver is used to manage non-volatile memory subsystem
   which follows NVM Express specification at PEI phase.
 
-  Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2018 - 2019, Intel Corporation. All rights reserved.<BR>
 
   SPDX-License-Identifier: BSD-2-Clause-Patent
 
@@ -34,17 +34,19 @@ ReadSectors (
   UINT32                                            BlockSize;
   PEI_NVME_CONTROLLER_PRIVATE_DATA                  *Private;
   UINT32                                            Bytes;
-  EDKII_PEI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET    CommandPacket;
-  EDKII_PEI_NVM_EXPRESS_COMMAND                     Command;
-  EDKII_PEI_NVM_EXPRESS_COMPLETION                  Completion;
+  EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET          CommandPacket;
+  EFI_NVM_EXPRESS_COMMAND                           Command;
+  EFI_NVM_EXPRESS_COMPLETION                        Completion;
+  EDKII_PEI_NVM_EXPRESS_PASS_THRU_PPI               *NvmePassThru;
 
   Private   = NamespaceInfo->Controller;
+  NvmePassThru = &Private->NvmePassThruPpi;
   BlockSize = NamespaceInfo->Media.BlockSize;
   Bytes     = Blocks * BlockSize;
 
-  ZeroMem (&CommandPacket, sizeof(EDKII_PEI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET));
-  ZeroMem (&Command, sizeof(EDKII_PEI_NVM_EXPRESS_COMMAND));
-  ZeroMem (&Completion, sizeof(EDKII_PEI_NVM_EXPRESS_COMPLETION));
+  ZeroMem (&CommandPacket, sizeof(EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET));
+  ZeroMem (&Command, sizeof(EFI_NVM_EXPRESS_COMMAND));
+  ZeroMem (&Completion, sizeof(EFI_NVM_EXPRESS_COMPLETION));
 
   CommandPacket.NvmeCmd        = &Command;
   CommandPacket.NvmeCompletion = &Completion;
@@ -63,11 +65,12 @@ ReadSectors (
 
   CommandPacket.NvmeCmd->Flags = CDW10_VALID | CDW11_VALID | CDW12_VALID;
 
-  Status = NvmePassThru (
-             Private,
-             NamespaceInfo->NamespaceId,
-             &CommandPacket
-             );
+  Status = NvmePassThru->PassThru (
+                           NvmePassThru,
+                           NamespaceInfo->NamespaceId,
+                           &CommandPacket
+                           );
+
   return Status;
 }
 
diff --git a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiHci.c b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiHci.c
index c290f5b56f..1d7e3d26e0 100644
--- a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiHci.c
+++ b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiHci.c
@@ -320,14 +320,14 @@ NvmeIdentifyController (
   IN VOID                                *Buffer
   )
 {
-  EDKII_PEI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET    CommandPacket;
-  EDKII_PEI_NVM_EXPRESS_COMMAND                     Command;
-  EDKII_PEI_NVM_EXPRESS_COMPLETION                  Completion;
-  EFI_STATUS                                        Status;
+  EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET    CommandPacket;
+  EFI_NVM_EXPRESS_COMMAND                     Command;
+  EFI_NVM_EXPRESS_COMPLETION                  Completion;
+  EFI_STATUS                                  Status;
 
-  ZeroMem (&CommandPacket, sizeof(EDKII_PEI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET));
-  ZeroMem (&Command, sizeof(EDKII_PEI_NVM_EXPRESS_COMMAND));
-  ZeroMem (&Completion, sizeof(EDKII_PEI_NVM_EXPRESS_COMPLETION));
+  ZeroMem (&CommandPacket, sizeof(EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET));
+  ZeroMem (&Command, sizeof(EFI_NVM_EXPRESS_COMMAND));
+  ZeroMem (&Completion, sizeof(EFI_NVM_EXPRESS_COMPLETION));
 
   Command.Cdw0.Opcode = NVME_ADMIN_IDENTIFY_CMD;
   //
@@ -348,7 +348,7 @@ NvmeIdentifyController (
   CommandPacket.NvmeCmd->Cdw10 = 1;
   CommandPacket.NvmeCmd->Flags = CDW10_VALID;
 
-  Status = NvmePassThru (
+  Status = NvmePassThruExecute (
              Private,
              NVME_CONTROLLER_NSID,
              &CommandPacket
@@ -374,14 +374,14 @@ NvmeIdentifyNamespace (
   IN VOID                                *Buffer
   )
 {
-  EDKII_PEI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET    CommandPacket;
-  EDKII_PEI_NVM_EXPRESS_COMMAND                     Command;
-  EDKII_PEI_NVM_EXPRESS_COMPLETION                  Completion;
-  EFI_STATUS                                        Status;
+  EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET    CommandPacket;
+  EFI_NVM_EXPRESS_COMMAND                     Command;
+  EFI_NVM_EXPRESS_COMPLETION                  Completion;
+  EFI_STATUS                                  Status;
 
-  ZeroMem (&CommandPacket, sizeof(EDKII_PEI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET));
-  ZeroMem (&Command, sizeof(EDKII_PEI_NVM_EXPRESS_COMMAND));
-  ZeroMem (&Completion, sizeof(EDKII_PEI_NVM_EXPRESS_COMPLETION));
+  ZeroMem (&CommandPacket, sizeof(EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET));
+  ZeroMem (&Command, sizeof(EFI_NVM_EXPRESS_COMMAND));
+  ZeroMem (&Completion, sizeof(EFI_NVM_EXPRESS_COMPLETION));
 
   Command.Cdw0.Opcode = NVME_ADMIN_IDENTIFY_CMD;
   Command.Nsid        = NamespaceId;
@@ -398,7 +398,7 @@ NvmeIdentifyNamespace (
   CommandPacket.NvmeCmd->Cdw10 = 0;
   CommandPacket.NvmeCmd->Flags = CDW10_VALID;
 
-  Status = NvmePassThru (
+  Status = NvmePassThruExecute (
              Private,
              NamespaceId,
              &CommandPacket
@@ -454,22 +454,21 @@ NvmeCreateIoCompletionQueue (
   IN PEI_NVME_CONTROLLER_PRIVATE_DATA    *Private
   )
 {
-  EDKII_PEI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET    CommandPacket;
-  EDKII_PEI_NVM_EXPRESS_COMMAND                     Command;
-  EDKII_PEI_NVM_EXPRESS_COMPLETION                  Completion;
-  EFI_STATUS                                        Status;
-  NVME_ADMIN_CRIOCQ                                 CrIoCq;
-
-  ZeroMem (&CommandPacket, sizeof(EDKII_PEI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET));
-  ZeroMem (&Command, sizeof(EDKII_PEI_NVM_EXPRESS_COMMAND));
-  ZeroMem (&Completion, sizeof(EDKII_PEI_NVM_EXPRESS_COMPLETION));
+  EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET    CommandPacket;
+  EFI_NVM_EXPRESS_COMMAND                     Command;
+  EFI_NVM_EXPRESS_COMPLETION                  Completion;
+  EFI_STATUS                                  Status;
+  NVME_ADMIN_CRIOCQ                           CrIoCq;
+
+  ZeroMem (&CommandPacket, sizeof(EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET));
+  ZeroMem (&Command, sizeof(EFI_NVM_EXPRESS_COMMAND));
+  ZeroMem (&Completion, sizeof(EFI_NVM_EXPRESS_COMPLETION));
   ZeroMem (&CrIoCq, sizeof(NVME_ADMIN_CRIOCQ));
 
   CommandPacket.NvmeCmd        = &Command;
   CommandPacket.NvmeCompletion = &Completion;
 
   Command.Cdw0.Opcode = NVME_ADMIN_CRIOCQ_CMD;
-  Command.Cdw0.Cid    = Private->Cid[NVME_ADMIN_QUEUE]++;
   CommandPacket.TransferBuffer = Private->CqBuffer[NVME_IO_QUEUE];
   CommandPacket.TransferLength = EFI_PAGE_SIZE;
   CommandPacket.CommandTimeout = NVME_GENERIC_TIMEOUT;
@@ -481,7 +480,7 @@ NvmeCreateIoCompletionQueue (
   CopyMem (&CommandPacket.NvmeCmd->Cdw10, &CrIoCq, sizeof (NVME_ADMIN_CRIOCQ));
   CommandPacket.NvmeCmd->Flags = CDW10_VALID | CDW11_VALID;
 
-  Status = NvmePassThru (
+  Status = NvmePassThruExecute (
              Private,
              NVME_CONTROLLER_NSID,
              &CommandPacket
@@ -503,22 +502,21 @@ NvmeCreateIoSubmissionQueue (
   IN PEI_NVME_CONTROLLER_PRIVATE_DATA    *Private
   )
 {
-  EDKII_PEI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET    CommandPacket;
-  EDKII_PEI_NVM_EXPRESS_COMMAND                     Command;
-  EDKII_PEI_NVM_EXPRESS_COMPLETION                  Completion;
-  EFI_STATUS                                        Status;
-  NVME_ADMIN_CRIOSQ                                 CrIoSq;
-
-  ZeroMem (&CommandPacket, sizeof(EDKII_PEI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET));
-  ZeroMem (&Command, sizeof(EDKII_PEI_NVM_EXPRESS_COMMAND));
-  ZeroMem (&Completion, sizeof(EDKII_PEI_NVM_EXPRESS_COMPLETION));
+  EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET    CommandPacket;
+  EFI_NVM_EXPRESS_COMMAND                     Command;
+  EFI_NVM_EXPRESS_COMPLETION                  Completion;
+  EFI_STATUS                                  Status;
+  NVME_ADMIN_CRIOSQ                           CrIoSq;
+
+  ZeroMem (&CommandPacket, sizeof(EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET));
+  ZeroMem (&Command, sizeof(EFI_NVM_EXPRESS_COMMAND));
+  ZeroMem (&Completion, sizeof(EFI_NVM_EXPRESS_COMPLETION));
   ZeroMem (&CrIoSq, sizeof(NVME_ADMIN_CRIOSQ));
 
   CommandPacket.NvmeCmd        = &Command;
   CommandPacket.NvmeCompletion = &Completion;
 
   Command.Cdw0.Opcode = NVME_ADMIN_CRIOSQ_CMD;
-  Command.Cdw0.Cid    = Private->Cid[NVME_ADMIN_QUEUE]++;
   CommandPacket.TransferBuffer = Private->SqBuffer[NVME_IO_QUEUE];
   CommandPacket.TransferLength = EFI_PAGE_SIZE;
   CommandPacket.CommandTimeout = NVME_GENERIC_TIMEOUT;
@@ -532,7 +530,7 @@ NvmeCreateIoSubmissionQueue (
   CopyMem (&CommandPacket.NvmeCmd->Cdw10, &CrIoSq, sizeof (NVME_ADMIN_CRIOSQ));
   CommandPacket.NvmeCmd->Flags = CDW10_VALID | CDW11_VALID;
 
-  Status = NvmePassThru (
+  Status = NvmePassThruExecute (
              Private,
              NVME_CONTROLLER_NSID,
              &CommandPacket
diff --git a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiPassThru.c b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiPassThru.c
index a33f5a872e..370a54e5a2 100644
--- a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiPassThru.c
+++ b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiPassThru.c
@@ -2,7 +2,7 @@
   The NvmExpressPei driver is used to manage non-volatile memory subsystem
   which follows NVM Express specification at PEI phase.
 
-  Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2018 - 2019, Intel Corporation. All rights reserved.<BR>
 
   SPDX-License-Identifier: BSD-2-Clause-Patent
 
@@ -332,10 +332,10 @@ NvmeCheckCqStatus (
 
 **/
 EFI_STATUS
-NvmePassThru (
+NvmePassThruExecute (
   IN     PEI_NVME_CONTROLLER_PRIVATE_DATA                  *Private,
   IN     UINT32                                            NamespaceId,
-  IN OUT EDKII_PEI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET    *Packet
+  IN OUT EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET          *Packet
   )
 {
   EFI_STATUS               Status;
@@ -411,9 +411,9 @@ NvmePassThru (
   }
 
   ZeroMem (Sq, sizeof (NVME_SQ));
-  Sq->Opc  = Packet->NvmeCmd->Cdw0.Opcode;
-  Sq->Fuse = Packet->NvmeCmd->Cdw0.FusedOperation;
-  Sq->Cid  = Packet->NvmeCmd->Cdw0.Cid;
+  Sq->Opc  = (UINT8)Packet->NvmeCmd->Cdw0.Opcode;
+  Sq->Fuse = (UINT8)Packet->NvmeCmd->Cdw0.FusedOperation;
+  Sq->Cid  = Private->Cid[QueueId]++;;
   Sq->Nsid = Packet->NvmeCmd->Nsid;
 
   //
@@ -603,7 +603,7 @@ NvmePassThru (
   //
   // Copy the Respose Queue entry for this command to the callers response buffer
   //
-  CopyMem (Packet->NvmeCompletion, Cq, sizeof (EDKII_PEI_NVM_EXPRESS_COMPLETION));
+  CopyMem (Packet->NvmeCompletion, Cq, sizeof (EFI_NVM_EXPRESS_COMPLETION));
 
   //
   // Check the NVMe cmd execution result
@@ -622,3 +622,207 @@ Exit:
 
   return Status;
 }
+
+/**
+  Gets the device path information of the underlying NVM Express host controller.
+
+  @param[in]  This                 The PPI instance pointer.
+  @param[out] DevicePathLength     The length of the device path in bytes specified
+                                   by DevicePath.
+  @param[out] DevicePath           The device path of the underlying NVM Express
+                                   host controller.
+                                   This field re-uses EFI Device Path Protocol as
+                                   defined by Section 10.2 EFI Device Path Protocol
+                                   of UEFI 2.7 Specification.
+
+  @retval EFI_SUCCESS              The operation succeeds.
+  @retval EFI_INVALID_PARAMETER    DevicePathLength or DevicePath is NULL.
+  @retval EFI_OUT_OF_RESOURCES     The operation fails due to lack of resources.
+
+**/
+EFI_STATUS
+EFIAPI
+NvmePassThruGetDevicePath (
+  IN  EDKII_PEI_NVM_EXPRESS_PASS_THRU_PPI    *This,
+  OUT UINTN                                  *DevicePathLength,
+  OUT EFI_DEVICE_PATH_PROTOCOL               **DevicePath
+  )
+{
+  PEI_NVME_CONTROLLER_PRIVATE_DATA         *Private;
+
+  if (This == NULL || DevicePathLength == NULL || DevicePath == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Private = GET_NVME_PEIM_HC_PRIVATE_DATA_FROM_THIS_NVME_PASSTHRU (This);
+
+  *DevicePathLength = Private->DevicePathLength;
+  *DevicePath       = AllocateCopyPool (Private->DevicePathLength, Private->DevicePath);
+  if (*DevicePath == NULL) {
+    *DevicePathLength = 0;
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Used to retrieve the next namespace ID for this NVM Express controller.
+
+  If on input the value pointed to by NamespaceId is 0xFFFFFFFF, then the first
+  valid namespace ID defined on the NVM Express controller is returned in the
+  location pointed to by NamespaceId and a status of EFI_SUCCESS is returned.
+
+  If on input the value pointed to by NamespaceId is an invalid namespace ID
+  other than 0xFFFFFFFF, then EFI_INVALID_PARAMETER is returned.
+
+  If on input the value pointed to by NamespaceId is a valid namespace ID, then
+  the next valid namespace ID on the NVM Express controller is returned in the
+  location pointed to by NamespaceId, and EFI_SUCCESS is returned.
+
+  If the value pointed to by NamespaceId is the namespace ID of the last
+  namespace on the NVM Express controller, then EFI_NOT_FOUND is returned.
+
+  @param[in]     This              The PPI instance pointer.
+  @param[in,out] NamespaceId       On input, a pointer to a legal NamespaceId
+                                   for an NVM Express namespace present on the
+                                   NVM Express controller. On output, a pointer
+                                   to the next NamespaceId of an NVM Express
+                                   namespace on an NVM Express controller. An
+                                   input value of 0xFFFFFFFF retrieves the
+                                   first NamespaceId for an NVM Express
+                                   namespace present on an NVM Express
+                                   controller.
+
+  @retval EFI_SUCCESS            The Namespace ID of the next Namespace was
+                                 returned.
+  @retval EFI_NOT_FOUND          There are no more namespaces defined on this
+                                 controller.
+  @retval EFI_INVALID_PARAMETER  NamespaceId is an invalid value other than
+                                 0xFFFFFFFF.
+
+**/
+EFI_STATUS
+EFIAPI
+NvmePassThruGetNextNameSpace (
+  IN     EDKII_PEI_NVM_EXPRESS_PASS_THRU_PPI   *This,
+  IN OUT UINT32                                *NamespaceId
+  )
+{
+  PEI_NVME_CONTROLLER_PRIVATE_DATA         *Private;
+  UINT32                                   DeviceIndex;
+  EFI_STATUS                               Status;
+
+  if (This == NULL || NamespaceId == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Private = GET_NVME_PEIM_HC_PRIVATE_DATA_FROM_THIS_NVME_PASSTHRU (This);
+
+  Status = EFI_NOT_FOUND;
+
+  //
+  // If active namespace number is 0, then valid namespace ID is unavailable
+  //
+  if (Private->ActiveNamespaceNum == 0) {
+    return EFI_NOT_FOUND;
+  }
+
+  //
+  // If the NamespaceId input value is 0xFFFFFFFF, then get the first valid namespace ID
+  //
+  if (*NamespaceId == 0xFFFFFFFF) {
+    //
+    // Start with the first namespace ID
+    //
+    *NamespaceId = Private->NamespaceInfo[0].NamespaceId;
+    Status = EFI_SUCCESS;
+  } else {
+    if (*NamespaceId > Private->ControllerData->Nn) {
+      return EFI_INVALID_PARAMETER;
+    }
+
+    if ((*NamespaceId + 1) > Private->ControllerData->Nn) {
+      return EFI_NOT_FOUND;
+    }
+
+    for (DeviceIndex = 0; DeviceIndex < Private->ActiveNamespaceNum; DeviceIndex++) {
+      if (*NamespaceId == Private->NamespaceInfo[DeviceIndex].NamespaceId) {
+        if ((DeviceIndex + 1) < Private->ActiveNamespaceNum) {
+          *NamespaceId = Private->NamespaceInfo[DeviceIndex + 1].NamespaceId;
+          Status = EFI_SUCCESS;
+        }
+        break;
+      }
+    }
+  }
+
+  return Status;
+
+}
+
+/**
+  Sends an NVM Express Command Packet to an NVM Express controller or namespace. This function only
+  supports blocking execution of the command.
+
+  @param[in]  This                 The PPI instance pointer.
+  @param[in] NamespaceId           Is a 32 bit Namespace ID to which the Nvm Express command packet will
+                                   be sent.
+                                   A Value of 0 denotes the NVM Express controller, a Value of all 0FFh in
+                                   the namespace ID specifies that the command packet should be sent to all
+                                   valid namespaces.
+  @param[in,out] Packet            A pointer to the EDKII PEI NVM Express PassThru Command Packet to send
+                                   to the NVMe namespace specified by NamespaceId.
+
+  @retval EFI_SUCCESS              The EDKII PEI NVM Express Command Packet was sent by the host.
+                                   TransferLength bytes were transferred to, or from DataBuffer.
+  @retval EFI_NOT_READY            The EDKII PEI NVM Express Command Packet could not be sent because
+                                   the controller is not ready. The caller may retry again later.
+  @retval EFI_DEVICE_ERROR         A device error occurred while attempting to send the EDKII PEI NVM
+                                   Express Command Packet.
+  @retval EFI_INVALID_PARAMETER    Namespace, or the contents of EDKII_PEI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET
+                                   are invalid.
+                                   The EDKII PEI NVM Express Command Packet was not sent, so no
+                                   additional status information is available.
+  @retval EFI_UNSUPPORTED          The command described by the EDKII PEI NVM Express Command Packet
+                                   is not supported by the host adapter.
+                                   The EDKII PEI NVM Express Command Packet was not sent, so no
+                                   additional status information is available.
+  @retval EFI_TIMEOUT              A timeout occurred while waiting for the EDKII PEI NVM Express Command
+                                   Packet to execute.
+
+**/
+EFI_STATUS
+EFIAPI
+NvmePassThru (
+  IN     EDKII_PEI_NVM_EXPRESS_PASS_THRU_PPI               *This,
+  IN     UINT32                                            NamespaceId,
+  IN OUT EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET          *Packet
+  )
+{
+  PEI_NVME_CONTROLLER_PRIVATE_DATA         *Private;
+  EFI_STATUS Status;
+
+  if (This == NULL || Packet == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Private = GET_NVME_PEIM_HC_PRIVATE_DATA_FROM_THIS_NVME_PASSTHRU (This);
+  //
+  // Check NamespaceId is valid or not.
+  //
+  if ((NamespaceId > Private->ControllerData->Nn) &&
+      (NamespaceId != (UINT32) -1)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Status = NvmePassThruExecute (
+             Private,
+             NamespaceId,
+             Packet
+             );
+
+  return Status;
+
+}
+
diff --git a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiPassThru.h b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiPassThru.h
index 81066bbd54..00e8f0abda 100644
--- a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiPassThru.h
+++ b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiPassThru.h
@@ -2,7 +2,7 @@
   The NvmExpressPei driver is used to manage non-volatile memory subsystem
   which follows NVM Express specification at PEI phase.
 
-  Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2018 - 2019, Intel Corporation. All rights reserved.<BR>
 
   SPDX-License-Identifier: BSD-2-Clause-Patent
 
@@ -11,52 +11,6 @@
 #ifndef _NVM_EXPRESS_PEI_PASSTHRU_H_
 #define _NVM_EXPRESS_PEI_PASSTHRU_H_
 
-#define NVME_CONTROLLER_NSID        0
-
-typedef struct {
-  UINT8                             Opcode;
-  UINT8                             FusedOperation;
-    #define NORMAL_CMD              0x00
-    #define FUSED_FIRST_CMD         0x01
-    #define FUSED_SECOND_CMD        0x02
-  UINT16                            Cid;
-} NVME_CDW0;
-
-typedef struct {
-  NVME_CDW0                         Cdw0;
-  UINT8                             Flags;
-    #define CDW10_VALID             0x01
-    #define CDW11_VALID             0x02
-    #define CDW12_VALID             0x04
-    #define CDW13_VALID             0x08
-    #define CDW14_VALID             0x10
-    #define CDW15_VALID             0x20
-  UINT32                            Nsid;
-  UINT32                            Cdw10;
-  UINT32                            Cdw11;
-  UINT32                            Cdw12;
-  UINT32                            Cdw13;
-  UINT32                            Cdw14;
-  UINT32                            Cdw15;
-} EDKII_PEI_NVM_EXPRESS_COMMAND;
-
-typedef struct {
-  UINT32                            Cdw0;
-  UINT32                            Cdw1;
-  UINT32                            Cdw2;
-  UINT32                            Cdw3;
-} EDKII_PEI_NVM_EXPRESS_COMPLETION;
-
-typedef struct {
-  UINT64                            CommandTimeout;
-  VOID                              *TransferBuffer;
-  UINT32                            TransferLength;
-  VOID                              *MetadataBuffer;
-  UINT32                            MetadataLength;
-  UINT8                             QueueType;
-  EDKII_PEI_NVM_EXPRESS_COMMAND     *NvmeCmd;
-  EDKII_PEI_NVM_EXPRESS_COMPLETION  *NvmeCompletion;
-} EDKII_PEI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET;
 
 
 /**
@@ -91,10 +45,117 @@ typedef struct {
 
 **/
 EFI_STATUS
-NvmePassThru (
+NvmePassThruExecute (
   IN     PEI_NVME_CONTROLLER_PRIVATE_DATA                  *Private,
   IN     UINT32                                            NamespaceId,
-  IN OUT EDKII_PEI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET    *Packet
+  IN OUT EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET          *Packet
+  );
+
+/**
+  Gets the device path information of the underlying NVM Express host controller.
+
+  @param[in]  This                 The PPI instance pointer.
+  @param[out] DevicePathLength     The length of the device path in bytes specified
+                                   by DevicePath.
+  @param[out] DevicePath           The device path of the underlying NVM Express
+                                   host controller.
+                                   This field re-uses EFI Device Path Protocol as
+                                   defined by Section 10.2 EFI Device Path Protocol
+                                   of UEFI 2.7 Specification.
+
+  @retval EFI_SUCCESS              The operation succeeds.
+  @retval EFI_INVALID_PARAMETER    DevicePathLength or DevicePath is NULL.
+  @retval EFI_OUT_OF_RESOURCES     The operation fails due to lack of resources.
+
+**/
+EFI_STATUS
+EFIAPI
+NvmePassThruGetDevicePath (
+  IN  EDKII_PEI_NVM_EXPRESS_PASS_THRU_PPI *This,
+  OUT UINTN                               *DevicePathLength,
+  OUT EFI_DEVICE_PATH_PROTOCOL            **DevicePath
+  );
+
+/**
+  Used to retrieve the next namespace ID for this NVM Express controller.
+
+  If on input the value pointed to by NamespaceId is 0xFFFFFFFF, then the first
+  valid namespace ID defined on the NVM Express controller is returned in the
+  location pointed to by NamespaceId and a status of EFI_SUCCESS is returned.
+
+  If on input the value pointed to by NamespaceId is an invalid namespace ID
+  other than 0xFFFFFFFF, then EFI_INVALID_PARAMETER is returned.
+
+  If on input the value pointed to by NamespaceId is a valid namespace ID, then
+  the next valid namespace ID on the NVM Express controller is returned in the
+  location pointed to by NamespaceId, and EFI_SUCCESS is returned.
+
+  If the value pointed to by NamespaceId is the namespace ID of the last
+  namespace on the NVM Express controller, then EFI_NOT_FOUND is returned.
+
+  @param[in]     This              The PPI instance pointer.
+  @param[in,out] NamespaceId       On input, a pointer to a legal NamespaceId
+                                   for an NVM Express namespace present on the
+                                   NVM Express controller. On output, a pointer
+                                   to the next NamespaceId of an NVM Express
+                                   namespace on an NVM Express controller. An
+                                   input value of 0xFFFFFFFF retrieves the
+                                   first NamespaceId for an NVM Express
+                                   namespace present on an NVM Express
+                                   controller.
+
+  @retval EFI_SUCCESS            The Namespace ID of the next Namespace was
+                                 returned.
+  @retval EFI_NOT_FOUND          There are no more namespaces defined on this
+                                 controller.
+  @retval EFI_INVALID_PARAMETER  NamespaceId is an invalid value other than
+                                 0xFFFFFFFF.
+
+**/
+EFI_STATUS
+EFIAPI
+NvmePassThruGetNextNameSpace (
+  IN     EDKII_PEI_NVM_EXPRESS_PASS_THRU_PPI   *This,
+  IN OUT UINT32                                *NamespaceId
+  );
+
+/**
+  Sends an NVM Express Command Packet to an NVM Express controller or namespace. This function only
+  supports blocking execution of the command.
+
+  @param[in] This                  The PPI instance pointer.
+  @param[in] NamespaceId           Is a 32 bit Namespace ID to which the Nvm Express command packet will
+                                   be sent.
+                                   A Value of 0 denotes the NVM Express controller, a Value of all 0FFh in
+                                   the namespace ID specifies that the command packet should be sent to all
+                                   valid namespaces.
+  @param[in,out] Packet            A pointer to the EDKII PEI NVM Express PassThru Command Packet to send
+                                   to the NVMe namespace specified by NamespaceId.
+
+  @retval EFI_SUCCESS              The EDKII PEI NVM Express Command Packet was sent by the host.
+                                   TransferLength bytes were transferred to, or from DataBuffer.
+  @retval EFI_NOT_READY            The EDKII PEI NVM Express Command Packet could not be sent because
+                                   the controller is not ready. The caller may retry again later.
+  @retval EFI_DEVICE_ERROR         A device error occurred while attempting to send the EDKII PEI NVM
+                                   Express Command Packet.
+  @retval EFI_INVALID_PARAMETER    Namespace, or the contents of EDKII_PEI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET
+                                   are invalid.
+                                   The EDKII PEI NVM Express Command Packet was not sent, so no
+                                   additional status information is available.
+  @retval EFI_UNSUPPORTED          The command described by the EDKII PEI NVM Express Command Packet
+                                   is not supported by the host adapter.
+                                   The EDKII PEI NVM Express Command Packet was not sent, so no
+                                   additional status information is available.
+  @retval EFI_TIMEOUT              A timeout occurred while waiting for the EDKII PEI NVM Express Command
+                                   Packet to execute.
+
+**/
+EFI_STATUS
+EFIAPI
+NvmePassThru (
+  IN     EDKII_PEI_NVM_EXPRESS_PASS_THRU_PPI               *This,
+  IN     UINT32                                            NamespaceId,
+  IN OUT EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET          *Packet
   );
 
 #endif
diff --git a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiStorageSecurity.c b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiStorageSecurity.c
index dda69988b1..094d61bb8a 100644
--- a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiStorageSecurity.c
+++ b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiStorageSecurity.c
@@ -57,15 +57,17 @@ TrustTransferNvmeDevice (
      OUT UINTN                               *TransferLengthOut
   )
 {
-  EDKII_PEI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET    CommandPacket;
-  EDKII_PEI_NVM_EXPRESS_COMMAND                     Command;
-  EDKII_PEI_NVM_EXPRESS_COMPLETION                  Completion;
+  EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET          CommandPacket;
+  EFI_NVM_EXPRESS_COMMAND                           Command;
+  EFI_NVM_EXPRESS_COMPLETION                        Completion;
   EFI_STATUS                                        Status;
   UINT16                                            SpecificData;
+  EDKII_PEI_NVM_EXPRESS_PASS_THRU_PPI               *NvmePassThru;
 
-  ZeroMem (&CommandPacket, sizeof(EDKII_PEI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET));
-  ZeroMem (&Command, sizeof(EDKII_PEI_NVM_EXPRESS_COMMAND));
-  ZeroMem (&Completion, sizeof(EDKII_PEI_NVM_EXPRESS_COMPLETION));
+  NvmePassThru = &Private->NvmePassThruPpi;
+  ZeroMem (&CommandPacket, sizeof(EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET));
+  ZeroMem (&Command, sizeof(EFI_NVM_EXPRESS_COMMAND));
+  ZeroMem (&Completion, sizeof(EFI_NVM_EXPRESS_COMPLETION));
 
   CommandPacket.NvmeCmd        = &Command;
   CommandPacket.NvmeCompletion = &Completion;
@@ -94,11 +96,11 @@ TrustTransferNvmeDevice (
   CommandPacket.CommandTimeout = Timeout;
   CommandPacket.QueueType      = NVME_ADMIN_QUEUE;
 
-  Status = NvmePassThru (
-             Private,
-             NVME_CONTROLLER_NSID,
-             &CommandPacket
-             );
+  Status = NvmePassThru->PassThru (
+                           NvmePassThru,
+                           NVME_CONTROLLER_NSID,
+                           &CommandPacket
+                           );
 
   if (!IsTrustSend) {
     if (EFI_ERROR (Status))  {
-- 
2.16.2.windows.1


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [edk2-devel] [PATCH] MdeModulePkg/NvmExpressPei: Produce NVM Express PassThru PPI
  2019-06-17  2:11 [PATCH] MdeModulePkg/NvmExpressPei: Produce NVM Express PassThru PPI Maggie Chu
@ 2019-06-18 12:34 ` Wu, Hao A
  2019-06-24  1:10   ` Wu, Hao A
  0 siblings, 1 reply; 3+ messages in thread
From: Wu, Hao A @ 2019-06-18 12:34 UTC (permalink / raw)
  To: devel@edk2.groups.io, Chu, Maggie; +Cc: Wang, Jian J, Ni, Ray, Zeng, Star

> -----Original Message-----
> From: devel@edk2.groups.io [mailto:devel@edk2.groups.io] On Behalf Of
> Maggie Chu
> Sent: Monday, June 17, 2019 10:11 AM
> To: devel@edk2.groups.io
> Cc: Wu, Hao A; Wang, Jian J; Ni, Ray; Zeng, Star
> Subject: [edk2-devel] [PATCH] MdeModulePkg/NvmExpressPei: Produce
> NVM Express PassThru PPI
> 
> https://bugzilla.tianocore.org/show_bug.cgi?id=1879
> This commit will add codes to produce the NVM Express PassThru PPI.
> 
> Signed-off-by: Maggie Chu <maggie.chu@intel.com>
> Cc: Hao A Wu <hao.a.wu@intel.com>
> Cc: Jian J Wang <jian.j.wang@intel.com>
> Cc: Ray Ni <ray.ni@intel.com>
> Cc: Star Zeng <star.zeng@intel.com>
> ---
>  MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.c |  26 +++
>  MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.h |   8 +
>  .../Bus/Pci/NvmExpressPei/NvmExpressPei.inf        |   1 +
>  .../Bus/Pci/NvmExpressPei/NvmExpressPeiBlockIo.c   |  27 +--
>  .../Bus/Pci/NvmExpressPei/NvmExpressPeiHci.c       |  74 ++++---
>  .../Bus/Pci/NvmExpressPei/NvmExpressPeiPassThru.c  | 218
> ++++++++++++++++++++-
>  .../Bus/Pci/NvmExpressPei/NvmExpressPeiPassThru.h  | 159 ++++++++++----
> -
>  .../NvmExpressPei/NvmExpressPeiStorageSecurity.c   |  24 +--
>  8 files changed, 420 insertions(+), 117 deletions(-)
> 
> diff --git a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.c
> b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.c
> index 0e79b29f82..987eed420e 100644
> --- a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.c
> +++ b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.c
> @@ -28,6 +28,12 @@ EFI_PEI_PPI_DESCRIPTOR
> mNvmeStorageSecurityPpiListTemplate = {
>    NULL
>  };
> 
> +EFI_PEI_PPI_DESCRIPTOR  mNvmePassThruPpiListTemplate = {
> +  (EFI_PEI_PPI_DESCRIPTOR_PPI |
> EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
> +  &gEdkiiPeiNvmExpressPassThruPpiGuid,
> +  NULL
> +};
> +
>  EFI_PEI_NOTIFY_DESCRIPTOR  mNvmeEndOfPeiNotifyListTemplate = {
>    (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK |
> EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
>    &gEfiEndOfPeiSignalPpiGuid,
> @@ -392,6 +398,26 @@ NvmExpressPeimEntry (
>      Private->BlkIo2PpiList.Ppi                 = &Private->BlkIo2Ppi;
>      PeiServicesInstallPpi (&Private->BlkIoPpiList);
> 
> +    //
> +    // Nvm Express Pass Thru PPI
> +    //
> +    Private->PassThruMode.Attributes            =
> EFI_NVM_EXPRESS_PASS_THRU_ATTRIBUTES_PHYSICAL |
> +
> EFI_NVM_EXPRESS_PASS_THRU_ATTRIBUTES_LOGICAL |
> +
> EFI_NVM_EXPRESS_PASS_THRU_ATTRIBUTES_CMD_SET_NVM;
> +    Private->PassThruMode.IoAlign               = sizeof (UINTN);
> +    Private->PassThruMode.NvmeVersion           =
> EDKII_PEI_NVM_EXPRESS_PASS_THRU_PPI_REVISION;
> +    Private->NvmePassThruPpi.Mode               = &Private->PassThruMode;
> +    Private->NvmePassThruPpi.GetDevicePath      =
> NvmePassThruGetDevicePath;
> +    Private->NvmePassThruPpi.GetNextNameSpace   =
> NvmePassThruGetNextNameSpace;
> +    Private->NvmePassThruPpi.PassThru           = NvmePassThru;
> +    CopyMem (
> +      &Private->NvmePassThruPpiList,
> +      &mNvmePassThruPpiListTemplate,
> +      sizeof (EFI_PEI_PPI_DESCRIPTOR)
> +      );
> +    Private->NvmePassThruPpiList.Ppi            = &Private->NvmePassThruPpi;
> +    PeiServicesInstallPpi (&Private->NvmePassThruPpiList);
> +
>      //
>      // Check if the NVME controller supports the Security Receive/Send
> commands
>      //
> diff --git a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.h
> b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.h
> index 6b2e2f0326..8cd905191b 100644
> --- a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.h
> +++ b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.h
> @@ -19,6 +19,7 @@
>  #include <Ppi/BlockIo.h>
>  #include <Ppi/BlockIo2.h>
>  #include <Ppi/StorageSecurityCommand.h>
> +#include <Ppi/NvmExpressPassThru.h>
>  #include <Ppi/IoMmu.h>
>  #include <Ppi/EndOfPeiPhase.h>
> 
> @@ -74,6 +75,8 @@ struct _PEI_NVME_NAMESPACE_INFO {
>    PEI_NVME_CONTROLLER_PRIVATE_DATA          *Controller;
>  };
> 
> +#define NVME_CONTROLLER_NSID        0
> +
>  //
>  // Unique signature for private data structure.
>  //
> @@ -85,15 +88,18 @@ struct _PEI_NVME_NAMESPACE_INFO {
>  struct _PEI_NVME_CONTROLLER_PRIVATE_DATA {
>    UINT32                                    Signature;
>    UINTN                                     MmioBase;
> +  EFI_NVM_EXPRESS_PASS_THRU_MODE            PassThruMode;
>    UINTN                                     DevicePathLength;
>    EFI_DEVICE_PATH_PROTOCOL                  *DevicePath;
> 
>    EFI_PEI_RECOVERY_BLOCK_IO_PPI             BlkIoPpi;
>    EFI_PEI_RECOVERY_BLOCK_IO2_PPI            BlkIo2Ppi;
>    EDKII_PEI_STORAGE_SECURITY_CMD_PPI        StorageSecurityPpi;
> +  EDKII_PEI_NVM_EXPRESS_PASS_THRU_PPI       NvmePassThruPpi;
>    EFI_PEI_PPI_DESCRIPTOR                    BlkIoPpiList;
>    EFI_PEI_PPI_DESCRIPTOR                    BlkIo2PpiList;
>    EFI_PEI_PPI_DESCRIPTOR                    StorageSecurityPpiList;
> +  EFI_PEI_PPI_DESCRIPTOR                    NvmePassThruPpiList;
>    EFI_PEI_NOTIFY_DESCRIPTOR                 EndOfPeiNotifyList;
> 
>    //
> @@ -145,6 +151,8 @@ struct _PEI_NVME_CONTROLLER_PRIVATE_DATA {
>    CR (a, PEI_NVME_CONTROLLER_PRIVATE_DATA, BlkIo2Ppi,
> NVME_PEI_CONTROLLER_PRIVATE_DATA_SIGNATURE)
>  #define
> GET_NVME_PEIM_HC_PRIVATE_DATA_FROM_THIS_STROAGE_SECURITY(a)
> \
>    CR (a, PEI_NVME_CONTROLLER_PRIVATE_DATA, StorageSecurityPpi,
> NVME_PEI_CONTROLLER_PRIVATE_DATA_SIGNATURE)
> +#define
> GET_NVME_PEIM_HC_PRIVATE_DATA_FROM_THIS_NVME_PASSTHRU(a)       \
> +  CR (a, PEI_NVME_CONTROLLER_PRIVATE_DATA, NvmePassThruPpi,
> NVME_PEI_CONTROLLER_PRIVATE_DATA_SIGNATURE)
>  #define GET_NVME_PEIM_HC_PRIVATE_DATA_FROM_THIS_NOTIFY(a)
> \
>    CR (a, PEI_NVME_CONTROLLER_PRIVATE_DATA, EndOfPeiNotifyList,
> NVME_PEI_CONTROLLER_PRIVATE_DATA_SIGNATURE)
> 
> diff --git a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.inf
> b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.inf
> index a8e4808e6b..4dd6c5704f 100644
> --- a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.inf
> +++ b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.inf
> @@ -56,6 +56,7 @@
>    gEdkiiPeiNvmExpressHostControllerPpiGuid       ## CONSUMES
>    gEdkiiIoMmuPpiGuid                             ## CONSUMES
>    gEfiEndOfPeiSignalPpiGuid                      ## CONSUMES
> +  gEdkiiPeiNvmExpressPassThruPpiGuid             ## SOMETIMES_PRODUCES
>    gEfiPeiVirtualBlockIoPpiGuid                   ## SOMETIMES_PRODUCES
>    gEfiPeiVirtualBlockIo2PpiGuid                  ## SOMETIMES_PRODUCES
>    gEdkiiPeiStorageSecurityCommandPpiGuid         ## SOMETIMES_PRODUCES
> diff --git
> a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiBlockIo.c
> b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiBlockIo.c
> index 94cdd05f33..a9bf4f8190 100644
> --- a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiBlockIo.c
> +++ b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiBlockIo.c
> @@ -2,7 +2,7 @@
>    The NvmExpressPei driver is used to manage non-volatile memory
> subsystem
>    which follows NVM Express specification at PEI phase.
> 
> -  Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
> +  Copyright (c) 2018 - 2019, Intel Corporation. All rights reserved.<BR>
> 
>    SPDX-License-Identifier: BSD-2-Clause-Patent
> 
> @@ -34,17 +34,19 @@ ReadSectors (
>    UINT32                                            BlockSize;
>    PEI_NVME_CONTROLLER_PRIVATE_DATA                  *Private;
>    UINT32                                            Bytes;
> -  EDKII_PEI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET
> CommandPacket;
> -  EDKII_PEI_NVM_EXPRESS_COMMAND                     Command;
> -  EDKII_PEI_NVM_EXPRESS_COMPLETION                  Completion;
> +  EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET
> CommandPacket;
> +  EFI_NVM_EXPRESS_COMMAND                           Command;
> +  EFI_NVM_EXPRESS_COMPLETION                        Completion;
> +  EDKII_PEI_NVM_EXPRESS_PASS_THRU_PPI               *NvmePassThru;
> 
>    Private   = NamespaceInfo->Controller;
> +  NvmePassThru = &Private->NvmePassThruPpi;
>    BlockSize = NamespaceInfo->Media.BlockSize;
>    Bytes     = Blocks * BlockSize;
> 
> -  ZeroMem (&CommandPacket,
> sizeof(EDKII_PEI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET));
> -  ZeroMem (&Command, sizeof(EDKII_PEI_NVM_EXPRESS_COMMAND));
> -  ZeroMem (&Completion, sizeof(EDKII_PEI_NVM_EXPRESS_COMPLETION));
> +  ZeroMem (&CommandPacket,
> sizeof(EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET));
> +  ZeroMem (&Command, sizeof(EFI_NVM_EXPRESS_COMMAND));
> +  ZeroMem (&Completion, sizeof(EFI_NVM_EXPRESS_COMPLETION));
> 
>    CommandPacket.NvmeCmd        = &Command;
>    CommandPacket.NvmeCompletion = &Completion;
> @@ -63,11 +65,12 @@ ReadSectors (
> 
>    CommandPacket.NvmeCmd->Flags = CDW10_VALID | CDW11_VALID |
> CDW12_VALID;
> 
> -  Status = NvmePassThru (
> -             Private,
> -             NamespaceInfo->NamespaceId,
> -             &CommandPacket
> -             );
> +  Status = NvmePassThru->PassThru (
> +                           NvmePassThru,
> +                           NamespaceInfo->NamespaceId,
> +                           &CommandPacket
> +                           );
> +
>    return Status;
>  }
> 
> diff --git a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiHci.c
> b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiHci.c
> index c290f5b56f..1d7e3d26e0 100644
> --- a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiHci.c
> +++ b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiHci.c
> @@ -320,14 +320,14 @@ NvmeIdentifyController (
>    IN VOID                                *Buffer
>    )
>  {
> -  EDKII_PEI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET
> CommandPacket;
> -  EDKII_PEI_NVM_EXPRESS_COMMAND                     Command;
> -  EDKII_PEI_NVM_EXPRESS_COMPLETION                  Completion;
> -  EFI_STATUS                                        Status;
> +  EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET    CommandPacket;
> +  EFI_NVM_EXPRESS_COMMAND                     Command;
> +  EFI_NVM_EXPRESS_COMPLETION                  Completion;
> +  EFI_STATUS                                  Status;
> 
> -  ZeroMem (&CommandPacket,
> sizeof(EDKII_PEI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET));
> -  ZeroMem (&Command, sizeof(EDKII_PEI_NVM_EXPRESS_COMMAND));
> -  ZeroMem (&Completion, sizeof(EDKII_PEI_NVM_EXPRESS_COMPLETION));
> +  ZeroMem (&CommandPacket,
> sizeof(EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET));
> +  ZeroMem (&Command, sizeof(EFI_NVM_EXPRESS_COMMAND));
> +  ZeroMem (&Completion, sizeof(EFI_NVM_EXPRESS_COMPLETION));
> 
>    Command.Cdw0.Opcode = NVME_ADMIN_IDENTIFY_CMD;
>    //
> @@ -348,7 +348,7 @@ NvmeIdentifyController (
>    CommandPacket.NvmeCmd->Cdw10 = 1;
>    CommandPacket.NvmeCmd->Flags = CDW10_VALID;
> 
> -  Status = NvmePassThru (
> +  Status = NvmePassThruExecute (
>               Private,
>               NVME_CONTROLLER_NSID,
>               &CommandPacket
> @@ -374,14 +374,14 @@ NvmeIdentifyNamespace (
>    IN VOID                                *Buffer
>    )
>  {
> -  EDKII_PEI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET
> CommandPacket;
> -  EDKII_PEI_NVM_EXPRESS_COMMAND                     Command;
> -  EDKII_PEI_NVM_EXPRESS_COMPLETION                  Completion;
> -  EFI_STATUS                                        Status;
> +  EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET    CommandPacket;
> +  EFI_NVM_EXPRESS_COMMAND                     Command;
> +  EFI_NVM_EXPRESS_COMPLETION                  Completion;
> +  EFI_STATUS                                  Status;
> 
> -  ZeroMem (&CommandPacket,
> sizeof(EDKII_PEI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET));
> -  ZeroMem (&Command, sizeof(EDKII_PEI_NVM_EXPRESS_COMMAND));
> -  ZeroMem (&Completion, sizeof(EDKII_PEI_NVM_EXPRESS_COMPLETION));
> +  ZeroMem (&CommandPacket,
> sizeof(EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET));
> +  ZeroMem (&Command, sizeof(EFI_NVM_EXPRESS_COMMAND));
> +  ZeroMem (&Completion, sizeof(EFI_NVM_EXPRESS_COMPLETION));
> 
>    Command.Cdw0.Opcode = NVME_ADMIN_IDENTIFY_CMD;
>    Command.Nsid        = NamespaceId;
> @@ -398,7 +398,7 @@ NvmeIdentifyNamespace (
>    CommandPacket.NvmeCmd->Cdw10 = 0;
>    CommandPacket.NvmeCmd->Flags = CDW10_VALID;
> 
> -  Status = NvmePassThru (
> +  Status = NvmePassThruExecute (
>               Private,
>               NamespaceId,
>               &CommandPacket
> @@ -454,22 +454,21 @@ NvmeCreateIoCompletionQueue (
>    IN PEI_NVME_CONTROLLER_PRIVATE_DATA    *Private
>    )
>  {
> -  EDKII_PEI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET
> CommandPacket;
> -  EDKII_PEI_NVM_EXPRESS_COMMAND                     Command;
> -  EDKII_PEI_NVM_EXPRESS_COMPLETION                  Completion;
> -  EFI_STATUS                                        Status;
> -  NVME_ADMIN_CRIOCQ                                 CrIoCq;
> -
> -  ZeroMem (&CommandPacket,
> sizeof(EDKII_PEI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET));
> -  ZeroMem (&Command, sizeof(EDKII_PEI_NVM_EXPRESS_COMMAND));
> -  ZeroMem (&Completion, sizeof(EDKII_PEI_NVM_EXPRESS_COMPLETION));
> +  EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET    CommandPacket;
> +  EFI_NVM_EXPRESS_COMMAND                     Command;
> +  EFI_NVM_EXPRESS_COMPLETION                  Completion;
> +  EFI_STATUS                                  Status;
> +  NVME_ADMIN_CRIOCQ                           CrIoCq;
> +
> +  ZeroMem (&CommandPacket,
> sizeof(EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET));
> +  ZeroMem (&Command, sizeof(EFI_NVM_EXPRESS_COMMAND));
> +  ZeroMem (&Completion, sizeof(EFI_NVM_EXPRESS_COMPLETION));
>    ZeroMem (&CrIoCq, sizeof(NVME_ADMIN_CRIOCQ));
> 
>    CommandPacket.NvmeCmd        = &Command;
>    CommandPacket.NvmeCompletion = &Completion;
> 
>    Command.Cdw0.Opcode = NVME_ADMIN_CRIOCQ_CMD;
> -  Command.Cdw0.Cid    = Private->Cid[NVME_ADMIN_QUEUE]++;
>    CommandPacket.TransferBuffer = Private->CqBuffer[NVME_IO_QUEUE];
>    CommandPacket.TransferLength = EFI_PAGE_SIZE;
>    CommandPacket.CommandTimeout = NVME_GENERIC_TIMEOUT;
> @@ -481,7 +480,7 @@ NvmeCreateIoCompletionQueue (
>    CopyMem (&CommandPacket.NvmeCmd->Cdw10, &CrIoCq, sizeof
> (NVME_ADMIN_CRIOCQ));
>    CommandPacket.NvmeCmd->Flags = CDW10_VALID | CDW11_VALID;
> 
> -  Status = NvmePassThru (
> +  Status = NvmePassThruExecute (
>               Private,
>               NVME_CONTROLLER_NSID,
>               &CommandPacket
> @@ -503,22 +502,21 @@ NvmeCreateIoSubmissionQueue (
>    IN PEI_NVME_CONTROLLER_PRIVATE_DATA    *Private
>    )
>  {
> -  EDKII_PEI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET
> CommandPacket;
> -  EDKII_PEI_NVM_EXPRESS_COMMAND                     Command;
> -  EDKII_PEI_NVM_EXPRESS_COMPLETION                  Completion;
> -  EFI_STATUS                                        Status;
> -  NVME_ADMIN_CRIOSQ                                 CrIoSq;
> -
> -  ZeroMem (&CommandPacket,
> sizeof(EDKII_PEI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET));
> -  ZeroMem (&Command, sizeof(EDKII_PEI_NVM_EXPRESS_COMMAND));
> -  ZeroMem (&Completion, sizeof(EDKII_PEI_NVM_EXPRESS_COMPLETION));
> +  EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET    CommandPacket;
> +  EFI_NVM_EXPRESS_COMMAND                     Command;
> +  EFI_NVM_EXPRESS_COMPLETION                  Completion;
> +  EFI_STATUS                                  Status;
> +  NVME_ADMIN_CRIOSQ                           CrIoSq;
> +
> +  ZeroMem (&CommandPacket,
> sizeof(EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET));
> +  ZeroMem (&Command, sizeof(EFI_NVM_EXPRESS_COMMAND));
> +  ZeroMem (&Completion, sizeof(EFI_NVM_EXPRESS_COMPLETION));
>    ZeroMem (&CrIoSq, sizeof(NVME_ADMIN_CRIOSQ));
> 
>    CommandPacket.NvmeCmd        = &Command;
>    CommandPacket.NvmeCompletion = &Completion;
> 
>    Command.Cdw0.Opcode = NVME_ADMIN_CRIOSQ_CMD;
> -  Command.Cdw0.Cid    = Private->Cid[NVME_ADMIN_QUEUE]++;
>    CommandPacket.TransferBuffer = Private->SqBuffer[NVME_IO_QUEUE];
>    CommandPacket.TransferLength = EFI_PAGE_SIZE;
>    CommandPacket.CommandTimeout = NVME_GENERIC_TIMEOUT;
> @@ -532,7 +530,7 @@ NvmeCreateIoSubmissionQueue (
>    CopyMem (&CommandPacket.NvmeCmd->Cdw10, &CrIoSq, sizeof
> (NVME_ADMIN_CRIOSQ));
>    CommandPacket.NvmeCmd->Flags = CDW10_VALID | CDW11_VALID;
> 
> -  Status = NvmePassThru (
> +  Status = NvmePassThruExecute (
>               Private,
>               NVME_CONTROLLER_NSID,
>               &CommandPacket
> diff --git
> a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiPassThru.c
> b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiPassThru.c
> index a33f5a872e..370a54e5a2 100644
> --- a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiPassThru.c
> +++ b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiPassThru.c
> @@ -2,7 +2,7 @@
>    The NvmExpressPei driver is used to manage non-volatile memory
> subsystem
>    which follows NVM Express specification at PEI phase.
> 
> -  Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
> +  Copyright (c) 2018 - 2019, Intel Corporation. All rights reserved.<BR>
> 
>    SPDX-License-Identifier: BSD-2-Clause-Patent
> 
> @@ -332,10 +332,10 @@ NvmeCheckCqStatus (
> 
>  **/
>  EFI_STATUS
> -NvmePassThru (
> +NvmePassThruExecute (
>    IN     PEI_NVME_CONTROLLER_PRIVATE_DATA                  *Private,
>    IN     UINT32                                            NamespaceId,
> -  IN OUT EDKII_PEI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET
> *Packet
> +  IN OUT EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET          *Packet
>    )
>  {
>    EFI_STATUS               Status;
> @@ -411,9 +411,9 @@ NvmePassThru (
>    }
> 
>    ZeroMem (Sq, sizeof (NVME_SQ));
> -  Sq->Opc  = Packet->NvmeCmd->Cdw0.Opcode;
> -  Sq->Fuse = Packet->NvmeCmd->Cdw0.FusedOperation;
> -  Sq->Cid  = Packet->NvmeCmd->Cdw0.Cid;
> +  Sq->Opc  = (UINT8)Packet->NvmeCmd->Cdw0.Opcode;
> +  Sq->Fuse = (UINT8)Packet->NvmeCmd->Cdw0.FusedOperation;
> +  Sq->Cid  = Private->Cid[QueueId]++;;
>    Sq->Nsid = Packet->NvmeCmd->Nsid;
> 
>    //
> @@ -603,7 +603,7 @@ NvmePassThru (
>    //
>    // Copy the Respose Queue entry for this command to the callers response
> buffer
>    //
> -  CopyMem (Packet->NvmeCompletion, Cq, sizeof
> (EDKII_PEI_NVM_EXPRESS_COMPLETION));
> +  CopyMem (Packet->NvmeCompletion, Cq, sizeof
> (EFI_NVM_EXPRESS_COMPLETION));
> 
>    //
>    // Check the NVMe cmd execution result
> @@ -622,3 +622,207 @@ Exit:
> 
>    return Status;
>  }
> +
> +/**
> +  Gets the device path information of the underlying NVM Express host
> controller.
> +
> +  @param[in]  This                 The PPI instance pointer.
> +  @param[out] DevicePathLength     The length of the device path in bytes
> specified
> +                                   by DevicePath.
> +  @param[out] DevicePath           The device path of the underlying NVM
> Express
> +                                   host controller.
> +                                   This field re-uses EFI Device Path Protocol as
> +                                   defined by Section 10.2 EFI Device Path Protocol
> +                                   of UEFI 2.7 Specification.
> +
> +  @retval EFI_SUCCESS              The operation succeeds.
> +  @retval EFI_INVALID_PARAMETER    DevicePathLength or DevicePath is
> NULL.
> +  @retval EFI_OUT_OF_RESOURCES     The operation fails due to lack of
> resources.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +NvmePassThruGetDevicePath (
> +  IN  EDKII_PEI_NVM_EXPRESS_PASS_THRU_PPI    *This,
> +  OUT UINTN                                  *DevicePathLength,
> +  OUT EFI_DEVICE_PATH_PROTOCOL               **DevicePath
> +  )
> +{
> +  PEI_NVME_CONTROLLER_PRIVATE_DATA         *Private;
> +
> +  if (This == NULL || DevicePathLength == NULL || DevicePath == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  Private =
> GET_NVME_PEIM_HC_PRIVATE_DATA_FROM_THIS_NVME_PASSTHRU (This);
> +
> +  *DevicePathLength = Private->DevicePathLength;
> +  *DevicePath       = AllocateCopyPool (Private->DevicePathLength, Private-
> >DevicePath);
> +  if (*DevicePath == NULL) {
> +    *DevicePathLength = 0;
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Used to retrieve the next namespace ID for this NVM Express controller.
> +
> +  If on input the value pointed to by NamespaceId is 0xFFFFFFFF, then the
> first
> +  valid namespace ID defined on the NVM Express controller is returned in
> the
> +  location pointed to by NamespaceId and a status of EFI_SUCCESS is
> returned.
> +
> +  If on input the value pointed to by NamespaceId is an invalid namespace
> ID
> +  other than 0xFFFFFFFF, then EFI_INVALID_PARAMETER is returned.
> +
> +  If on input the value pointed to by NamespaceId is a valid namespace ID,
> then
> +  the next valid namespace ID on the NVM Express controller is returned in
> the
> +  location pointed to by NamespaceId, and EFI_SUCCESS is returned.
> +
> +  If the value pointed to by NamespaceId is the namespace ID of the last
> +  namespace on the NVM Express controller, then EFI_NOT_FOUND is
> returned.
> +
> +  @param[in]     This              The PPI instance pointer.
> +  @param[in,out] NamespaceId       On input, a pointer to a legal
> NamespaceId
> +                                   for an NVM Express namespace present on the
> +                                   NVM Express controller. On output, a pointer
> +                                   to the next NamespaceId of an NVM Express
> +                                   namespace on an NVM Express controller. An
> +                                   input value of 0xFFFFFFFF retrieves the
> +                                   first NamespaceId for an NVM Express
> +                                   namespace present on an NVM Express
> +                                   controller.
> +
> +  @retval EFI_SUCCESS            The Namespace ID of the next Namespace was
> +                                 returned.
> +  @retval EFI_NOT_FOUND          There are no more namespaces defined on
> this
> +                                 controller.
> +  @retval EFI_INVALID_PARAMETER  NamespaceId is an invalid value other
> than
> +                                 0xFFFFFFFF.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +NvmePassThruGetNextNameSpace (
> +  IN     EDKII_PEI_NVM_EXPRESS_PASS_THRU_PPI   *This,
> +  IN OUT UINT32                                *NamespaceId
> +  )
> +{
> +  PEI_NVME_CONTROLLER_PRIVATE_DATA         *Private;
> +  UINT32                                   DeviceIndex;
> +  EFI_STATUS                               Status;
> +
> +  if (This == NULL || NamespaceId == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  Private =
> GET_NVME_PEIM_HC_PRIVATE_DATA_FROM_THIS_NVME_PASSTHRU (This);
> +
> +  Status = EFI_NOT_FOUND;
> +
> +  //
> +  // If active namespace number is 0, then valid namespace ID is
> unavailable
> +  //
> +  if (Private->ActiveNamespaceNum == 0) {
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  //
> +  // If the NamespaceId input value is 0xFFFFFFFF, then get the first valid
> namespace ID
> +  //
> +  if (*NamespaceId == 0xFFFFFFFF) {
> +    //
> +    // Start with the first namespace ID
> +    //
> +    *NamespaceId = Private->NamespaceInfo[0].NamespaceId;
> +    Status = EFI_SUCCESS;
> +  } else {
> +    if (*NamespaceId > Private->ControllerData->Nn) {
> +      return EFI_INVALID_PARAMETER;
> +    }
> +
> +    if ((*NamespaceId + 1) > Private->ControllerData->Nn) {
> +      return EFI_NOT_FOUND;
> +    }
> +
> +    for (DeviceIndex = 0; DeviceIndex < Private->ActiveNamespaceNum;
> DeviceIndex++) {
> +      if (*NamespaceId == Private-
> >NamespaceInfo[DeviceIndex].NamespaceId) {
> +        if ((DeviceIndex + 1) < Private->ActiveNamespaceNum) {
> +          *NamespaceId = Private->NamespaceInfo[DeviceIndex +
> 1].NamespaceId;
> +          Status = EFI_SUCCESS;
> +        }
> +        break;
> +      }
> +    }
> +  }
> +
> +  return Status;
> +
> +}
> +
> +/**
> +  Sends an NVM Express Command Packet to an NVM Express controller or
> namespace. This function only
> +  supports blocking execution of the command.
> +
> +  @param[in]  This                 The PPI instance pointer.
> +  @param[in] NamespaceId           Is a 32 bit Namespace ID to which the Nvm
> Express command packet will
> +                                   be sent.
> +                                   A Value of 0 denotes the NVM Express controller, a Value
> of all 0FFh in
> +                                   the namespace ID specifies that the command packet
> should be sent to all
> +                                   valid namespaces.
> +  @param[in,out] Packet            A pointer to the EDKII PEI NVM Express
> PassThru Command Packet to send
> +                                   to the NVMe namespace specified by NamespaceId.
> +
> +  @retval EFI_SUCCESS              The EDKII PEI NVM Express Command Packet
> was sent by the host.
> +                                   TransferLength bytes were transferred to, or from
> DataBuffer.
> +  @retval EFI_NOT_READY            The EDKII PEI NVM Express Command
> Packet could not be sent because
> +                                   the controller is not ready. The caller may retry again later.
> +  @retval EFI_DEVICE_ERROR         A device error occurred while attempting
> to send the EDKII PEI NVM
> +                                   Express Command Packet.
> +  @retval EFI_INVALID_PARAMETER    Namespace, or the contents of
> EDKII_PEI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET
> +                                   are invalid.
> +                                   The EDKII PEI NVM Express Command Packet was not sent,
> so no
> +                                   additional status information is available.
> +  @retval EFI_UNSUPPORTED          The command described by the EDKII PEI
> NVM Express Command Packet
> +                                   is not supported by the host adapter.
> +                                   The EDKII PEI NVM Express Command Packet was not sent,
> so no
> +                                   additional status information is available.
> +  @retval EFI_TIMEOUT              A timeout occurred while waiting for the
> EDKII PEI NVM Express Command
> +                                   Packet to execute.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +NvmePassThru (
> +  IN     EDKII_PEI_NVM_EXPRESS_PASS_THRU_PPI               *This,
> +  IN     UINT32                                            NamespaceId,
> +  IN OUT EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET          *Packet
> +  )
> +{
> +  PEI_NVME_CONTROLLER_PRIVATE_DATA         *Private;
> +  EFI_STATUS Status;
> +
> +  if (This == NULL || Packet == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  Private =
> GET_NVME_PEIM_HC_PRIVATE_DATA_FROM_THIS_NVME_PASSTHRU (This);
> +  //
> +  // Check NamespaceId is valid or not.
> +  //
> +  if ((NamespaceId > Private->ControllerData->Nn) &&
> +      (NamespaceId != (UINT32) -1)) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  Status = NvmePassThruExecute (
> +             Private,
> +             NamespaceId,
> +             Packet
> +             );
> +
> +  return Status;
> +
> +}
> +
> diff --git
> a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiPassThru.h
> b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiPassThru.h
> index 81066bbd54..00e8f0abda 100644
> --- a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiPassThru.h
> +++ b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiPassThru.h
> @@ -2,7 +2,7 @@
>    The NvmExpressPei driver is used to manage non-volatile memory
> subsystem
>    which follows NVM Express specification at PEI phase.
> 
> -  Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
> +  Copyright (c) 2018 - 2019, Intel Corporation. All rights reserved.<BR>
> 
>    SPDX-License-Identifier: BSD-2-Clause-Patent
> 
> @@ -11,52 +11,6 @@
>  #ifndef _NVM_EXPRESS_PEI_PASSTHRU_H_
>  #define _NVM_EXPRESS_PEI_PASSTHRU_H_
> 
> -#define NVME_CONTROLLER_NSID        0
> -
> -typedef struct {
> -  UINT8                             Opcode;
> -  UINT8                             FusedOperation;
> -    #define NORMAL_CMD              0x00
> -    #define FUSED_FIRST_CMD         0x01
> -    #define FUSED_SECOND_CMD        0x02
> -  UINT16                            Cid;
> -} NVME_CDW0;
> -
> -typedef struct {
> -  NVME_CDW0                         Cdw0;
> -  UINT8                             Flags;
> -    #define CDW10_VALID             0x01
> -    #define CDW11_VALID             0x02
> -    #define CDW12_VALID             0x04
> -    #define CDW13_VALID             0x08
> -    #define CDW14_VALID             0x10
> -    #define CDW15_VALID             0x20
> -  UINT32                            Nsid;
> -  UINT32                            Cdw10;
> -  UINT32                            Cdw11;
> -  UINT32                            Cdw12;
> -  UINT32                            Cdw13;
> -  UINT32                            Cdw14;
> -  UINT32                            Cdw15;
> -} EDKII_PEI_NVM_EXPRESS_COMMAND;
> -
> -typedef struct {
> -  UINT32                            Cdw0;
> -  UINT32                            Cdw1;
> -  UINT32                            Cdw2;
> -  UINT32                            Cdw3;
> -} EDKII_PEI_NVM_EXPRESS_COMPLETION;
> -
> -typedef struct {
> -  UINT64                            CommandTimeout;
> -  VOID                              *TransferBuffer;
> -  UINT32                            TransferLength;
> -  VOID                              *MetadataBuffer;
> -  UINT32                            MetadataLength;
> -  UINT8                             QueueType;
> -  EDKII_PEI_NVM_EXPRESS_COMMAND     *NvmeCmd;
> -  EDKII_PEI_NVM_EXPRESS_COMPLETION  *NvmeCompletion;
> -} EDKII_PEI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET;
> 
> 
>  /**
> @@ -91,10 +45,117 @@ typedef struct {
> 
>  **/
>  EFI_STATUS
> -NvmePassThru (
> +NvmePassThruExecute (
>    IN     PEI_NVME_CONTROLLER_PRIVATE_DATA                  *Private,
>    IN     UINT32                                            NamespaceId,
> -  IN OUT EDKII_PEI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET
> *Packet
> +  IN OUT EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET          *Packet
> +  );
> +
> +/**
> +  Gets the device path information of the underlying NVM Express host
> controller.
> +
> +  @param[in]  This                 The PPI instance pointer.
> +  @param[out] DevicePathLength     The length of the device path in bytes
> specified
> +                                   by DevicePath.
> +  @param[out] DevicePath           The device path of the underlying NVM
> Express
> +                                   host controller.
> +                                   This field re-uses EFI Device Path Protocol as
> +                                   defined by Section 10.2 EFI Device Path Protocol
> +                                   of UEFI 2.7 Specification.
> +
> +  @retval EFI_SUCCESS              The operation succeeds.
> +  @retval EFI_INVALID_PARAMETER    DevicePathLength or DevicePath is
> NULL.
> +  @retval EFI_OUT_OF_RESOURCES     The operation fails due to lack of
> resources.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +NvmePassThruGetDevicePath (
> +  IN  EDKII_PEI_NVM_EXPRESS_PASS_THRU_PPI *This,
> +  OUT UINTN                               *DevicePathLength,
> +  OUT EFI_DEVICE_PATH_PROTOCOL            **DevicePath
> +  );
> +
> +/**
> +  Used to retrieve the next namespace ID for this NVM Express controller.
> +
> +  If on input the value pointed to by NamespaceId is 0xFFFFFFFF, then the
> first
> +  valid namespace ID defined on the NVM Express controller is returned in
> the
> +  location pointed to by NamespaceId and a status of EFI_SUCCESS is
> returned.
> +
> +  If on input the value pointed to by NamespaceId is an invalid namespace
> ID
> +  other than 0xFFFFFFFF, then EFI_INVALID_PARAMETER is returned.
> +
> +  If on input the value pointed to by NamespaceId is a valid namespace ID,
> then
> +  the next valid namespace ID on the NVM Express controller is returned in
> the
> +  location pointed to by NamespaceId, and EFI_SUCCESS is returned.
> +
> +  If the value pointed to by NamespaceId is the namespace ID of the last
> +  namespace on the NVM Express controller, then EFI_NOT_FOUND is
> returned.
> +
> +  @param[in]     This              The PPI instance pointer.
> +  @param[in,out] NamespaceId       On input, a pointer to a legal
> NamespaceId
> +                                   for an NVM Express namespace present on the
> +                                   NVM Express controller. On output, a pointer
> +                                   to the next NamespaceId of an NVM Express
> +                                   namespace on an NVM Express controller. An
> +                                   input value of 0xFFFFFFFF retrieves the
> +                                   first NamespaceId for an NVM Express
> +                                   namespace present on an NVM Express
> +                                   controller.
> +
> +  @retval EFI_SUCCESS            The Namespace ID of the next Namespace was
> +                                 returned.
> +  @retval EFI_NOT_FOUND          There are no more namespaces defined on
> this
> +                                 controller.
> +  @retval EFI_INVALID_PARAMETER  NamespaceId is an invalid value other
> than
> +                                 0xFFFFFFFF.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +NvmePassThruGetNextNameSpace (
> +  IN     EDKII_PEI_NVM_EXPRESS_PASS_THRU_PPI   *This,
> +  IN OUT UINT32                                *NamespaceId
> +  );
> +
> +/**
> +  Sends an NVM Express Command Packet to an NVM Express controller or
> namespace. This function only
> +  supports blocking execution of the command.
> +
> +  @param[in] This                  The PPI instance pointer.
> +  @param[in] NamespaceId           Is a 32 bit Namespace ID to which the Nvm
> Express command packet will
> +                                   be sent.
> +                                   A Value of 0 denotes the NVM Express controller, a Value
> of all 0FFh in
> +                                   the namespace ID specifies that the command packet
> should be sent to all
> +                                   valid namespaces.
> +  @param[in,out] Packet            A pointer to the EDKII PEI NVM Express
> PassThru Command Packet to send
> +                                   to the NVMe namespace specified by NamespaceId.
> +
> +  @retval EFI_SUCCESS              The EDKII PEI NVM Express Command Packet
> was sent by the host.
> +                                   TransferLength bytes were transferred to, or from
> DataBuffer.
> +  @retval EFI_NOT_READY            The EDKII PEI NVM Express Command
> Packet could not be sent because
> +                                   the controller is not ready. The caller may retry again later.
> +  @retval EFI_DEVICE_ERROR         A device error occurred while attempting
> to send the EDKII PEI NVM
> +                                   Express Command Packet.
> +  @retval EFI_INVALID_PARAMETER    Namespace, or the contents of
> EDKII_PEI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET
> +                                   are invalid.
> +                                   The EDKII PEI NVM Express Command Packet was not sent,
> so no
> +                                   additional status information is available.
> +  @retval EFI_UNSUPPORTED          The command described by the EDKII PEI
> NVM Express Command Packet
> +                                   is not supported by the host adapter.
> +                                   The EDKII PEI NVM Express Command Packet was not sent,
> so no
> +                                   additional status information is available.
> +  @retval EFI_TIMEOUT              A timeout occurred while waiting for the
> EDKII PEI NVM Express Command
> +                                   Packet to execute.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +NvmePassThru (
> +  IN     EDKII_PEI_NVM_EXPRESS_PASS_THRU_PPI               *This,
> +  IN     UINT32                                            NamespaceId,
> +  IN OUT EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET          *Packet
>    );
> 
>  #endif
> diff --git
> a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiStorageSecurity.
> c
> b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiStorageSecurity.
> c
> index dda69988b1..094d61bb8a 100644
> ---
> a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiStorageSecurity.
> c
> +++
> b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiStorageSecurity.
> c
> @@ -57,15 +57,17 @@ TrustTransferNvmeDevice (
>       OUT UINTN                               *TransferLengthOut
>    )
>  {
> -  EDKII_PEI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET
> CommandPacket;
> -  EDKII_PEI_NVM_EXPRESS_COMMAND                     Command;
> -  EDKII_PEI_NVM_EXPRESS_COMPLETION                  Completion;
> +  EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET
> CommandPacket;
> +  EFI_NVM_EXPRESS_COMMAND                           Command;
> +  EFI_NVM_EXPRESS_COMPLETION                        Completion;
>    EFI_STATUS                                        Status;
>    UINT16                                            SpecificData;
> +  EDKII_PEI_NVM_EXPRESS_PASS_THRU_PPI               *NvmePassThru;
> 
> -  ZeroMem (&CommandPacket,
> sizeof(EDKII_PEI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET));
> -  ZeroMem (&Command, sizeof(EDKII_PEI_NVM_EXPRESS_COMMAND));
> -  ZeroMem (&Completion, sizeof(EDKII_PEI_NVM_EXPRESS_COMPLETION));
> +  NvmePassThru = &Private->NvmePassThruPpi;
> +  ZeroMem (&CommandPacket,
> sizeof(EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET));
> +  ZeroMem (&Command, sizeof(EFI_NVM_EXPRESS_COMMAND));
> +  ZeroMem (&Completion, sizeof(EFI_NVM_EXPRESS_COMPLETION));
> 
>    CommandPacket.NvmeCmd        = &Command;
>    CommandPacket.NvmeCompletion = &Completion;
> @@ -94,11 +96,11 @@ TrustTransferNvmeDevice (
>    CommandPacket.CommandTimeout = Timeout;
>    CommandPacket.QueueType      = NVME_ADMIN_QUEUE;
> 
> -  Status = NvmePassThru (
> -             Private,
> -             NVME_CONTROLLER_NSID,
> -             &CommandPacket
> -             );
> +  Status = NvmePassThru->PassThru (
> +                           NvmePassThru,
> +                           NVME_CONTROLLER_NSID,
> +                           &CommandPacket
> +                           );


Reviewed-by: Hao A Wu <hao.a.wu@intel.com>

Best Regards,
Hao Wu


> 
>    if (!IsTrustSend) {
>      if (EFI_ERROR (Status))  {
> --
> 2.16.2.windows.1
> 
> 
> 


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [edk2-devel] [PATCH] MdeModulePkg/NvmExpressPei: Produce NVM Express PassThru PPI
  2019-06-18 12:34 ` [edk2-devel] " Wu, Hao A
@ 2019-06-24  1:10   ` Wu, Hao A
  0 siblings, 0 replies; 3+ messages in thread
From: Wu, Hao A @ 2019-06-24  1:10 UTC (permalink / raw)
  To: devel@edk2.groups.io, Wu, Hao A, Chu, Maggie
  Cc: Wang, Jian J, Ni, Ray, Zeng, Star

> -----Original Message-----
> From: devel@edk2.groups.io [mailto:devel@edk2.groups.io] On Behalf Of
> Wu, Hao A
> Sent: Tuesday, June 18, 2019 8:34 PM
> To: devel@edk2.groups.io; Chu, Maggie
> Cc: Wang, Jian J; Ni, Ray; Zeng, Star
> Subject: Re: [edk2-devel] [PATCH] MdeModulePkg/NvmExpressPei: Produce
> NVM Express PassThru PPI
> 
> > -----Original Message-----
> > From: devel@edk2.groups.io [mailto:devel@edk2.groups.io] On Behalf Of
> > Maggie Chu
> > Sent: Monday, June 17, 2019 10:11 AM
> > To: devel@edk2.groups.io
> > Cc: Wu, Hao A; Wang, Jian J; Ni, Ray; Zeng, Star
> > Subject: [edk2-devel] [PATCH] MdeModulePkg/NvmExpressPei: Produce
> > NVM Express PassThru PPI
> >
> > https://bugzilla.tianocore.org/show_bug.cgi?id=1879
> > This commit will add codes to produce the NVM Express PassThru PPI.
> >
> > Signed-off-by: Maggie Chu <maggie.chu@intel.com>
> > Cc: Hao A Wu <hao.a.wu@intel.com>
> > Cc: Jian J Wang <jian.j.wang@intel.com>
> > Cc: Ray Ni <ray.ni@intel.com>
> > Cc: Star Zeng <star.zeng@intel.com>
> > ---
> >  MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.c |  26 +++
> >  MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.h |   8 +
> >  .../Bus/Pci/NvmExpressPei/NvmExpressPei.inf        |   1 +
> >  .../Bus/Pci/NvmExpressPei/NvmExpressPeiBlockIo.c   |  27 +--
> >  .../Bus/Pci/NvmExpressPei/NvmExpressPeiHci.c       |  74 ++++---
> >  .../Bus/Pci/NvmExpressPei/NvmExpressPeiPassThru.c  | 218
> > ++++++++++++++++++++-
> >  .../Bus/Pci/NvmExpressPei/NvmExpressPeiPassThru.h  | 159
> ++++++++++----
> > -
> >  .../NvmExpressPei/NvmExpressPeiStorageSecurity.c   |  24 +--
> >  8 files changed, 420 insertions(+), 117 deletions(-)
> >
> > diff --git a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.c
> > b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.c
> > index 0e79b29f82..987eed420e 100644
> > --- a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.c
> > +++ b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.c
> > @@ -28,6 +28,12 @@ EFI_PEI_PPI_DESCRIPTOR
> > mNvmeStorageSecurityPpiListTemplate = {
> >    NULL
> >  };
> >
> > +EFI_PEI_PPI_DESCRIPTOR  mNvmePassThruPpiListTemplate = {
> > +  (EFI_PEI_PPI_DESCRIPTOR_PPI |
> > EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
> > +  &gEdkiiPeiNvmExpressPassThruPpiGuid,
> > +  NULL
> > +};
> > +
> >  EFI_PEI_NOTIFY_DESCRIPTOR  mNvmeEndOfPeiNotifyListTemplate = {
> >    (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK |
> > EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
> >    &gEfiEndOfPeiSignalPpiGuid,
> > @@ -392,6 +398,26 @@ NvmExpressPeimEntry (
> >      Private->BlkIo2PpiList.Ppi                 = &Private->BlkIo2Ppi;
> >      PeiServicesInstallPpi (&Private->BlkIoPpiList);
> >
> > +    //
> > +    // Nvm Express Pass Thru PPI
> > +    //
> > +    Private->PassThruMode.Attributes            =
> > EFI_NVM_EXPRESS_PASS_THRU_ATTRIBUTES_PHYSICAL |
> > +
> > EFI_NVM_EXPRESS_PASS_THRU_ATTRIBUTES_LOGICAL |
> > +
> > EFI_NVM_EXPRESS_PASS_THRU_ATTRIBUTES_CMD_SET_NVM;
> > +    Private->PassThruMode.IoAlign               = sizeof (UINTN);
> > +    Private->PassThruMode.NvmeVersion           =
> > EDKII_PEI_NVM_EXPRESS_PASS_THRU_PPI_REVISION;
> > +    Private->NvmePassThruPpi.Mode               = &Private->PassThruMode;
> > +    Private->NvmePassThruPpi.GetDevicePath      =
> > NvmePassThruGetDevicePath;
> > +    Private->NvmePassThruPpi.GetNextNameSpace   =
> > NvmePassThruGetNextNameSpace;
> > +    Private->NvmePassThruPpi.PassThru           = NvmePassThru;
> > +    CopyMem (
> > +      &Private->NvmePassThruPpiList,
> > +      &mNvmePassThruPpiListTemplate,
> > +      sizeof (EFI_PEI_PPI_DESCRIPTOR)
> > +      );
> > +    Private->NvmePassThruPpiList.Ppi            = &Private->NvmePassThruPpi;
> > +    PeiServicesInstallPpi (&Private->NvmePassThruPpiList);
> > +
> >      //
> >      // Check if the NVME controller supports the Security Receive/Send
> > commands
> >      //
> > diff --git a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.h
> > b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.h
> > index 6b2e2f0326..8cd905191b 100644
> > --- a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.h
> > +++ b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.h
> > @@ -19,6 +19,7 @@
> >  #include <Ppi/BlockIo.h>
> >  #include <Ppi/BlockIo2.h>
> >  #include <Ppi/StorageSecurityCommand.h>
> > +#include <Ppi/NvmExpressPassThru.h>
> >  #include <Ppi/IoMmu.h>
> >  #include <Ppi/EndOfPeiPhase.h>
> >
> > @@ -74,6 +75,8 @@ struct _PEI_NVME_NAMESPACE_INFO {
> >    PEI_NVME_CONTROLLER_PRIVATE_DATA          *Controller;
> >  };
> >
> > +#define NVME_CONTROLLER_NSID        0
> > +
> >  //
> >  // Unique signature for private data structure.
> >  //
> > @@ -85,15 +88,18 @@ struct _PEI_NVME_NAMESPACE_INFO {
> >  struct _PEI_NVME_CONTROLLER_PRIVATE_DATA {
> >    UINT32                                    Signature;
> >    UINTN                                     MmioBase;
> > +  EFI_NVM_EXPRESS_PASS_THRU_MODE            PassThruMode;
> >    UINTN                                     DevicePathLength;
> >    EFI_DEVICE_PATH_PROTOCOL                  *DevicePath;
> >
> >    EFI_PEI_RECOVERY_BLOCK_IO_PPI             BlkIoPpi;
> >    EFI_PEI_RECOVERY_BLOCK_IO2_PPI            BlkIo2Ppi;
> >    EDKII_PEI_STORAGE_SECURITY_CMD_PPI        StorageSecurityPpi;
> > +  EDKII_PEI_NVM_EXPRESS_PASS_THRU_PPI       NvmePassThruPpi;
> >    EFI_PEI_PPI_DESCRIPTOR                    BlkIoPpiList;
> >    EFI_PEI_PPI_DESCRIPTOR                    BlkIo2PpiList;
> >    EFI_PEI_PPI_DESCRIPTOR                    StorageSecurityPpiList;
> > +  EFI_PEI_PPI_DESCRIPTOR                    NvmePassThruPpiList;
> >    EFI_PEI_NOTIFY_DESCRIPTOR                 EndOfPeiNotifyList;
> >
> >    //
> > @@ -145,6 +151,8 @@ struct _PEI_NVME_CONTROLLER_PRIVATE_DATA {
> >    CR (a, PEI_NVME_CONTROLLER_PRIVATE_DATA, BlkIo2Ppi,
> > NVME_PEI_CONTROLLER_PRIVATE_DATA_SIGNATURE)
> >  #define
> >
> GET_NVME_PEIM_HC_PRIVATE_DATA_FROM_THIS_STROAGE_SECURITY(a)
> > \
> >    CR (a, PEI_NVME_CONTROLLER_PRIVATE_DATA, StorageSecurityPpi,
> > NVME_PEI_CONTROLLER_PRIVATE_DATA_SIGNATURE)
> > +#define
> > GET_NVME_PEIM_HC_PRIVATE_DATA_FROM_THIS_NVME_PASSTHRU(a)
> \
> > +  CR (a, PEI_NVME_CONTROLLER_PRIVATE_DATA, NvmePassThruPpi,
> > NVME_PEI_CONTROLLER_PRIVATE_DATA_SIGNATURE)
> >  #define GET_NVME_PEIM_HC_PRIVATE_DATA_FROM_THIS_NOTIFY(a)
> > \
> >    CR (a, PEI_NVME_CONTROLLER_PRIVATE_DATA, EndOfPeiNotifyList,
> > NVME_PEI_CONTROLLER_PRIVATE_DATA_SIGNATURE)
> >
> > diff --git a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.inf
> > b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.inf
> > index a8e4808e6b..4dd6c5704f 100644
> > --- a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.inf
> > +++ b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.inf
> > @@ -56,6 +56,7 @@
> >    gEdkiiPeiNvmExpressHostControllerPpiGuid       ## CONSUMES
> >    gEdkiiIoMmuPpiGuid                             ## CONSUMES
> >    gEfiEndOfPeiSignalPpiGuid                      ## CONSUMES
> > +  gEdkiiPeiNvmExpressPassThruPpiGuid             ## SOMETIMES_PRODUCES
> >    gEfiPeiVirtualBlockIoPpiGuid                   ## SOMETIMES_PRODUCES
> >    gEfiPeiVirtualBlockIo2PpiGuid                  ## SOMETIMES_PRODUCES
> >    gEdkiiPeiStorageSecurityCommandPpiGuid         ##
> SOMETIMES_PRODUCES
> > diff --git
> > a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiBlockIo.c
> > b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiBlockIo.c
> > index 94cdd05f33..a9bf4f8190 100644
> > --- a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiBlockIo.c
> > +++ b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiBlockIo.c
> > @@ -2,7 +2,7 @@
> >    The NvmExpressPei driver is used to manage non-volatile memory
> > subsystem
> >    which follows NVM Express specification at PEI phase.
> >
> > -  Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
> > +  Copyright (c) 2018 - 2019, Intel Corporation. All rights reserved.<BR>
> >
> >    SPDX-License-Identifier: BSD-2-Clause-Patent
> >
> > @@ -34,17 +34,19 @@ ReadSectors (
> >    UINT32                                            BlockSize;
> >    PEI_NVME_CONTROLLER_PRIVATE_DATA                  *Private;
> >    UINT32                                            Bytes;
> > -  EDKII_PEI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET
> > CommandPacket;
> > -  EDKII_PEI_NVM_EXPRESS_COMMAND                     Command;
> > -  EDKII_PEI_NVM_EXPRESS_COMPLETION                  Completion;
> > +  EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET
> > CommandPacket;
> > +  EFI_NVM_EXPRESS_COMMAND                           Command;
> > +  EFI_NVM_EXPRESS_COMPLETION                        Completion;
> > +  EDKII_PEI_NVM_EXPRESS_PASS_THRU_PPI               *NvmePassThru;
> >
> >    Private   = NamespaceInfo->Controller;
> > +  NvmePassThru = &Private->NvmePassThruPpi;
> >    BlockSize = NamespaceInfo->Media.BlockSize;
> >    Bytes     = Blocks * BlockSize;
> >
> > -  ZeroMem (&CommandPacket,
> > sizeof(EDKII_PEI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET));
> > -  ZeroMem (&Command, sizeof(EDKII_PEI_NVM_EXPRESS_COMMAND));
> > -  ZeroMem (&Completion,
> sizeof(EDKII_PEI_NVM_EXPRESS_COMPLETION));
> > +  ZeroMem (&CommandPacket,
> > sizeof(EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET));
> > +  ZeroMem (&Command, sizeof(EFI_NVM_EXPRESS_COMMAND));
> > +  ZeroMem (&Completion, sizeof(EFI_NVM_EXPRESS_COMPLETION));
> >
> >    CommandPacket.NvmeCmd        = &Command;
> >    CommandPacket.NvmeCompletion = &Completion;
> > @@ -63,11 +65,12 @@ ReadSectors (
> >
> >    CommandPacket.NvmeCmd->Flags = CDW10_VALID | CDW11_VALID |
> > CDW12_VALID;
> >
> > -  Status = NvmePassThru (
> > -             Private,
> > -             NamespaceInfo->NamespaceId,
> > -             &CommandPacket
> > -             );
> > +  Status = NvmePassThru->PassThru (
> > +                           NvmePassThru,
> > +                           NamespaceInfo->NamespaceId,
> > +                           &CommandPacket
> > +                           );
> > +
> >    return Status;
> >  }
> >
> > diff --git a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiHci.c
> > b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiHci.c
> > index c290f5b56f..1d7e3d26e0 100644
> > --- a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiHci.c
> > +++ b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiHci.c
> > @@ -320,14 +320,14 @@ NvmeIdentifyController (
> >    IN VOID                                *Buffer
> >    )
> >  {
> > -  EDKII_PEI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET
> > CommandPacket;
> > -  EDKII_PEI_NVM_EXPRESS_COMMAND                     Command;
> > -  EDKII_PEI_NVM_EXPRESS_COMPLETION                  Completion;
> > -  EFI_STATUS                                        Status;
> > +  EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET
> CommandPacket;
> > +  EFI_NVM_EXPRESS_COMMAND                     Command;
> > +  EFI_NVM_EXPRESS_COMPLETION                  Completion;
> > +  EFI_STATUS                                  Status;
> >
> > -  ZeroMem (&CommandPacket,
> > sizeof(EDKII_PEI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET));
> > -  ZeroMem (&Command, sizeof(EDKII_PEI_NVM_EXPRESS_COMMAND));
> > -  ZeroMem (&Completion,
> sizeof(EDKII_PEI_NVM_EXPRESS_COMPLETION));
> > +  ZeroMem (&CommandPacket,
> > sizeof(EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET));
> > +  ZeroMem (&Command, sizeof(EFI_NVM_EXPRESS_COMMAND));
> > +  ZeroMem (&Completion, sizeof(EFI_NVM_EXPRESS_COMPLETION));
> >
> >    Command.Cdw0.Opcode = NVME_ADMIN_IDENTIFY_CMD;
> >    //
> > @@ -348,7 +348,7 @@ NvmeIdentifyController (
> >    CommandPacket.NvmeCmd->Cdw10 = 1;
> >    CommandPacket.NvmeCmd->Flags = CDW10_VALID;
> >
> > -  Status = NvmePassThru (
> > +  Status = NvmePassThruExecute (
> >               Private,
> >               NVME_CONTROLLER_NSID,
> >               &CommandPacket
> > @@ -374,14 +374,14 @@ NvmeIdentifyNamespace (
> >    IN VOID                                *Buffer
> >    )
> >  {
> > -  EDKII_PEI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET
> > CommandPacket;
> > -  EDKII_PEI_NVM_EXPRESS_COMMAND                     Command;
> > -  EDKII_PEI_NVM_EXPRESS_COMPLETION                  Completion;
> > -  EFI_STATUS                                        Status;
> > +  EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET
> CommandPacket;
> > +  EFI_NVM_EXPRESS_COMMAND                     Command;
> > +  EFI_NVM_EXPRESS_COMPLETION                  Completion;
> > +  EFI_STATUS                                  Status;
> >
> > -  ZeroMem (&CommandPacket,
> > sizeof(EDKII_PEI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET));
> > -  ZeroMem (&Command, sizeof(EDKII_PEI_NVM_EXPRESS_COMMAND));
> > -  ZeroMem (&Completion,
> sizeof(EDKII_PEI_NVM_EXPRESS_COMPLETION));
> > +  ZeroMem (&CommandPacket,
> > sizeof(EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET));
> > +  ZeroMem (&Command, sizeof(EFI_NVM_EXPRESS_COMMAND));
> > +  ZeroMem (&Completion, sizeof(EFI_NVM_EXPRESS_COMPLETION));
> >
> >    Command.Cdw0.Opcode = NVME_ADMIN_IDENTIFY_CMD;
> >    Command.Nsid        = NamespaceId;
> > @@ -398,7 +398,7 @@ NvmeIdentifyNamespace (
> >    CommandPacket.NvmeCmd->Cdw10 = 0;
> >    CommandPacket.NvmeCmd->Flags = CDW10_VALID;
> >
> > -  Status = NvmePassThru (
> > +  Status = NvmePassThruExecute (
> >               Private,
> >               NamespaceId,
> >               &CommandPacket
> > @@ -454,22 +454,21 @@ NvmeCreateIoCompletionQueue (
> >    IN PEI_NVME_CONTROLLER_PRIVATE_DATA    *Private
> >    )
> >  {
> > -  EDKII_PEI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET
> > CommandPacket;
> > -  EDKII_PEI_NVM_EXPRESS_COMMAND                     Command;
> > -  EDKII_PEI_NVM_EXPRESS_COMPLETION                  Completion;
> > -  EFI_STATUS                                        Status;
> > -  NVME_ADMIN_CRIOCQ                                 CrIoCq;
> > -
> > -  ZeroMem (&CommandPacket,
> > sizeof(EDKII_PEI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET));
> > -  ZeroMem (&Command, sizeof(EDKII_PEI_NVM_EXPRESS_COMMAND));
> > -  ZeroMem (&Completion,
> sizeof(EDKII_PEI_NVM_EXPRESS_COMPLETION));
> > +  EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET
> CommandPacket;
> > +  EFI_NVM_EXPRESS_COMMAND                     Command;
> > +  EFI_NVM_EXPRESS_COMPLETION                  Completion;
> > +  EFI_STATUS                                  Status;
> > +  NVME_ADMIN_CRIOCQ                           CrIoCq;
> > +
> > +  ZeroMem (&CommandPacket,
> > sizeof(EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET));
> > +  ZeroMem (&Command, sizeof(EFI_NVM_EXPRESS_COMMAND));
> > +  ZeroMem (&Completion, sizeof(EFI_NVM_EXPRESS_COMPLETION));
> >    ZeroMem (&CrIoCq, sizeof(NVME_ADMIN_CRIOCQ));
> >
> >    CommandPacket.NvmeCmd        = &Command;
> >    CommandPacket.NvmeCompletion = &Completion;
> >
> >    Command.Cdw0.Opcode = NVME_ADMIN_CRIOCQ_CMD;
> > -  Command.Cdw0.Cid    = Private->Cid[NVME_ADMIN_QUEUE]++;
> >    CommandPacket.TransferBuffer = Private->CqBuffer[NVME_IO_QUEUE];
> >    CommandPacket.TransferLength = EFI_PAGE_SIZE;
> >    CommandPacket.CommandTimeout = NVME_GENERIC_TIMEOUT;
> > @@ -481,7 +480,7 @@ NvmeCreateIoCompletionQueue (
> >    CopyMem (&CommandPacket.NvmeCmd->Cdw10, &CrIoCq, sizeof
> > (NVME_ADMIN_CRIOCQ));
> >    CommandPacket.NvmeCmd->Flags = CDW10_VALID | CDW11_VALID;
> >
> > -  Status = NvmePassThru (
> > +  Status = NvmePassThruExecute (
> >               Private,
> >               NVME_CONTROLLER_NSID,
> >               &CommandPacket
> > @@ -503,22 +502,21 @@ NvmeCreateIoSubmissionQueue (
> >    IN PEI_NVME_CONTROLLER_PRIVATE_DATA    *Private
> >    )
> >  {
> > -  EDKII_PEI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET
> > CommandPacket;
> > -  EDKII_PEI_NVM_EXPRESS_COMMAND                     Command;
> > -  EDKII_PEI_NVM_EXPRESS_COMPLETION                  Completion;
> > -  EFI_STATUS                                        Status;
> > -  NVME_ADMIN_CRIOSQ                                 CrIoSq;
> > -
> > -  ZeroMem (&CommandPacket,
> > sizeof(EDKII_PEI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET));
> > -  ZeroMem (&Command, sizeof(EDKII_PEI_NVM_EXPRESS_COMMAND));
> > -  ZeroMem (&Completion,
> sizeof(EDKII_PEI_NVM_EXPRESS_COMPLETION));
> > +  EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET
> CommandPacket;
> > +  EFI_NVM_EXPRESS_COMMAND                     Command;
> > +  EFI_NVM_EXPRESS_COMPLETION                  Completion;
> > +  EFI_STATUS                                  Status;
> > +  NVME_ADMIN_CRIOSQ                           CrIoSq;
> > +
> > +  ZeroMem (&CommandPacket,
> > sizeof(EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET));
> > +  ZeroMem (&Command, sizeof(EFI_NVM_EXPRESS_COMMAND));
> > +  ZeroMem (&Completion, sizeof(EFI_NVM_EXPRESS_COMPLETION));
> >    ZeroMem (&CrIoSq, sizeof(NVME_ADMIN_CRIOSQ));
> >
> >    CommandPacket.NvmeCmd        = &Command;
> >    CommandPacket.NvmeCompletion = &Completion;
> >
> >    Command.Cdw0.Opcode = NVME_ADMIN_CRIOSQ_CMD;
> > -  Command.Cdw0.Cid    = Private->Cid[NVME_ADMIN_QUEUE]++;
> >    CommandPacket.TransferBuffer = Private->SqBuffer[NVME_IO_QUEUE];
> >    CommandPacket.TransferLength = EFI_PAGE_SIZE;
> >    CommandPacket.CommandTimeout = NVME_GENERIC_TIMEOUT;
> > @@ -532,7 +530,7 @@ NvmeCreateIoSubmissionQueue (
> >    CopyMem (&CommandPacket.NvmeCmd->Cdw10, &CrIoSq, sizeof
> > (NVME_ADMIN_CRIOSQ));
> >    CommandPacket.NvmeCmd->Flags = CDW10_VALID | CDW11_VALID;
> >
> > -  Status = NvmePassThru (
> > +  Status = NvmePassThruExecute (
> >               Private,
> >               NVME_CONTROLLER_NSID,
> >               &CommandPacket
> > diff --git
> > a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiPassThru.c
> > b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiPassThru.c
> > index a33f5a872e..370a54e5a2 100644
> > --- a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiPassThru.c
> > +++ b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiPassThru.c
> > @@ -2,7 +2,7 @@
> >    The NvmExpressPei driver is used to manage non-volatile memory
> > subsystem
> >    which follows NVM Express specification at PEI phase.
> >
> > -  Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
> > +  Copyright (c) 2018 - 2019, Intel Corporation. All rights reserved.<BR>
> >
> >    SPDX-License-Identifier: BSD-2-Clause-Patent
> >
> > @@ -332,10 +332,10 @@ NvmeCheckCqStatus (
> >
> >  **/
> >  EFI_STATUS
> > -NvmePassThru (
> > +NvmePassThruExecute (
> >    IN     PEI_NVME_CONTROLLER_PRIVATE_DATA                  *Private,
> >    IN     UINT32                                            NamespaceId,
> > -  IN OUT EDKII_PEI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET
> > *Packet
> > +  IN OUT EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET
> *Packet
> >    )
> >  {
> >    EFI_STATUS               Status;
> > @@ -411,9 +411,9 @@ NvmePassThru (
> >    }
> >
> >    ZeroMem (Sq, sizeof (NVME_SQ));
> > -  Sq->Opc  = Packet->NvmeCmd->Cdw0.Opcode;
> > -  Sq->Fuse = Packet->NvmeCmd->Cdw0.FusedOperation;
> > -  Sq->Cid  = Packet->NvmeCmd->Cdw0.Cid;
> > +  Sq->Opc  = (UINT8)Packet->NvmeCmd->Cdw0.Opcode;
> > +  Sq->Fuse = (UINT8)Packet->NvmeCmd->Cdw0.FusedOperation;
> > +  Sq->Cid  = Private->Cid[QueueId]++;;
> >    Sq->Nsid = Packet->NvmeCmd->Nsid;
> >
> >    //
> > @@ -603,7 +603,7 @@ NvmePassThru (
> >    //
> >    // Copy the Respose Queue entry for this command to the callers
> response
> > buffer
> >    //
> > -  CopyMem (Packet->NvmeCompletion, Cq, sizeof
> > (EDKII_PEI_NVM_EXPRESS_COMPLETION));
> > +  CopyMem (Packet->NvmeCompletion, Cq, sizeof
> > (EFI_NVM_EXPRESS_COMPLETION));
> >
> >    //
> >    // Check the NVMe cmd execution result
> > @@ -622,3 +622,207 @@ Exit:
> >
> >    return Status;
> >  }
> > +
> > +/**
> > +  Gets the device path information of the underlying NVM Express host
> > controller.
> > +
> > +  @param[in]  This                 The PPI instance pointer.
> > +  @param[out] DevicePathLength     The length of the device path in bytes
> > specified
> > +                                   by DevicePath.
> > +  @param[out] DevicePath           The device path of the underlying NVM
> > Express
> > +                                   host controller.
> > +                                   This field re-uses EFI Device Path Protocol as
> > +                                   defined by Section 10.2 EFI Device Path Protocol
> > +                                   of UEFI 2.7 Specification.
> > +
> > +  @retval EFI_SUCCESS              The operation succeeds.
> > +  @retval EFI_INVALID_PARAMETER    DevicePathLength or DevicePath is
> > NULL.
> > +  @retval EFI_OUT_OF_RESOURCES     The operation fails due to lack of
> > resources.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +NvmePassThruGetDevicePath (
> > +  IN  EDKII_PEI_NVM_EXPRESS_PASS_THRU_PPI    *This,
> > +  OUT UINTN                                  *DevicePathLength,
> > +  OUT EFI_DEVICE_PATH_PROTOCOL               **DevicePath
> > +  )
> > +{
> > +  PEI_NVME_CONTROLLER_PRIVATE_DATA         *Private;
> > +
> > +  if (This == NULL || DevicePathLength == NULL || DevicePath == NULL) {
> > +    return EFI_INVALID_PARAMETER;
> > +  }
> > +
> > +  Private =
> > GET_NVME_PEIM_HC_PRIVATE_DATA_FROM_THIS_NVME_PASSTHRU
> (This);
> > +
> > +  *DevicePathLength = Private->DevicePathLength;
> > +  *DevicePath       = AllocateCopyPool (Private->DevicePathLength,
> Private-
> > >DevicePath);
> > +  if (*DevicePath == NULL) {
> > +    *DevicePathLength = 0;
> > +    return EFI_OUT_OF_RESOURCES;
> > +  }
> > +
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +/**
> > +  Used to retrieve the next namespace ID for this NVM Express controller.
> > +
> > +  If on input the value pointed to by NamespaceId is 0xFFFFFFFF, then the
> > first
> > +  valid namespace ID defined on the NVM Express controller is returned in
> > the
> > +  location pointed to by NamespaceId and a status of EFI_SUCCESS is
> > returned.
> > +
> > +  If on input the value pointed to by NamespaceId is an invalid namespace
> > ID
> > +  other than 0xFFFFFFFF, then EFI_INVALID_PARAMETER is returned.
> > +
> > +  If on input the value pointed to by NamespaceId is a valid namespace ID,
> > then
> > +  the next valid namespace ID on the NVM Express controller is returned
> in
> > the
> > +  location pointed to by NamespaceId, and EFI_SUCCESS is returned.
> > +
> > +  If the value pointed to by NamespaceId is the namespace ID of the last
> > +  namespace on the NVM Express controller, then EFI_NOT_FOUND is
> > returned.
> > +
> > +  @param[in]     This              The PPI instance pointer.
> > +  @param[in,out] NamespaceId       On input, a pointer to a legal
> > NamespaceId
> > +                                   for an NVM Express namespace present on the
> > +                                   NVM Express controller. On output, a pointer
> > +                                   to the next NamespaceId of an NVM Express
> > +                                   namespace on an NVM Express controller. An
> > +                                   input value of 0xFFFFFFFF retrieves the
> > +                                   first NamespaceId for an NVM Express
> > +                                   namespace present on an NVM Express
> > +                                   controller.
> > +
> > +  @retval EFI_SUCCESS            The Namespace ID of the next Namespace
> was
> > +                                 returned.
> > +  @retval EFI_NOT_FOUND          There are no more namespaces defined
> on
> > this
> > +                                 controller.
> > +  @retval EFI_INVALID_PARAMETER  NamespaceId is an invalid value
> other
> > than
> > +                                 0xFFFFFFFF.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +NvmePassThruGetNextNameSpace (
> > +  IN     EDKII_PEI_NVM_EXPRESS_PASS_THRU_PPI   *This,
> > +  IN OUT UINT32                                *NamespaceId
> > +  )
> > +{
> > +  PEI_NVME_CONTROLLER_PRIVATE_DATA         *Private;
> > +  UINT32                                   DeviceIndex;
> > +  EFI_STATUS                               Status;
> > +
> > +  if (This == NULL || NamespaceId == NULL) {
> > +    return EFI_INVALID_PARAMETER;
> > +  }
> > +
> > +  Private =
> > GET_NVME_PEIM_HC_PRIVATE_DATA_FROM_THIS_NVME_PASSTHRU
> (This);
> > +
> > +  Status = EFI_NOT_FOUND;
> > +
> > +  //
> > +  // If active namespace number is 0, then valid namespace ID is
> > unavailable
> > +  //
> > +  if (Private->ActiveNamespaceNum == 0) {
> > +    return EFI_NOT_FOUND;
> > +  }
> > +
> > +  //
> > +  // If the NamespaceId input value is 0xFFFFFFFF, then get the first valid
> > namespace ID
> > +  //
> > +  if (*NamespaceId == 0xFFFFFFFF) {
> > +    //
> > +    // Start with the first namespace ID
> > +    //
> > +    *NamespaceId = Private->NamespaceInfo[0].NamespaceId;
> > +    Status = EFI_SUCCESS;
> > +  } else {
> > +    if (*NamespaceId > Private->ControllerData->Nn) {
> > +      return EFI_INVALID_PARAMETER;
> > +    }
> > +
> > +    if ((*NamespaceId + 1) > Private->ControllerData->Nn) {
> > +      return EFI_NOT_FOUND;
> > +    }
> > +
> > +    for (DeviceIndex = 0; DeviceIndex < Private->ActiveNamespaceNum;
> > DeviceIndex++) {
> > +      if (*NamespaceId == Private-
> > >NamespaceInfo[DeviceIndex].NamespaceId) {
> > +        if ((DeviceIndex + 1) < Private->ActiveNamespaceNum) {
> > +          *NamespaceId = Private->NamespaceInfo[DeviceIndex +
> > 1].NamespaceId;
> > +          Status = EFI_SUCCESS;
> > +        }
> > +        break;
> > +      }
> > +    }
> > +  }
> > +
> > +  return Status;
> > +
> > +}
> > +
> > +/**
> > +  Sends an NVM Express Command Packet to an NVM Express controller
> or
> > namespace. This function only
> > +  supports blocking execution of the command.
> > +
> > +  @param[in]  This                 The PPI instance pointer.
> > +  @param[in] NamespaceId           Is a 32 bit Namespace ID to which the
> Nvm
> > Express command packet will
> > +                                   be sent.
> > +                                   A Value of 0 denotes the NVM Express controller, a
> Value
> > of all 0FFh in
> > +                                   the namespace ID specifies that the command packet
> > should be sent to all
> > +                                   valid namespaces.
> > +  @param[in,out] Packet            A pointer to the EDKII PEI NVM Express
> > PassThru Command Packet to send
> > +                                   to the NVMe namespace specified by NamespaceId.
> > +
> > +  @retval EFI_SUCCESS              The EDKII PEI NVM Express Command
> Packet
> > was sent by the host.
> > +                                   TransferLength bytes were transferred to, or from
> > DataBuffer.
> > +  @retval EFI_NOT_READY            The EDKII PEI NVM Express Command
> > Packet could not be sent because
> > +                                   the controller is not ready. The caller may retry again
> later.
> > +  @retval EFI_DEVICE_ERROR         A device error occurred while
> attempting
> > to send the EDKII PEI NVM
> > +                                   Express Command Packet.
> > +  @retval EFI_INVALID_PARAMETER    Namespace, or the contents of
> > EDKII_PEI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET
> > +                                   are invalid.
> > +                                   The EDKII PEI NVM Express Command Packet was not
> sent,
> > so no
> > +                                   additional status information is available.
> > +  @retval EFI_UNSUPPORTED          The command described by the EDKII
> PEI
> > NVM Express Command Packet
> > +                                   is not supported by the host adapter.
> > +                                   The EDKII PEI NVM Express Command Packet was not
> sent,
> > so no
> > +                                   additional status information is available.
> > +  @retval EFI_TIMEOUT              A timeout occurred while waiting for the
> > EDKII PEI NVM Express Command
> > +                                   Packet to execute.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +NvmePassThru (
> > +  IN     EDKII_PEI_NVM_EXPRESS_PASS_THRU_PPI               *This,
> > +  IN     UINT32                                            NamespaceId,
> > +  IN OUT EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET
> *Packet
> > +  )
> > +{
> > +  PEI_NVME_CONTROLLER_PRIVATE_DATA         *Private;
> > +  EFI_STATUS Status;
> > +
> > +  if (This == NULL || Packet == NULL) {
> > +    return EFI_INVALID_PARAMETER;
> > +  }
> > +
> > +  Private =
> > GET_NVME_PEIM_HC_PRIVATE_DATA_FROM_THIS_NVME_PASSTHRU
> (This);
> > +  //
> > +  // Check NamespaceId is valid or not.
> > +  //
> > +  if ((NamespaceId > Private->ControllerData->Nn) &&
> > +      (NamespaceId != (UINT32) -1)) {
> > +    return EFI_INVALID_PARAMETER;
> > +  }
> > +
> > +  Status = NvmePassThruExecute (
> > +             Private,
> > +             NamespaceId,
> > +             Packet
> > +             );
> > +
> > +  return Status;
> > +
> > +}
> > +
> > diff --git
> > a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiPassThru.h
> > b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiPassThru.h
> > index 81066bbd54..00e8f0abda 100644
> > --- a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiPassThru.h
> > +++
> b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiPassThru.h
> > @@ -2,7 +2,7 @@
> >    The NvmExpressPei driver is used to manage non-volatile memory
> > subsystem
> >    which follows NVM Express specification at PEI phase.
> >
> > -  Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
> > +  Copyright (c) 2018 - 2019, Intel Corporation. All rights reserved.<BR>
> >
> >    SPDX-License-Identifier: BSD-2-Clause-Patent
> >
> > @@ -11,52 +11,6 @@
> >  #ifndef _NVM_EXPRESS_PEI_PASSTHRU_H_
> >  #define _NVM_EXPRESS_PEI_PASSTHRU_H_
> >
> > -#define NVME_CONTROLLER_NSID        0
> > -
> > -typedef struct {
> > -  UINT8                             Opcode;
> > -  UINT8                             FusedOperation;
> > -    #define NORMAL_CMD              0x00
> > -    #define FUSED_FIRST_CMD         0x01
> > -    #define FUSED_SECOND_CMD        0x02
> > -  UINT16                            Cid;
> > -} NVME_CDW0;
> > -
> > -typedef struct {
> > -  NVME_CDW0                         Cdw0;
> > -  UINT8                             Flags;
> > -    #define CDW10_VALID             0x01
> > -    #define CDW11_VALID             0x02
> > -    #define CDW12_VALID             0x04
> > -    #define CDW13_VALID             0x08
> > -    #define CDW14_VALID             0x10
> > -    #define CDW15_VALID             0x20
> > -  UINT32                            Nsid;
> > -  UINT32                            Cdw10;
> > -  UINT32                            Cdw11;
> > -  UINT32                            Cdw12;
> > -  UINT32                            Cdw13;
> > -  UINT32                            Cdw14;
> > -  UINT32                            Cdw15;
> > -} EDKII_PEI_NVM_EXPRESS_COMMAND;
> > -
> > -typedef struct {
> > -  UINT32                            Cdw0;
> > -  UINT32                            Cdw1;
> > -  UINT32                            Cdw2;
> > -  UINT32                            Cdw3;
> > -} EDKII_PEI_NVM_EXPRESS_COMPLETION;
> > -
> > -typedef struct {
> > -  UINT64                            CommandTimeout;
> > -  VOID                              *TransferBuffer;
> > -  UINT32                            TransferLength;
> > -  VOID                              *MetadataBuffer;
> > -  UINT32                            MetadataLength;
> > -  UINT8                             QueueType;
> > -  EDKII_PEI_NVM_EXPRESS_COMMAND     *NvmeCmd;
> > -  EDKII_PEI_NVM_EXPRESS_COMPLETION  *NvmeCompletion;
> > -} EDKII_PEI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET;
> >
> >
> >  /**
> > @@ -91,10 +45,117 @@ typedef struct {
> >
> >  **/
> >  EFI_STATUS
> > -NvmePassThru (
> > +NvmePassThruExecute (
> >    IN     PEI_NVME_CONTROLLER_PRIVATE_DATA                  *Private,
> >    IN     UINT32                                            NamespaceId,
> > -  IN OUT EDKII_PEI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET
> > *Packet
> > +  IN OUT EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET
> *Packet
> > +  );
> > +
> > +/**
> > +  Gets the device path information of the underlying NVM Express host
> > controller.
> > +
> > +  @param[in]  This                 The PPI instance pointer.
> > +  @param[out] DevicePathLength     The length of the device path in bytes
> > specified
> > +                                   by DevicePath.
> > +  @param[out] DevicePath           The device path of the underlying NVM
> > Express
> > +                                   host controller.
> > +                                   This field re-uses EFI Device Path Protocol as
> > +                                   defined by Section 10.2 EFI Device Path Protocol
> > +                                   of UEFI 2.7 Specification.
> > +
> > +  @retval EFI_SUCCESS              The operation succeeds.
> > +  @retval EFI_INVALID_PARAMETER    DevicePathLength or DevicePath is
> > NULL.
> > +  @retval EFI_OUT_OF_RESOURCES     The operation fails due to lack of
> > resources.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +NvmePassThruGetDevicePath (
> > +  IN  EDKII_PEI_NVM_EXPRESS_PASS_THRU_PPI *This,
> > +  OUT UINTN                               *DevicePathLength,
> > +  OUT EFI_DEVICE_PATH_PROTOCOL            **DevicePath
> > +  );
> > +
> > +/**
> > +  Used to retrieve the next namespace ID for this NVM Express controller.
> > +
> > +  If on input the value pointed to by NamespaceId is 0xFFFFFFFF, then the
> > first
> > +  valid namespace ID defined on the NVM Express controller is returned in
> > the
> > +  location pointed to by NamespaceId and a status of EFI_SUCCESS is
> > returned.
> > +
> > +  If on input the value pointed to by NamespaceId is an invalid namespace
> > ID
> > +  other than 0xFFFFFFFF, then EFI_INVALID_PARAMETER is returned.
> > +
> > +  If on input the value pointed to by NamespaceId is a valid namespace ID,
> > then
> > +  the next valid namespace ID on the NVM Express controller is returned
> in
> > the
> > +  location pointed to by NamespaceId, and EFI_SUCCESS is returned.
> > +
> > +  If the value pointed to by NamespaceId is the namespace ID of the last
> > +  namespace on the NVM Express controller, then EFI_NOT_FOUND is
> > returned.
> > +
> > +  @param[in]     This              The PPI instance pointer.
> > +  @param[in,out] NamespaceId       On input, a pointer to a legal
> > NamespaceId
> > +                                   for an NVM Express namespace present on the
> > +                                   NVM Express controller. On output, a pointer
> > +                                   to the next NamespaceId of an NVM Express
> > +                                   namespace on an NVM Express controller. An
> > +                                   input value of 0xFFFFFFFF retrieves the
> > +                                   first NamespaceId for an NVM Express
> > +                                   namespace present on an NVM Express
> > +                                   controller.
> > +
> > +  @retval EFI_SUCCESS            The Namespace ID of the next Namespace
> was
> > +                                 returned.
> > +  @retval EFI_NOT_FOUND          There are no more namespaces defined
> on
> > this
> > +                                 controller.
> > +  @retval EFI_INVALID_PARAMETER  NamespaceId is an invalid value
> other
> > than
> > +                                 0xFFFFFFFF.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +NvmePassThruGetNextNameSpace (
> > +  IN     EDKII_PEI_NVM_EXPRESS_PASS_THRU_PPI   *This,
> > +  IN OUT UINT32                                *NamespaceId
> > +  );
> > +
> > +/**
> > +  Sends an NVM Express Command Packet to an NVM Express controller
> or
> > namespace. This function only
> > +  supports blocking execution of the command.
> > +
> > +  @param[in] This                  The PPI instance pointer.
> > +  @param[in] NamespaceId           Is a 32 bit Namespace ID to which the
> Nvm
> > Express command packet will
> > +                                   be sent.
> > +                                   A Value of 0 denotes the NVM Express controller, a
> Value
> > of all 0FFh in
> > +                                   the namespace ID specifies that the command packet
> > should be sent to all
> > +                                   valid namespaces.
> > +  @param[in,out] Packet            A pointer to the EDKII PEI NVM Express
> > PassThru Command Packet to send
> > +                                   to the NVMe namespace specified by NamespaceId.
> > +
> > +  @retval EFI_SUCCESS              The EDKII PEI NVM Express Command
> Packet
> > was sent by the host.
> > +                                   TransferLength bytes were transferred to, or from
> > DataBuffer.
> > +  @retval EFI_NOT_READY            The EDKII PEI NVM Express Command
> > Packet could not be sent because
> > +                                   the controller is not ready. The caller may retry again
> later.
> > +  @retval EFI_DEVICE_ERROR         A device error occurred while
> attempting
> > to send the EDKII PEI NVM
> > +                                   Express Command Packet.
> > +  @retval EFI_INVALID_PARAMETER    Namespace, or the contents of
> > EDKII_PEI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET
> > +                                   are invalid.
> > +                                   The EDKII PEI NVM Express Command Packet was not
> sent,
> > so no
> > +                                   additional status information is available.
> > +  @retval EFI_UNSUPPORTED          The command described by the EDKII
> PEI
> > NVM Express Command Packet
> > +                                   is not supported by the host adapter.
> > +                                   The EDKII PEI NVM Express Command Packet was not
> sent,
> > so no
> > +                                   additional status information is available.
> > +  @retval EFI_TIMEOUT              A timeout occurred while waiting for the
> > EDKII PEI NVM Express Command
> > +                                   Packet to execute.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +NvmePassThru (
> > +  IN     EDKII_PEI_NVM_EXPRESS_PASS_THRU_PPI               *This,
> > +  IN     UINT32                                            NamespaceId,
> > +  IN OUT EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET
> *Packet
> >    );
> >
> >  #endif
> > diff --git
> >
> a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiStorageSecurity.
> > c
> >
> b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiStorageSecurity.
> > c
> > index dda69988b1..094d61bb8a 100644
> > ---
> >
> a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiStorageSecurity.
> > c
> > +++
> >
> b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiStorageSecurity.
> > c
> > @@ -57,15 +57,17 @@ TrustTransferNvmeDevice (
> >       OUT UINTN                               *TransferLengthOut
> >    )
> >  {
> > -  EDKII_PEI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET
> > CommandPacket;
> > -  EDKII_PEI_NVM_EXPRESS_COMMAND                     Command;
> > -  EDKII_PEI_NVM_EXPRESS_COMPLETION                  Completion;
> > +  EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET
> > CommandPacket;
> > +  EFI_NVM_EXPRESS_COMMAND                           Command;
> > +  EFI_NVM_EXPRESS_COMPLETION                        Completion;
> >    EFI_STATUS                                        Status;
> >    UINT16                                            SpecificData;
> > +  EDKII_PEI_NVM_EXPRESS_PASS_THRU_PPI               *NvmePassThru;
> >
> > -  ZeroMem (&CommandPacket,
> > sizeof(EDKII_PEI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET));
> > -  ZeroMem (&Command, sizeof(EDKII_PEI_NVM_EXPRESS_COMMAND));
> > -  ZeroMem (&Completion,
> sizeof(EDKII_PEI_NVM_EXPRESS_COMPLETION));
> > +  NvmePassThru = &Private->NvmePassThruPpi;
> > +  ZeroMem (&CommandPacket,
> > sizeof(EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET));
> > +  ZeroMem (&Command, sizeof(EFI_NVM_EXPRESS_COMMAND));
> > +  ZeroMem (&Completion, sizeof(EFI_NVM_EXPRESS_COMPLETION));
> >
> >    CommandPacket.NvmeCmd        = &Command;
> >    CommandPacket.NvmeCompletion = &Completion;
> > @@ -94,11 +96,11 @@ TrustTransferNvmeDevice (
> >    CommandPacket.CommandTimeout = Timeout;
> >    CommandPacket.QueueType      = NVME_ADMIN_QUEUE;
> >
> > -  Status = NvmePassThru (
> > -             Private,
> > -             NVME_CONTROLLER_NSID,
> > -             &CommandPacket
> > -             );
> > +  Status = NvmePassThru->PassThru (
> > +                           NvmePassThru,
> > +                           NVME_CONTROLLER_NSID,
> > +                           &CommandPacket
> > +                           );
> 
> 
> Reviewed-by: Hao A Wu <hao.a.wu@intel.com>


Thanks for the contribution.
Pushed via commit ba3aa1c4e7.

Best Regards,
Hao Wu


> 
> Best Regards,
> Hao Wu
> 
> 
> >
> >    if (!IsTrustSend) {
> >      if (EFI_ERROR (Status))  {
> > --
> > 2.16.2.windows.1
> >
> >
> >
> 
> 
> 


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2019-06-24  1:10 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-06-17  2:11 [PATCH] MdeModulePkg/NvmExpressPei: Produce NVM Express PassThru PPI Maggie Chu
2019-06-18 12:34 ` [edk2-devel] " Wu, Hao A
2019-06-24  1:10   ` Wu, Hao A

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox