From: "Wu, Hao A" <hao.a.wu@intel.com>
To: "Dong, Eric" <eric.dong@intel.com>,
"edk2-devel@lists.01.org" <edk2-devel@lists.01.org>
Subject: Re: [PATCH v5 06/13] MdeModulePkg/NvmExpressPei: Add logic to produce SSC PPI
Date: Mon, 18 Feb 2019 06:06:58 +0000 [thread overview]
Message-ID: <B80AF82E9BFB8E4FBD8C89DA810C6A093C897ADB@SHSMSX104.ccr.corp.intel.com> (raw)
In-Reply-To: <ED077930C258884BBCB450DB737E662259DB1022@shsmsx102.ccr.corp.intel.com>
> -----Original Message-----
> From: Dong, Eric
> Sent: Monday, February 18, 2019 10:59 AM
> To: Wu, Hao A; edk2-devel@lists.01.org
> Cc: Wang, Jian J; Ni, Ray
> Subject: RE: [PATCH v5 06/13] MdeModulePkg/NvmExpressPei: Add logic to
> produce SSC PPI
>
> 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 <hao.a.wu@intel.com>; Wang, Jian J
> <jian.j.wang@intel.com>;
> > Ni, Ray <ray.ni@intel.com>; Dong, Eric <eric.dong@intel.com>
> > Subject: [PATCH v5 06/13] MdeModulePkg/NvmExpressPei: Add logic to
> > produce SSC PPI
> >
> > REF:https://bugzilla.tianocore.org/show_bug.cgi?id=1409
> >
> > For the NvmExpressPei driver, this commit will add codes to produce the
> > Storage Security Command PPI if the underlying NVM Express controller
> > supports the Security Send and Security Receive commands.
> >
> > Cc: Jian J Wang <jian.j.wang@intel.com>
> > Cc: Ray Ni <ray.ni@intel.com>
> > Cc: Eric Dong <eric.dong@intel.com>
> > Contributed-under: TianoCore Contribution Agreement 1.1
> > Signed-off-by: Hao Wu <hao.a.wu@intel.com>
> > ---
> > MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.inf | 10
> +-
> > MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.h | 58
> ++-
> > MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiHci.h | 20
> +-
> >
> MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiStorageSecurity.h
> > | 247 ++++++++++++
> > MdeModulePkg/Bus/Pci/NvmExpressPei/DevicePath.c | 231
> > +++++++++++
> > MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.c | 143
> > +++++--
> > MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiHci.c | 32
> +-
> >
> MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiStorageSecurity.c
> > | 423 ++++++++++++++++++++
> > 8 files changed, 1075 insertions(+), 89 deletions(-)
> >
> > diff --git a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.inf
> > b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.inf
> > index 9591572fec..0666e5892b 100644
> > --- a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.inf
> > +++ b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.inf
> > @@ -2,7 +2,7 @@
> > # The NvmExpressPei driver is used to manage non-volatile memory
> > subsystem
> > # which follows NVM Express specification at PEI phase.
> > #
> > -# Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
> > +# Copyright (c) 2018 - 2019, Intel Corporation. All rights reserved.<BR>
> > #
> > # This program and the accompanying materials
> > # are licensed and made available under the terms and conditions of the
> > BSD License
> > @@ -30,6 +30,7 @@
> > #
> >
> > [Sources]
> > + DevicePath.c
> > DmaMem.c
> > NvmExpressPei.c
> > NvmExpressPei.h
> > @@ -39,6 +40,8 @@
> > NvmExpressPeiHci.h
> > NvmExpressPeiPassThru.c
> > NvmExpressPeiPassThru.h
> > + NvmExpressPeiStorageSecurity.c
> > + NvmExpressPeiStorageSecurity.h
> >
> > [Packages]
> > MdePkg/MdePkg.dec
> > @@ -54,11 +57,12 @@
> > PeimEntryPoint
> >
> > [Ppis]
> > - gEfiPeiVirtualBlockIoPpiGuid ## PRODUCES
> > - gEfiPeiVirtualBlockIo2PpiGuid ## PRODUCES
> > gEdkiiPeiNvmExpressHostControllerPpiGuid ## CONSUMES
> > gEdkiiIoMmuPpiGuid ## CONSUMES
> > gEfiEndOfPeiSignalPpiGuid ## CONSUMES
> > + gEfiPeiVirtualBlockIoPpiGuid ## SOMETIMES_PRODUCES
> > + gEfiPeiVirtualBlockIo2PpiGuid ## SOMETIMES_PRODUCES
> > + gEdkiiPeiStorageSecurityCommandPpiGuid ##
> > SOMETIMES_PRODUCES
> >
> > [Depex]
> > gEfiPeiMemoryDiscoveredPpiGuid AND
> > diff --git a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.h
> > b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.h
> > index 0135eca6f0..92c3854c6e 100644
> > --- a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.h
> > +++ b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.h
> > @@ -25,6 +25,7 @@
> > #include <Ppi/NvmExpressHostController.h>
> > #include <Ppi/BlockIo.h>
> > #include <Ppi/BlockIo2.h>
> > +#include <Ppi/StorageSecurityCommand.h>
> > #include <Ppi/IoMmu.h>
> > #include <Ppi/EndOfPeiPhase.h>
> >
> > @@ -44,6 +45,7 @@ typedef struct
> > _PEI_NVME_CONTROLLER_PRIVATE_DATA
> > PEI_NVME_CONTROLLER_PRIVATE_DA
> > #include "NvmExpressPeiHci.h"
> > #include "NvmExpressPeiPassThru.h"
> > #include "NvmExpressPeiBlockIo.h"
> > +#include "NvmExpressPeiStorageSecurity.h"
> >
> > //
> > // NVME PEI driver implementation related definitions
> > @@ -90,10 +92,15 @@ struct _PEI_NVME_NAMESPACE_INFO {
> > struct _PEI_NVME_CONTROLLER_PRIVATE_DATA {
> > UINT32 Signature;
> > UINTN MmioBase;
> > + UINTN DevicePathLength;
> > + EFI_DEVICE_PATH_PROTOCOL *DevicePath;
> > +
> > EFI_PEI_RECOVERY_BLOCK_IO_PPI BlkIoPpi;
> > EFI_PEI_RECOVERY_BLOCK_IO2_PPI BlkIo2Ppi;
> > + EDKII_PEI_STORAGE_SECURITY_CMD_PPI StorageSecurityPpi;
> > EFI_PEI_PPI_DESCRIPTOR BlkIoPpiList;
> > EFI_PEI_PPI_DESCRIPTOR BlkIo2PpiList;
> > + EFI_PEI_PPI_DESCRIPTOR StorageSecurityPpiList;
> > EFI_PEI_NOTIFY_DESCRIPTOR EndOfPeiNotifyList;
> >
> > //
> > @@ -139,11 +146,13 @@ struct _PEI_NVME_CONTROLLER_PRIVATE_DATA
> {
> > PEI_NVME_NAMESPACE_INFO *NamespaceInfo;
> > };
> >
> > -#define GET_NVME_PEIM_HC_PRIVATE_DATA_FROM_THIS_BLKIO(a) \
> > +#define GET_NVME_PEIM_HC_PRIVATE_DATA_FROM_THIS_BLKIO(a)
> > \
> > CR (a, PEI_NVME_CONTROLLER_PRIVATE_DATA, BlkIoPpi,
> > NVME_PEI_CONTROLLER_PRIVATE_DATA_SIGNATURE)
> > -#define GET_NVME_PEIM_HC_PRIVATE_DATA_FROM_THIS_BLKIO2(a)
> \
> > +#define GET_NVME_PEIM_HC_PRIVATE_DATA_FROM_THIS_BLKIO2(a)
> > \
> > CR (a, PEI_NVME_CONTROLLER_PRIVATE_DATA, BlkIo2Ppi,
> > NVME_PEI_CONTROLLER_PRIVATE_DATA_SIGNATURE)
> > -#define GET_NVME_PEIM_HC_PRIVATE_DATA_FROM_THIS_NOTIFY(a)
> \
> > +#define
> >
> GET_NVME_PEIM_HC_PRIVATE_DATA_FROM_THIS_STROAGE_SECURITY(a)
> > \
> > + CR (a, PEI_NVME_CONTROLLER_PRIVATE_DATA, StorageSecurityPpi,
> > NVME_PEI_CONTROLLER_PRIVATE_DATA_SIGNATURE)
> > +#define GET_NVME_PEIM_HC_PRIVATE_DATA_FROM_THIS_NOTIFY(a)
> > \
> > CR (a, PEI_NVME_CONTROLLER_PRIVATE_DATA, EndOfPeiNotifyList,
> > NVME_PEI_CONTROLLER_PRIVATE_DATA_SIGNATURE)
> >
> >
> > @@ -257,4 +266,47 @@ NvmePeimEndOfPei (
> > IN VOID *Ppi
> > );
> >
> > +/**
> > + Check the validity of the device path of a NVM Express host controller.
> > +
> > + @param[in] DevicePath A pointer to the
> > EFI_DEVICE_PATH_PROTOCOL
> > + structure.
> > + @param[in] DevicePathLength The length of the device path.
> > +
> > + @retval EFI_SUCCESS The device path is valid.
> > + @retval EFI_INVALID_PARAMETER The device path is invalid.
> > +
> > +**/
> > +EFI_STATUS
> > +NvmeCheckHcDevicePath (
> > + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
> > + IN UINTN DevicePathLength
> > + );
> > +
> > +/**
> > + Build the device path for an Nvm Express device with given namespace
> > identifier
> > + and namespace extended unique identifier.
> > +
> > + @param[in] Private A pointer to the
> > PEI_NVME_CONTROLLER_PRIVATE_DATA
> > + data structure.
> > + @param[in] NamespaceId The given namespace identifier.
> > + @param[in] NamespaceUuid The given namespace extended unique
> > identifier.
> > + @param[out] DevicePathLength The length of the device path in bytes
> > specified
> > + by DevicePath.
> > + @param[out] DevicePath The device path of Nvm Express device.
> > +
> > + @retval EFI_SUCCESS The operation succeeds.
> > + @retval EFI_INVALID_PARAMETER The parameters are invalid.
> > + @retval EFI_OUT_OF_RESOURCES The operation fails due to lack of
> > resources.
> > +
> > +**/
> > +EFI_STATUS
> > +NvmeBuildDevicePath (
> > + IN PEI_NVME_CONTROLLER_PRIVATE_DATA *Private,
> > + IN UINT32 NamespaceId,
> > + IN UINT64 NamespaceUuid,
> > + OUT UINTN *DevicePathLength,
> > + OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath
> > + );
> > +
> > #endif
> > diff --git a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiHci.h
> > b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiHci.h
> > index ff334e3e17..ad1d5d0d8a 100644
> > --- a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiHci.h
> > +++ b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiHci.h
> > @@ -2,7 +2,7 @@
> > The NvmExpressPei driver is used to manage non-volatile memory
> > subsystem
> > which follows NVM Express specification at PEI phase.
> >
> > - Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
> > + Copyright (c) 2018 - 2019, Intel Corporation. All rights reserved.<BR>
> >
> > This program and the accompanying materials
> > are licensed and made available under the terms and conditions
> > @@ -107,20 +107,6 @@ NvmeBaseMemPageOffset (
> > );
> >
> > /**
> > - Disable the Nvm Express controller.
> > -
> > - @param[in] Private The pointer to the
> > PEI_NVME_CONTROLLER_PRIVATE_DATA data structure.
> > -
> > - @return EFI_SUCCESS Successfully disable the controller.
> > - @return others Fail to disable the controller.
> > -
> > -**/
> > -EFI_STATUS
> > -NvmeDisableController (
> > - IN PEI_NVME_CONTROLLER_PRIVATE_DATA *Private
> > - );
> > -
> > -/**
> > Initialize the Nvm Express controller.
> >
> > @param[in] Private The pointer to the
> > PEI_NVME_CONTROLLER_PRIVATE_DATA data structure.
> > @@ -153,13 +139,13 @@ NvmeIdentifyNamespace (
> > );
> >
> > /**
> > - Free the resources allocated by an NVME controller.
> > + Free the DMA resources allocated by an NVME controller.
> >
> > @param[in] Private The pointer to the
> > PEI_NVME_CONTROLLER_PRIVATE_DATA data structure.
> >
> > **/
> > VOID
> > -NvmeFreeControllerResource (
> > +NvmeFreeDmaResource (
> > IN PEI_NVME_CONTROLLER_PRIVATE_DATA *Private
> > );
> >
> > diff --git
> >
> a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiStorageSecurity.
> > h
> >
> b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiStorageSecurity.
> > h
> > new file mode 100644
> > index 0000000000..8ccfb425e7
> > --- /dev/null
> > +++
> >
> b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiStorageSecurity.
> > h
> > @@ -0,0 +1,247 @@
> > +/** @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.<BR>
> > +
> > + 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.
> > +
> > +**/
> > +
> > +#ifndef _NVM_EXPRESS_PEI_STORAGE_SECURITY_H_
> > +#define _NVM_EXPRESS_PEI_STORAGE_SECURITY_H_
> > +
> > +/**
> > + Gets the count of storage security devices that one specific driver
> detects.
> > +
> > + @param[in] This The PPI instance pointer.
> > + @param[out] NumberofDevices The number of storage security
> devices
> > discovered.
> > +
> > + @retval EFI_SUCCESS The operation performed successfully.
> > + @retval EFI_INVALID_PARAMETER The parameters are invalid.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +NvmeStorageSecurityGetDeviceNo (
> > + IN EDKII_PEI_STORAGE_SECURITY_CMD_PPI *This,
> > + OUT UINTN *NumberofDevices
> > + );
> > +
> > +/**
> > + Gets the device path of a specific storage security device.
> > +
> > + @param[in] This The PPI instance pointer.
> > + @param[in] DeviceIndex Specifies the storage security device to
> > which
> > + the function wants to talk. Because the driver
> > + that implements Storage Security Command PPIs
> > + will manage multiple storage devices, the PPIs
> > + that want to talk to a single device must specify
> > + the device index that was assigned during the
> > + enumeration process. This index is a number from
> > + one to NumberofDevices.
> > + @param[out] DevicePathLength The length of the device path in bytes
> > specified
> > + by DevicePath.
> > + @param[out] DevicePath The device path of storage security device.
> > + This field re-uses EFI Device Path Protocol as
> > + defined by Section 10.2 EFI Device Path Protocol
> > + of UEFI 2.7 Specification.
> > +
> > + @retval EFI_SUCCESS The operation succeeds.
> > + @retval EFI_INVALID_PARAMETER DevicePathLength or DevicePath is
> > NULL.
> > + @retval EFI_NOT_FOUND The specified storage security device not
> > found.
> > + @retval EFI_OUT_OF_RESOURCES The operation fails due to lack of
> > resources.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +NvmeStorageSecurityGetDevicePath (
> > + IN EDKII_PEI_STORAGE_SECURITY_CMD_PPI *This,
> > + IN UINTN DeviceIndex,
> > + OUT UINTN *DevicePathLength,
> > + OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath
> > + );
> > +
> > +/**
> > + Send a security protocol command to a device that receives data and/or
> > the result
> > + of one or more commands sent by SendData.
> > +
> > + The ReceiveData function sends a security protocol command to the
> given
> > DeviceIndex.
> > + The security protocol command sent is defined by SecurityProtocolId and
> > contains
> > + the security protocol specific data SecurityProtocolSpecificData. The
> > function
> > + returns the data from the security protocol command in PayloadBuffer.
> > +
> > + For devices supporting the SCSI command set, the security protocol
> > command is sent
> > + using the SECURITY PROTOCOL IN command defined in SPC-4.
> > +
> > + For devices supporting the ATA command set, the security protocol
> > command is sent
> > + using one of the TRUSTED RECEIVE commands defined in ATA8-ACS if
> > PayloadBufferSize
> > + is non-zero.
> > +
> > + If the PayloadBufferSize is zero, the security protocol command is sent
> > using the
> > + Trusted Non-Data command defined in ATA8-ACS.
> > +
> > + If PayloadBufferSize is too small to store the available data from the
> > security
> > + protocol command, the function shall copy PayloadBufferSize bytes into
> > the
> > + PayloadBuffer and return EFI_WARN_BUFFER_TOO_SMALL.
> > +
> > + If PayloadBuffer or PayloadTransferSize is NULL and PayloadBufferSize is
> > non-zero,
> > + the function shall return EFI_INVALID_PARAMETER.
> > +
> > + If the given DeviceIndex does not support security protocol commands,
> > the function
> > + shall return EFI_UNSUPPORTED.
> > +
> > + If the security protocol fails to complete within the Timeout period, the
> > function
> > + shall return EFI_TIMEOUT.
> > +
> > + If the security protocol command completes without an error, the
> function
> > shall
> > + return EFI_SUCCESS. If the security protocol command completes with
> an
> > error, the
> > + function shall return EFI_DEVICE_ERROR.
> > +
> > + @param[in] This The PPI instance pointer.
> > + @param[in] DeviceIndex Specifies the storage security device to
> which
> > the
> > + function wants to talk. Because the driver that
> > + implements Storage Security Command PPIs will manage
> > + multiple storage devices, the PPIs that want to talk
> > + to a single device must specify the device index
> > + that was assigned during the enumeration process.
> > + This index is a number from one to NumberofDevices.
> > + @param[in] Timeout The timeout, in 100ns units, to use for the
> > execution
> > + of the security protocol command. A Timeout value
> > + of 0 means that this function will wait indefinitely
> > + for the security protocol command to execute. If
> > + Timeout is greater than zero, then this function
> > + will return EFI_TIMEOUT if the time required to
> > + execute the receive data command is greater than
> > + Timeout.
> > + @param[in] SecurityProtocolId
> > + The value of the "Security Protocol" parameter of
> > + the security protocol command to be sent.
> > + @param[in] SecurityProtocolSpecificData
> > + The value of the "Security Protocol Specific"
> > + parameter of the security protocol command to be
> > + sent.
> > + @param[in] PayloadBufferSize
> > + Size in bytes of the payload data buffer.
> > + @param[out] PayloadBuffer A pointer to a destination buffer to store
> > the
> > + security protocol command specific payload data
> > + for the security protocol command. The caller is
> > + responsible for having either implicit or explicit
> > + ownership of the buffer.
> > + @param[out] PayloadTransferSize
> > + A pointer to a buffer to store the size in bytes
> > + of the data written to the payload data buffer.
> > +
> > + @retval EFI_SUCCESS The security protocol command
> completed
> > + successfully.
> > + @retval EFI_WARN_BUFFER_TOO_SMALL The PayloadBufferSize was
> too
> > small to
> > + store the available data from the device.
> > + The PayloadBuffer contains the truncated
> > + data.
> > + @retval EFI_UNSUPPORTED The given DeviceIndex does not
> > support
> > + security protocol commands.
> > + @retval EFI_DEVICE_ERROR The security protocol command
> > completed
> > + with an error.
> > + @retval EFI_INVALID_PARAMETER The PayloadBuffer or
> > PayloadTransferSize
> > + is NULL and PayloadBufferSize is non-zero.
> > + @retval EFI_TIMEOUT A timeout occurred while waiting for the
> > + security protocol command to execute.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +NvmeStorageSecurityReceiveData (
> > + IN EDKII_PEI_STORAGE_SECURITY_CMD_PPI *This,
> > + IN UINTN DeviceIndex,
> > + IN UINT64 Timeout,
> > + IN UINT8 SecurityProtocolId,
> > + IN UINT16 SecurityProtocolSpecificData,
> > + IN UINTN PayloadBufferSize,
> > + OUT VOID *PayloadBuffer,
> > + OUT UINTN *PayloadTransferSize
> > + );
> > +
> > +/**
> > + Send a security protocol command to a device.
> > +
> > + The SendData function sends a security protocol command containing
> the
> > payload
> > + PayloadBuffer to the given DeviceIndex. The security protocol command
> > sent is
> > + defined by SecurityProtocolId and contains the security protocol specific
> > data
> > + SecurityProtocolSpecificData. If the underlying protocol command
> requires
> > a
> > + specific padding for the command payload, the SendData function shall
> > add padding
> > + bytes to the command payload to satisfy the padding requirements.
> > +
> > + For devices supporting the SCSI command set, the security protocol
> > command is
> > + sent using the SECURITY PROTOCOL OUT command defined in SPC-4.
> > +
> > + For devices supporting the ATA command set, the security protocol
> > command is
> > + sent using one of the TRUSTED SEND commands defined in ATA8-ACS if
> > PayloadBufferSize
> > + is non-zero. If the PayloadBufferSize is zero, the security protocol
> > command
> > + is sent using the Trusted Non-Data command defined in ATA8-ACS.
> > +
> > + If PayloadBuffer is NULL and PayloadBufferSize is non-zero, the function
> > shall
> > + return EFI_INVALID_PARAMETER.
> > +
> > + If the given DeviceIndex does not support security protocol commands,
> > the function
> > + shall return EFI_UNSUPPORTED.
> > +
> > + If the security protocol fails to complete within the Timeout period, the
> > function
> > + shall return EFI_TIMEOUT.
> > +
> > + If the security protocol command completes without an error, the
> function
> > shall
> > + return EFI_SUCCESS. If the security protocol command completes with
> an
> > error,
> > + the functio shall return EFI_DEVICE_ERROR.
> > +
> > + @param[in] This The PPI instance pointer.
> > + @param[in] DeviceIndex The ID of the device.
> > + @param[in] Timeout The timeout, in 100ns units, to use for the
> > execution
> > + of the security protocol command. A Timeout value
> > + of 0 means that this function will wait indefinitely
> > + for the security protocol command to execute. If
> > + Timeout is greater than zero, then this function
> > + will return EFI_TIMEOUT if the time required to
> > + execute the receive data command is greater than
> > + Timeout.
> > + @param[in] SecurityProtocolId
> > + The value of the "Security Protocol" parameter of
> > + the security protocol command to be sent.
> > + @param[in] SecurityProtocolSpecificData
> > + The value of the "Security Protocol Specific"
> > + parameter of the security protocol command to be
> > + sent.
> > + @param[in] PayloadBufferSize Size in bytes of the payload data buffer.
> > + @param[in] PayloadBuffer A pointer to a destination buffer to store
> the
> > + security protocol command specific payload data
> > + for the security protocol command.
> > +
> > + @retval EFI_SUCCESS The security protocol command completed
> > successfully.
> > + @retval EFI_UNSUPPORTED The given DeviceIndex does not
> support
> > security
> > + protocol commands.
> > + @retval EFI_DEVICE_ERROR The security protocol command
> > completed with
> > + an error.
> > + @retval EFI_INVALID_PARAMETER The PayloadBuffer is NULL and
> > PayloadBufferSize
> > + is non-zero.
> > + @retval EFI_TIMEOUT A timeout occurred while waiting for the
> > security
> > + protocol command to execute.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +NvmeStorageSecuritySendData (
> > + IN EDKII_PEI_STORAGE_SECURITY_CMD_PPI *This,
> > + IN UINTN DeviceIndex,
> > + IN UINT64 Timeout,
> > + IN UINT8 SecurityProtocolId,
> > + IN UINT16 SecurityProtocolSpecificData,
> > + IN UINTN PayloadBufferSize,
> > + IN VOID *PayloadBuffer
> > + );
> > +
> > +#endif
> > diff --git a/MdeModulePkg/Bus/Pci/NvmExpressPei/DevicePath.c
> > b/MdeModulePkg/Bus/Pci/NvmExpressPei/DevicePath.c
> > new file mode 100644
> > index 0000000000..5dab447f09
> > --- /dev/null
> > +++ b/MdeModulePkg/Bus/Pci/NvmExpressPei/DevicePath.c
> > @@ -0,0 +1,231 @@
> > +/** @file
> > + The device path help function.
> > +
> > + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> > +
> > + 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"
> > +
> > +//
> > +// Template for an Nvm Express Device Path node
> > +//
> > +NVME_NAMESPACE_DEVICE_PATH mNvmeDevicePathNodeTemplate =
> {
> > + { // Header
> > + MESSAGING_DEVICE_PATH,
> > + MSG_NVME_NAMESPACE_DP,
> > + {
> > + (UINT8) (sizeof (NVME_NAMESPACE_DEVICE_PATH)),
> > + (UINT8) ((sizeof (NVME_NAMESPACE_DEVICE_PATH)) >> 8)
> > + }
> > + },
> > + 0x0, // NamespaceId
> > + 0x0 // NamespaceUuid
> > +};
> > +
> > +//
> > +// Template for an End of entire Device Path node
> > +//
> > +EFI_DEVICE_PATH_PROTOCOL mNvmeEndDevicePathNodeTemplate = {
> > + END_DEVICE_PATH_TYPE,
> > + END_ENTIRE_DEVICE_PATH_SUBTYPE,
> > + {
> > + (UINT8) (sizeof (EFI_DEVICE_PATH_PROTOCOL)),
> > + (UINT8) ((sizeof (EFI_DEVICE_PATH_PROTOCOL)) >> 8)
> > + }
> > +};
> > +
> > +/**
> > + 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]);
> > +}
>
> 1. DevicePathLib has same API, can leverage that API.
Hi Eric,
Actually, Ray had similar comments as well. For the comments on patch
06/13 & 07/13, the reason I choose to add driver internal implementation
of those functions are:
1. I found that the DevicePathLib instances will consume the Boot Services
Table (e.g. try to get the 'Handle' of a device path), which is not available
in the PEI phase.
2. There are some differences between the driver-internal implementation
and the library implementation. Within the driver, some memory allocation
operations are optimized away according to no actual needs.
Best Regards,
Hao Wu
>
> > +
> > +/**
> > + 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));
> > +}
>
> 2. DevicePathLib has same API, can leverage that API.
>
> > +
> > +/**
> > + Check the validity of the device path of a NVM Express host controller.
> > +
> > + @param[in] DevicePath A pointer to the
> > EFI_DEVICE_PATH_PROTOCOL
> > + structure.
> > + @param[in] DevicePathLength The length of the device path.
> > +
> > + @retval EFI_SUCCESS The device path is valid.
> > + @retval EFI_INVALID_PARAMETER The device path is invalid.
> > +
> > +**/
> > +EFI_STATUS
> > +NvmeCheckHcDevicePath (
> > + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
> > + IN UINTN DevicePathLength
> > + )
> > +{
> > + EFI_DEVICE_PATH_PROTOCOL *Start;
> > + UINTN Size;
> > +
> > + if (DevicePath == NULL) {
> > + return EFI_INVALID_PARAMETER;
> > + }
> > +
> > + //
> > + // Validate the DevicePathLength is big enough to touch the first node.
> > + //
> > + if (DevicePathLength < sizeof (EFI_DEVICE_PATH_PROTOCOL)) {
> > + return EFI_INVALID_PARAMETER;
> > + }
> > +
> > + Start = DevicePath;
> > + while (!(DevicePath->Type == END_DEVICE_PATH_TYPE &&
> > + DevicePath->SubType == END_ENTIRE_DEVICE_PATH_SUBTYPE)) {
> > + DevicePath = NextDevicePathNode (DevicePath);
> > +
> > + //
> > + // Prevent overflow and invalid zero in the 'Length' field of a device path
> > + // node.
> > + //
> > + if ((UINTN) DevicePath <= (UINTN) Start) {
> > + return EFI_INVALID_PARAMETER;
> > + }
> > +
> > + //
> > + // Prevent touching memory beyond given DevicePathLength.
> > + //
> > + if ((UINTN) DevicePath - (UINTN) Start >
> > + DevicePathLength - sizeof (EFI_DEVICE_PATH_PROTOCOL)) {
> > + return EFI_INVALID_PARAMETER;
> > + }
> > + }
> > +
> > + //
> > + // Check if the device path and its size match exactly with each other.
> > + //
> > + Size = ((UINTN) DevicePath - (UINTN) Start) + sizeof
> > (EFI_DEVICE_PATH_PROTOCOL);
> > + if (Size != DevicePathLength) {
> > + return EFI_INVALID_PARAMETER;
> > + }
> > +
> > + return EFI_SUCCESS;
> > +}
>
> 3. Seems like this function just do validation for the input device path.
> UefiDevicePathLib has IsDevicePathValid API, can we leverage that function?
>
> Thanks,
> Eric
> > +
> > +/**
> > + Build the device path for an Nvm Express device with given namespace
> > identifier
> > + and namespace extended unique identifier.
> > +
> > + @param[in] Private A pointer to the
> > PEI_NVME_CONTROLLER_PRIVATE_DATA
> > + data structure.
> > + @param[in] NamespaceId The given namespace identifier.
> > + @param[in] NamespaceUuid The given namespace extended unique
> > identifier.
> > + @param[out] DevicePathLength The length of the device path in bytes
> > specified
> > + by DevicePath.
> > + @param[out] DevicePath The device path of Nvm Express device.
> > +
> > + @retval EFI_SUCCESS The operation succeeds.
> > + @retval EFI_INVALID_PARAMETER The parameters are invalid.
> > + @retval EFI_OUT_OF_RESOURCES The operation fails due to lack of
> > resources.
> > +
> > +**/
> > +EFI_STATUS
> > +NvmeBuildDevicePath (
> > + IN PEI_NVME_CONTROLLER_PRIVATE_DATA *Private,
> > + IN UINT32 NamespaceId,
> > + IN UINT64 NamespaceUuid,
> > + OUT UINTN *DevicePathLength,
> > + OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath
> > + )
> > +{
> > + EFI_DEVICE_PATH_PROTOCOL *DevicePathWalker;
> > + NVME_NAMESPACE_DEVICE_PATH *NvmeDeviceNode;
> > +
> > + if (DevicePathLength == NULL || DevicePath == NULL) {
> > + return EFI_INVALID_PARAMETER;
> > + }
> > +
> > + *DevicePathLength = Private->DevicePathLength + sizeof
> > (NVME_NAMESPACE_DEVICE_PATH);
> > + *DevicePath = AllocatePool (*DevicePathLength);
> > + if (*DevicePath == NULL) {
> > + *DevicePathLength = 0;
> > + return EFI_OUT_OF_RESOURCES;
> > + }
> > +
> > + //
> > + // Construct the host controller part device nodes
> > + //
> > + DevicePathWalker = *DevicePath;
> > + CopyMem (
> > + DevicePathWalker,
> > + Private->DevicePath,
> > + Private->DevicePathLength - sizeof (EFI_DEVICE_PATH_PROTOCOL)
> > + );
> > +
> > + //
> > + // Construct the Nvm Express device node
> > + //
> > + DevicePathWalker = (EFI_DEVICE_PATH_PROTOCOL *) ((UINT8
> > *)DevicePathWalker +
> > + (Private->DevicePathLength - sizeof
> > (EFI_DEVICE_PATH_PROTOCOL)));
> > + CopyMem (
> > + DevicePathWalker,
> > + &mNvmeDevicePathNodeTemplate,
> > + sizeof (mNvmeDevicePathNodeTemplate)
> > + );
> > + NvmeDeviceNode = (NVME_NAMESPACE_DEVICE_PATH
> > *)DevicePathWalker;
> > + NvmeDeviceNode->NamespaceId = NamespaceId;
> > + NvmeDeviceNode->NamespaceUuid = NamespaceUuid;
> > +
> > + //
> > + // Construct the end device node
> > + //
> > + DevicePathWalker = (EFI_DEVICE_PATH_PROTOCOL *) ((UINT8
> > *)DevicePathWalker +
> > + sizeof (NVME_NAMESPACE_DEVICE_PATH));
> > + CopyMem (
> > + DevicePathWalker,
> > + &mNvmeEndDevicePathNodeTemplate,
> > + sizeof (mNvmeEndDevicePathNodeTemplate)
> > + );
> > +
> > + return EFI_SUCCESS;
> > +}
> > diff --git a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.c
> > b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.c
> > index 2fe73e942c..96622e6fd5 100644
> > --- a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.c
> > +++ b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.c
> > @@ -24,11 +24,17 @@ EFI_PEI_PPI_DESCRIPTOR
> > mNvmeBlkIoPpiListTemplate = {
> > };
> >
> > EFI_PEI_PPI_DESCRIPTOR mNvmeBlkIo2PpiListTemplate = {
> > - EFI_PEI_PPI_DESCRIPTOR_PPI |
> > EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
> > + (EFI_PEI_PPI_DESCRIPTOR_PPI |
> > EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
> > &gEfiPeiVirtualBlockIo2PpiGuid,
> > NULL
> > };
> >
> > +EFI_PEI_PPI_DESCRIPTOR mNvmeStorageSecurityPpiListTemplate = {
> > + (EFI_PEI_PPI_DESCRIPTOR_PPI |
> > EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
> > + &gEdkiiPeiStorageSecurityCommandPpiGuid,
> > + NULL
> > +};
> > +
> > EFI_PEI_NOTIFY_DESCRIPTOR mNvmeEndOfPeiNotifyListTemplate = {
> > (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK |
> > EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
> > &gEfiEndOfPeiSignalPpiGuid,
> > @@ -185,8 +191,7 @@ NvmePeimEndOfPei (
> > PEI_NVME_CONTROLLER_PRIVATE_DATA *Private;
> >
> > Private = GET_NVME_PEIM_HC_PRIVATE_DATA_FROM_THIS_NOTIFY
> > (NotifyDescriptor);
> > - NvmeDisableController (Private);
> > - NvmeFreeControllerResource (Private);
> > + NvmeFreeDmaResource (Private);
> >
> > return EFI_SUCCESS;
> > }
> > @@ -211,9 +216,13 @@ NvmExpressPeimEntry (
> > 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;
> >
> > + DEBUG ((DEBUG_INFO, "%a: Enters.\n", __FUNCTION__));
> > +
> > //
> > // Locate the NVME host controller PPI
> > //
> > @@ -243,16 +252,41 @@ NvmExpressPeimEntry (
> > break;
> > }
> >
> > + Status = NvmeHcPpi->GetNvmeHcDevicePath (
> > + NvmeHcPpi,
> > + Controller,
> > + &DevicePathLength,
> > + &DevicePath
> > + );
> > + if (EFI_ERROR (Status)) {
> > + DEBUG ((
> > + DEBUG_ERROR, "%a: Fail to allocate get the device path for
> > Controller %d.\n",
> > + __FUNCTION__, Controller
> > + ));
> > + return Status;
> > + }
> > +
> > + //
> > + // Check validity of the device path of the NVM Express controller.
> > + //
> > + Status = NvmeCheckHcDevicePath (DevicePath, DevicePathLength);
> > + if (EFI_ERROR (Status)) {
> > + DEBUG ((
> > + DEBUG_ERROR, "%a: The device path is invalid for Controller %d.\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
> > + DEBUG_ERROR, "%a: Fail to allocate private data for Controller %d.\n",
> > + __FUNCTION__, Controller
> > ));
> > return EFI_OUT_OF_RESOURCES;
> > }
> > @@ -268,12 +302,9 @@ NvmExpressPeimEntry (
> > );
> > if (EFI_ERROR (Status)) {
> > DEBUG ((
> > - DEBUG_ERROR,
> > - "%a: Fail to allocate DMA buffers for Controller %d.\n",
> > - __FUNCTION__,
> > - Controller
> > + DEBUG_ERROR, "%a: Fail to allocate DMA buffers for
> Controller %d.\n",
> > + __FUNCTION__, Controller
> > ));
> > - NvmeFreeControllerResource (Private);
> > return Status;
> > }
> > ASSERT (DeviceAddress == ((EFI_PHYSICAL_ADDRESS) (UINTN) Private-
> > >Buffer));
> > @@ -282,20 +313,10 @@ NvmExpressPeimEntry (
> > //
> > // Initialize controller private data
> > //
> > - Private->Signature =
> > NVME_PEI_CONTROLLER_PRIVATE_DATA_SIGNATURE;
> > - Private->MmioBase = MmioBase;
> > - Private->BlkIoPpi.GetNumberOfBlockDevices =
> > NvmeBlockIoPeimGetDeviceNo;
> > - Private->BlkIoPpi.GetBlockDeviceMediaInfo =
> > NvmeBlockIoPeimGetMediaInfo;
> > - Private->BlkIoPpi.ReadBlocks = NvmeBlockIoPeimReadBlocks;
> > - Private->BlkIo2Ppi.Revision =
> > EFI_PEI_RECOVERY_BLOCK_IO2_PPI_REVISION;
> > - Private->BlkIo2Ppi.GetNumberOfBlockDevices =
> > NvmeBlockIoPeimGetDeviceNo2;
> > - Private->BlkIo2Ppi.GetBlockDeviceMediaInfo =
> > NvmeBlockIoPeimGetMediaInfo2;
> > - Private->BlkIo2Ppi.ReadBlocks = NvmeBlockIoPeimReadBlocks2;
> > - CopyMem (&Private->BlkIoPpiList, &mNvmeBlkIoPpiListTemplate,
> sizeof
> > (EFI_PEI_PPI_DESCRIPTOR));
> > - CopyMem (&Private->BlkIo2PpiList, &mNvmeBlkIo2PpiListTemplate,
> > sizeof (EFI_PEI_PPI_DESCRIPTOR));
> > - CopyMem (&Private->EndOfPeiNotifyList,
> > &mNvmeEndOfPeiNotifyListTemplate, sizeof
> > (EFI_PEI_NOTIFY_DESCRIPTOR));
> > - Private->BlkIoPpiList.Ppi = &Private->BlkIoPpi;
> > - Private->BlkIo2PpiList.Ppi = &Private->BlkIo2Ppi;
> > + Private->Signature =
> > NVME_PEI_CONTROLLER_PRIVATE_DATA_SIGNATURE;
> > + Private->MmioBase = MmioBase;
> > + Private->DevicePathLength = DevicePathLength;
> > + Private->DevicePath = DevicePath;
> >
> > //
> > // Initialize the NVME controller
> > @@ -305,11 +326,9 @@ NvmExpressPeimEntry (
> > DEBUG ((
> > DEBUG_ERROR,
> > "%a: Controller initialization fail for Controller %d with Status - %r.\n",
> > - __FUNCTION__,
> > - Controller,
> > - Status
> > + __FUNCTION__, Controller, Status
> > ));
> > - NvmeFreeControllerResource (Private);
> > + NvmeFreeDmaResource (Private);
> > Controller++;
> > continue;
> > }
> > @@ -325,22 +344,68 @@ NvmExpressPeimEntry (
> > DEBUG ((
> > DEBUG_ERROR,
> > "%a: Namespaces discovery fail for Controller %d with Status - %r.\n",
> > - __FUNCTION__,
> > - Controller,
> > - Status
> > + __FUNCTION__, Controller, Status
> > ));
> > - NvmeFreeControllerResource (Private);
> > + NvmeFreeDmaResource (Private);
> > Controller++;
> > continue;
> > }
> >
> > + 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);
> > - PeiServicesNotifyPpi (&Private->EndOfPeiNotifyList);
> > +
> > + //
> > + // 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 for
> > Controller %d.\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: BlockIO PPI has been installed on Controller %d.\n",
> > - __FUNCTION__,
> > - Controller
> > + DEBUG_INFO, "%a: Controller %d has been successfully initialized.\n",
> > + __FUNCTION__, Controller
> > ));
> > Controller++;
> > }
> > diff --git a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiHci.c
> > b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiHci.c
> > index d4056a2a5b..b9fa3230f8 100644
> > --- a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiHci.c
> > +++ b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiHci.c
> > @@ -2,7 +2,7 @@
> > The NvmExpressPei driver is used to manage non-volatile memory
> > subsystem
> > which follows NVM Express specification at PEI phase.
> >
> > - Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
> > + Copyright (c) 2018 - 2019, Intel Corporation. All rights reserved.<BR>
> >
> > This program and the accompanying materials
> > are licensed and made available under the terms and conditions
> > @@ -702,47 +702,25 @@ NvmeControllerInit (
> > }
> >
> > /**
> > - Free the resources allocated by an NVME controller.
> > + Free the DMA resources allocated by an NVME controller.
> >
> > @param[in] Private The pointer to the
> > PEI_NVME_CONTROLLER_PRIVATE_DATA data structure.
> >
> > **/
> > VOID
> > -NvmeFreeControllerResource (
> > +NvmeFreeDmaResource (
> > IN PEI_NVME_CONTROLLER_PRIVATE_DATA *Private
> > )
> > {
> > - //
> > - // Free the controller data buffer
> > - //
> > - if (Private->ControllerData != NULL) {
> > - FreePool (Private->ControllerData);
> > - Private->ControllerData = NULL;
> > - }
> > + ASSERT (Private != NULL);
> >
> > - //
> > - // Free the DMA buffers
> > - //
> > - if (Private->Buffer != NULL) {
> > + if (Private->BufferMapping != NULL) {
> > IoMmuFreeBuffer (
> > NVME_MEM_MAX_PAGES,
> > Private->Buffer,
> > Private->BufferMapping
> > );
> > - Private->Buffer = NULL;
> > }
> >
> > - //
> > - // Free the namespaces information buffer
> > - //
> > - if (Private->NamespaceInfo != NULL) {
> > - FreePool (Private->NamespaceInfo);
> > - Private->NamespaceInfo = NULL;
> > - }
> > -
> > - //
> > - // Free the controller private data structure
> > - //
> > - FreePool (Private);
> > return;
> > }
> > diff --git
> >
> a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiStorageSecurity.
> > c
> >
> b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiStorageSecurity.
> > c
> > new file mode 100644
> > index 0000000000..e5a2cef3d6
> > --- /dev/null
> > +++
> >
> b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiStorageSecurity.
> > c
> > @@ -0,0 +1,423 @@
> > +/** @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.<BR>
> > +
> > + 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"
> > +
> > +/**
> > + Trust transfer data from/to NVM Express device.
> > +
> > + This function performs one NVMe transaction to do a trust transfer
> > from/to NVM
> > + Express device.
> > +
> > + @param[in] Private The pointer to the
> > PEI_NVME_CONTROLLER_PRIVATE_DATA
> > + data structure.
> > + @param[in,out] Buffer The pointer to the current transaction
> buffer.
> > + @param[in] SecurityProtocolId
> > + The value of the "Security Protocol" parameter
> > + of the security protocol command to be sent.
> > + @param[in] SecurityProtocolSpecificData
> > + The value of the "Security Protocol Specific"
> > + parameter of the security protocol command to
> > + be sent.
> > + @param[in] TransferLength The block number or sector count of the
> > transfer.
> > + @param[in] IsTrustSend Indicates whether it is a trust send
> operation
> > + or not.
> > + @param[in] Timeout The timeout, in 100ns units, to use for the
> > + execution of the security protocol command.
> > + A Timeout value of 0 means that this function
> > + will wait indefinitely for the security protocol
> > + command to execute. If Timeout is greater than
> > + zero, then this function will return EFI_TIMEOUT
> > + if the time required to execute the receive
> > + data command is greater than Timeout.
> > + @param[out] TransferLengthOut A pointer to a buffer to store the size
> in
> > bytes
> > + of the data written to the buffer. Ignore it
> > + when IsTrustSend is TRUE.
> > +
> > + @retval EFI_SUCCESS The data transfer is complete successfully.
> > + @return others Some error occurs when transferring data.
> > +
> > +**/
> > +EFI_STATUS
> > +TrustTransferNvmeDevice (
> > + IN PEI_NVME_CONTROLLER_PRIVATE_DATA *Private,
> > + IN OUT VOID *Buffer,
> > + IN UINT8 SecurityProtocolId,
> > + IN UINT16 SecurityProtocolSpecificData,
> > + IN UINTN TransferLength,
> > + IN BOOLEAN IsTrustSend,
> > + IN UINT64 Timeout,
> > + OUT UINTN *TransferLengthOut
> > + )
> > +{
> > + EDKII_PEI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET
> > CommandPacket;
> > + EDKII_PEI_NVM_EXPRESS_COMMAND Command;
> > + EDKII_PEI_NVM_EXPRESS_COMPLETION Completion;
> > + EFI_STATUS Status;
> > + UINT16 SpecificData;
> > +
> > + ZeroMem (&CommandPacket,
> > sizeof(EDKII_PEI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET));
> > + ZeroMem (&Command, sizeof(EDKII_PEI_NVM_EXPRESS_COMMAND));
> > + ZeroMem (&Completion,
> > sizeof(EDKII_PEI_NVM_EXPRESS_COMPLETION));
> > +
> > + CommandPacket.NvmeCmd = &Command;
> > + CommandPacket.NvmeCompletion = &Completion;
> > +
> > + //
> > + // Change Endianness of SecurityProtocolSpecificData
> > + //
> > + SpecificData = (((SecurityProtocolSpecificData << 8) & 0xFF00) |
> > (SecurityProtocolSpecificData >> 8));
> > +
> > + if (IsTrustSend) {
> > + Command.Cdw0.Opcode = NVME_ADMIN_SECURITY_SEND_CMD;
> > + CommandPacket.TransferBuffer = Buffer;
> > + CommandPacket.TransferLength = (UINT32)TransferLength;
> > + CommandPacket.NvmeCmd->Cdw10 = (UINT32)((SecurityProtocolId <<
> > 24) | (SpecificData << 8));
> > + CommandPacket.NvmeCmd->Cdw11 = (UINT32)TransferLength;
> > + } else {
> > + Command.Cdw0.Opcode =
> NVME_ADMIN_SECURITY_RECEIVE_CMD;
> > + CommandPacket.TransferBuffer = Buffer;
> > + CommandPacket.TransferLength = (UINT32)TransferLength;
> > + CommandPacket.NvmeCmd->Cdw10 = (UINT32)((SecurityProtocolId <<
> > 24) | (SpecificData << 8));
> > + CommandPacket.NvmeCmd->Cdw11 = (UINT32)TransferLength;
> > + }
> > +
> > + CommandPacket.NvmeCmd->Flags = CDW10_VALID | CDW11_VALID;
> > + CommandPacket.NvmeCmd->Nsid = NVME_CONTROLLER_NSID;
> > + CommandPacket.CommandTimeout = Timeout;
> > + CommandPacket.QueueType = NVME_ADMIN_QUEUE;
> > +
> > + Status = NvmePassThru (
> > + Private,
> > + NVME_CONTROLLER_NSID,
> > + &CommandPacket
> > + );
> > +
> > + if (!IsTrustSend) {
> > + if (EFI_ERROR (Status)) {
> > + *TransferLengthOut = 0;
> > + } else {
> > + *TransferLengthOut = (UINTN) TransferLength;
> > + }
> > + }
> > +
> > + return Status;
> > +}
> > +
> > +/**
> > + Gets the count of storage security devices that one specific driver
> detects.
> > +
> > + @param[in] This The PPI instance pointer.
> > + @param[out] NumberofDevices The number of storage security
> devices
> > discovered.
> > +
> > + @retval EFI_SUCCESS The operation performed successfully.
> > + @retval EFI_INVALID_PARAMETER The parameters are invalid.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +NvmeStorageSecurityGetDeviceNo (
> > + IN EDKII_PEI_STORAGE_SECURITY_CMD_PPI *This,
> > + OUT UINTN *NumberofDevices
> > + )
> > +{
> > + PEI_NVME_CONTROLLER_PRIVATE_DATA *Private;
> > +
> > + if (This == NULL || NumberofDevices == NULL) {
> > + return EFI_INVALID_PARAMETER;
> > + }
> > +
> > + Private =
> > GET_NVME_PEIM_HC_PRIVATE_DATA_FROM_THIS_STROAGE_SECURITY
> > (This);
> > + *NumberofDevices = Private->ActiveNamespaceNum;
> > +
> > + return EFI_SUCCESS;
> > +}
> > +
> > +/**
> > + Gets the device path of a specific storage security device.
> > +
> > + @param[in] This The PPI instance pointer.
> > + @param[in] DeviceIndex Specifies the storage security device to
> > which
> > + the function wants to talk. Because the driver
> > + that implements Storage Security Command PPIs
> > + will manage multiple storage devices, the PPIs
> > + that want to talk to a single device must specify
> > + the device index that was assigned during the
> > + enumeration process. This index is a number from
> > + one to NumberofDevices.
> > + @param[out] DevicePathLength The length of the device path in bytes
> > specified
> > + by DevicePath.
> > + @param[out] DevicePath The device path of storage security device.
> > + This field re-uses EFI Device Path Protocol as
> > + defined by Section 10.2 EFI Device Path Protocol
> > + of UEFI 2.7 Specification.
> > +
> > + @retval EFI_SUCCESS The operation succeeds.
> > + @retval EFI_INVALID_PARAMETER DevicePathLength or DevicePath is
> > NULL.
> > + @retval EFI_NOT_FOUND The specified storage security device not
> > found.
> > + @retval EFI_OUT_OF_RESOURCES The operation fails due to lack of
> > resources.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +NvmeStorageSecurityGetDevicePath (
> > + IN EDKII_PEI_STORAGE_SECURITY_CMD_PPI *This,
> > + IN UINTN DeviceIndex,
> > + OUT UINTN *DevicePathLength,
> > + OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath
> > + )
> > +{
> > + PEI_NVME_CONTROLLER_PRIVATE_DATA *Private;
> > +
> > + if (This == NULL || DevicePathLength == NULL || DevicePath == NULL) {
> > + return EFI_INVALID_PARAMETER;
> > + }
> > +
> > + Private =
> > GET_NVME_PEIM_HC_PRIVATE_DATA_FROM_THIS_STROAGE_SECURITY
> > (This);
> > + if ((DeviceIndex == 0) || (DeviceIndex > Private-
> >ActiveNamespaceNum))
> > {
> > + return EFI_INVALID_PARAMETER;
> > + }
> > +
> > + return NvmeBuildDevicePath (
> > + Private,
> > + Private->NamespaceInfo[DeviceIndex-1].NamespaceId,
> > + Private->NamespaceInfo[DeviceIndex-1].NamespaceUuid,
> > + DevicePathLength,
> > + DevicePath
> > + );
> > +}
> > +
> > +/**
> > + Send a security protocol command to a device that receives data and/or
> > the result
> > + of one or more commands sent by SendData.
> > +
> > + The ReceiveData function sends a security protocol command to the
> given
> > DeviceIndex.
> > + The security protocol command sent is defined by SecurityProtocolId and
> > contains
> > + the security protocol specific data SecurityProtocolSpecificData. The
> > function
> > + returns the data from the security protocol command in PayloadBuffer.
> > +
> > + For devices supporting the SCSI command set, the security protocol
> > command is sent
> > + using the SECURITY PROTOCOL IN command defined in SPC-4.
> > +
> > + For devices supporting the ATA command set, the security protocol
> > command is sent
> > + using one of the TRUSTED RECEIVE commands defined in ATA8-ACS if
> > PayloadBufferSize
> > + is non-zero.
> > +
> > + If the PayloadBufferSize is zero, the security protocol command is sent
> > using the
> > + Trusted Non-Data command defined in ATA8-ACS.
> > +
> > + If PayloadBufferSize is too small to store the available data from the
> > security
> > + protocol command, the function shall copy PayloadBufferSize bytes into
> > the
> > + PayloadBuffer and return EFI_WARN_BUFFER_TOO_SMALL.
> > +
> > + If PayloadBuffer or PayloadTransferSize is NULL and PayloadBufferSize is
> > non-zero,
> > + the function shall return EFI_INVALID_PARAMETER.
> > +
> > + If the given DeviceIndex does not support security protocol commands,
> > the function
> > + shall return EFI_UNSUPPORTED.
> > +
> > + If the security protocol fails to complete within the Timeout period, the
> > function
> > + shall return EFI_TIMEOUT.
> > +
> > + If the security protocol command completes without an error, the
> function
> > shall
> > + return EFI_SUCCESS. If the security protocol command completes with
> an
> > error, the
> > + function shall return EFI_DEVICE_ERROR.
> > +
> > + @param[in] This The PPI instance pointer.
> > + @param[in] DeviceIndex Specifies the storage security device to
> which
> > the
> > + function wants to talk. Because the driver that
> > + implements Storage Security Command PPIs will manage
> > + multiple storage devices, the PPIs that want to talk
> > + to a single device must specify the device index
> > + that was assigned during the enumeration process.
> > + This index is a number from one to NumberofDevices.
> > + @param[in] Timeout The timeout, in 100ns units, to use for the
> > execution
> > + of the security protocol command. A Timeout value
> > + of 0 means that this function will wait indefinitely
> > + for the security protocol command to execute. If
> > + Timeout is greater than zero, then this function
> > + will return EFI_TIMEOUT if the time required to
> > + execute the receive data command is greater than
> > + Timeout.
> > + @param[in] SecurityProtocolId
> > + The value of the "Security Protocol" parameter of
> > + the security protocol command to be sent.
> > + @param[in] SecurityProtocolSpecificData
> > + The value of the "Security Protocol Specific"
> > + parameter of the security protocol command to be
> > + sent.
> > + @param[in] PayloadBufferSize
> > + Size in bytes of the payload data buffer.
> > + @param[out] PayloadBuffer A pointer to a destination buffer to store
> > the
> > + security protocol command specific payload data
> > + for the security protocol command. The caller is
> > + responsible for having either implicit or explicit
> > + ownership of the buffer.
> > + @param[out] PayloadTransferSize
> > + A pointer to a buffer to store the size in bytes
> > + of the data written to the payload data buffer.
> > +
> > + @retval EFI_SUCCESS The security protocol command
> completed
> > + successfully.
> > + @retval EFI_WARN_BUFFER_TOO_SMALL The PayloadBufferSize was
> too
> > small to
> > + store the available data from the device.
> > + The PayloadBuffer contains the truncated
> > + data.
> > + @retval EFI_UNSUPPORTED The given DeviceIndex does not
> > support
> > + security protocol commands.
> > + @retval EFI_DEVICE_ERROR The security protocol command
> > completed
> > + with an error.
> > + @retval EFI_INVALID_PARAMETER The PayloadBuffer or
> > PayloadTransferSize
> > + is NULL and PayloadBufferSize is non-zero.
> > + @retval EFI_TIMEOUT A timeout occurred while waiting for the
> > + security protocol command to execute.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +NvmeStorageSecurityReceiveData (
> > + IN EDKII_PEI_STORAGE_SECURITY_CMD_PPI *This,
> > + IN UINTN DeviceIndex,
> > + IN UINT64 Timeout,
> > + IN UINT8 SecurityProtocolId,
> > + IN UINT16 SecurityProtocolSpecificData,
> > + IN UINTN PayloadBufferSize,
> > + OUT VOID *PayloadBuffer,
> > + OUT UINTN *PayloadTransferSize
> > + )
> > +{
> > + PEI_NVME_CONTROLLER_PRIVATE_DATA *Private;
> > + EFI_STATUS Status;
> > +
> > + if ((PayloadBuffer == NULL) || (PayloadTransferSize == NULL) ||
> > (PayloadBufferSize == 0)) {
> > + return EFI_INVALID_PARAMETER;
> > + }
> > +
> > + Private =
> > GET_NVME_PEIM_HC_PRIVATE_DATA_FROM_THIS_STROAGE_SECURITY
> > (This);
> > +
> > + Status = TrustTransferNvmeDevice (
> > + Private,
> > + PayloadBuffer,
> > + SecurityProtocolId,
> > + SecurityProtocolSpecificData,
> > + PayloadBufferSize,
> > + FALSE,
> > + Timeout,
> > + PayloadTransferSize
> > + );
> > +
> > + return Status;
> > +}
> > +
> > +/**
> > + Send a security protocol command to a device.
> > +
> > + The SendData function sends a security protocol command containing
> the
> > payload
> > + PayloadBuffer to the given DeviceIndex. The security protocol command
> > sent is
> > + defined by SecurityProtocolId and contains the security protocol specific
> > data
> > + SecurityProtocolSpecificData. If the underlying protocol command
> requires
> > a
> > + specific padding for the command payload, the SendData function shall
> > add padding
> > + bytes to the command payload to satisfy the padding requirements.
> > +
> > + For devices supporting the SCSI command set, the security protocol
> > command is
> > + sent using the SECURITY PROTOCOL OUT command defined in SPC-4.
> > +
> > + For devices supporting the ATA command set, the security protocol
> > command is
> > + sent using one of the TRUSTED SEND commands defined in ATA8-ACS if
> > PayloadBufferSize
> > + is non-zero. If the PayloadBufferSize is zero, the security protocol
> > command
> > + is sent using the Trusted Non-Data command defined in ATA8-ACS.
> > +
> > + If PayloadBuffer is NULL and PayloadBufferSize is non-zero, the function
> > shall
> > + return EFI_INVALID_PARAMETER.
> > +
> > + If the given DeviceIndex does not support security protocol commands,
> > the function
> > + shall return EFI_UNSUPPORTED.
> > +
> > + If the security protocol fails to complete within the Timeout period, the
> > function
> > + shall return EFI_TIMEOUT.
> > +
> > + If the security protocol command completes without an error, the
> function
> > shall
> > + return EFI_SUCCESS. If the security protocol command completes with
> an
> > error,
> > + the functio shall return EFI_DEVICE_ERROR.
> > +
> > + @param[in] This The PPI instance pointer.
> > + @param[in] DeviceIndex The ID of the device.
> > + @param[in] Timeout The timeout, in 100ns units, to use for the
> > execution
> > + of the security protocol command. A Timeout value
> > + of 0 means that this function will wait indefinitely
> > + for the security protocol command to execute. If
> > + Timeout is greater than zero, then this function
> > + will return EFI_TIMEOUT if the time required to
> > + execute the receive data command is greater than
> > + Timeout.
> > + @param[in] SecurityProtocolId
> > + The value of the "Security Protocol" parameter of
> > + the security protocol command to be sent.
> > + @param[in] SecurityProtocolSpecificData
> > + The value of the "Security Protocol Specific"
> > + parameter of the security protocol command to be
> > + sent.
> > + @param[in] PayloadBufferSize Size in bytes of the payload data buffer.
> > + @param[in] PayloadBuffer A pointer to a destination buffer to store
> the
> > + security protocol command specific payload data
> > + for the security protocol command.
> > +
> > + @retval EFI_SUCCESS The security protocol command completed
> > successfully.
> > + @retval EFI_UNSUPPORTED The given DeviceIndex does not
> support
> > security
> > + protocol commands.
> > + @retval EFI_DEVICE_ERROR The security protocol command
> > completed with
> > + an error.
> > + @retval EFI_INVALID_PARAMETER The PayloadBuffer is NULL and
> > PayloadBufferSize
> > + is non-zero.
> > + @retval EFI_TIMEOUT A timeout occurred while waiting for the
> > security
> > + protocol command to execute.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +NvmeStorageSecuritySendData (
> > + IN EDKII_PEI_STORAGE_SECURITY_CMD_PPI *This,
> > + IN UINTN DeviceIndex,
> > + IN UINT64 Timeout,
> > + IN UINT8 SecurityProtocolId,
> > + IN UINT16 SecurityProtocolSpecificData,
> > + IN UINTN PayloadBufferSize,
> > + IN VOID *PayloadBuffer
> > + )
> > +{
> > + PEI_NVME_CONTROLLER_PRIVATE_DATA *Private;
> > + EFI_STATUS Status;
> > +
> > + if ((PayloadBuffer == NULL) && (PayloadBufferSize != 0)) {
> > + return EFI_INVALID_PARAMETER;
> > + }
> > +
> > + Private =
> > GET_NVME_PEIM_HC_PRIVATE_DATA_FROM_THIS_STROAGE_SECURITY
> > (This);
> > +
> > + Status = TrustTransferNvmeDevice (
> > + Private,
> > + PayloadBuffer,
> > + SecurityProtocolId,
> > + SecurityProtocolSpecificData,
> > + PayloadBufferSize,
> > + TRUE,
> > + Timeout,
> > + NULL
> > + );
> > +
> > + return Status;
> > +}
> > --
> > 2.12.0.windows.1
next prev parent reply other threads:[~2019-02-18 6:07 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-02-15 6:23 [PATCH v5 00/13] Split the S3 PEI phase HW init codes from Opal driver Hao Wu
2019-02-15 6:23 ` [PATCH v5 01/13] MdeModulePkg: Add definitions for ATA AHCI host controller PPI Hao Wu
2019-02-18 1:44 ` Dong, Eric
2019-02-15 6:23 ` [PATCH v5 02/13] MdeModulePkg: Add definitions for EDKII PEI ATA PassThru PPI Hao Wu
2019-02-18 1:44 ` Dong, Eric
2019-02-15 6:23 ` [PATCH v5 03/13] MdeModulePkg: Add definitions for Storage Security Command PPI Hao Wu
2019-02-18 1:45 ` Dong, Eric
2019-02-15 6:23 ` [PATCH v5 04/13] MdeModulePkg: Add GUID for LockBox to save storage dev to init in S3 Hao Wu
2019-02-18 1:45 ` Dong, Eric
2019-02-15 6:23 ` [PATCH v5 05/13] MdeModulePkg/NvmExpressPei: Avoid updating the module-level variable Hao Wu
2019-02-15 6:23 ` [PATCH v5 06/13] MdeModulePkg/NvmExpressPei: Add logic to produce SSC PPI Hao Wu
2019-02-18 2:58 ` Dong, Eric
2019-02-18 6:06 ` Wu, Hao A [this message]
2019-02-18 6:29 ` Dong, Eric
2019-02-20 8:33 ` Ni, Ray
2019-02-15 6:23 ` [PATCH v5 07/13] MdeModulePkg/NvmExpressPei: Consume S3StorageDeviceInitList LockBox Hao Wu
2019-02-18 3:01 ` Dong, Eric
2019-02-20 9:41 ` Ni, Ray
2019-02-15 6:23 ` [PATCH v5 08/13] MdeModulePkg/AhciPei: Add AHCI mode ATA device support in PEI Hao Wu
2019-02-20 9:51 ` Ni, Ray
2019-02-15 6:23 ` [PATCH v5 09/13] MdeModulePkg/SmmLockBoxLib: Use 'DEBUG_' prefix instead of 'EFI_D_' Hao Wu
2019-02-15 6:23 ` [PATCH v5 10/13] MdeModulePkg/SmmLockBox(PEI): Remove an ASSERT in RestoreLockBox() Hao Wu
2019-02-15 6:23 ` [PATCH v5 11/13] MdeModulePkg/SmmLockBoxLib: Support LockBox enlarge in UpdateLockBox() Hao Wu
2019-02-15 6:23 ` [PATCH v5 12/13] OvmfPkg/LockBoxLib: Update the comments for API UpdateLockBox() Hao Wu
2019-02-15 6:23 ` [PATCH v5 13/13] SecurityPkg/OpalPassword: Remove HW init codes and consume SSC PPI Hao Wu
2019-02-18 6:20 ` Dong, Eric
2019-02-19 2:50 ` Wu, Hao A
2019-02-20 13:08 ` Ni, Ray
2019-02-15 13:23 ` [PATCH v5 00/13] Split the S3 PEI phase HW init codes from Opal driver Laszlo Ersek
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=B80AF82E9BFB8E4FBD8C89DA810C6A093C897ADB@SHSMSX104.ccr.corp.intel.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox