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.88; helo=mga01.intel.com; envelope-from=eric.dong@intel.com; receiver=edk2-devel@lists.01.org Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) (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 37EE2202E5343 for ; Sun, 17 Feb 2019 19:02:39 -0800 (PST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga008.jf.intel.com ([10.7.209.65]) by fmsmga101.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 17 Feb 2019 19:02:39 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.58,382,1544515200"; d="scan'208";a="118713988" Received: from fmsmsx108.amr.corp.intel.com ([10.18.124.206]) by orsmga008.jf.intel.com with ESMTP; 17 Feb 2019 19:02:37 -0800 Received: from shsmsx152.ccr.corp.intel.com (10.239.6.52) by FMSMSX108.amr.corp.intel.com (10.18.124.206) with Microsoft SMTP Server (TLS) id 14.3.408.0; Sun, 17 Feb 2019 19:02:16 -0800 Received: from shsmsx102.ccr.corp.intel.com ([169.254.2.207]) by SHSMSX152.ccr.corp.intel.com ([169.254.6.109]) with mapi id 14.03.0415.000; Mon, 18 Feb 2019 11:02:00 +0800 From: "Dong, Eric" To: "Wu, Hao A" , "edk2-devel@lists.01.org" Thread-Topic: [PATCH v5 07/13] MdeModulePkg/NvmExpressPei: Consume S3StorageDeviceInitList LockBox Thread-Index: AQHUxPcJGGAoc/f//UWlYozn5BGJdKXk4gYQ Date: Mon, 18 Feb 2019 03:01:59 +0000 Message-ID: References: <20190215062338.19412-1-hao.a.wu@intel.com> <20190215062338.19412-8-hao.a.wu@intel.com> In-Reply-To: <20190215062338.19412-8-hao.a.wu@intel.com> Accept-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [10.239.127.40] MIME-Version: 1.0 Subject: Re: [PATCH v5 07/13] 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: Mon, 18 Feb 2019 03:02:40 -0000 Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Hi Hao, > -----Original Message----- > From: Wu, Hao A > Sent: Friday, February 15, 2019 2:24 PM > To: edk2-devel@lists.01.org > Cc: Wu, Hao A ; Wang, Jian J ; > Ni, Ray ; Dong, Eric > Subject: [PATCH v5 07/13] MdeModulePkg/NvmExpressPei: Consume > S3StorageDeviceInitList LockBox >=20 > REF:https://bugzilla.tianocore.org/show_bug.cgi?id=3D1409 >=20 > For the NvmExpressPei driver, this commit will update the driver to consu= me > the S3StorageDeviceInitList LockBox in S3 phase. The purpose is to perfor= m > an on-demand (partial) NVM Express device enumeration/initialization to > benefit the S3 resume performance. >=20 > 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 | 36 +++++++ > MdeModulePkg/Bus/Pci/NvmExpressPei/DevicePath.c | 53 +++++++++ > MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.c | 20 ++++ > MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiS3.c | 114 > ++++++++++++++++++++ > 5 files changed, 230 insertions(+), 1 deletion(-) >=20 > 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 >=20 > @@ -54,6 +55,7 @@ > BaseMemoryLib > IoLib > TimerLib > + LockBoxLib > PeimEntryPoint >=20 > [Ppis] > @@ -64,9 +66,13 @@ > gEfiPeiVirtualBlockIo2PpiGuid ## SOMETIMES_PRODUCES > gEdkiiPeiStorageSecurityCommandPpiGuid ## SOMETIMES_PRODUCES >=20 > +[Guids] > + gS3StorageDeviceInitListGuid ## SOMETIMES_CONSUMES #= # > UNDEFINED > + > [Depex] > gEfiPeiMemoryDiscoveredPpiGuid AND > - gEdkiiPeiNvmExpressHostControllerPpiGuid > + gEdkiiPeiNvmExpressHostControllerPpiGuid AND > + gEfiPeiMasterBootModePpiGuid >=20 > [UserExtensions.TianoCore."ExtraFiles"] > NvmExpressPeiExtra.uni > diff --git a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.h > b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.h > index 92c3854c6e..e2a693abe8 100644 > --- a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.h > +++ b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.h > @@ -267,6 +267,26 @@ NvmePeimEndOfPei ( > ); >=20 > /** > + Get the size of the current device path instance. > + > + @param[in] DevicePath A pointer to the > EFI_DEVICE_PATH_PROTOCOL > + structure. > + @param[out] InstanceSize The size of the current device path > instance. > + @param[out] EntireDevicePathEnd Indicate whether the instance is th= e > last > + one in the device path strucure. > + > + @retval EFI_SUCCESS The size of the current device path instance is > fetched. > + @retval Others Fails to get the size of the current device pat= h instance. > + > +**/ > +EFI_STATUS > +GetDevicePathInstanceSize ( > + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, > + OUT UINTN *InstanceSize, > + OUT BOOLEAN *EntireDevicePathEnd > + ); > + > +/** > Check the validity of the device path of a NVM Express host controller= . >=20 > @param[in] DevicePath A pointer to the EFI_DEVICE_PATH_PROTOC= OL > @@ -309,4 +329,20 @@ NvmeBuildDevicePath ( > OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath > ); >=20 > +/** > + Determine if a specific NVM Express controller can be skipped for S3 p= hase. > + > + @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/DevicePath.c > b/MdeModulePkg/Bus/Pci/NvmExpressPei/DevicePath.c > index 5dab447f09..ed05d7a2be 100644 > --- a/MdeModulePkg/Bus/Pci/NvmExpressPei/DevicePath.c > +++ b/MdeModulePkg/Bus/Pci/NvmExpressPei/DevicePath.c > @@ -89,6 +89,59 @@ NextDevicePathNode ( > } >=20 > /** > + Get the size of the current device path instance. > + > + @param[in] DevicePath A pointer to the > EFI_DEVICE_PATH_PROTOCOL > + structure. > + @param[out] InstanceSize The size of the current device path > instance. > + @param[out] EntireDevicePathEnd Indicate whether the instance is th= e > last > + one in the device path strucure. > + > + @retval EFI_SUCCESS The size of the current device path instance is > fetched. > + @retval Others Fails to get the size of the current device pat= h instance. > + > +**/ > +EFI_STATUS > +GetDevicePathInstanceSize ( > + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, > + OUT UINTN *InstanceSize, > + OUT BOOLEAN *EntireDevicePathEnd > + ) > +{ > + EFI_DEVICE_PATH_PROTOCOL *Walker; > + > + if (DevicePath =3D=3D NULL || InstanceSize =3D=3D NULL || EntireDevice= PathEnd =3D=3D > NULL) { > + return EFI_INVALID_PARAMETER; > + } > + > + // > + // Find the end of the device path instance // Walker =3D DevicePath= ; > + while (Walker->Type !=3D END_DEVICE_PATH_TYPE) { > + Walker =3D NextDevicePathNode (Walker); } > + > + // > + // Check if 'Walker' points to the end of an entire device path // > + if (Walker->SubType =3D=3D END_ENTIRE_DEVICE_PATH_SUBTYPE) { > + *EntireDevicePathEnd =3D TRUE; > + } else if (Walker->SubType =3D=3D END_INSTANCE_DEVICE_PATH_SUBTYPE) { > + *EntireDevicePathEnd =3D FALSE; > + } else { > + return EFI_INVALID_PARAMETER; > + } > + > + // > + // Compute the size of the device path instance // *InstanceSize =3D > + ((UINTN) Walker - (UINTN) (DevicePath)) + sizeof > + (EFI_DEVICE_PATH_PROTOCOL); > + > + return EFI_SUCCESS; > +} Check whether can leverage UefiDevicePathLib API. Thanks, Eric > + > +/** > Check the validity of the device path of a NVM Express host controller= . >=20 > @param[in] DevicePath A pointer to the EFI_DEVICE_PATH_PROTOC= OL > 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__)); >=20 > // > + // Get the current boot mode. > + // > + Status =3D 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 =3D PeiServicesLocatePpi ( > @@ -279,6 +289,16 @@ NvmExpressPeimEntry ( > continue; > } >=20 > + 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 > // > diff --git a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiS3.c > b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiS3.c > new file mode 100644 > index 0000000000..eb3af75b89 > --- /dev/null > +++ b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiS3.c > @@ -0,0 +1,114 @@ > +/** @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 p= hase. > + > + @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 EntireEnd; > + BOOLEAN Skip; > + > + // > + // From the LockBox, get the list of device paths for devices need to > + be // initialized in S3. > + // > + S3InitDevices =3D NULL; > + S3InitDevicesLength =3D sizeof (DummyData); > + EntireEnd =3D FALSE; > + Skip =3D TRUE; > + Status =3D RestoreLockBox (&gS3StorageDeviceInitListGuid, &DummyData, > + &S3InitDevicesLength); if (Status !=3D EFI_BUFFER_TOO_SMALL) { > + return Skip; > + } else { > + S3InitDevices =3D AllocatePool (S3InitDevicesLength); > + if (S3InitDevices =3D=3D NULL) { > + return Skip; > + } > + > + Status =3D RestoreLockBox (&gS3StorageDeviceInitListGuid, S3InitDevi= ces, > &S3InitDevicesLength); > + if (EFI_ERROR (Status)) { > + return Skip; > + } > + } > + > + if (S3InitDevices =3D=3D NULL) { > + return Skip; > + } > + > + // > + // Only need to initialize the controllers that exist in the device li= st. > + // > + do { > + // > + // Fetch the size of current device path instance. > + // > + Status =3D GetDevicePathInstanceSize ( > + S3InitDevices, > + &DevicePathInstLength, > + &EntireEnd > + ); > + if (EFI_ERROR (Status)) { > + break; > + } > + > + DevicePathInst =3D S3InitDevices; > + S3InitDevices =3D (EFI_DEVICE_PATH_PROTOCOL *)((UINTN) S3InitDevice= s > + + DevicePathInstLength); > + > + if (HcDevicePathLength >=3D DevicePathInstLength) { > + 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) > + ) =3D=3D 0) { > + Skip =3D FALSE; > + break; > + } > + } while (!EntireEnd); > + > + return Skip; > +} > -- > 2.12.0.windows.1