From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=192.55.52.120; helo=mga04.intel.com; envelope-from=hao.a.wu@intel.com; receiver=edk2-devel@lists.01.org Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 6FF29211BB8D9 for ; Tue, 29 Jan 2019 05:44:37 -0800 (PST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by fmsmga104.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 29 Jan 2019 05:44:38 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.56,537,1539673200"; d="scan'208";a="129454610" Received: from shwdeopenpsi014.ccr.corp.intel.com ([10.239.9.8]) by FMSMGA003.fm.intel.com with ESMTP; 29 Jan 2019 05:44:36 -0800 From: Hao Wu To: edk2-devel@lists.01.org Cc: Hao Wu , Jian J Wang , Ray Ni , Eric Dong Date: Tue, 29 Jan 2019 21:44:19 +0800 Message-Id: <20190129134424.5308-8-hao.a.wu@intel.com> X-Mailer: git-send-email 2.12.0.windows.1 In-Reply-To: <20190129134424.5308-1-hao.a.wu@intel.com> References: <20190129134424.5308-1-hao.a.wu@intel.com> Subject: [PATCH v1 07/12] MdeModulePkg/NvmExpressPei: Consume S3StorageDeviceInitList LockBox X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 29 Jan 2019 13:44:37 -0000 REF:https://bugzilla.tianocore.org/show_bug.cgi?id=1409 For the NvmExpressPei driver, this commit will update the driver to consume the S3StorageDeviceInitList LockBox in S3 phase. The purpose is to perform an on-demand (partial) NVM Express device enumeration/initialization to benefit the S3 resume performance. Cc: Jian J Wang Cc: Ray Ni Cc: Eric Dong Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Hao Wu --- MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.inf | 8 +- MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.h | 16 +++ MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.c | 20 ++++ MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiS3.c | 106 ++++++++++++++++++++ 4 files changed, 149 insertions(+), 1 deletion(-) diff --git a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.inf b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.inf index 0666e5892b..22b703e971 100644 --- a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.inf +++ b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.inf @@ -40,6 +40,7 @@ NvmExpressPeiHci.h NvmExpressPeiPassThru.c NvmExpressPeiPassThru.h + NvmExpressPeiS3.c NvmExpressPeiStorageSecurity.c NvmExpressPeiStorageSecurity.h @@ -54,6 +55,7 @@ BaseMemoryLib IoLib TimerLib + LockBoxLib PeimEntryPoint [Ppis] @@ -64,9 +66,13 @@ gEfiPeiVirtualBlockIo2PpiGuid ## SOMETIMES_PRODUCES gEdkiiPeiStorageSecurityCommandPpiGuid ## SOMETIMES_PRODUCES +[Guids] + gS3StorageDeviceInitListGuid ## SOMETIMES_CONSUMES ## UNDEFINED + [Depex] gEfiPeiMemoryDiscoveredPpiGuid AND - gEdkiiPeiNvmExpressHostControllerPpiGuid + gEdkiiPeiNvmExpressHostControllerPpiGuid AND + gEfiPeiMasterBootModePpiGuid [UserExtensions.TianoCore."ExtraFiles"] NvmExpressPeiExtra.uni diff --git a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.h b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.h index 7047c4f3ff..6f01413e6d 100644 --- a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.h +++ b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.h @@ -332,4 +332,20 @@ NvmeBuildDevicePath ( OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath ); +/** + Determine if a specific NVM Express controller can be skipped for S3 phase. + + @param[in] HcDevicePath Device path of the controller. + @param[in] HcDevicePathLength Length of the device path specified by + HcDevicePath. + + @retval The number of ports that need to be enumerated. + +**/ +BOOLEAN +NvmeS3SkipThisController ( + IN EFI_DEVICE_PATH_PROTOCOL *HcDevicePath, + IN UINTN HcDevicePathLength + ); + #endif diff --git a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.c b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.c index 96622e6fd5..43b2dfc3e7 100644 --- a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.c +++ b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.c @@ -213,6 +213,7 @@ NvmExpressPeimEntry ( ) { EFI_STATUS Status; + EFI_BOOT_MODE BootMode; EDKII_NVM_EXPRESS_HOST_CONTROLLER_PPI *NvmeHcPpi; UINT8 Controller; UINTN MmioBase; @@ -224,6 +225,15 @@ NvmExpressPeimEntry ( DEBUG ((DEBUG_INFO, "%a: Enters.\n", __FUNCTION__)); // + // Get the current boot mode. + // + Status = PeiServicesGetBootMode (&BootMode); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: Fail to get the current boot mode.\n", __FUNCTION__)); + return Status; + } + + // // Locate the NVME host controller PPI // Status = PeiServicesLocatePpi ( @@ -279,6 +289,16 @@ NvmExpressPeimEntry ( continue; } + 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 // diff --git a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiS3.c b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiS3.c new file mode 100644 index 0000000000..afcf5f6c0a --- /dev/null +++ b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiS3.c @@ -0,0 +1,106 @@ +/** @file + The NvmExpressPei driver is used to manage non-volatile memory subsystem + which follows NVM Express specification at PEI phase. + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions + of the BSD License which accompanies this distribution. The + full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "NvmExpressPei.h" + +#include + +#include + +/** + Determine if a specific NVM Express controller can be skipped for S3 phase. + + @param[in] HcDevicePath Device path of the controller. + @param[in] HcDevicePathLength Length of the device path specified by + HcDevicePath. + + @retval The number of ports that need to be enumerated. + +**/ +BOOLEAN +NvmeS3SkipThisController ( + IN EFI_DEVICE_PATH_PROTOCOL *HcDevicePath, + IN UINTN HcDevicePathLength + ) +{ + EFI_STATUS Status; + UINT8 DummyData; + UINTN S3InitDevicesLength; + EFI_DEVICE_PATH_PROTOCOL *S3InitDevices; + EFI_DEVICE_PATH_PROTOCOL *DevicePathInst; + UINTN DevicePathInstLength; + BOOLEAN Skip; + + // + // From the LockBox, get the list of device paths for devices need to be + // initialized in S3. + // + S3InitDevices = NULL; + S3InitDevicesLength = sizeof (DummyData); + Skip = TRUE; + Status = RestoreLockBox (&gS3StorageDeviceInitListGuid, &DummyData, &S3InitDevicesLength); + if (Status != EFI_BUFFER_TOO_SMALL) { + return Skip; + } else { + S3InitDevices = AllocatePool (S3InitDevicesLength); + if (S3InitDevices == NULL) { + return Skip; + } + + Status = RestoreLockBox (&gS3StorageDeviceInitListGuid, S3InitDevices, &S3InitDevicesLength); + if (EFI_ERROR (Status)) { + return Skip; + } + } + + if (S3InitDevices == NULL) { + return Skip; + } + + // + // Only need to initialize the controllers that exist in the device list. + // + do { + // + // Fetch the next device path instance. + // + DevicePathInst = GetNextDevicePathInstance (&S3InitDevices, &DevicePathInstLength); + if (DevicePathInst == NULL) { + break; + } + + if ((HcDevicePathLength >= DevicePathInstLength) || + (HcDevicePathLength <= sizeof (EFI_DEVICE_PATH_PROTOCOL))) { + continue; + } + + // + // Compare the device paths to determine if the device is managed by this + // controller. + // + if (CompareMem ( + DevicePathInst, + HcDevicePath, + HcDevicePathLength - sizeof (EFI_DEVICE_PATH_PROTOCOL) + ) == 0) { + Skip = FALSE; + break; + } + } while (S3InitDevices != NULL); + + return Skip; +} -- 2.12.0.windows.1