From nobody Sun May 19 21:29:38 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+92945+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+92945+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1661821637; cv=none; d=zohomail.com; s=zohoarc; b=lj26ANxXi8BzWwkdmY0aznkl3hM0fcOxRnds103hPgWBY/ukWIvqtdfOigG2APK6aY7HO39MDaPLUmx5r17f9IrMLDvAz7g2cjqVACLkIvqIOciutqdhpm/2Ls2ERlLeTMmGpJ6o3cCDbPyYh8Yc5Mf9lEuAbLkx9WgnFFiFl3Y= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1661821637; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=qp3BKL6gHvrS9giy9qTh/e8has4EfIJptMY9H6zi5kw=; b=VdRwIE2oAYrMAGF9pnrR38Uje2hovjmD5ksr6peEamiIz4LJ1U+H7a5enYs8iLdnAi6A4R0Fugj3uLKwvALUQWB6u3WLpLvQWJDsmGT0hsm5TEfUToLw5jl/rgPQTtNhrgWadSvP6OEWGSM8lJ5kGPTGnaw4oHxVhR/rmTfQF+8= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+92945+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1661821637472915.159886631394; Mon, 29 Aug 2022 18:07:17 -0700 (PDT) Return-Path: X-Received: by 127.0.0.2 with SMTP id FSiAYY1788612xLYbdfM2FPP; Mon, 29 Aug 2022 18:07:16 -0700 X-Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by mx.groups.io with SMTP id smtpd.web12.6453.1661821635419151723 for ; Mon, 29 Aug 2022 18:07:15 -0700 X-IronPort-AV: E=McAfee;i="6500,9779,10454"; a="295826985" X-IronPort-AV: E=Sophos;i="5.93,274,1654585200"; d="scan'208";a="295826985" X-Received: from orsmga008.jf.intel.com ([10.7.209.65]) by orsmga102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 29 Aug 2022 18:07:14 -0700 X-IronPort-AV: E=Sophos;i="5.93,273,1654585200"; d="scan'208";a="641156414" X-Received: from chenxia1-desk.ccr.corp.intel.com ([10.239.216.34]) by orsmga008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 29 Aug 2022 18:07:13 -0700 From: "chenxia1" To: devel@edk2.groups.io Cc: Xiao X Chen , Hao A Wu , Ray Ni Subject: [edk2-devel] [PATCH 1/1] MdeModulePkg/NvmExpressPei: Use PCI_DEVICE_PPI to manage Nvme device Date: Tue, 30 Aug 2022 09:06:22 +0800 Message-Id: In-Reply-To: References: MIME-Version: 1.0 Precedence: Bulk List-Unsubscribe: List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,xiao.x.chen@intel.com X-Gm-Message-State: iwhkRLq5BkuIjA4hKCoJfScQx1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1661821636; bh=AveumCQV7U6ftZk9IXfQf+yaOFZwn+Z6haOT2+udZr4=; h=Cc:Date:From:Reply-To:Subject:To; b=TQtpta+QuGbuMv2Xx3JW6mwQ4vFV8BR/mhLomJbrDP6pD+n4FkHWjBNGAUMpmUKZvLC o1iIAUQ+d0VOZBNKF7lK9H0Yl76MBRNC1Ku7EBcObDiFHjZhCF17a463+Ho2c/Q1ugOHb SYN+EewE9sXcBUy5RyBRXq72Ac4EDY+NzXg= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1661821638756100003 Content-Type: text/plain; charset="utf-8" https://bugzilla.tianocore.org/show_bug.cgi?id=3D4017 This change modifies NvmExpressPei library to allow usage both EDKII_PCI_DEVICE_PPI and EDKII_NVM_EXPRESS_HOST_CONTROLLER_PPI to manage Nvme device. Signed-off-by: Xiao X Chen Cc: Hao A Wu Cc: Ray Ni --- .../Bus/Pci/NvmExpressPei/DevicePath.c | 44 -- .../Bus/Pci/NvmExpressPei/NvmExpressPei.c | 628 ++++++++++++------ .../Bus/Pci/NvmExpressPei/NvmExpressPei.h | 54 ++ .../Bus/Pci/NvmExpressPei/NvmExpressPei.inf | 3 +- 4 files changed, 477 insertions(+), 252 deletions(-) diff --git a/MdeModulePkg/Bus/Pci/NvmExpressPei/DevicePath.c b/MdeModulePkg= /Bus/Pci/NvmExpressPei/DevicePath.c index 9b454a7dd8f4..307045be70ea 100644 --- a/MdeModulePkg/Bus/Pci/NvmExpressPei/DevicePath.c +++ b/MdeModulePkg/Bus/Pci/NvmExpressPei/DevicePath.c @@ -37,50 +37,6 @@ EFI_DEVICE_PATH_PROTOCOL mNvmeEndDevicePathNodeTemplate= =3D { } }; =20 -/** - Returns the 16-bit Length field of a device path node. - - Returns the 16-bit Length field of the device path node specified by Nod= e. - Node is not required to be aligned on a 16-bit boundary, so it is recomm= ended - that a function such as ReadUnaligned16() be used to extract the content= s 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 Nod= e. - -**/ -UINTN -DevicePathNodeLength ( - IN CONST VOID *Node - ) -{ - ASSERT (Node !=3D 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 n= ode - specified by Node. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -NextDevicePathNode ( - IN CONST VOID *Node - ) -{ - ASSERT (Node !=3D NULL); - return (EFI_DEVICE_PATH_PROTOCOL *)((UINT8 *)(Node) + DevicePathNodeLeng= th (Node)); -} - /** Get the size of the current device path instance. =20 diff --git a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.c b/MdeModule= Pkg/Bus/Pci/NvmExpressPei/NvmExpressPei.c index 2d6a79028fcd..210c8c2c268f 100644 --- a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.c +++ b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.c @@ -40,6 +40,18 @@ EFI_PEI_NOTIFY_DESCRIPTOR mNvmeEndOfPeiNotifyListTempla= te =3D { NvmePeimEndOfPei }; =20 +EFI_PEI_NOTIFY_DESCRIPTOR mNvmeHostControllerNotify =3D { + (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINA= TE_LIST), + &gEdkiiPeiNvmExpressHostControllerPpiGuid, + NvmeHostControllerPpiInstallationCallback +}; + +EFI_PEI_NOTIFY_DESCRIPTOR mPciDevicePpiNotify =3D { + (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINA= TE_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 ( } =20 /** - Entry point of the PEIM. + Initialize and install PrivateData PPIs. =20 - @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 contro= ller + @param[in] DevicePath A pointer to the EFI_DEVICE_PATH_PROTOCOL + structure. + @param[in] DevicePathLength Length of the device path. =20 + @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; =20 DEBUG ((DEBUG_INFO, "%a: Enters.\n", __FUNCTION__)); =20 @@ -249,19 +258,347 @@ NvmExpressPeimEntry ( } =20 // - // Locate the NVME host controller PPI + // Check validity of the device path of the NVM Express controller. // - Status =3D PeiServicesLocatePpi ( - &gEdkiiPeiNvmExpressHostControllerPpiGuid, - 0, - NULL, - (VOID **)&NvmeHcPpi + Status =3D 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 controll= ers + // will be initialized. The driver consumes the content within + // S3StorageDeviceInitList LockBox to see if a controller will be skipped + // during S3 resume. + // + if ((BootMode =3D=3D 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 =3D AllocateZeroPool (sizeof (PEI_NVME_CONTROLLER_PRIVATE_DATA)); + if (Private =3D=3D NULL) { + DEBUG (( + DEBUG_ERROR, + "%a: Fail to allocate private data.\n", + __FUNCTION__ + )); + return EFI_OUT_OF_RESOURCES; + } + + // + // Memory allocation for transfer-related data + // + Status =3D 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 =3D=3D ((EFI_PHYSICAL_ADDRESS)(UINTN)Private->Buff= er)); + DEBUG ((DEBUG_INFO, "%a: DMA buffer base at 0x%x\n", __FUNCTION__, Priva= te->Buffer)); + + // + // Initialize controller private data + // + Private->Signature =3D NVME_PEI_CONTROLLER_PRIVATE_DATA_SIGNATURE; + Private->MmioBase =3D MmioBase; + Private->DevicePathLength =3D DevicePathLength; + Private->DevicePath =3D DevicePath; + + // + // Initialize the NVME controller + // + Status =3D 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 =3D 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 =3D EFI_NVM_EXPRESS_PASS_THRU_ATTRIBUTE= S_PHYSICAL | + EFI_NVM_EXPRESS_PASS_THRU_ATTRIBUTES_= LOGICAL | + EFI_NVM_EXPRESS_PASS_THRU_ATTRIBUTES_= CMD_SET_NVM; + Private->PassThruMode.IoAlign =3D sizeof (UINTN); + Private->PassThruMode.NvmeVersion =3D EDKII_PEI_NVM_EXPRESS_PASS= _THRU_PPI_REVISION; + Private->NvmePassThruPpi.Mode =3D &Private->PassThruMode; + Private->NvmePassThruPpi.GetDevicePath =3D NvmePassThruGetDevicePath; + Private->NvmePassThruPpi.GetNextNameSpace =3D NvmePassThruGetNextNameSpa= ce; + Private->NvmePassThruPpi.PassThru =3D NvmePassThru; + CopyMem ( + &Private->NvmePassThruPpiList, + &mNvmePassThruPpiListTemplate, + sizeof (EFI_PEI_PPI_DESCRIPTOR) + ); + Private->NvmePassThruPpiList.Ppi =3D &Private->NvmePassThruPpi; + PeiServicesInstallPpi (&Private->NvmePassThruPpiList); + + // + // Block Io PPI + // + Private->BlkIoPpi.GetNumberOfBlockDevices =3D NvmeBlockIoPeimGetDeviceNo; + Private->BlkIoPpi.GetBlockDeviceMediaInfo =3D NvmeBlockIoPeimGetMediaInf= o; + Private->BlkIoPpi.ReadBlocks =3D NvmeBlockIoPeimReadBlocks; + CopyMem ( + &Private->BlkIoPpiList, + &mNvmeBlkIoPpiListTemplate, + sizeof (EFI_PEI_PPI_DESCRIPTOR) + ); + Private->BlkIoPpiList.Ppi =3D &Private->BlkIoPpi; + + Private->BlkIo2Ppi.Revision =3D EFI_PEI_RECOVERY_BLOCK_IO= 2_PPI_REVISION; + Private->BlkIo2Ppi.GetNumberOfBlockDevices =3D NvmeBlockIoPeimGetDeviceN= o2; + Private->BlkIo2Ppi.GetBlockDeviceMediaInfo =3D NvmeBlockIoPeimGetMediaIn= fo2; + Private->BlkIo2Ppi.ReadBlocks =3D NvmeBlockIoPeimReadBlocks= 2; + CopyMem ( + &Private->BlkIo2PpiList, + &mNvmeBlkIo2PpiListTemplate, + sizeof (EFI_PEI_PPI_DESCRIPTOR) + ); + Private->BlkIo2PpiList.Ppi =3D &Private->BlkIo2Ppi; + PeiServicesInstallPpi (&Private->BlkIoPpiList); + + // + // Check if the NVME controller supports the Security Receive/Send comma= nds + // + if ((Private->ControllerData->Oacs & SECURITY_SEND_RECEIVE_SUPPORTED) != =3D 0) { + DEBUG (( + DEBUG_INFO, + "%a: Security Security Command PPI will be produced.\n", + __FUNCTION__ + )); + Private->StorageSecurityPpi.Revision =3D EDKII_STORAGE_SECUR= ITY_PPI_REVISION; + Private->StorageSecurityPpi.GetNumberofDevices =3D NvmeStorageSecurity= GetDeviceNo; + Private->StorageSecurityPpi.GetDevicePath =3D NvmeStorageSecurity= GetDevicePath; + Private->StorageSecurityPpi.ReceiveData =3D NvmeStorageSecurity= ReceiveData; + Private->StorageSecurityPpi.SendData =3D NvmeStorageSecurity= SendData; + CopyMem ( + &Private->StorageSecurityPpiList, + &mNvmeStorageSecurityPpiListTemplate, + sizeof (EFI_PEI_PPI_DESCRIPTOR) + ); + Private->StorageSecurityPpiList.Ppi =3D &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 dev= ice +**/ +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 Nvm= e controller + // + Status =3D 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; } =20 + Status =3D PciDevice->PciIo.Attributes ( + &PciDevice->PciIo, + EfiPciIoAttributeOperationSupported, + 0, + &EnabledPciAttributes + ); + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } else { + EnabledPciAttributes &=3D (UINT64)EFI_PCI_DEVICE_ENABLE; + Status =3D PciDevice->PciIo.Attributes ( + &PciDevice->PciIo, + EfiPciIoAttributeOperationE= nable, + EnabledPciAttributes, + NULL + ); + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + } + + Status =3D PciDevice->PciIo.Pci.Read ( + &PciDevice->PciIo, + EfiPciIoWidthUint32, + PCI_BASE_ADDRESSREG_OFFSET, + 1, + &MmioBase + ); + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + + if (MmioBase & BIT2) { + // + // For 64 bit bar, read the high 32bits of this 64 bit bar + // + Status =3D 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 !=3D 0) && (sizeof (UINTN) =3D=3D sizeof (UINT32)))) + { + return EFI_UNSUPPORTED; + } + + MmioBase =3D MmioBase & 0xFFFFFFF0; + MmioBase |=3D LShiftU64 ((UINT64)MmioBaseH, 32); + } else { + MmioBase =3D MmioBase & 0xFFFFFFF0; + } + + DevicePathLength =3D GetDevicePathSize (PciDevice->DevicePath); + DevicePath =3D PciDevice->DevicePath; + + Status =3D 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 Notific= ation + event that caused this function to execut= e. + @param[in] Ppi Pointer to the PPI data associated with t= his function. + + @retval EFI_SUCCESS The function completes successfully + @retval Others Cannot initialize Nvme controller from gi= ven 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 =3D (EDKII_PCI_DEVICE_PPI *)Ppi; + + return NvmeInitControllerDataFromPciDevice (PciDevice); +} + +/** + Initialize Nvme controller from EDKII_NVM_EXPRESS_HOST_CONTROLLER_PPI in= stance. + + @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 =3D 0; MmioBase =3D 0; while (TRUE) { @@ -293,88 +630,7 @@ NvmExpressPeimEntry ( return Status; } =20 - // - // Check validity of the device path of the NVM Express controller. - // - Status =3D 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 contro= llers - // will be initialized. The driver consumes the content within - // S3StorageDeviceInitList LockBox to see if a controller will be skip= ped - // during S3 resume. - // - if ((BootMode =3D=3D 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 =3D AllocateZeroPool (sizeof (PEI_NVME_CONTROLLER_PRIVATE_DATA= )); - if (Private =3D=3D 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 =3D 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 =3D=3D ((EFI_PHYSICAL_ADDRESS)(UINTN)Private->Bu= ffer)); - DEBUG ((DEBUG_INFO, "%a: DMA buffer base at 0x%x\n", __FUNCTION__, Pri= vate->Buffer)); - - // - // Initialize controller private data - // - Private->Signature =3D NVME_PEI_CONTROLLER_PRIVATE_DATA_SIGNATU= RE; - Private->MmioBase =3D MmioBase; - Private->DevicePathLength =3D DevicePathLength; - Private->DevicePath =3D DevicePath; - - // - // Initialize the NVME controller - // - Status =3D NvmeControllerInit (Private); + Status =3D NvmeInitPrivateData (MmioBase, DevicePath, DevicePathLength= ); if (EFI_ERROR (Status)) { DEBUG (( DEBUG_ERROR, @@ -383,115 +639,73 @@ NvmExpressPeimEntry ( Controller, Status )); - NvmeFreeDmaResource (Private); - Controller++; - continue; - } - - // - // Enumerate the NVME namespaces on the controller - // - Status =3D 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 =3D EFI_NVM_EXPRESS_PASS_THRU_ATTRIBU= TES_PHYSICAL | - EFI_NVM_EXPRESS_PASS_THRU_ATTRIBUTE= S_LOGICAL | - EFI_NVM_EXPRESS_PASS_THRU_ATTRIBUTE= S_CMD_SET_NVM; - Private->PassThruMode.IoAlign =3D sizeof (UINTN); - Private->PassThruMode.NvmeVersion =3D EDKII_PEI_NVM_EXPRESS_PA= SS_THRU_PPI_REVISION; - Private->NvmePassThruPpi.Mode =3D &Private->PassThruMode; - Private->NvmePassThruPpi.GetDevicePath =3D NvmePassThruGetDevicePat= h; - Private->NvmePassThruPpi.GetNextNameSpace =3D NvmePassThruGetNextNameS= pace; - Private->NvmePassThruPpi.PassThru =3D NvmePassThru; - CopyMem ( - &Private->NvmePassThruPpiList, - &mNvmePassThruPpiListTemplate, - sizeof (EFI_PEI_PPI_DESCRIPTOR) - ); - Private->NvmePassThruPpiList.Ppi =3D &Private->NvmePassThruPpi; - PeiServicesInstallPpi (&Private->NvmePassThruPpiList); - - // - // Block Io PPI - // - Private->BlkIoPpi.GetNumberOfBlockDevices =3D NvmeBlockIoPeimGetDevice= No; - Private->BlkIoPpi.GetBlockDeviceMediaInfo =3D NvmeBlockIoPeimGetMediaI= nfo; - Private->BlkIoPpi.ReadBlocks =3D NvmeBlockIoPeimReadBlock= s; - CopyMem ( - &Private->BlkIoPpiList, - &mNvmeBlkIoPpiListTemplate, - sizeof (EFI_PEI_PPI_DESCRIPTOR) - ); - Private->BlkIoPpiList.Ppi =3D &Private->BlkIoPpi; - - Private->BlkIo2Ppi.Revision =3D EFI_PEI_RECOVERY_BLOCK_= IO2_PPI_REVISION; - Private->BlkIo2Ppi.GetNumberOfBlockDevices =3D NvmeBlockIoPeimGetDevic= eNo2; - Private->BlkIo2Ppi.GetBlockDeviceMediaInfo =3D NvmeBlockIoPeimGetMedia= Info2; - Private->BlkIo2Ppi.ReadBlocks =3D NvmeBlockIoPeimReadBloc= ks2; - CopyMem ( - &Private->BlkIo2PpiList, - &mNvmeBlkIo2PpiListTemplate, - sizeof (EFI_PEI_PPI_DESCRIPTOR) - ); - Private->BlkIo2PpiList.Ppi =3D &Private->BlkIo2Ppi; - PeiServicesInstallPpi (&Private->BlkIoPpiList); - - // - // Check if the NVME controller supports the Security Receive/Send com= mands - // - if ((Private->ControllerData->Oacs & SECURITY_SEND_RECEIVE_SUPPORTED) = !=3D 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 =3D EDKII_STORAGE_SEC= URITY_PPI_REVISION; - Private->StorageSecurityPpi.GetNumberofDevices =3D NvmeStorageSecuri= tyGetDeviceNo; - Private->StorageSecurityPpi.GetDevicePath =3D NvmeStorageSecuri= tyGetDevicePath; - Private->StorageSecurityPpi.ReceiveData =3D NvmeStorageSecuri= tyReceiveData; - Private->StorageSecurityPpi.SendData =3D NvmeStorageSecuri= tySendData; - CopyMem ( - &Private->StorageSecurityPpiList, - &mNvmeStorageSecurityPpiListTemplate, - sizeof (EFI_PEI_PPI_DESCRIPTOR) - ); - Private->StorageSecurityPpiList.Ppi =3D &Private->StorageSecurityPpi; - PeiServicesInstallPpi (&Private->StorageSecurityPpiList); } =20 - 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++; } =20 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 Notific= ation + event that caused this function to execut= e. + @param[in] Ppi Pointer to the PPI data associated with t= his function. + + @retval EFI_SUCCESS The function completes successfully + @retval Others Cannot initialize Nvme controller from gi= ven 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 =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + NvmeHcPpi =3D (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; +} diff --git a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.h b/MdeModule= Pkg/Bus/Pci/NvmExpressPei/NvmExpressPei.h index 78a6b7016503..12a7624099c0 100644 --- a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.h +++ b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.h @@ -14,6 +14,7 @@ #include =20 #include +#include =20 #include #include @@ -22,6 +23,7 @@ #include #include #include +#include =20 #include #include @@ -29,6 +31,7 @@ #include #include #include +#include =20 // // 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_PRIV= ATE_DATA; =20 +/** + 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_CLAS= S_MASS_STORAGE_SOLID_STATE, PCI_IF_MASS_STORAGE_SOLID_STATE_ENTERPRISE_NVMH= CI) + #include "NvmExpressPeiHci.h" #include "NvmExpressPeiPassThru.h" #include "NvmExpressPeiBlockIo.h" @@ -345,4 +359,44 @@ NvmeS3SkipThisController ( IN UINTN HcDevicePathLength ); =20 +/** + Callback for EDKII_PCI_DEVICE_PPI installation. + + @param[in] PeiServices Pointer to PEI Services Table. + @param[in] NotifyDescriptor Pointer to the descriptor for the Notific= ation + event that caused this function to execut= e. + @param[in] Ppi Pointer to the PPI data associated with t= his function. + + @retval EFI_SUCCESS The function completes successfully + @retval Others Cannot initialize Nvme controller from gi= ven 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 Notific= ation + event that caused this function to execut= e. + @param[in] Ppi Pointer to the PPI data associated with t= his function. + + @retval EFI_SUCCESS The function completes successfully + @retval Others Cannot initialize Nvme controller from gi= ven 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 diff --git a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.inf b/MdeModu= lePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.inf index 4dd6c5704fa3..ba6f1afbf168 100644 --- a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.inf +++ b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.inf @@ -44,6 +44,7 @@ =20 [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 @@ =20 [Depex] gEfiPeiMemoryDiscoveredPpiGuid AND - gEdkiiPeiNvmExpressHostControllerPpiGuid AND gEfiPeiMasterBootModePpiGuid =20 [UserExtensions.TianoCore."ExtraFiles"] --=20 2.37.0.windows.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#92945): https://edk2.groups.io/g/devel/message/92945 Mute This Topic: https://groups.io/mt/93340344/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-