> -----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....@intel.com> > Cc: Hao A Wu <hao.a...@intel.com> > Cc: Jian J Wang <jian.j.w...@intel.com> > Cc: Ray Ni <ray...@intel.com> > Cc: Star Zeng <star.z...@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...@intel.com> Best Regards, Hao Wu > > if (!IsTrustSend) { > if (EFI_ERROR (Status)) { > -- > 2.16.2.windows.1 > > > -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#42541): https://edk2.groups.io/g/devel/message/42541 Mute This Topic: https://groups.io/mt/32090308/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-