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