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>
Reviewed-by: 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>
This commit is contained in:
Maggie Chu 2019-06-17 10:11:26 +08:00 committed by Hao A Wu
parent 4128d8a8cb
commit ba3aa1c4e7
8 changed files with 418 additions and 115 deletions

View File

@ -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
//

View File

@ -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)

View File

@ -56,6 +56,7 @@
gEdkiiPeiNvmExpressHostControllerPpiGuid ## CONSUMES
gEdkiiIoMmuPpiGuid ## CONSUMES
gEfiEndOfPeiSignalPpiGuid ## CONSUMES
gEdkiiPeiNvmExpressPassThruPpiGuid ## SOMETIMES_PRODUCES
gEfiPeiVirtualBlockIoPpiGuid ## SOMETIMES_PRODUCES
gEfiPeiVirtualBlockIo2PpiGuid ## SOMETIMES_PRODUCES
gEdkiiPeiStorageSecurityCommandPpiGuid ## SOMETIMES_PRODUCES

View File

@ -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;
}

View File

@ -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;
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(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));
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;
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(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));
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

View File

@ -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;
}

View File

@ -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

View File

@ -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)) {