MdeModulePkg/NvmExpressPei: Use PCI_DEVICE_PPI to manage Nvme device

https://bugzilla.tianocore.org/show_bug.cgi?id=4017

This change modifies NvmExpressPei library
to allow usage both EDKII_PCI_DEVICE_PPI and
EDKII_NVM_EXPRESS_HOST_CONTROLLER_PPI to manage Nvme device.

Cc: Hao A Wu <hao.a.wu@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Signed-off-by: Xiao X Chen <xiao.x.chen@intel.com>
Reviewed-by: Hao A Wu <hao.a.wu@intel.com>
This commit is contained in:
Chen, Xiao X 2022-08-30 13:46:48 +08:00 committed by mergify[bot]
parent 31a94f7fba
commit 9ca7ece8b3
4 changed files with 488 additions and 252 deletions

View File

@ -37,50 +37,6 @@ EFI_DEVICE_PATH_PROTOCOL mNvmeEndDevicePathNodeTemplate = {
}
};
/**
Returns the 16-bit Length field of a device path node.
Returns the 16-bit Length field of the device path node specified by Node.
Node is not required to be aligned on a 16-bit boundary, so it is recommended
that a function such as ReadUnaligned16() be used to extract the contents of
the Length field.
If Node is NULL, then ASSERT().
@param Node A pointer to a device path node data structure.
@return The 16-bit Length field of the device path node specified by Node.
**/
UINTN
DevicePathNodeLength (
IN CONST VOID *Node
)
{
ASSERT (Node != NULL);
return ReadUnaligned16 ((UINT16 *)&((EFI_DEVICE_PATH_PROTOCOL *)(Node))->Length[0]);
}
/**
Returns a pointer to the next node in a device path.
If Node is NULL, then ASSERT().
@param Node A pointer to a device path node data structure.
@return a pointer to the device path node that follows the device path node
specified by Node.
**/
EFI_DEVICE_PATH_PROTOCOL *
NextDevicePathNode (
IN CONST VOID *Node
)
{
ASSERT (Node != NULL);
return (EFI_DEVICE_PATH_PROTOCOL *)((UINT8 *)(Node) + DevicePathNodeLength (Node));
}
/**
Get the size of the current device path instance.

View File

@ -40,6 +40,18 @@ EFI_PEI_NOTIFY_DESCRIPTOR mNvmeEndOfPeiNotifyListTemplate = {
NvmePeimEndOfPei
};
EFI_PEI_NOTIFY_DESCRIPTOR mNvmeHostControllerNotify = {
(EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
&gEdkiiPeiNvmExpressHostControllerPpiGuid,
NvmeHostControllerPpiInstallationCallback
};
EFI_PEI_NOTIFY_DESCRIPTOR mPciDevicePpiNotify = {
(EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
&gEdkiiPeiPciDevicePpiGuid,
NvmePciDevicePpiInstallationCallback
};
/**
Check if the specified Nvm Express device namespace is active, and then get the Identify
Namespace data.
@ -212,30 +224,27 @@ NvmePeimEndOfPei (
}
/**
Entry point of the PEIM.
Initialize and install PrivateData PPIs.
@param[in] FileHandle Handle of the file being invoked.
@param[in] PeiServices Describes the list of possible PEI Services.
@retval EFI_SUCCESS PPI successfully installed.
@param[in] MmioBase MMIO base address of specific Nvme controller
@param[in] DevicePath A pointer to the EFI_DEVICE_PATH_PROTOCOL
structure.
@param[in] DevicePathLength Length of the device path.
@retval EFI_SUCCESS Nvme controller initialized and PPIs installed
@retval others Failed to initialize Nvme controller
**/
EFI_STATUS
EFIAPI
NvmExpressPeimEntry (
IN EFI_PEI_FILE_HANDLE FileHandle,
IN CONST EFI_PEI_SERVICES **PeiServices
NvmeInitPrivateData (
IN UINTN MmioBase,
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
IN UINTN DevicePathLength
)
{
EFI_STATUS Status;
EFI_BOOT_MODE BootMode;
EDKII_NVM_EXPRESS_HOST_CONTROLLER_PPI *NvmeHcPpi;
UINT8 Controller;
UINTN MmioBase;
UINTN DevicePathLength;
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
PEI_NVME_CONTROLLER_PRIVATE_DATA *Private;
EFI_PHYSICAL_ADDRESS DeviceAddress;
EFI_STATUS Status;
EFI_BOOT_MODE BootMode;
PEI_NVME_CONTROLLER_PRIVATE_DATA *Private;
EFI_PHYSICAL_ADDRESS DeviceAddress;
DEBUG ((DEBUG_INFO, "%a: Enters.\n", __FUNCTION__));
@ -249,19 +258,358 @@ NvmExpressPeimEntry (
}
//
// Locate the NVME host controller PPI
// Check validity of the device path of the NVM Express controller.
//
Status = PeiServicesLocatePpi (
&gEdkiiPeiNvmExpressHostControllerPpiGuid,
0,
NULL,
(VOID **)&NvmeHcPpi
Status = NvmeIsHcDevicePathValid (DevicePath, DevicePathLength);
if (EFI_ERROR (Status)) {
DEBUG ((
DEBUG_ERROR,
"%a: The device path is invalid for Controller %d.\n",
__FUNCTION__
));
return Status;
}
//
// For S3 resume performance consideration, not all NVM Express controllers
// will be initialized. The driver consumes the content within
// S3StorageDeviceInitList LockBox to see if a controller will be skipped
// during S3 resume.
//
if ((BootMode == BOOT_ON_S3_RESUME) &&
(NvmeS3SkipThisController (DevicePath, DevicePathLength)))
{
DEBUG ((
DEBUG_ERROR,
"%a: skipped during S3.\n",
__FUNCTION__
));
return EFI_SUCCESS;
}
//
// Memory allocation for controller private data
//
Private = AllocateZeroPool (sizeof (PEI_NVME_CONTROLLER_PRIVATE_DATA));
if (Private == NULL) {
DEBUG ((
DEBUG_ERROR,
"%a: Fail to allocate private data.\n",
__FUNCTION__
));
return EFI_OUT_OF_RESOURCES;
}
//
// Memory allocation for transfer-related data
//
Status = IoMmuAllocateBuffer (
NVME_MEM_MAX_PAGES,
&Private->Buffer,
&DeviceAddress,
&Private->BufferMapping
);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "%a: Fail to locate NvmeHostControllerPpi.\n", __FUNCTION__));
DEBUG ((
DEBUG_ERROR,
"%a: Fail to allocate DMA buffers.\n",
__FUNCTION__
));
return Status;
}
ASSERT (DeviceAddress == ((EFI_PHYSICAL_ADDRESS)(UINTN)Private->Buffer));
DEBUG ((DEBUG_INFO, "%a: DMA buffer base at 0x%x\n", __FUNCTION__, Private->Buffer));
//
// Initialize controller private data
//
Private->Signature = NVME_PEI_CONTROLLER_PRIVATE_DATA_SIGNATURE;
Private->MmioBase = MmioBase;
Private->DevicePathLength = DevicePathLength;
Private->DevicePath = DevicePath;
//
// Initialize the NVME controller
//
Status = NvmeControllerInit (Private);
if (EFI_ERROR (Status)) {
DEBUG ((
DEBUG_ERROR,
"%a: Controller initialization fail with Status - %r.\n",
__FUNCTION__,
Status
));
NvmeFreeDmaResource (Private);
return Status;
}
//
// Enumerate the NVME namespaces on the controller
//
Status = NvmeDiscoverNamespaces (Private);
if (EFI_ERROR (Status)) {
//
// No active namespace was found on the controller
//
DEBUG ((
DEBUG_ERROR,
"%a: Namespaces discovery fail with Status - %r.\n",
__FUNCTION__,
Status
));
NvmeFreeDmaResource (Private);
return Status;
}
//
// 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);
//
// Block Io PPI
//
Private->BlkIoPpi.GetNumberOfBlockDevices = NvmeBlockIoPeimGetDeviceNo;
Private->BlkIoPpi.GetBlockDeviceMediaInfo = NvmeBlockIoPeimGetMediaInfo;
Private->BlkIoPpi.ReadBlocks = NvmeBlockIoPeimReadBlocks;
CopyMem (
&Private->BlkIoPpiList,
&mNvmeBlkIoPpiListTemplate,
sizeof (EFI_PEI_PPI_DESCRIPTOR)
);
Private->BlkIoPpiList.Ppi = &Private->BlkIoPpi;
Private->BlkIo2Ppi.Revision = EFI_PEI_RECOVERY_BLOCK_IO2_PPI_REVISION;
Private->BlkIo2Ppi.GetNumberOfBlockDevices = NvmeBlockIoPeimGetDeviceNo2;
Private->BlkIo2Ppi.GetBlockDeviceMediaInfo = NvmeBlockIoPeimGetMediaInfo2;
Private->BlkIo2Ppi.ReadBlocks = NvmeBlockIoPeimReadBlocks2;
CopyMem (
&Private->BlkIo2PpiList,
&mNvmeBlkIo2PpiListTemplate,
sizeof (EFI_PEI_PPI_DESCRIPTOR)
);
Private->BlkIo2PpiList.Ppi = &Private->BlkIo2Ppi;
PeiServicesInstallPpi (&Private->BlkIoPpiList);
//
// Check if the NVME controller supports the Security Receive/Send commands
//
if ((Private->ControllerData->Oacs & SECURITY_SEND_RECEIVE_SUPPORTED) != 0) {
DEBUG ((
DEBUG_INFO,
"%a: Security Security Command PPI will be produced.\n",
__FUNCTION__
));
Private->StorageSecurityPpi.Revision = EDKII_STORAGE_SECURITY_PPI_REVISION;
Private->StorageSecurityPpi.GetNumberofDevices = NvmeStorageSecurityGetDeviceNo;
Private->StorageSecurityPpi.GetDevicePath = NvmeStorageSecurityGetDevicePath;
Private->StorageSecurityPpi.ReceiveData = NvmeStorageSecurityReceiveData;
Private->StorageSecurityPpi.SendData = NvmeStorageSecuritySendData;
CopyMem (
&Private->StorageSecurityPpiList,
&mNvmeStorageSecurityPpiListTemplate,
sizeof (EFI_PEI_PPI_DESCRIPTOR)
);
Private->StorageSecurityPpiList.Ppi = &Private->StorageSecurityPpi;
PeiServicesInstallPpi (&Private->StorageSecurityPpiList);
}
CopyMem (
&Private->EndOfPeiNotifyList,
&mNvmeEndOfPeiNotifyListTemplate,
sizeof (EFI_PEI_NOTIFY_DESCRIPTOR)
);
PeiServicesNotifyPpi (&Private->EndOfPeiNotifyList);
return EFI_SUCCESS;
}
/**
Initialize Nvme controller from fiven PCI_DEVICE_PPI.
@param[in] PciDevice Pointer to the PCI Device PPI instance.
@retval EFI_SUCCESS The function completes successfully
@retval Others Cannot initialize Nvme controller for given device
**/
EFI_STATUS
NvmeInitControllerDataFromPciDevice (
EDKII_PCI_DEVICE_PPI *PciDevice
)
{
EFI_STATUS Status;
PCI_TYPE00 PciData;
UINTN MmioBase;
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
UINTN DevicePathLength;
UINT64 EnabledPciAttributes;
UINT32 MmioBaseH;
//
// Now further check the PCI header: Base Class (offset 0x0B), Sub Class (offset 0x0A) and
// Programming Interface (offset 0x09). This controller should be an Nvme controller
//
Status = PciDevice->PciIo.Pci.Read (
&PciDevice->PciIo,
EfiPciIoWidthUint8,
PCI_CLASSCODE_OFFSET,
sizeof (PciData.Hdr.ClassCode),
PciData.Hdr.ClassCode
);
if (EFI_ERROR (Status)) {
return EFI_UNSUPPORTED;
}
if (!IS_PCI_NVMHCI (&PciData)) {
return EFI_UNSUPPORTED;
}
Status = PciDevice->PciIo.Attributes (
&PciDevice->PciIo,
EfiPciIoAttributeOperationSupported,
0,
&EnabledPciAttributes
);
if (EFI_ERROR (Status)) {
return EFI_UNSUPPORTED;
} else {
EnabledPciAttributes &= (UINT64)EFI_PCI_DEVICE_ENABLE;
Status = PciDevice->PciIo.Attributes (
&PciDevice->PciIo,
EfiPciIoAttributeOperationEnable,
EnabledPciAttributes,
NULL
);
if (EFI_ERROR (Status)) {
return EFI_UNSUPPORTED;
}
}
Status = PciDevice->PciIo.Pci.Read (
&PciDevice->PciIo,
EfiPciIoWidthUint32,
PCI_BASE_ADDRESSREG_OFFSET,
1,
&MmioBase
);
if (EFI_ERROR (Status)) {
return EFI_UNSUPPORTED;
}
switch (MmioBase & 0x07) {
case 0x0:
//
// Memory space for 32 bit bar address
//
MmioBase = MmioBase & 0xFFFFFFF0;
break;
case 0x4:
//
// For 64 bit bar address, read the high 32bits of this 64 bit bar
//
Status = PciDevice->PciIo.Pci.Read (
&PciDevice->PciIo,
EfiPciIoWidthUint32,
PCI_BASE_ADDRESSREG_OFFSET + 4,
1,
&MmioBaseH
);
//
// For 32 bit environment, high 32bits of the bar should be zero.
//
if ( EFI_ERROR (Status)
|| ((MmioBaseH != 0) && (sizeof (UINTN) == sizeof (UINT32))))
{
return EFI_UNSUPPORTED;
}
MmioBase = MmioBase & 0xFFFFFFF0;
MmioBase |= LShiftU64 ((UINT64)MmioBaseH, 32);
break;
default:
//
// Unknown bar type
//
return EFI_UNSUPPORTED;
}
DevicePathLength = GetDevicePathSize (PciDevice->DevicePath);
DevicePath = PciDevice->DevicePath;
Status = NvmeInitPrivateData (MmioBase, DevicePath, DevicePathLength);
if (EFI_ERROR (Status)) {
DEBUG ((
DEBUG_INFO,
"%a: Failed to init controller, with Status - %r\n",
__FUNCTION__,
Status
));
}
return EFI_SUCCESS;
}
/**
Callback for EDKII_PCI_DEVICE_PPI installation.
@param[in] PeiServices Pointer to PEI Services Table.
@param[in] NotifyDescriptor Pointer to the descriptor for the Notification
event that caused this function to execute.
@param[in] Ppi Pointer to the PPI data associated with this function.
@retval EFI_SUCCESS The function completes successfully
@retval Others Cannot initialize Nvme controller from given PCI_DEVICE_PPI
**/
EFI_STATUS
EFIAPI
NvmePciDevicePpiInstallationCallback (
IN EFI_PEI_SERVICES **PeiServices,
IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
IN VOID *Ppi
)
{
EDKII_PCI_DEVICE_PPI *PciDevice;
PciDevice = (EDKII_PCI_DEVICE_PPI *)Ppi;
return NvmeInitControllerDataFromPciDevice (PciDevice);
}
/**
Initialize Nvme controller from EDKII_NVM_EXPRESS_HOST_CONTROLLER_PPI instance.
@param[in] NvmeHcPpi Pointer to the Nvme Host Controller PPI instance.
@retval EFI_SUCCESS PPI successfully installed.
**/
EFI_STATUS
NvmeInitControllerFromHostControllerPpi (
IN EDKII_NVM_EXPRESS_HOST_CONTROLLER_PPI *NvmeHcPpi
)
{
UINT8 Controller;
UINTN MmioBase;
UINTN DevicePathLength;
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
EFI_STATUS Status;
Controller = 0;
MmioBase = 0;
while (TRUE) {
@ -293,88 +641,7 @@ NvmExpressPeimEntry (
return Status;
}
//
// Check validity of the device path of the NVM Express controller.
//
Status = NvmeIsHcDevicePathValid (DevicePath, DevicePathLength);
if (EFI_ERROR (Status)) {
DEBUG ((
DEBUG_ERROR,
"%a: The device path is invalid for Controller %d.\n",
__FUNCTION__,
Controller
));
Controller++;
continue;
}
//
// For S3 resume performance consideration, not all NVM Express controllers
// will be initialized. The driver consumes the content within
// S3StorageDeviceInitList LockBox to see if a controller will be skipped
// during S3 resume.
//
if ((BootMode == BOOT_ON_S3_RESUME) &&
(NvmeS3SkipThisController (DevicePath, DevicePathLength)))
{
DEBUG ((
DEBUG_ERROR,
"%a: Controller %d is skipped during S3.\n",
__FUNCTION__,
Controller
));
Controller++;
continue;
}
//
// Memory allocation for controller private data
//
Private = AllocateZeroPool (sizeof (PEI_NVME_CONTROLLER_PRIVATE_DATA));
if (Private == NULL) {
DEBUG ((
DEBUG_ERROR,
"%a: Fail to allocate private data for Controller %d.\n",
__FUNCTION__,
Controller
));
return EFI_OUT_OF_RESOURCES;
}
//
// Memory allocation for transfer-related data
//
Status = IoMmuAllocateBuffer (
NVME_MEM_MAX_PAGES,
&Private->Buffer,
&DeviceAddress,
&Private->BufferMapping
);
if (EFI_ERROR (Status)) {
DEBUG ((
DEBUG_ERROR,
"%a: Fail to allocate DMA buffers for Controller %d.\n",
__FUNCTION__,
Controller
));
return Status;
}
ASSERT (DeviceAddress == ((EFI_PHYSICAL_ADDRESS)(UINTN)Private->Buffer));
DEBUG ((DEBUG_INFO, "%a: DMA buffer base at 0x%x\n", __FUNCTION__, Private->Buffer));
//
// Initialize controller private data
//
Private->Signature = NVME_PEI_CONTROLLER_PRIVATE_DATA_SIGNATURE;
Private->MmioBase = MmioBase;
Private->DevicePathLength = DevicePathLength;
Private->DevicePath = DevicePath;
//
// Initialize the NVME controller
//
Status = NvmeControllerInit (Private);
Status = NvmeInitPrivateData (MmioBase, DevicePath, DevicePathLength);
if (EFI_ERROR (Status)) {
DEBUG ((
DEBUG_ERROR,
@ -383,115 +650,73 @@ NvmExpressPeimEntry (
Controller,
Status
));
NvmeFreeDmaResource (Private);
Controller++;
continue;
}
//
// Enumerate the NVME namespaces on the controller
//
Status = NvmeDiscoverNamespaces (Private);
if (EFI_ERROR (Status)) {
//
// No active namespace was found on the controller
//
DEBUG ((
DEBUG_ERROR,
"%a: Namespaces discovery fail for Controller %d with Status - %r.\n",
__FUNCTION__,
Controller,
Status
));
NvmeFreeDmaResource (Private);
Controller++;
continue;
}
//
// 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);
//
// Block Io PPI
//
Private->BlkIoPpi.GetNumberOfBlockDevices = NvmeBlockIoPeimGetDeviceNo;
Private->BlkIoPpi.GetBlockDeviceMediaInfo = NvmeBlockIoPeimGetMediaInfo;
Private->BlkIoPpi.ReadBlocks = NvmeBlockIoPeimReadBlocks;
CopyMem (
&Private->BlkIoPpiList,
&mNvmeBlkIoPpiListTemplate,
sizeof (EFI_PEI_PPI_DESCRIPTOR)
);
Private->BlkIoPpiList.Ppi = &Private->BlkIoPpi;
Private->BlkIo2Ppi.Revision = EFI_PEI_RECOVERY_BLOCK_IO2_PPI_REVISION;
Private->BlkIo2Ppi.GetNumberOfBlockDevices = NvmeBlockIoPeimGetDeviceNo2;
Private->BlkIo2Ppi.GetBlockDeviceMediaInfo = NvmeBlockIoPeimGetMediaInfo2;
Private->BlkIo2Ppi.ReadBlocks = NvmeBlockIoPeimReadBlocks2;
CopyMem (
&Private->BlkIo2PpiList,
&mNvmeBlkIo2PpiListTemplate,
sizeof (EFI_PEI_PPI_DESCRIPTOR)
);
Private->BlkIo2PpiList.Ppi = &Private->BlkIo2Ppi;
PeiServicesInstallPpi (&Private->BlkIoPpiList);
//
// Check if the NVME controller supports the Security Receive/Send commands
//
if ((Private->ControllerData->Oacs & SECURITY_SEND_RECEIVE_SUPPORTED) != 0) {
} else {
DEBUG ((
DEBUG_INFO,
"%a: Security Security Command PPI will be produced for Controller %d.\n",
"%a: Controller %d has been successfully initialized.\n",
__FUNCTION__,
Controller
));
Private->StorageSecurityPpi.Revision = EDKII_STORAGE_SECURITY_PPI_REVISION;
Private->StorageSecurityPpi.GetNumberofDevices = NvmeStorageSecurityGetDeviceNo;
Private->StorageSecurityPpi.GetDevicePath = NvmeStorageSecurityGetDevicePath;
Private->StorageSecurityPpi.ReceiveData = NvmeStorageSecurityReceiveData;
Private->StorageSecurityPpi.SendData = NvmeStorageSecuritySendData;
CopyMem (
&Private->StorageSecurityPpiList,
&mNvmeStorageSecurityPpiListTemplate,
sizeof (EFI_PEI_PPI_DESCRIPTOR)
);
Private->StorageSecurityPpiList.Ppi = &Private->StorageSecurityPpi;
PeiServicesInstallPpi (&Private->StorageSecurityPpiList);
}
CopyMem (
&Private->EndOfPeiNotifyList,
&mNvmeEndOfPeiNotifyListTemplate,
sizeof (EFI_PEI_NOTIFY_DESCRIPTOR)
);
PeiServicesNotifyPpi (&Private->EndOfPeiNotifyList);
DEBUG ((
DEBUG_INFO,
"%a: Controller %d has been successfully initialized.\n",
__FUNCTION__,
Controller
));
Controller++;
}
return EFI_SUCCESS;
}
/**
Callback for EDKII_NVM_EXPRESS_HOST_CONTROLLER_PPI installation.
@param[in] PeiServices Pointer to PEI Services Table.
@param[in] NotifyDescriptor Pointer to the descriptor for the Notification
event that caused this function to execute.
@param[in] Ppi Pointer to the PPI data associated with this function.
@retval EFI_SUCCESS The function completes successfully
@retval Others Cannot initialize Nvme controller from given EDKII_NVM_EXPRESS_HOST_CONTROLLER_PPI
**/
EFI_STATUS
EFIAPI
NvmeHostControllerPpiInstallationCallback (
IN EFI_PEI_SERVICES **PeiServices,
IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
IN VOID *Ppi
)
{
EDKII_NVM_EXPRESS_HOST_CONTROLLER_PPI *NvmeHcPpi;
if (Ppi == NULL) {
return EFI_INVALID_PARAMETER;
}
NvmeHcPpi = (EDKII_NVM_EXPRESS_HOST_CONTROLLER_PPI *)Ppi;
return NvmeInitControllerFromHostControllerPpi (NvmeHcPpi);
}
/**
Entry point of the PEIM.
@param[in] FileHandle Handle of the file being invoked.
@param[in] PeiServices Describes the list of possible PEI Services.
@retval EFI_SUCCESS PPI successfully installed.
**/
EFI_STATUS
EFIAPI
NvmExpressPeimEntry (
IN EFI_PEI_FILE_HANDLE FileHandle,
IN CONST EFI_PEI_SERVICES **PeiServices
)
{
DEBUG ((DEBUG_INFO, "%a: Enters.\n", __FUNCTION__));
PeiServicesNotifyPpi (&mNvmeHostControllerNotify);
PeiServicesNotifyPpi (&mPciDevicePpiNotify);
return EFI_SUCCESS;
}

View File

@ -14,6 +14,7 @@
#include <PiPei.h>
#include <IndustryStandard/Nvme.h>
#include <IndustryStandard/Pci.h>
#include <Ppi/NvmExpressHostController.h>
#include <Ppi/BlockIo.h>
@ -22,6 +23,7 @@
#include <Ppi/NvmExpressPassThru.h>
#include <Ppi/IoMmu.h>
#include <Ppi/EndOfPeiPhase.h>
#include <Ppi/PciDevice.h>
#include <Library/DebugLib.h>
#include <Library/PeiServicesLib.h>
@ -29,6 +31,7 @@
#include <Library/BaseMemoryLib.h>
#include <Library/IoLib.h>
#include <Library/TimerLib.h>
#include <Library/DevicePathLib.h>
//
// Structure forward declarations
@ -36,6 +39,17 @@
typedef struct _PEI_NVME_NAMESPACE_INFO PEI_NVME_NAMESPACE_INFO;
typedef struct _PEI_NVME_CONTROLLER_PRIVATE_DATA PEI_NVME_CONTROLLER_PRIVATE_DATA;
/**
Macro that checks whether device is a NVMHCI Interface.
@param _p Specified device.
@retval TRUE Device is a NVMHCI Interface.
@retval FALSE Device is not a NVMHCI Interface.
**/
#define IS_PCI_NVMHCI(_p) IS_CLASS3 (_p, PCI_CLASS_MASS_STORAGE, PCI_CLASS_MASS_STORAGE_SOLID_STATE, PCI_IF_MASS_STORAGE_SOLID_STATE_ENTERPRISE_NVMHCI)
#include "NvmExpressPeiHci.h"
#include "NvmExpressPeiPassThru.h"
#include "NvmExpressPeiBlockIo.h"
@ -345,4 +359,44 @@ NvmeS3SkipThisController (
IN UINTN HcDevicePathLength
);
/**
Callback for EDKII_PCI_DEVICE_PPI installation.
@param[in] PeiServices Pointer to PEI Services Table.
@param[in] NotifyDescriptor Pointer to the descriptor for the Notification
event that caused this function to execute.
@param[in] Ppi Pointer to the PPI data associated with this function.
@retval EFI_SUCCESS The function completes successfully
@retval Others Cannot initialize Nvme controller from given PCI_DEVICE_PPI
**/
EFI_STATUS
EFIAPI
NvmePciDevicePpiInstallationCallback (
IN EFI_PEI_SERVICES **PeiServices,
IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
IN VOID *Ppi
);
/**
Callback for EDKII_NVM_EXPRESS_HOST_CONTROLLER_PPI installation.
@param[in] PeiServices Pointer to PEI Services Table.
@param[in] NotifyDescriptor Pointer to the descriptor for the Notification
event that caused this function to execute.
@param[in] Ppi Pointer to the PPI data associated with this function.
@retval EFI_SUCCESS The function completes successfully
@retval Others Cannot initialize Nvme controller from given EDKII_NVM_EXPRESS_HOST_CONTROLLER_PPI
**/
EFI_STATUS
EFIAPI
NvmeHostControllerPpiInstallationCallback (
IN EFI_PEI_SERVICES **PeiServices,
IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
IN VOID *Ppi
);
#endif

View File

@ -44,6 +44,7 @@
[LibraryClasses]
DebugLib
DevicePathLib
PeiServicesLib
MemoryAllocationLib
BaseMemoryLib
@ -56,6 +57,7 @@
gEdkiiPeiNvmExpressHostControllerPpiGuid ## CONSUMES
gEdkiiIoMmuPpiGuid ## CONSUMES
gEfiEndOfPeiSignalPpiGuid ## CONSUMES
gEdkiiPeiPciDevicePpiGuid ## CONSUMES
gEdkiiPeiNvmExpressPassThruPpiGuid ## SOMETIMES_PRODUCES
gEfiPeiVirtualBlockIoPpiGuid ## SOMETIMES_PRODUCES
gEfiPeiVirtualBlockIo2PpiGuid ## SOMETIMES_PRODUCES
@ -66,7 +68,6 @@
[Depex]
gEfiPeiMemoryDiscoveredPpiGuid AND
gEdkiiPeiNvmExpressHostControllerPpiGuid AND
gEfiPeiMasterBootModePpiGuid
[UserExtensions.TianoCore."ExtraFiles"]