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>
Cc: "Zhang, Chao B" <chao.b.zhang@intel.com>,
"Yao, Jiewen" <jiewen.yao@intel.com>,
"Ni, Ray" <ray.ni@intel.com>
Subject: Re: [PATCH v5 13/13] SecurityPkg/OpalPassword: Remove HW init codes and consume SSC PPI
Date: Tue, 19 Feb 2019 02:50:24 +0000 [thread overview]
Message-ID: <B80AF82E9BFB8E4FBD8C89DA810C6A093C897E4D@SHSMSX104.ccr.corp.intel.com> (raw)
In-Reply-To: <ED077930C258884BBCB450DB737E662259DB1153@shsmsx102.ccr.corp.intel.com>
> -----Original Message-----
> From: Dong, Eric
> Sent: Monday, February 18, 2019 2:21 PM
> To: Wu, Hao A; edk2-devel@lists.01.org
> Cc: Zhang, Chao B; Yao, Jiewen; Ni, Ray
> Subject: RE: [PATCH v5 13/13] SecurityPkg/OpalPassword: Remove HW init
> codes and consume SSC PPI
>
> Hi Hao,
>
> Only one minor change that below zero action is not needed.
> > + ZeroMem (S3InitDevices, S3InitDevicesLength);
Thanks Eric, got your point.
I will also remove the line:
ZeroMem (S3InitDevicesBak, GetDevicePathSize (S3InitDevicesBak));
which similarly clear the device path information in memory.
Best Regards,
Hao Wu
>
> With above changes, Reviewed-by: Eric Dong <eric.dong@intel.com>
>
> Thanks,
> Eric
>
> > -----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>; Zhang, Chao B
> > <chao.b.zhang@intel.com>; Yao, Jiewen <jiewen.yao@intel.com>; Ni, Ray
> > <ray.ni@intel.com>; Dong, Eric <eric.dong@intel.com>
> > Subject: [PATCH v5 13/13] SecurityPkg/OpalPassword: Remove HW init
> codes
> > and consume SSC PPI
> >
> > REF:https://bugzilla.tianocore.org/show_bug.cgi?id=1409
> >
> > For the current implementation of OpalPassword drivers, it has a feature
> > to support devices being automatically unlocked in the S3 resume. For this
> > feature, two types of devices are supported:
> >
> > * ATA hard disks working under AHCI mode
> > * NVM Express devices
> >
> > The support of this feature requires the above 2 types of device to be
> > initialized at the PEI phase during S3 resume, which is done by the
> > co-work of the OpalPasswordDxe driver and the OpalPasswordPei driver.
> >
> > More specifically, the OpalPasswordDxe will handle:
> >
> > * Pre-allocate MMIO resource and save it in a driver internal LockBox for
> > OpalPasswordPei to retrieve;
> > * Save the PCI configuration space of ATA controllers into boot script.
> >
> > Meanwhile, the OpalPasswordPei will handle:
> >
> > * Rely on the boot script for the PCI configuration space program of ATA
> > controllers;
> > * Restore the driver internal LockBox to get the MMIO resource;
> > * Complete the PCI configuration space program for ATA and NVME
> > controllers;
> > * Initialize ATA and NVME controllers and devices.
> >
> > This commit will remove these hardware initialization related codes from
> > the OpalPassword drivers. The hardware initialization will be covered by
> > PEI storage device drivers (e.g. NvmExpressPei & AhciPei in the
> > MdeModulePkg).
> >
> > After such codes removal, the OpalPasswordDxe will only handle:
> >
> > * Construct/update the S3StorageDeviceInitList LockBox with the managing
> > ATA and NVME devices.
> >
> > And the OpalPasswordPei will only handle:
> >
> > * Locate Storage Security Command PPI instances to perform the device
> > automatic unlock during the S3 resume.
> >
> > Cc: Chao Zhang <chao.b.zhang@intel.com>
> > Cc: Jiewen Yao <jiewen.yao@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>
> > ---
> > SecurityPkg/Tcg/Opal/OpalPassword/OpalPasswordDxe.inf | 6 +-
> > SecurityPkg/Tcg/Opal/OpalPassword/OpalPasswordPei.inf | 12 +-
> > SecurityPkg/Tcg/Opal/OpalPassword/OpalAhciMode.h | 412 -----
> > SecurityPkg/Tcg/Opal/OpalPassword/OpalDriver.h | 4 +-
> > SecurityPkg/Tcg/Opal/OpalPassword/OpalNvmeMode.h | 327 ----
> > SecurityPkg/Tcg/Opal/OpalPassword/OpalNvmeReg.h | 815 ---------
> > SecurityPkg/Tcg/Opal/OpalPassword/OpalPasswordCommon.h | 45 +-
> > SecurityPkg/Tcg/Opal/OpalPassword/OpalPasswordPei.h | 106 +-
> > SecurityPkg/Tcg/Opal/OpalPassword/OpalAhciMode.c | 1282 ------------
> --
> > SecurityPkg/Tcg/Opal/OpalPassword/OpalDriver.c | 416 ++---
> > SecurityPkg/Tcg/Opal/OpalPassword/OpalNvmeMode.c | 1823 ----------
> --
> > --------
> > SecurityPkg/Tcg/Opal/OpalPassword/OpalPasswordPei.c | 757 ++------
> > 12 files changed, 361 insertions(+), 5644 deletions(-)
> >
> > diff --git a/SecurityPkg/Tcg/Opal/OpalPassword/OpalPasswordDxe.inf
> > b/SecurityPkg/Tcg/Opal/OpalPassword/OpalPasswordDxe.inf
> > index 11e58b95cd..2e343a4707 100644
> > --- a/SecurityPkg/Tcg/Opal/OpalPassword/OpalPasswordDxe.inf
> > +++ b/SecurityPkg/Tcg/Opal/OpalPassword/OpalPasswordDxe.inf
> > @@ -4,7 +4,7 @@
> > # This module is used to Management the Opal feature
> > # for Opal supported devices.
> > #
> > -# Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
> > +# Copyright (c) 2016 - 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
> > @@ -62,7 +62,6 @@
> > TcgStorageOpalLib
> > Tcg2PhysicalPresenceLib
> > PciLib
> > - S3BootScriptLib
> > LockBoxLib
> >
> > [Protocols]
> > @@ -73,7 +72,8 @@
> > gEfiBlockIoProtocolGuid ## CONSUMES
> >
> > [Guids]
> > - gEfiEndOfDxeEventGroupGuid ## CONSUMES ## Event
> > + gEfiEndOfDxeEventGroupGuid ## CONSUMES ## Event
> > + gS3StorageDeviceInitListGuid ## SOMETIMES_PRODUCES ##
> > UNDEFINED
> >
> > [Pcd]
> > gEfiSecurityPkgTokenSpaceGuid.PcdSkipOpalDxeUnlock ## CONSUMES
> > diff --git a/SecurityPkg/Tcg/Opal/OpalPassword/OpalPasswordPei.inf
> > b/SecurityPkg/Tcg/Opal/OpalPassword/OpalPasswordPei.inf
> > index 482b7c25af..5abfc69e80 100644
> > --- a/SecurityPkg/Tcg/Opal/OpalPassword/OpalPasswordPei.inf
> > +++ b/SecurityPkg/Tcg/Opal/OpalPassword/OpalPasswordPei.inf
> > @@ -1,7 +1,7 @@
> > ## @file
> > # This is a Opal Password PEI driver.
> > #
> > -# Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
> > +# Copyright (c) 2016 - 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
> > @@ -29,11 +29,6 @@
> > OpalPasswordPei.c
> > OpalPasswordPei.h
> > OpalPasswordCommon.h
> > - OpalAhciMode.c
> > - OpalAhciMode.h
> > - OpalNvmeMode.c
> > - OpalNvmeMode.h
> > - OpalNvmeReg.h
> >
> > [Packages]
> > MdePkg/MdePkg.dec
> > @@ -49,14 +44,13 @@
> > BaseLib
> > BaseMemoryLib
> > MemoryAllocationLib
> > - TimerLib
> > LockBoxLib
> > TcgStorageOpalLib
> > Tcg2PhysicalPresenceLib
> > + PeiServicesTablePointerLib
> >
> > [Ppis]
> > - gEdkiiIoMmuPpiGuid ## SOMETIMES_CONSUMES
> > - gEfiEndOfPeiSignalPpiGuid ## NOTIFY
> > + gEdkiiPeiStorageSecurityCommandPpiGuid ## NOTIFY
> >
> > [Depex]
> > gEfiPeiMasterBootModePpiGuid
> > diff --git a/SecurityPkg/Tcg/Opal/OpalPassword/OpalAhciMode.h
> > b/SecurityPkg/Tcg/Opal/OpalPassword/OpalAhciMode.h
> > deleted file mode 100644
> > index 2076b0411b..0000000000
> > --- a/SecurityPkg/Tcg/Opal/OpalPassword/OpalAhciMode.h
> > +++ /dev/null
> > @@ -1,412 +0,0 @@
> > -/** @file
> > - Header file for AHCI mode of ATA host controller.
> > -
> > -Copyright (c) 2016 - 2018, 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 __OPAL_PASSWORD_AHCI_MODE_H__
> > -#define __OPAL_PASSWORD_AHCI_MODE_H__
> > -
> > -//
> > -// OPAL LIBRARY CALLBACKS
> > -//
> > -#define ATA_COMMAND_TRUSTED_RECEIVE 0x5C
> > -#define ATA_COMMAND_TRUSTED_SEND 0x5E
> > -
> > -//
> > -// ATA TRUSTED commands express transfer Length in 512 byte multiple
> > -//
> > -#define ATA_TRUSTED_TRANSFER_LENGTH_MULTIPLE 512
> > -#define ATA_DEVICE_LBA 0x40 ///< Set for commands with
> > LBA (rather than CHS) addresses
> > -
> > -
> > -#define EFI_AHCI_BAR_INDEX 0x05
> > -
> > -#define EFI_AHCI_CAPABILITY_OFFSET 0x0000
> > -#define EFI_AHCI_CAP_SAM BIT18
> > -#define EFI_AHCI_GHC_OFFSET 0x0004
> > -#define EFI_AHCI_GHC_RESET BIT0
> > -#define EFI_AHCI_GHC_IE BIT1
> > -#define EFI_AHCI_GHC_ENABLE BIT31
> > -#define EFI_AHCI_IS_OFFSET 0x0008
> > -#define EFI_AHCI_PI_OFFSET 0x000C
> > -
> > -typedef struct {
> > - UINT32 Lower32;
> > - UINT32 Upper32;
> > -} DATA_32;
> > -
> > -typedef union {
> > - DATA_32 Uint32;
> > - UINT64 Uint64;
> > -} DATA_64;
> > -
> > -//
> > -// Each PRDT entry can point to a memory block up to 4M byte
> > -//
> > -#define EFI_AHCI_MAX_DATA_PER_PRDT 0x400000
> > -
> > -#define EFI_AHCI_FIS_REGISTER_H2D 0x27 //Register FIS - Host
> to
> > Device
> > -#define EFI_AHCI_FIS_REGISTER_H2D_LENGTH 20
> > -#define EFI_AHCI_FIS_REGISTER_D2H 0x34 //Register FIS -
> Device
> > to Host
> > -#define EFI_AHCI_FIS_REGISTER_D2H_LENGTH 20
> > -#define EFI_AHCI_FIS_DMA_ACTIVATE 0x39 //DMA Activate FIS -
> > Device to Host
> > -#define EFI_AHCI_FIS_DMA_ACTIVATE_LENGTH 4
> > -#define EFI_AHCI_FIS_DMA_SETUP 0x41 //DMA Setup FIS - Bi-
> > directional
> > -#define EFI_AHCI_FIS_DMA_SETUP_LENGTH 28
> > -#define EFI_AHCI_FIS_DATA 0x46 //Data FIS - Bi-directional
> > -#define EFI_AHCI_FIS_BIST 0x58 //BIST Activate FIS - Bi-
> > directional
> > -#define EFI_AHCI_FIS_BIST_LENGTH 12
> > -#define EFI_AHCI_FIS_PIO_SETUP 0x5F //PIO Setup FIS - Device
> > to Host
> > -#define EFI_AHCI_FIS_PIO_SETUP_LENGTH 20
> > -#define EFI_AHCI_FIS_SET_DEVICE 0xA1 //Set Device Bits FIS -
> > Device to Host
> > -#define EFI_AHCI_FIS_SET_DEVICE_LENGTH 8
> > -
> > -#define EFI_AHCI_D2H_FIS_OFFSET 0x40
> > -#define EFI_AHCI_DMA_FIS_OFFSET 0x00
> > -#define EFI_AHCI_PIO_FIS_OFFSET 0x20
> > -#define EFI_AHCI_SDB_FIS_OFFSET 0x58
> > -#define EFI_AHCI_FIS_TYPE_MASK 0xFF
> > -#define EFI_AHCI_U_FIS_OFFSET 0x60
> > -
> > -//
> > -// Port register
> > -//
> > -#define EFI_AHCI_PORT_START 0x0100
> > -#define EFI_AHCI_PORT_REG_WIDTH 0x0080
> > -#define EFI_AHCI_PORT_CLB 0x0000
> > -#define EFI_AHCI_PORT_CLBU 0x0004
> > -#define EFI_AHCI_PORT_FB 0x0008
> > -#define EFI_AHCI_PORT_FBU 0x000C
> > -#define EFI_AHCI_PORT_IS 0x0010
> > -#define EFI_AHCI_PORT_IS_DHRS BIT0
> > -#define EFI_AHCI_PORT_IS_PSS BIT1
> > -#define EFI_AHCI_PORT_IS_SSS BIT2
> > -#define EFI_AHCI_PORT_IS_SDBS BIT3
> > -#define EFI_AHCI_PORT_IS_UFS BIT4
> > -#define EFI_AHCI_PORT_IS_DPS BIT5
> > -#define EFI_AHCI_PORT_IS_PCS BIT6
> > -#define EFI_AHCI_PORT_IS_DIS BIT7
> > -#define EFI_AHCI_PORT_IS_PRCS BIT22
> > -#define EFI_AHCI_PORT_IS_IPMS BIT23
> > -#define EFI_AHCI_PORT_IS_OFS BIT24
> > -#define EFI_AHCI_PORT_IS_INFS BIT26
> > -#define EFI_AHCI_PORT_IS_IFS BIT27
> > -#define EFI_AHCI_PORT_IS_HBDS BIT28
> > -#define EFI_AHCI_PORT_IS_HBFS BIT29
> > -#define EFI_AHCI_PORT_IS_TFES BIT30
> > -#define EFI_AHCI_PORT_IS_CPDS BIT31
> > -#define EFI_AHCI_PORT_IS_CLEAR 0xFFFFFFFF
> > -#define EFI_AHCI_PORT_IS_FIS_CLEAR 0x0000000F
> > -
> > -#define EFI_AHCI_PORT_IE 0x0014
> > -#define EFI_AHCI_PORT_CMD 0x0018
> > -#define EFI_AHCI_PORT_CMD_ST_MASK 0xFFFFFFFE
> > -#define EFI_AHCI_PORT_CMD_ST BIT0
> > -#define EFI_AHCI_PORT_CMD_SUD BIT1
> > -#define EFI_AHCI_PORT_CMD_POD BIT2
> > -#define EFI_AHCI_PORT_CMD_COL BIT3
> > -#define EFI_AHCI_PORT_CMD_CR BIT15
> > -#define EFI_AHCI_PORT_CMD_FRE BIT4
> > -#define EFI_AHCI_PORT_CMD_FR BIT14
> > -#define EFI_AHCI_PORT_CMD_MASK ~(EFI_AHCI_PORT_CMD_ST
> |
> > EFI_AHCI_PORT_CMD_FRE | EFI_AHCI_PORT_CMD_COL)
> > -#define EFI_AHCI_PORT_CMD_PMA BIT17
> > -#define EFI_AHCI_PORT_CMD_HPCP BIT18
> > -#define EFI_AHCI_PORT_CMD_MPSP BIT19
> > -#define EFI_AHCI_PORT_CMD_CPD BIT20
> > -#define EFI_AHCI_PORT_CMD_ESP BIT21
> > -#define EFI_AHCI_PORT_CMD_ATAPI BIT24
> > -#define EFI_AHCI_PORT_CMD_DLAE BIT25
> > -#define EFI_AHCI_PORT_CMD_ALPE BIT26
> > -#define EFI_AHCI_PORT_CMD_ASP BIT27
> > -#define EFI_AHCI_PORT_CMD_ICC_MASK (BIT28 | BIT29 | BIT30 |
> > BIT31)
> > -#define EFI_AHCI_PORT_CMD_ACTIVE (1 << 28 )
> > -#define EFI_AHCI_PORT_TFD 0x0020
> > -#define EFI_AHCI_PORT_TFD_MASK (BIT7 | BIT3 | BIT0)
> > -#define EFI_AHCI_PORT_TFD_BSY BIT7
> > -#define EFI_AHCI_PORT_TFD_DRQ BIT3
> > -#define EFI_AHCI_PORT_TFD_ERR BIT0
> > -#define EFI_AHCI_PORT_TFD_ERR_MASK 0x00FF00
> > -#define EFI_AHCI_PORT_SIG 0x0024
> > -#define EFI_AHCI_PORT_SSTS 0x0028
> > -#define EFI_AHCI_PORT_SSTS_DET_MASK 0x000F
> > -#define EFI_AHCI_PORT_SSTS_DET 0x0001
> > -#define EFI_AHCI_PORT_SSTS_DET_PCE 0x0003
> > -#define EFI_AHCI_PORT_SSTS_SPD_MASK 0x00F0
> > -#define EFI_AHCI_PORT_SCTL 0x002C
> > -#define EFI_AHCI_PORT_SCTL_DET_MASK 0x000F
> > -#define EFI_AHCI_PORT_SCTL_MASK
> > (~EFI_AHCI_PORT_SCTL_DET_MASK)
> > -#define EFI_AHCI_PORT_SCTL_DET_INIT 0x0001
> > -#define EFI_AHCI_PORT_SCTL_DET_PHYCOMM 0x0003
> > -#define EFI_AHCI_PORT_SCTL_SPD_MASK 0x00F0
> > -#define EFI_AHCI_PORT_SCTL_IPM_MASK 0x0F00
> > -#define EFI_AHCI_PORT_SCTL_IPM_INIT 0x0300
> > -#define EFI_AHCI_PORT_SCTL_IPM_PSD 0x0100
> > -#define EFI_AHCI_PORT_SCTL_IPM_SSD 0x0200
> > -#define EFI_AHCI_PORT_SERR 0x0030
> > -#define EFI_AHCI_PORT_SERR_RDIE BIT0
> > -#define EFI_AHCI_PORT_SERR_RCE BIT1
> > -#define EFI_AHCI_PORT_SERR_TDIE BIT8
> > -#define EFI_AHCI_PORT_SERR_PCDIE BIT9
> > -#define EFI_AHCI_PORT_SERR_PE BIT10
> > -#define EFI_AHCI_PORT_SERR_IE BIT11
> > -#define EFI_AHCI_PORT_SERR_PRC BIT16
> > -#define EFI_AHCI_PORT_SERR_PIE BIT17
> > -#define EFI_AHCI_PORT_SERR_CW BIT18
> > -#define EFI_AHCI_PORT_SERR_BDE BIT19
> > -#define EFI_AHCI_PORT_SERR_DE BIT20
> > -#define EFI_AHCI_PORT_SERR_CRCE BIT21
> > -#define EFI_AHCI_PORT_SERR_HE BIT22
> > -#define EFI_AHCI_PORT_SERR_LSE BIT23
> > -#define EFI_AHCI_PORT_SERR_TSTE BIT24
> > -#define EFI_AHCI_PORT_SERR_UFT BIT25
> > -#define EFI_AHCI_PORT_SERR_EX BIT26
> > -#define EFI_AHCI_PORT_ERR_CLEAR 0xFFFFFFFF
> > -#define EFI_AHCI_PORT_SACT 0x0034
> > -#define EFI_AHCI_PORT_CI 0x0038
> > -#define EFI_AHCI_PORT_SNTF 0x003C
> > -
> > -
> > -#pragma pack(1)
> > -//
> > -// Command List structure includes total 32 entries.
> > -// The entry Data structure is listed at the following.
> > -//
> > -typedef struct {
> > - UINT32 AhciCmdCfl:5; //Command FIS Length
> > - UINT32 AhciCmdA:1; //ATAPI
> > - UINT32 AhciCmdW:1; //Write
> > - UINT32 AhciCmdP:1; //Prefetchable
> > - UINT32 AhciCmdR:1; //Reset
> > - UINT32 AhciCmdB:1; //BIST
> > - UINT32 AhciCmdC:1; //Clear Busy upon R_OK
> > - UINT32 AhciCmdRsvd:1;
> > - UINT32 AhciCmdPmp:4; //Port Multiplier Port
> > - UINT32 AhciCmdPrdtl:16; //Physical Region Descriptor Table Length
> > - UINT32 AhciCmdPrdbc; //Physical Region Descriptor Byte Count
> > - UINT32 AhciCmdCtba; //Command Table Descriptor Base Address
> > - UINT32 AhciCmdCtbau; //Command Table Descriptor Base Address
> > Upper 32-BITs
> > - UINT32 AhciCmdRsvd1[4];
> > -} EFI_AHCI_COMMAND_LIST;
> > -
> > -//
> > -// This is a software constructed FIS.
> > -// For Data transfer operations, this is the H2D Register FIS format as
> > -// specified in the Serial ATA Revision 2.6 specification.
> > -//
> > -typedef struct {
> > - UINT8 AhciCFisType;
> > - UINT8 AhciCFisPmNum:4;
> > - UINT8 AhciCFisRsvd:1;
> > - UINT8 AhciCFisRsvd1:1;
> > - UINT8 AhciCFisRsvd2:1;
> > - UINT8 AhciCFisCmdInd:1;
> > - UINT8 AhciCFisCmd;
> > - UINT8 AhciCFisFeature;
> > - UINT8 AhciCFisSecNum;
> > - UINT8 AhciCFisClyLow;
> > - UINT8 AhciCFisClyHigh;
> > - UINT8 AhciCFisDevHead;
> > - UINT8 AhciCFisSecNumExp;
> > - UINT8 AhciCFisClyLowExp;
> > - UINT8 AhciCFisClyHighExp;
> > - UINT8 AhciCFisFeatureExp;
> > - UINT8 AhciCFisSecCount;
> > - UINT8 AhciCFisSecCountExp;
> > - UINT8 AhciCFisRsvd3;
> > - UINT8 AhciCFisControl;
> > - UINT8 AhciCFisRsvd4[4];
> > - UINT8 AhciCFisRsvd5[44];
> > -} EFI_AHCI_COMMAND_FIS;
> > -
> > -//
> > -// ACMD: ATAPI command (12 or 16 bytes)
> > -//
> > -typedef struct {
> > - UINT8 AtapiCmd[0x10];
> > -} EFI_AHCI_ATAPI_COMMAND;
> > -
> > -//
> > -// Physical Region Descriptor Table includes up to 65535 entries
> > -// The entry Data structure is listed at the following.
> > -// the actual entry number comes from the PRDTL field in the command
> > -// list entry for this command slot.
> > -//
> > -typedef struct {
> > - UINT32 AhciPrdtDba; //Data Base Address
> > - UINT32 AhciPrdtDbau; //Data Base Address Upper 32-BITs
> > - UINT32 AhciPrdtRsvd;
> > - UINT32 AhciPrdtDbc:22; //Data Byte Count
> > - UINT32 AhciPrdtRsvd1:9;
> > - UINT32 AhciPrdtIoc:1; //Interrupt on Completion
> > -} EFI_AHCI_COMMAND_PRDT;
> > -
> > -//
> > -// Command table Data strucute which is pointed to by the entry in the
> > command list
> > -//
> > -typedef struct {
> > - EFI_AHCI_COMMAND_FIS CommandFis; // A software constructed
> > FIS.
> > - EFI_AHCI_ATAPI_COMMAND AtapiCmd; // 12 or 16 bytes ATAPI
> cmd.
> > - UINT8 Reserved[0x30];
> > - EFI_AHCI_COMMAND_PRDT PrdtTable; // The scatter/gather list for
> > Data transfer
> > -} EFI_AHCI_COMMAND_TABLE;
> > -
> > -//
> > -// Received FIS structure
> > -//
> > -typedef struct {
> > - UINT8 AhciDmaSetupFis[0x1C]; // Dma Setup Fis: offset 0x00
> > - UINT8 AhciDmaSetupFisRsvd[0x04];
> > - UINT8 AhciPioSetupFis[0x14]; // Pio Setup Fis: offset 0x20
> > - UINT8 AhciPioSetupFisRsvd[0x0C];
> > - UINT8 AhciD2HRegisterFis[0x14]; // D2H Register Fis: offset 0x40
> > - UINT8 AhciD2HRegisterFisRsvd[0x04];
> > - UINT64 AhciSetDeviceBitsFis; // Set Device Bits Fix: offset 0x58
> > - UINT8 AhciUnknownFis[0x40]; // Unkonwn Fis: offset 0x60
> > - UINT8 AhciUnknownFisRsvd[0x60];
> > -} EFI_AHCI_RECEIVED_FIS;
> > -
> > -#pragma pack()
> > -
> > -typedef struct {
> > - EFI_AHCI_RECEIVED_FIS *AhciRFis;
> > - VOID *AhciRFisMapping;
> > - EFI_AHCI_COMMAND_LIST *AhciCmdList;
> > - VOID *AhciCmdListMapping;
> > - EFI_AHCI_COMMAND_TABLE *AhciCommandTable;
> > - VOID *AhciCommandTableMapping;
> > -} EFI_AHCI_REGISTERS;
> > -
> > -typedef struct {
> > - VOID *Buffer;
> > - VOID *BufferMapping;
> > - EFI_AHCI_REGISTERS AhciRegisters;
> > - UINT32 AhciBar;
> > -} AHCI_CONTEXT;
> > -
> > -/**
> > - Allocate transfer-related data struct which is used at AHCI mode.
> > -
> > - @param[in, out] AhciContext The pointer to the AHCI_CONTEXT.
> > -
> > - @retval EFI_OUT_OF_RESOURCE No enough resource.
> > - @retval EFI_SUCCESS Successful to allocate resource.
> > -
> > -**/
> > -EFI_STATUS
> > -EFIAPI
> > -AhciAllocateResource (
> > - IN OUT AHCI_CONTEXT *AhciContext
> > - );
> > -
> > -/**
> > - Free allocated transfer-related data struct which is used at AHCI mode.
> > -
> > - @param[in, out] AhciContext The pointer to the AHCI_CONTEXT.
> > -
> > -**/
> > -VOID
> > -EFIAPI
> > -AhciFreeResource (
> > - IN OUT AHCI_CONTEXT *AhciContext
> > - );
> > -
> > -/**
> > - Initialize ATA host controller at AHCI mode.
> > -
> > - The function is designed to initialize ATA host controller.
> > -
> > - @param[in] AhciContext The pointer to the AHCI_CONTEXT.
> > - @param[in] Port The port number to do initialization.
> > -
> > -**/
> > -EFI_STATUS
> > -EFIAPI
> > -AhciModeInitialize (
> > - IN AHCI_CONTEXT *AhciContext,
> > - IN UINT8 Port
> > - );
> > -
> > -typedef struct _EFI_ATA_COMMAND_BLOCK {
> > - UINT8 Reserved1[2];
> > - UINT8 AtaCommand;
> > - UINT8 AtaFeatures;
> > - UINT8 AtaSectorNumber;
> > - UINT8 AtaCylinderLow;
> > - UINT8 AtaCylinderHigh;
> > - UINT8 AtaDeviceHead;
> > - UINT8 AtaSectorNumberExp;
> > - UINT8 AtaCylinderLowExp;
> > - UINT8 AtaCylinderHighExp;
> > - UINT8 AtaFeaturesExp;
> > - UINT8 AtaSectorCount;
> > - UINT8 AtaSectorCountExp;
> > - UINT8 Reserved2[6];
> > -} EFI_ATA_COMMAND_BLOCK;
> > -
> > -typedef struct _EFI_ATA_STATUS_BLOCK {
> > - UINT8 Reserved1[2];
> > - UINT8 AtaStatus;
> > - UINT8 AtaError;
> > - UINT8 AtaSectorNumber;
> > - UINT8 AtaCylinderLow;
> > - UINT8 AtaCylinderHigh;
> > - UINT8 AtaDeviceHead;
> > - UINT8 AtaSectorNumberExp;
> > - UINT8 AtaCylinderLowExp;
> > - UINT8 AtaCylinderHighExp;
> > - UINT8 Reserved2;
> > - UINT8 AtaSectorCount;
> > - UINT8 AtaSectorCountExp;
> > - UINT8 Reserved3[6];
> > -} EFI_ATA_STATUS_BLOCK;
> > -
> > -/**
> > - Start a PIO Data transfer on specific port.
> > -
> > - @param AhciContext The pointer to the AHCI_CONTEXT.
> > - @param Port The number of port.
> > - @param PortMultiplier The timeout Value of stop.
> > - @param AtapiCommand The atapi command will be used for the
> > transfer.
> > - @param AtapiCommandLength The Length of the atapi command.
> > - @param Read The transfer direction.
> > - @param AtaCommandBlock The EFI_ATA_COMMAND_BLOCK Data.
> > - @param AtaStatusBlock The EFI_ATA_STATUS_BLOCK Data.
> > - @param MemoryAddr The pointer to the Data Buffer.
> > - @param DataCount The Data count to be transferred.
> > - @param Timeout The timeout Value of non Data transfer.
> > -
> > - @retval EFI_DEVICE_ERROR The PIO Data transfer abort with error
> occurs.
> > - @retval EFI_TIMEOUT The operation is time out.
> > - @retval EFI_UNSUPPORTED The device is not ready for transfer.
> > - @retval EFI_SUCCESS The PIO Data transfer executes successfully.
> > -
> > -**/
> > -EFI_STATUS
> > -EFIAPI
> > -AhciPioTransfer (
> > - IN AHCI_CONTEXT *AhciContext,
> > - IN UINT8 Port,
> > - IN UINT8 PortMultiplier,
> > - IN EFI_AHCI_ATAPI_COMMAND *AtapiCommand OPTIONAL,
> > - IN UINT8 AtapiCommandLength,
> > - IN BOOLEAN Read,
> > - IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock,
> > - IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock,
> > - IN OUT VOID *MemoryAddr,
> > - IN UINT32 DataCount,
> > - IN UINT64 Timeout
> > - );
> > -
> > -
> > -#endif
> > -
> > diff --git a/SecurityPkg/Tcg/Opal/OpalPassword/OpalDriver.h
> > b/SecurityPkg/Tcg/Opal/OpalPassword/OpalDriver.h
> > index 2bca770620..1baa483e72 100644
> > --- a/SecurityPkg/Tcg/Opal/OpalPassword/OpalDriver.h
> > +++ b/SecurityPkg/Tcg/Opal/OpalPassword/OpalDriver.h
> > @@ -1,7 +1,7 @@
> > /** @file
> > Values defined and used by the Opal UEFI Driver.
> >
> > -Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
> > +Copyright (c) 2016 - 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
> > @@ -28,6 +28,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF
> ANY
> > KIND, EITHER EXPRESS OR IMPLIED.
> > #include <Protocol/StorageSecurityCommand.h>
> >
> > #include <Guid/EventGroup.h>
> > +#include <Guid/S3StorageDeviceInitList.h>
> >
> > #include <Library/UefiLib.h>
> > #include <Library/UefiBootServicesTableLib.h>
> > @@ -42,7 +43,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF
> ANY
> > KIND, EITHER EXPRESS OR IMPLIED.
> > #include <Library/HiiLib.h>
> > #include <Library/UefiHiiServicesLib.h>
> > #include <Library/PciLib.h>
> > -#include <Library/S3BootScriptLib.h>
> > #include <Library/LockBoxLib.h>
> > #include <Library/TcgStorageOpalLib.h>
> > #include <Library/Tcg2PhysicalPresenceLib.h>
> > diff --git a/SecurityPkg/Tcg/Opal/OpalPassword/OpalNvmeMode.h
> > b/SecurityPkg/Tcg/Opal/OpalPassword/OpalNvmeMode.h
> > deleted file mode 100644
> > index bd2bd5239d..0000000000
> > --- a/SecurityPkg/Tcg/Opal/OpalPassword/OpalNvmeMode.h
> > +++ /dev/null
> > @@ -1,327 +0,0 @@
> > -/** @file
> > - Header file for NVMe function definitions
> > -
> > -Copyright (c) 2016 - 2018, 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 __OPAL_PASSWORD_NVME_MODE_H__
> > -#define __OPAL_PASSWORD_NVME_MODE_H__
> > -
> > -
> > -#include "OpalNvmeReg.h"
> > -
> > -#define NVME_MAX_SECTORS 0x10000
> > -//
> > -// QueueId
> > -//
> > -#define NVME_ADMIN_QUEUE 0x00
> > -#define NVME_IO_QUEUE 0x01
> > -
> > -typedef struct {
> > - UINT8 Opcode;
> > - UINT8 FusedOperation;
> > - #define NORMAL_CMD 0x00
> > - #define FUSED_FIRST_CMD 0x01
> > - #define FUSED_SECOND_CMD 0x02
> > - UINT16 Cid;
> > -} NVME_CDW0;
> > -
> > -typedef struct {
> > - NVME_CDW0 Cdw0;
> > - UINT8 Flags;
> > - #define CDW10_VALID 0x01
> > - #define CDW11_VALID 0x02
> > - #define CDW12_VALID 0x04
> > - #define CDW13_VALID 0x08
> > - #define CDW14_VALID 0x10
> > - #define CDW15_VALID 0x20
> > - UINT32 Nsid;
> > - UINT32 Cdw10;
> > - UINT32 Cdw11;
> > - UINT32 Cdw12;
> > - UINT32 Cdw13;
> > - UINT32 Cdw14;
> > - UINT32 Cdw15;
> > -} NVM_EXPRESS_COMMAND;
> > -
> > -typedef struct {
> > - UINT32 Cdw0;
> > - UINT32 Cdw1;
> > - UINT32 Cdw2;
> > - UINT32 Cdw3;
> > -} NVM_EXPRESS_RESPONSE;
> > -
> > -typedef struct {
> > - UINT64 CommandTimeout;
> > - UINT64 TransferBuffer;
> > - UINT32 TransferLength;
> > - UINT64 MetadataBuffer;
> > - UINT32 MetadataLength;
> > - UINT8 QueueId;
> > - NVM_EXPRESS_COMMAND *NvmeCmd;
> > - NVM_EXPRESS_RESPONSE *NvmeResponse;
> > -} NVM_EXPRESS_PASS_THRU_COMMAND_PACKET;
> > -
> > -
> > -#pragma pack(1)
> > -
> > -// Internal fields
> > -typedef enum {
> > - NvmeStatusUnknown,
> > - NvmeStatusInit,
> > - NvmeStatusInuse,
> > - NvmeStatusMax,
> > -} NVME_STATUS;
> > -
> > -typedef struct {
> > - UINT32 Nbar;
> > - VOID *BaseMem;
> > - VOID *BaseMemMapping;
> > - BOOLEAN PollCancellation;
> > - UINT16 NvmeInitWaitTime;
> > -
> > - NVME_STATUS State;
> > - UINT8 BusID;
> > - UINT8 DeviceID;
> > - UINT8 FuncID;
> > - UINTN PciBase;
> > -
> > - UINT32 Nsid;
> > - UINT64 Nsuuid;
> > - UINT32 BlockSize;
> > - EFI_LBA LastBlock;
> > -
> > - //
> > - // Pointers to 4kB aligned submission & completion queues.
> > - //
> > - NVME_SQ *SqBuffer[NVME_MAX_IO_QUEUES];
> > - NVME_CQ *CqBuffer[NVME_MAX_IO_QUEUES];
> > - UINT16 Cid[NVME_MAX_IO_QUEUES];
> > -
> > - //
> > - // Submission and completion queue indices.
> > - //
> > - NVME_SQTDBL SqTdbl[NVME_MAX_IO_QUEUES];
> > - NVME_CQHDBL CqHdbl[NVME_MAX_IO_QUEUES];
> > - UINT8 Pt[NVME_MAX_IO_QUEUES];
> > -
> > - UINTN SqeCount[NVME_MAX_IO_QUEUES];
> > -
> > - //
> > - // Nvme controller capabilities
> > - //
> > - NVME_CAP Cap;
> > -
> > - //
> > - // pointer to identify controller Data
> > - //
> > - NVME_ADMIN_CONTROLLER_DATA *ControllerData;
> > - NVME_ADMIN_NAMESPACE_DATA *NamespaceData;
> > -} NVME_CONTEXT;
> > -
> > -#pragma pack()
> > -
> > -/**
> > - Transfer MMIO Data to memory.
> > -
> > - @param[in,out] MemBuffer - Destination: Memory address
> > - @param[in] MmioAddr - Source: MMIO address
> > - @param[in] Size - Size for read
> > -
> > - @retval EFI_SUCCESS - MMIO read sucessfully
> > -**/
> > -EFI_STATUS
> > -NvmeMmioRead (
> > - IN OUT VOID *MemBuffer,
> > - IN UINTN MmioAddr,
> > - IN UINTN Size
> > - );
> > -
> > -/**
> > - Transfer memory Data to MMIO.
> > -
> > - @param[in,out] MmioAddr - Destination: MMIO address
> > - @param[in] MemBuffer - Source: Memory address
> > - @param[in] Size - Size for write
> > -
> > - @retval EFI_SUCCESS - MMIO write sucessfully
> > -**/
> > -EFI_STATUS
> > -NvmeMmioWrite (
> > - IN OUT UINTN MmioAddr,
> > - IN VOID *MemBuffer,
> > - IN UINTN Size
> > - );
> > -
> > -/**
> > - Transfer memory data to MMIO.
> > -
> > - @param[in,out] MmioAddr - Destination: MMIO address
> > - @param[in] MemBuffer - Source: Memory address
> > - @param[in] Size - Size for write
> > -
> > - @retval EFI_SUCCESS - MMIO write sucessfully
> > -**/
> > -EFI_STATUS
> > -OpalPciWrite (
> > - IN OUT UINTN MmioAddr,
> > - IN VOID *MemBuffer,
> > - IN UINTN Size
> > - );
> > -
> > -/**
> > - Transfer MMIO data to memory.
> > -
> > - @param[in,out] MemBuffer - Destination: Memory address
> > - @param[in] MmioAddr - Source: MMIO address
> > - @param[in] Size - Size for read
> > -
> > - @retval EFI_SUCCESS - MMIO read sucessfully
> > -**/
> > -EFI_STATUS
> > -OpalPciRead (
> > - IN OUT VOID *MemBuffer,
> > - IN UINTN MmioAddr,
> > - IN UINTN Size
> > - );
> > -
> > -/**
> > - Allocate transfer-related Data struct which is used at Nvme.
> > -
> > - @param[in, out] Nvme The pointer to the NVME_CONTEXT Data
> > structure.
> > -
> > - @retval EFI_OUT_OF_RESOURCE No enough resource.
> > - @retval EFI_SUCCESS Successful to allocate resource.
> > -
> > -**/
> > -EFI_STATUS
> > -EFIAPI
> > -NvmeAllocateResource (
> > - IN OUT NVME_CONTEXT *Nvme
> > - );
> > -
> > -/**
> > - Free allocated transfer-related Data struct which is used at NVMe.
> > -
> > - @param[in, out] Nvme The pointer to the NVME_CONTEXT Data
> > structure.
> > -
> > -**/
> > -VOID
> > -EFIAPI
> > -NvmeFreeResource (
> > - IN OUT NVME_CONTEXT *Nvme
> > - );
> > -
> > -/**
> > - Sends an NVM Express Command Packet to an NVM Express controller or
> > namespace. This function supports
> > - both blocking I/O and nonblocking I/O. The blocking I/O functionality is
> > required, and the nonblocking
> > - I/O functionality is optional.
> > -
> > - @param[in] Nvme - The pointer to the NVME_CONTEXT Data
> > structure.
> > - @param[in] NamespaceId - Is a 32 bit Namespace ID to which the
> > Express HCI command packet will be sent.
> > - A Value of 0 denotes the NVM Express controller, a
> Value
> > of all 0FFh in the namespace
> > - ID specifies that the command packet should be sent to
> > all valid namespaces.
> > - @param[in] NamespaceUuid - Is a 64 bit Namespace UUID to which
> > the Express HCI command packet will be sent.
> > - A Value of 0 denotes the NVM Express controller, a
> Value
> > of all 0FFh in the namespace
> > - UUID specifies that the command packet should be
> sent
> > to all valid namespaces.
> > - @param[in,out] Packet - A pointer to the NVM Express HCI
> > Command Packet to send to the NVMe namespace specified
> > - by NamespaceId.
> > -
> > - @retval EFI_SUCCESS - The NVM Express Command Packet was
> sent
> > by the host. TransferLength bytes were transferred
> > - to, or from DataBuffer.
> > - @retval EFI_NOT_READY - The NVM Express Command Packet
> could
> > not be sent because the controller is not ready. The caller
> > - may retry again later.
> > - @retval EFI_DEVICE_ERROR - A device error occurred while
> attempting
> > to send the NVM Express Command Packet.
> > - @retval EFI_INVALID_PARAMETER - Namespace, or the contents of
> > NVM_EXPRESS_PASS_THRU_COMMAND_PACKET are invalid. The NVM
> > - Express Command Packet was not sent, so no
> additional
> > status information is available.
> > - @retval EFI_UNSUPPORTED - The command described by the NVM
> > Express Command Packet is not supported by the host adapter.
> > - The NVM Express Command Packet was not sent, so no
> > additional status information is available.
> > - @retval EFI_TIMEOUT - A timeout occurred while waiting for the
> > NVM Express Command Packet to execute.
> > -
> > -**/
> > -EFI_STATUS
> > -NvmePassThru (
> > - IN NVME_CONTEXT *Nvme,
> > - IN UINT32 NamespaceId,
> > - IN UINT64 NamespaceUuid,
> > - IN OUT NVM_EXPRESS_PASS_THRU_COMMAND_PACKET *Packet
> > - );
> > -
> > -/**
> > - Waits until all NVME commands completed.
> > -
> > - @param[in] Nvme - The pointer to the NVME_CONTEXT Data
> > structure.
> > - @param[in] Qid - Queue index
> > -
> > - @retval EFI_SUCCESS - All NVME commands have completed
> > - @retval EFI_TIMEOUT - Timeout occured
> > - @retval EFI_NOT_READY - Not all NVME commands have
> completed
> > - @retval others - Error occurred on device side.
> > -**/
> > -EFI_STATUS
> > -NvmeWaitAllComplete (
> > - IN NVME_CONTEXT *Nvme,
> > - IN UINT8 Qid
> > - );
> > -
> > -/**
> > - Initialize the Nvm Express controller.
> > -
> > - @param[in] Nvme - The pointer to the NVME_CONTEXT Data
> > structure.
> > -
> > - @retval EFI_SUCCESS - The NVM Express Controller is initialized
> > successfully.
> > - @retval Others - A device error occurred while initializing the
> > controller.
> > -
> > -**/
> > -EFI_STATUS
> > -NvmeControllerInit (
> > - IN NVME_CONTEXT *Nvme
> > - );
> > -
> > -/**
> > - Un-initialize the Nvm Express controller.
> > -
> > - @param[in] Nvme - The pointer to the NVME_CONTEXT Data
> > structure.
> > -
> > - @retval EFI_SUCCESS - The NVM Express Controller is un-
> initialized
> > successfully.
> > - @retval Others - A device error occurred while un-initializing the
> > controller.
> > -
> > -**/
> > -EFI_STATUS
> > -NvmeControllerExit (
> > - IN NVME_CONTEXT *Nvme
> > - );
> > -
> > -/**
> > - Security send and receive commands.
> > -
> > - @param[in] Nvme - The pointer to the NVME_CONTEXT Data
> > structure.
> > - @param[in] SendCommand - The flag to indicate the command
> > type, TRUE for Send command and FALSE for receive command
> > - @param[in] SecurityProtocol - Security Protocol
> > - @param[in] SpSpecific - Security Protocol Specific
> > - @param[in] TransferLength - Transfer Length of Buffer (in bytes) -
> > always a multiple of 512
> > - @param[in,out] TransferBuffer - Address of Data to transfer
> > -
> > - @return EFI_SUCCESS - Successfully create io submission queue.
> > - @return others - Fail to send/receive commands.
> > -
> > -**/
> > -EFI_STATUS
> > -NvmeSecuritySendReceive (
> > - IN NVME_CONTEXT *Nvme,
> > - IN BOOLEAN SendCommand,
> > - IN UINT8 SecurityProtocol,
> > - IN UINT16 SpSpecific,
> > - IN UINTN TransferLength,
> > - IN OUT VOID *TransferBuffer
> > - );
> > -
> > -#endif
> > diff --git a/SecurityPkg/Tcg/Opal/OpalPassword/OpalNvmeReg.h
> > b/SecurityPkg/Tcg/Opal/OpalPassword/OpalNvmeReg.h
> > deleted file mode 100644
> > index 03376b9e6c..0000000000
> > --- a/SecurityPkg/Tcg/Opal/OpalPassword/OpalNvmeReg.h
> > +++ /dev/null
> > @@ -1,815 +0,0 @@
> > -/** @file
> > - Header file for Registers and Structure definitions
> > -
> > -Copyright (c) 2016 - 2018, 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 __OPAL_PASSWORD_NVME_REG_H__
> > -#define __OPAL_PASSWORD_NVME_REG_H__
> > -
> > -//
> > -// PCI Header for PCIe root port configuration
> > -//
> > -#define NVME_PCIE_PCICMD 0x04
> > -#define NVME_PCIE_BNUM 0x18
> > -#define NVME_PCIE_SEC_BNUM 0x19
> > -#define NVME_PCIE_IOBL 0x1C
> > -#define NVME_PCIE_MBL 0x20
> > -#define NVME_PCIE_PMBL 0x24
> > -#define NVME_PCIE_PMBU32 0x28
> > -#define NVME_PCIE_PMLU32 0x2C
> > -#define NVME_PCIE_INTR 0x3C
> > -
> > -//
> > -// NVMe related definitions
> > -//
> > -#define PCI_CLASS_MASS_STORAGE_NVM 0x08 // mass storage
> > sub-class non-volatile memory.
> > -#define PCI_IF_NVMHCI 0x02 // mass storage programming
> > interface NVMHCI.
> > -
> > -#define NVME_ASQ_SIZE 1 // Number of admin
> > submission queue entries, which is 0-based
> > -#define NVME_ACQ_SIZE 1 // Number of admin
> > completion queue entries, which is 0-based
> > -
> > -#define NVME_CSQ_SIZE 63 // Number of I/O
> > submission queue entries, which is 0-based
> > -#define NVME_CCQ_SIZE 63 // Number of I/O
> > completion queue entries, which is 0-based
> > -
> > -#define NVME_MAX_IO_QUEUES 2 // Number of I/O
> > queues supported by the driver, 1 for AQ, 1 for CQ
> > -
> > -#define NVME_CSQ_DEPTH (NVME_CSQ_SIZE+1)
> > -#define NVME_CCQ_DEPTH (NVME_CCQ_SIZE+1)
> > -#define NVME_PRP_SIZE (4) // Pages of PRP list
> > -
> > -#define NVME_CONTROLLER_ID 0
> > -
> > -//
> > -// Time out Value for Nvme transaction execution
> > -//
> > -#define NVME_GENERIC_TIMEOUT 5000000 ///< us
> > -#define NVME_CMD_WAIT 100 ///< us
> > -#define NVME_CMD_TIMEOUT 20000000 ///< us
> > -
> > -
> > -
> > -#define NVME_MEM_MAX_SIZE \
> > - (( \
> > - 1 /* Controller Data */ + \
> > - 1 /* Identify Data */ + \
> > - 1 /* ASQ */ + \
> > - 1 /* ACQ */ + \
> > - 1 /* SQs */ + \
> > - 1 /* CQs */ + \
> > - NVME_PRP_SIZE * NVME_CSQ_DEPTH /* PRPs */ + \
> > - 1 /* SECURITY */ \
> > - ) * EFI_PAGE_SIZE)
> > -
> > -
> > -//
> > -// controller register offsets
> > -//
> > -#define NVME_CAP_OFFSET 0x0000 // Controller Capabilities
> > -#define NVME_VER_OFFSET 0x0008 // Version
> > -#define NVME_INTMS_OFFSET 0x000c // Interrupt Mask Set
> > -#define NVME_INTMC_OFFSET 0x0010 // Interrupt Mask Clear
> > -#define NVME_CC_OFFSET 0x0014 // Controller Configuration
> > -#define NVME_CSTS_OFFSET 0x001c // Controller Status
> > -#define NVME_AQA_OFFSET 0x0024 // Admin Queue Attributes
> > -#define NVME_ASQ_OFFSET 0x0028 // Admin Submission Queue
> Base
> > Address
> > -#define NVME_ACQ_OFFSET 0x0030 // Admin Completion Queue
> Base
> > Address
> > -#define NVME_SQ0_OFFSET 0x1000 // Submission Queue 0 (admin)
> > Tail Doorbell
> > -#define NVME_CQ0_OFFSET 0x1004 // Completion Queue 0 (admin)
> > Head Doorbell
> > -
> > -//
> > -// These register offsets are defined as 0x1000 + (N * (4 << CAP.DSTRD))
> > -// Get the doorbell stride bit shift Value from the controller capabilities.
> > -//
> > -#define NVME_SQTDBL_OFFSET(QID, DSTRD) 0x1000 + ((2 * (QID)) * (4
> <<
> > (DSTRD))) // Submission Queue y (NVM) Tail Doorbell
> > -#define NVME_CQHDBL_OFFSET(QID, DSTRD) 0x1000 + (((2 * (QID)) + 1)
> *
> > (4 << (DSTRD))) // Completion Queue y (NVM) Head Doorbell
> > -
> > -
> > -#pragma pack(1)
> > -
> > -//
> > -// 3.1.1 Offset 00h: CAP - Controller Capabilities
> > -//
> > -typedef struct {
> > - UINT16 Mqes; // Maximum Queue Entries Supported
> > - UINT8 Cqr:1; // Contiguous Queues Required
> > - UINT8 Ams:2; // Arbitration Mechanism Supported
> > - UINT8 Rsvd1:5;
> > - UINT8 To; // Timeout
> > - UINT16 Dstrd:4;
> > - UINT16 Rsvd2:1;
> > - UINT16 Css:4; // Command Sets Supported
> > - UINT16 Rsvd3:7;
> > - UINT8 Mpsmin:4;
> > - UINT8 Mpsmax:4;
> > - UINT8 Rsvd4;
> > -} NVME_CAP;
> > -
> > -//
> > -// 3.1.2 Offset 08h: VS - Version
> > -//
> > -typedef struct {
> > - UINT16 Mnr; // Minor version number
> > - UINT16 Mjr; // Major version number
> > -} NVME_VER;
> > -
> > -//
> > -// 3.1.5 Offset 14h: CC - Controller Configuration
> > -//
> > -typedef struct {
> > - UINT16 En:1; // Enable
> > - UINT16 Rsvd1:3;
> > - UINT16 Css:3; // Command Set Selected
> > - UINT16 Mps:4; // Memory Page Size
> > - UINT16 Ams:3; // Arbitration Mechanism Selected
> > - UINT16 Shn:2; // Shutdown Notification
> > - UINT8 Iosqes:4; // I/O Submission Queue Entry Size
> > - UINT8 Iocqes:4; // I/O Completion Queue Entry Size
> > - UINT8 Rsvd2;
> > -} NVME_CC;
> > -
> > -//
> > -// 3.1.6 Offset 1Ch: CSTS - Controller Status
> > -//
> > -typedef struct {
> > - UINT32 Rdy:1; // Ready
> > - UINT32 Cfs:1; // Controller Fatal Status
> > - UINT32 Shst:2; // Shutdown Status
> > - UINT32 Nssro:1; // NVM Subsystem Reset Occurred
> > - UINT32 Rsvd1:27;
> > -} NVME_CSTS;
> > -
> > -//
> > -// 3.1.8 Offset 24h: AQA - Admin Queue Attributes
> > -//
> > -typedef struct {
> > - UINT16 Asqs:12; // Submission Queue Size
> > - UINT16 Rsvd1:4;
> > - UINT16 Acqs:12; // Completion Queue Size
> > - UINT16 Rsvd2:4;
> > -} NVME_AQA;
> > -
> > -//
> > -// 3.1.9 Offset 28h: ASQ - Admin Submission Queue Base Address
> > -//
> > -#define NVME_ASQ UINT64
> > -
> > -//
> > -// 3.1.10 Offset 30h: ACQ - Admin Completion Queue Base Address
> > -//
> > -#define NVME_ACQ UINT64
> > -
> > -//
> > -// 3.1.11 Offset (1000h + ((2y) * (4 << CAP.DSTRD))): SQyTDBL - Submission
> > Queue y Tail Doorbell
> > -//
> > -typedef struct {
> > - UINT16 Sqt;
> > - UINT16 Rsvd1;
> > -} NVME_SQTDBL;
> > -
> > -//
> > -// 3.1.12 Offset (1000h + ((2y + 1) * (4 << CAP.DSTRD))): CQyHDBL -
> > Completion Queue y Head Doorbell
> > -//
> > -typedef struct {
> > - UINT16 Cqh;
> > - UINT16 Rsvd1;
> > -} NVME_CQHDBL;
> > -
> > -//
> > -// NVM command set structures
> > -//
> > -// Read Command
> > -//
> > -typedef struct {
> > - //
> > - // CDW 10, 11
> > - //
> > - UINT64 Slba; /* Starting Sector Address */
> > - //
> > - // CDW 12
> > - //
> > - UINT16 Nlb; /* Number of Sectors */
> > - UINT16 Rsvd1:10;
> > - UINT16 Prinfo:4; /* Protection Info Check */
> > - UINT16 Fua:1; /* Force Unit Access */
> > - UINT16 Lr:1; /* Limited Retry */
> > - //
> > - // CDW 13
> > - //
> > - UINT32 Af:4; /* Access Frequency */
> > - UINT32 Al:2; /* Access Latency */
> > - UINT32 Sr:1; /* Sequential Request */
> > - UINT32 In:1; /* Incompressible */
> > - UINT32 Rsvd2:24;
> > - //
> > - // CDW 14
> > - //
> > - UINT32 Eilbrt; /* Expected Initial Logical Block Reference Tag */
> > - //
> > - // CDW 15
> > - //
> > - UINT16 Elbat; /* Expected Logical Block Application Tag */
> > - UINT16 Elbatm; /* Expected Logical Block Application Tag Mask */
> > -} NVME_READ;
> > -
> > -//
> > -// Write Command
> > -//
> > -typedef struct {
> > - //
> > - // CDW 10, 11
> > - //
> > - UINT64 Slba; /* Starting Sector Address */
> > - //
> > - // CDW 12
> > - //
> > - UINT16 Nlb; /* Number of Sectors */
> > - UINT16 Rsvd1:10;
> > - UINT16 Prinfo:4; /* Protection Info Check */
> > - UINT16 Fua:1; /* Force Unit Access */
> > - UINT16 Lr:1; /* Limited Retry */
> > - //
> > - // CDW 13
> > - //
> > - UINT32 Af:4; /* Access Frequency */
> > - UINT32 Al:2; /* Access Latency */
> > - UINT32 Sr:1; /* Sequential Request */
> > - UINT32 In:1; /* Incompressible */
> > - UINT32 Rsvd2:24;
> > - //
> > - // CDW 14
> > - //
> > - UINT32 Ilbrt; /* Initial Logical Block Reference Tag */
> > - //
> > - // CDW 15
> > - //
> > - UINT16 Lbat; /* Logical Block Application Tag */
> > - UINT16 Lbatm; /* Logical Block Application Tag Mask */
> > -} NVME_WRITE;
> > -
> > -//
> > -// Flush
> > -//
> > -typedef struct {
> > - //
> > - // CDW 10
> > - //
> > - UINT32 Flush; /* Flush */
> > -} NVME_FLUSH;
> > -
> > -//
> > -// Write Uncorrectable command
> > -//
> > -typedef struct {
> > - //
> > - // CDW 10, 11
> > - //
> > - UINT64 Slba; /* Starting LBA */
> > - //
> > - // CDW 12
> > - //
> > - UINT32 Nlb:16; /* Number of Logical Blocks */
> > - UINT32 Rsvd1:16;
> > -} NVME_WRITE_UNCORRECTABLE;
> > -
> > -//
> > -// Write Zeroes command
> > -//
> > -typedef struct {
> > - //
> > - // CDW 10, 11
> > - //
> > - UINT64 Slba; /* Starting LBA */
> > - //
> > - // CDW 12
> > - //
> > - UINT16 Nlb; /* Number of Logical Blocks */
> > - UINT16 Rsvd1:10;
> > - UINT16 Prinfo:4; /* Protection Info Check */
> > - UINT16 Fua:1; /* Force Unit Access */
> > - UINT16 Lr:1; /* Limited Retry */
> > - //
> > - // CDW 13
> > - //
> > - UINT32 Rsvd2;
> > - //
> > - // CDW 14
> > - //
> > - UINT32 Ilbrt; /* Initial Logical Block Reference Tag */
> > - //
> > - // CDW 15
> > - //
> > - UINT16 Lbat; /* Logical Block Application Tag */
> > - UINT16 Lbatm; /* Logical Block Application Tag Mask */
> > -} NVME_WRITE_ZEROES;
> > -
> > -//
> > -// Compare command
> > -//
> > -typedef struct {
> > - //
> > - // CDW 10, 11
> > - //
> > - UINT64 Slba; /* Starting LBA */
> > - //
> > - // CDW 12
> > - //
> > - UINT16 Nlb; /* Number of Logical Blocks */
> > - UINT16 Rsvd1:10;
> > - UINT16 Prinfo:4; /* Protection Info Check */
> > - UINT16 Fua:1; /* Force Unit Access */
> > - UINT16 Lr:1; /* Limited Retry */
> > - //
> > - // CDW 13
> > - //
> > - UINT32 Rsvd2;
> > - //
> > - // CDW 14
> > - //
> > - UINT32 Eilbrt; /* Expected Initial Logical Block Reference Tag */
> > - //
> > - // CDW 15
> > - //
> > - UINT16 Elbat; /* Expected Logical Block Application Tag */
> > - UINT16 Elbatm; /* Expected Logical Block Application Tag Mask */
> > -} NVME_COMPARE;
> > -
> > -typedef union {
> > - NVME_READ Read;
> > - NVME_WRITE Write;
> > - NVME_FLUSH Flush;
> > - NVME_WRITE_UNCORRECTABLE WriteUncorrectable;
> > - NVME_WRITE_ZEROES WriteZeros;
> > - NVME_COMPARE Compare;
> > -} NVME_CMD;
> > -
> > -typedef struct {
> > - UINT16 Mp; /* Maximum Power */
> > - UINT8 Rsvd1; /* Reserved as of Nvm Express 1.1 Spec */
> > - UINT8 Mps:1; /* Max Power Scale */
> > - UINT8 Nops:1; /* Non-Operational State */
> > - UINT8 Rsvd2:6; /* Reserved as of Nvm Express 1.1 Spec */
> > - UINT32 Enlat; /* Entry Latency */
> > - UINT32 Exlat; /* Exit Latency */
> > - UINT8 Rrt:5; /* Relative Read Throughput */
> > - UINT8 Rsvd3:3; /* Reserved as of Nvm Express 1.1 Spec */
> > - UINT8 Rrl:5; /* Relative Read Leatency */
> > - UINT8 Rsvd4:3; /* Reserved as of Nvm Express 1.1 Spec */
> > - UINT8 Rwt:5; /* Relative Write Throughput */
> > - UINT8 Rsvd5:3; /* Reserved as of Nvm Express 1.1 Spec */
> > - UINT8 Rwl:5; /* Relative Write Leatency */
> > - UINT8 Rsvd6:3; /* Reserved as of Nvm Express 1.1 Spec */
> > - UINT8 Rsvd7[16]; /* Reserved as of Nvm Express 1.1 Spec */
> > -} NVME_PSDESCRIPTOR;
> > -
> > -//
> > -// Identify Controller Data
> > -//
> > -typedef struct {
> > - //
> > - // Controller Capabilities and Features 0-255
> > - //
> > - UINT16 Vid; /* PCI Vendor ID */
> > - UINT16 Ssvid; /* PCI sub-system vendor ID */
> > - UINT8 Sn[20]; /* Produce serial number */
> > -
> > - UINT8 Mn[40]; /* Proeduct model number */
> > - UINT8 Fr[8]; /* Firmware Revision */
> > - UINT8 Rab; /* Recommended Arbitration Burst */
> > - UINT8 Ieee_oiu[3]; /* Organization Unique Identifier */
> > - UINT8 Cmic; /* Multi-interface Capabilities */
> > - UINT8 Mdts; /* Maximum Data Transfer Size */
> > - UINT8 Cntlid[2]; /* Controller ID */
> > - UINT8 Rsvd1[176]; /* Reserved as of Nvm Express 1.1 Spec */
> > - //
> > - // Admin Command Set Attributes
> > - //
> > - UINT16 Oacs; /* Optional Admin Command Support */
> > - UINT8 Acl; /* Abort Command Limit */
> > - UINT8 Aerl; /* Async Event Request Limit */
> > - UINT8 Frmw; /* Firmware updates */
> > - UINT8 Lpa; /* Log Page Attributes */
> > - UINT8 Elpe; /* Error Log Page Entries */
> > - UINT8 Npss; /* Number of Power States Support */
> > - UINT8 Avscc; /* Admin Vendor Specific Command Configuration
> */
> > - UINT8 Apsta; /* Autonomous Power State Transition Attributes */
> > - UINT8 Rsvd2[246]; /* Reserved as of Nvm Express 1.1 Spec */
> > - //
> > - // NVM Command Set Attributes
> > - //
> > - UINT8 Sqes; /* Submission Queue Entry Size */
> > - UINT8 Cqes; /* Completion Queue Entry Size */
> > - UINT16 Rsvd3; /* Reserved as of Nvm Express 1.1 Spec */
> > - UINT32 Nn; /* Number of Namespaces */
> > - UINT16 Oncs; /* Optional NVM Command Support */
> > - UINT16 Fuses; /* Fused Operation Support */
> > - UINT8 Fna; /* Format NVM Attributes */
> > - UINT8 Vwc; /* Volatile Write Cache */
> > - UINT16 Awun; /* Atomic Write Unit Normal */
> > - UINT16 Awupf; /* Atomic Write Unit Power Fail */
> > - UINT8 Nvscc; /* NVM Vendor Specific Command Configuration */
> > - UINT8 Rsvd4; /* Reserved as of Nvm Express 1.1 Spec */
> > - UINT16 Acwu; /* Atomic Compare & Write Unit */
> > - UINT16 Rsvd5; /* Reserved as of Nvm Express 1.1 Spec */
> > - UINT32 Sgls; /* SGL Support */
> > - UINT8 Rsvd6[164]; /* Reserved as of Nvm Express 1.1 Spec */
> > - //
> > - // I/O Command set Attributes
> > - //
> > - UINT8 Rsvd7[1344]; /* Reserved as of Nvm Express 1.1 Spec */
> > - //
> > - // Power State Descriptors
> > - //
> > - NVME_PSDESCRIPTOR PsDescriptor[32];
> > -
> > - UINT8 VendorData[1024]; /* Vendor specific Data */
> > -} NVME_ADMIN_CONTROLLER_DATA;
> > -
> > -typedef struct {
> > - UINT16 Security : 1; /* supports security send/receive commands */
> > - UINT16 Format : 1; /* supports format nvm command */
> > - UINT16 Firmware : 1; /* supports firmware activate/download
> > commands */
> > - UINT16 Oacs_rsvd : 13;
> > - } OACS; // optional admin command support:
> > NVME_ADMIN_CONTROLLER_DATA.Oacs
> > -
> > -typedef struct {
> > - UINT16 Ms; /* Metadata Size */
> > - UINT8 Lbads; /* LBA Data Size */
> > - UINT8 Rp:2; /* Relative Performance */
> > - #define LBAF_RP_BEST 00b
> > - #define LBAF_RP_BETTER 01b
> > - #define LBAF_RP_GOOD 10b
> > - #define LBAF_RP_DEGRADED 11b
> > - UINT8 Rsvd1:6; /* Reserved as of Nvm Express 1.1 Spec */
> > -} NVME_LBAFORMAT;
> > -
> > -//
> > -// Identify Namespace Data
> > -//
> > -typedef struct {
> > - //
> > - // NVM Command Set Specific
> > - //
> > - UINT64 Nsze; /* Namespace Size (total number of blocks in
> > formatted namespace) */
> > - UINT64 Ncap; /* Namespace Capacity (max number of logical
> blocks)
> > */
> > - UINT64 Nuse; /* Namespace Utilization */
> > - UINT8 Nsfeat; /* Namespace Features */
> > - UINT8 Nlbaf; /* Number of LBA Formats */
> > - UINT8 Flbas; /* Formatted LBA Size */
> > - UINT8 Mc; /* Metadata Capabilities */
> > - UINT8 Dpc; /* End-to-end Data Protection capabilities */
> > - UINT8 Dps; /* End-to-end Data Protection Type Settings */
> > - UINT8 Nmic; /* Namespace Multi-path I/O and Namespace
> Sharing
> > Capabilities */
> > - UINT8 Rescap; /* Reservation Capabilities */
> > - UINT8 Rsvd1[88]; /* Reserved as of Nvm Express 1.1 Spec */
> > - UINT64 Eui64; /* IEEE Extended Unique Identifier */
> > - //
> > - // LBA Format
> > - //
> > - NVME_LBAFORMAT LbaFormat[16];
> > -
> > - UINT8 Rsvd2[192]; /* Reserved as of Nvm Express 1.1 Spec */
> > - UINT8 VendorData[3712]; /* Vendor specific Data */
> > -} NVME_ADMIN_NAMESPACE_DATA;
> > -
> > -//
> > -// NvmExpress Admin Identify Cmd
> > -//
> > -typedef struct {
> > - //
> > - // CDW 10
> > - //
> > - UINT32 Cns:2;
> > - UINT32 Rsvd1:30;
> > -} NVME_ADMIN_IDENTIFY;
> > -
> > -//
> > -// NvmExpress Admin Create I/O Completion Queue
> > -//
> > -typedef struct {
> > - //
> > - // CDW 10
> > - //
> > - UINT32 Qid:16; /* Queue Identifier */
> > - UINT32 Qsize:16; /* Queue Size */
> > -
> > - //
> > - // CDW 11
> > - //
> > - UINT32 Pc:1; /* Physically Contiguous */
> > - UINT32 Ien:1; /* Interrupts Enabled */
> > - UINT32 Rsvd1:14; /* reserved as of Nvm Express 1.1 Spec */
> > - UINT32 Iv:16; /* Interrupt Vector */
> > -} NVME_ADMIN_CRIOCQ;
> > -
> > -//
> > -// NvmExpress Admin Create I/O Submission Queue
> > -//
> > -typedef struct {
> > - //
> > - // CDW 10
> > - //
> > - UINT32 Qid:16; /* Queue Identifier */
> > - UINT32 Qsize:16; /* Queue Size */
> > -
> > - //
> > - // CDW 11
> > - //
> > - UINT32 Pc:1; /* Physically Contiguous */
> > - UINT32 Qprio:2; /* Queue Priority */
> > - UINT32 Rsvd1:13; /* Reserved as of Nvm Express 1.1 Spec */
> > - UINT32 Cqid:16; /* Completion Queue ID */
> > -} NVME_ADMIN_CRIOSQ;
> > -
> > -//
> > -// NvmExpress Admin Delete I/O Completion Queue
> > -//
> > -typedef struct {
> > - //
> > - // CDW 10
> > - //
> > - UINT16 Qid;
> > - UINT16 Rsvd1;
> > -} NVME_ADMIN_DEIOCQ;
> > -
> > -//
> > -// NvmExpress Admin Delete I/O Submission Queue
> > -//
> > -typedef struct {
> > - //
> > - // CDW 10
> > - //
> > - UINT16 Qid;
> > - UINT16 Rsvd1;
> > -} NVME_ADMIN_DEIOSQ;
> > -
> > -//
> > -// NvmExpress Admin Security Send
> > -//
> > -typedef struct {
> > - //
> > - // CDW 10
> > - //
> > - UINT32 Resv:8; /* Reserve */
> > - UINT32 Spsp:16; /* SP Specific */
> > - UINT32 Secp:8; /* Security Protocol */
> > -
> > - //
> > - // CDW 11
> > - //
> > - UINT32 Tl; /* Transfer Length */
> > -} NVME_ADMIN_SECSEND;
> > -
> > -//
> > -// NvmExpress Admin Abort Command
> > -//
> > -typedef struct {
> > - //
> > - // CDW 10
> > - //
> > - UINT32 Sqid:16; /* Submission Queue identifier */
> > - UINT32 Cid:16; /* Command Identifier */
> > -} NVME_ADMIN_ABORT;
> > -
> > -//
> > -// NvmExpress Admin Firmware Activate Command
> > -//
> > -typedef struct {
> > - //
> > - // CDW 10
> > - //
> > - UINT32 Fs:3; /* Submission Queue identifier */
> > - UINT32 Aa:2; /* Command Identifier */
> > - UINT32 Rsvd1:27;
> > -} NVME_ADMIN_FIRMWARE_ACTIVATE;
> > -
> > -//
> > -// NvmExpress Admin Firmware Image Download Command
> > -//
> > -typedef struct {
> > - //
> > - // CDW 10
> > - //
> > - UINT32 Numd; /* Number of Dwords */
> > - //
> > - // CDW 11
> > - //
> > - UINT32 Ofst; /* Offset */
> > -} NVME_ADMIN_FIRMWARE_IMAGE_DOWNLOAD;
> > -
> > -//
> > -// NvmExpress Admin Get Features Command
> > -//
> > -typedef struct {
> > - //
> > - // CDW 10
> > - //
> > - UINT32 Fid:8; /* Feature Identifier */
> > - UINT32 Sel:3; /* Select */
> > - UINT32 Rsvd1:21;
> > -} NVME_ADMIN_GET_FEATURES;
> > -
> > -//
> > -// NvmExpress Admin Get Log Page Command
> > -//
> > -typedef struct {
> > - //
> > - // CDW 10
> > - //
> > - UINT32 Lid:8; /* Log Page Identifier */
> > - #define LID_ERROR_INFO
> > - #define LID_SMART_INFO
> > - #define LID_FW_SLOT_INFO
> > - UINT32 Rsvd1:8;
> > - UINT32 Numd:12; /* Number of Dwords */
> > - UINT32 Rsvd2:4; /* Reserved as of Nvm Express 1.1 Spec */
> > -} NVME_ADMIN_GET_LOG_PAGE;
> > -
> > -//
> > -// NvmExpress Admin Set Features Command
> > -//
> > -typedef struct {
> > - //
> > - // CDW 10
> > - //
> > - UINT32 Fid:8; /* Feature Identifier */
> > - UINT32 Rsvd1:23;
> > - UINT32 Sv:1; /* Save */
> > -} NVME_ADMIN_SET_FEATURES;
> > -
> > -//
> > -// NvmExpress Admin Format NVM Command
> > -//
> > -typedef struct {
> > - //
> > - // CDW 10
> > - //
> > - UINT32 Lbaf:4; /* LBA Format */
> > - UINT32 Ms:1; /* Metadata Settings */
> > - UINT32 Pi:3; /* Protection Information */
> > - UINT32 Pil:1; /* Protection Information Location */
> > - UINT32 Ses:3; /* Secure Erase Settings */
> > - UINT32 Rsvd1:20;
> > -} NVME_ADMIN_FORMAT_NVM;
> > -
> > -//
> > -// NvmExpress Admin Security Receive Command
> > -//
> > -typedef struct {
> > - //
> > - // CDW 10
> > - //
> > - UINT32 Rsvd1:8;
> > - UINT32 Spsp:16; /* SP Specific */
> > - UINT32 Secp:8; /* Security Protocol */
> > - //
> > - // CDW 11
> > - //
> > - UINT32 Al; /* Allocation Length */
> > -} NVME_ADMIN_SECURITY_RECEIVE;
> > -
> > -//
> > -// NvmExpress Admin Security Send Command
> > -//
> > -typedef struct {
> > - //
> > - // CDW 10
> > - //
> > - UINT32 Rsvd1:8;
> > - UINT32 Spsp:16; /* SP Specific */
> > - UINT32 Secp:8; /* Security Protocol */
> > - //
> > - // CDW 11
> > - //
> > - UINT32 Tl; /* Transfer Length */
> > -} NVME_ADMIN_SECURITY_SEND;
> > -
> > -typedef union {
> > - NVME_ADMIN_IDENTIFY Identify;
> > - NVME_ADMIN_CRIOCQ CrIoCq;
> > - NVME_ADMIN_CRIOSQ CrIoSq;
> > - NVME_ADMIN_DEIOCQ DeIoCq;
> > - NVME_ADMIN_DEIOSQ DeIoSq;
> > - NVME_ADMIN_ABORT Abort;
> > - NVME_ADMIN_FIRMWARE_ACTIVATE Activate;
> > - NVME_ADMIN_FIRMWARE_IMAGE_DOWNLOAD
> > FirmwareImageDownload;
> > - NVME_ADMIN_GET_FEATURES GetFeatures;
> > - NVME_ADMIN_GET_LOG_PAGE GetLogPage;
> > - NVME_ADMIN_SET_FEATURES SetFeatures;
> > - NVME_ADMIN_FORMAT_NVM FormatNvm;
> > - NVME_ADMIN_SECURITY_RECEIVE SecurityReceive;
> > - NVME_ADMIN_SECURITY_SEND SecuritySend;
> > -} NVME_ADMIN_CMD;
> > -
> > -typedef struct {
> > - UINT32 Cdw10;
> > - UINT32 Cdw11;
> > - UINT32 Cdw12;
> > - UINT32 Cdw13;
> > - UINT32 Cdw14;
> > - UINT32 Cdw15;
> > -} NVME_RAW;
> > -
> > -typedef union {
> > - NVME_ADMIN_CMD Admin; // Union of Admin commands
> > - NVME_CMD Nvm; // Union of Nvm commands
> > - NVME_RAW Raw;
> > -} NVME_PAYLOAD;
> > -
> > -//
> > -// Submission Queue
> > -//
> > -typedef struct {
> > - //
> > - // CDW 0, Common to all comnmands
> > - //
> > - UINT8 Opc; // Opcode
> > - UINT8 Fuse:2; // Fused Operation
> > - UINT8 Rsvd1:5;
> > - UINT8 Psdt:1; // PRP or SGL for Data Transfer
> > - UINT16 Cid; // Command Identifier
> > -
> > - //
> > - // CDW 1
> > - //
> > - UINT32 Nsid; // Namespace Identifier
> > -
> > - //
> > - // CDW 2,3
> > - //
> > - UINT64 Rsvd2;
> > -
> > - //
> > - // CDW 4,5
> > - //
> > - UINT64 Mptr; // Metadata Pointer
> > -
> > - //
> > - // CDW 6-9
> > - //
> > - UINT64 Prp[2]; // First and second PRP entries
> > -
> > - NVME_PAYLOAD Payload;
> > -
> > -} NVME_SQ;
> > -
> > -//
> > -// Completion Queue
> > -//
> > -typedef struct {
> > - //
> > - // CDW 0
> > - //
> > - UINT32 Dword0;
> > - //
> > - // CDW 1
> > - //
> > - UINT32 Rsvd1;
> > - //
> > - // CDW 2
> > - //
> > - UINT16 Sqhd; // Submission Queue Head Pointer
> > - UINT16 Sqid; // Submission Queue Identifier
> > - //
> > - // CDW 3
> > - //
> > - UINT16 Cid; // Command Identifier
> > - UINT16 Pt:1; // Phase Tag
> > - UINT16 Sc:8; // Status Code
> > - UINT16 Sct:3; // Status Code Type
> > - UINT16 Rsvd2:2;
> > - UINT16 Mo:1; // More
> > - UINT16 Dnr:1; // Retry
> > -} NVME_CQ;
> > -
> > -//
> > -// Nvm Express Admin cmd opcodes
> > -//
> > -#define NVME_ADMIN_DELIOSQ_OPC 0
> > -#define NVME_ADMIN_CRIOSQ_OPC 1
> > -#define NVME_ADMIN_DELIOCQ_OPC 4
> > -#define NVME_ADMIN_CRIOCQ_OPC 5
> > -#define NVME_ADMIN_IDENTIFY_OPC 6
> > -#define NVME_ADMIN_SECURITY_SEND_OPC 0x81
> > -#define NVME_ADMIN_SECURITY_RECV_OPC 0x82
> > -
> > -#define NVME_IO_FLUSH_OPC 0
> > -#define NVME_IO_WRITE_OPC 1
> > -#define NVME_IO_READ_OPC 2
> > -
> > -//
> > -// Offset from the beginning of private Data queue Buffer
> > -//
> > -#define NVME_ASQ_BUF_OFFSET EFI_PAGE_SIZE
> > -
> > -#pragma pack()
> > -
> > -#endif
> > -
> > diff --git a/SecurityPkg/Tcg/Opal/OpalPassword/OpalPasswordCommon.h
> > b/SecurityPkg/Tcg/Opal/OpalPassword/OpalPasswordCommon.h
> > index e10146e466..f9fdb64137 100644
> > --- a/SecurityPkg/Tcg/Opal/OpalPassword/OpalPasswordCommon.h
> > +++ b/SecurityPkg/Tcg/Opal/OpalPassword/OpalPasswordCommon.h
> > @@ -1,7 +1,7 @@
> > /** @file
> > Opal Password common header file.
> >
> > -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
> > which accompanies this distribution. The full text of the license may be
> > found at
> > @@ -30,38 +30,15 @@ typedef struct {
> > } OPAL_PCI_DEVICE;
> >
> > typedef struct {
> > - UINT16 Length;
> > - OPAL_PCI_DEVICE Device;
> > - UINT8 PasswordLength;
> > - UINT8 Password[OPAL_MAX_PASSWORD_SIZE];
> > - UINT16 OpalBaseComId;
> > - UINT32 BarAddr;
> > -} OPAL_DEVICE_COMMON;
> > -
> > -#define OPAL_DEVICE_ATA_GUID { 0xcb934fe1, 0xb8cd, 0x46b1, { 0xa0,
> > 0x58, 0xdd, 0xcb, 0x7, 0xb7, 0xb4, 0x17 } }
> > -
> > -typedef struct {
> > - UINT16 Length;
> > - OPAL_PCI_DEVICE Device;
> > - UINT8 PasswordLength;
> > - UINT8 Password[OPAL_MAX_PASSWORD_SIZE];
> > - UINT16 OpalBaseComId;
> > - UINT32 BarAddr;
> > - UINT16 Port;
> > - UINT16 PortMultiplierPort;
> > -} OPAL_DEVICE_ATA;
> > -
> > -#define OPAL_DEVICE_NVME_GUID { 0xde116925, 0xaf7f, 0x42d9, { 0x83,
> > 0xc0, 0x7e, 0xd6, 0x26, 0x59, 0x0, 0xfb } }
> > -
> > -typedef struct {
> > - UINT16 Length;
> > - OPAL_PCI_DEVICE Device;
> > - UINT8 PasswordLength;
> > - UINT8 Password[OPAL_MAX_PASSWORD_SIZE];
> > - UINT16 OpalBaseComId;
> > - UINT32 BarAddr;
> > - UINT32 NvmeNamespaceId;
> > - OPAL_PCI_DEVICE PciBridgeNode[0];
> > -} OPAL_DEVICE_NVME;
> > + UINT32 Length;
> > + OPAL_PCI_DEVICE Device;
> > + UINT8 PasswordLength;
> > + UINT8 Password[OPAL_MAX_PASSWORD_SIZE];
> > + UINT16 OpalBaseComId;
> > + UINT32 DevicePathLength;
> > + EFI_DEVICE_PATH_PROTOCOL DevicePath[];
> > +} OPAL_DEVICE_LOCKBOX_DATA;
> > +
> > +#define OPAL_DEVICE_LOCKBOX_GUID { 0x56a77f0d, 0x6f05, 0x4d47,
> > { 0xb9, 0x11, 0x4f, 0xd, 0xec, 0x5c, 0x58, 0x61 } }
> >
> > #endif // _OPAL_PASSWORD_COMMON_H_
> > diff --git a/SecurityPkg/Tcg/Opal/OpalPassword/OpalPasswordPei.h
> > b/SecurityPkg/Tcg/Opal/OpalPassword/OpalPasswordPei.h
> > index 31aab37f5d..c86598f21c 100644
> > --- a/SecurityPkg/Tcg/Opal/OpalPassword/OpalPasswordPei.h
> > +++ b/SecurityPkg/Tcg/Opal/OpalPassword/OpalPasswordPei.h
> > @@ -1,7 +1,7 @@
> > /** @file
> > Opal Password PEI driver which is used to unlock Opal Password for S3.
> >
> > -Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
> > +Copyright (c) 2016 - 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
> > @@ -16,8 +16,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF
> ANY
> > KIND, EITHER EXPRESS OR IMPLIED.
> > #define _OPAL_PASSWORD_PEI_H_
> >
> > #include <PiPei.h>
> > -#include <IndustryStandard/Atapi.h>
> > -#include <IndustryStandard/Pci.h>
> >
> > #include <Library/DebugLib.h>
> > #include <Library/IoLib.h>
> > @@ -27,107 +25,63 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF
> > ANY KIND, EITHER EXPRESS OR IMPLIED.
> > #include <Library/MemoryAllocationLib.h>
> > #include <Library/PeimEntryPoint.h>
> > #include <Library/PeiServicesLib.h>
> > -#include <Library/HobLib.h>
> > -#include <Library/TimerLib.h>
> > #include <Library/LockBoxLib.h>
> > #include <Library/TcgStorageOpalLib.h>
> > #include <Library/Tcg2PhysicalPresenceLib.h>
> > +#include <Library/PeiServicesTablePointerLib.h>
> >
> > #include <Protocol/StorageSecurityCommand.h>
> >
> > #include <Ppi/IoMmu.h>
> > +#include <Ppi/StorageSecurityCommand.h>
> >
> > #include "OpalPasswordCommon.h"
> > -#include "OpalAhciMode.h"
> > -#include "OpalNvmeMode.h"
> >
> > //
> > -// Time out Value for ATA pass through protocol
> > +// The maximum number of Storage Security Command PPI instance
> > supported
> > +// by the driver
> > //
> > -#define ATA_TIMEOUT 30000000
> > +#define OPAL_PEI_MAX_STORAGE_SECURITY_CMD_PPI 32
> >
> > //
> > -// The payload Length of HDD related ATA commands
> > +// The generic command timeout value (unit in us) for Storage Security
> > Command
> > +// PPI ReceiveData/SendData services
> > //
> > -#define HDD_PAYLOAD 512
> > -//
> > -// According to ATA spec, the max Length of hdd password is 32 bytes
> > -//
> > -#define OPAL_PASSWORD_MAX_LENGTH 32
> > +#define SSC_PPI_GENERIC_TIMEOUT 30000000
> >
> > #pragma pack(1)
> >
> > -/**
> > -* Opal I/O Type utilized by the Trusted IO callback
> > -*
> > -* The type indicates if the I/O is a send or receive
> > -*/
> > -typedef enum {
> > - //
> > - // I/O is a TCG Trusted Send command
> > - //
> > - OpalSend,
> > -
> > - //
> > - // I/O is a TCG Trusted Receive command
> > - //
> > - OpalRecv
> > -} OPAL_IO_TYPE;
> > -
> > -#define OPAL_PEI_DEVICE_SIGNATURE SIGNATURE_32 ('o', 'p', 'd', 's')
> > +#define OPAL_PEI_DEVICE_SIGNATURE SIGNATURE_32 ('o', 'p', 'd', 's')
> >
> > typedef struct {
> > - UINTN Signature;
> > - EFI_STORAGE_SECURITY_COMMAND_PROTOCOL Sscp;
> > - UINT8 DeviceType;
> > - OPAL_DEVICE_COMMON *Device;
> > - VOID *Context;
> > + UINTN Signature;
> > + EFI_STORAGE_SECURITY_COMMAND_PROTOCOL Sscp;
> > + OPAL_DEVICE_LOCKBOX_DATA *Device;
> > + VOID *Context;
> > + EDKII_PEI_STORAGE_SECURITY_CMD_PPI *SscPpi;
> > + UINTN DeviceIndex;
> > } OPAL_PEI_DEVICE;
> >
> > -#define OPAL_PEI_DEVICE_FROM_THIS(a) CR (a, OPAL_PEI_DEVICE, Sscp,
> > OPAL_PEI_DEVICE_SIGNATURE)
> > +#define OPAL_PEI_DEVICE_FROM_THIS(a) \
> > + CR (a, OPAL_PEI_DEVICE, Sscp, OPAL_PEI_DEVICE_SIGNATURE)
> >
> > #pragma pack()
> >
> > -/**
> > - Allocates pages that are suitable for an
> > OperationBusMasterCommonBuffer or
> > - OperationBusMasterCommonBuffer64 mapping.
> > -
> > - @param Pages The number of pages to allocate.
> > - @param HostAddress A pointer to store the base system memory
> > address of the
> > - allocated range.
> > - @param DeviceAddress The resulting map address for the bus
> master
> > PCI controller to use to
> > - access the hosts HostAddress.
> > - @param Mapping A resulting value to pass to Unmap().
> > -
> > - @retval EFI_SUCCESS The requested memory pages were allocated.
> > - @retval EFI_UNSUPPORTED Attributes is unsupported. The only legal
> > attribute bits are
> > - MEMORY_WRITE_COMBINE and MEMORY_CACHED.
> > - @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
> > - @retval EFI_OUT_OF_RESOURCES The memory pages could not be
> > allocated.
> > -
> > -**/
> > -EFI_STATUS
> > -IoMmuAllocateBuffer (
> > - IN UINTN Pages,
> > - OUT VOID **HostAddress,
> > - OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,
> > - OUT VOID **Mapping
> > - );
> > +//
> > +// Private data structure for Opal PEI driver
> > +//
> > +#define OPAL_PEI_DRIVER_SIGNATURE SIGNATURE_32 ('o', 'd', 'r', 'i')
> >
> > -/**
> > - Frees memory that was allocated with AllocateBuffer().
> > +typedef struct {
> > + UINTN Signature;
> > + EFI_PEI_NOTIFY_DESCRIPTOR SscPpiNotifyList;
> >
> > - @param Pages The number of pages to free.
> > - @param HostAddress The base system memory address of the
> > allocated range.
> > - @param Mapping The mapping value returned from Map().
> > + UINTN SscPpiInstanceNum;
> > + UINTN
> > SscPpiInstances[OPAL_PEI_MAX_STORAGE_SECURITY_CMD_PPI];
> > +} OPAL_PEI_DRIVER_PRIVATE_DATA;
> >
> > -**/
> > -VOID
> > -IoMmuFreeBuffer (
> > - IN UINTN Pages,
> > - IN VOID *HostAddress,
> > - IN VOID *Mapping
> > - );
> > +#define OPAL_PEI_PRIVATE_DATA_FROM_THIS_NOTIFY(a) \
> > + CR (a, OPAL_PEI_DRIVER_PRIVATE_DATA, SscPpiNotifyList,
> > OPAL_PEI_DRIVER_SIGNATURE)
> >
> > #endif // _OPAL_PASSWORD_PEI_H_
> >
> > diff --git a/SecurityPkg/Tcg/Opal/OpalPassword/OpalAhciMode.c
> > b/SecurityPkg/Tcg/Opal/OpalPassword/OpalAhciMode.c
> > deleted file mode 100644
> > index 0c4edd5346..0000000000
> > --- a/SecurityPkg/Tcg/Opal/OpalPassword/OpalAhciMode.c
> > +++ /dev/null
> > @@ -1,1282 +0,0 @@
> > -/** @file
> > - This driver is used for Opal Password Feature support at AHCI mode.
> > -
> > -Copyright (c) 2016 - 2018, 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 "OpalPasswordPei.h"
> > -
> > -/**
> > - Start command for give slot on specific port.
> > -
> > - @param AhciBar AHCI bar address.
> > - @param Port The number of port.
> > - @param CommandSlot The number of CommandSlot.
> > - @param Timeout The timeout Value of start.
> > -
> > - @retval EFI_DEVICE_ERROR The command start unsuccessfully.
> > - @retval EFI_TIMEOUT The operation is time out.
> > - @retval EFI_SUCCESS The command start successfully.
> > -
> > -**/
> > -EFI_STATUS
> > -EFIAPI
> > -AhciStartCommand (
> > - IN UINT32 AhciBar,
> > - IN UINT8 Port,
> > - IN UINT8 CommandSlot,
> > - IN UINT64 Timeout
> > - );
> > -
> > -/**
> > - Stop command running for giving port
> > -
> > - @param AhciBar AHCI bar address.
> > - @param Port The number of port.
> > - @param Timeout The timeout Value of stop.
> > -
> > - @retval EFI_DEVICE_ERROR The command stop unsuccessfully.
> > - @retval EFI_TIMEOUT The operation is time out.
> > - @retval EFI_SUCCESS The command stop successfully.
> > -
> > -**/
> > -EFI_STATUS
> > -EFIAPI
> > -AhciStopCommand (
> > - IN UINT32 AhciBar,
> > - IN UINT8 Port,
> > - IN UINT64 Timeout
> > - );
> > -
> > -/**
> > - Read AHCI Operation register.
> > -
> > - @param AhciBar AHCI bar address.
> > - @param Offset The operation register offset.
> > -
> > - @return The register content read.
> > -
> > -**/
> > -UINT32
> > -EFIAPI
> > -AhciReadReg (
> > - IN UINT32 AhciBar,
> > - IN UINT32 Offset
> > - )
> > -{
> > - UINT32 Data;
> > -
> > - Data = 0;
> > -
> > - Data = MmioRead32 (AhciBar + Offset);
> > -
> > - return Data;
> > -}
> > -
> > -/**
> > - Write AHCI Operation register.
> > -
> > - @param AhciBar AHCI bar address.
> > - @param Offset The operation register offset.
> > - @param Data The Data used to write down.
> > -
> > -**/
> > -VOID
> > -EFIAPI
> > -AhciWriteReg (
> > - IN UINT32 AhciBar,
> > - IN UINT32 Offset,
> > - IN UINT32 Data
> > - )
> > -{
> > - MmioWrite32 (AhciBar + Offset, Data);
> > -
> > - return ;
> > -}
> > -
> > -/**
> > - Do AND operation with the Value of AHCI Operation register.
> > -
> > - @param AhciBar AHCI bar address.
> > - @param Offset The operation register offset.
> > - @param AndData The Data used to do AND operation.
> > -
> > -**/
> > -VOID
> > -EFIAPI
> > -AhciAndReg (
> > - IN UINT32 AhciBar,
> > - IN UINT32 Offset,
> > - IN UINT32 AndData
> > - )
> > -{
> > - UINT32 Data;
> > -
> > - Data = AhciReadReg (AhciBar, Offset);
> > -
> > - Data &= AndData;
> > -
> > - AhciWriteReg (AhciBar, Offset, Data);
> > -}
> > -
> > -/**
> > - Do OR operation with the Value of AHCI Operation register.
> > -
> > - @param AhciBar AHCI bar address.
> > - @param Offset The operation register offset.
> > - @param OrData The Data used to do OR operation.
> > -
> > -**/
> > -VOID
> > -EFIAPI
> > -AhciOrReg (
> > - IN UINT32 AhciBar,
> > - IN UINT32 Offset,
> > - IN UINT32 OrData
> > - )
> > -{
> > - UINT32 Data;
> > -
> > - Data = AhciReadReg (AhciBar, Offset);
> > -
> > - Data |= OrData;
> > -
> > - AhciWriteReg (AhciBar, Offset, Data);
> > -}
> > -
> > -/**
> > - Wait for memory set to the test Value.
> > -
> > - @param AhciBar AHCI bar address.
> > - @param Offset The memory offset to test.
> > - @param MaskValue The mask Value of memory.
> > - @param TestValue The test Value of memory.
> > - @param Timeout The time out Value for wait memory set.
> > -
> > - @retval EFI_DEVICE_ERROR The memory is not set.
> > - @retval EFI_TIMEOUT The memory setting is time out.
> > - @retval EFI_SUCCESS The memory is correct set.
> > -
> > -**/
> > -EFI_STATUS
> > -EFIAPI
> > -AhciWaitMmioSet (
> > - IN UINT32 AhciBar,
> > - IN UINT32 Offset,
> > - IN UINT32 MaskValue,
> > - IN UINT32 TestValue,
> > - IN UINT64 Timeout
> > - )
> > -{
> > - UINT32 Value;
> > - UINT32 Delay;
> > -
> > - Delay = (UINT32) (DivU64x32(Timeout, 1000) + 1);
> > -
> > - do {
> > - Value = AhciReadReg (AhciBar, Offset) & MaskValue;
> > -
> > - if (Value == TestValue) {
> > - return EFI_SUCCESS;
> > - }
> > -
> > - //
> > - // Stall for 100 microseconds.
> > - //
> > - MicroSecondDelay (100);
> > -
> > - Delay--;
> > -
> > - } while (Delay > 0);
> > -
> > - return EFI_TIMEOUT;
> > -}
> > -/**
> > - Wait for the Value of the specified system memory set to the test Value.
> > -
> > - @param Address The system memory address to test.
> > - @param MaskValue The mask Value of memory.
> > - @param TestValue The test Value of memory.
> > - @param Timeout The time out Value for wait memory set, uses
> 100ns
> > as a unit.
> > -
> > - @retval EFI_TIMEOUT The system memory setting is time out.
> > - @retval EFI_SUCCESS The system memory is correct set.
> > -
> > -**/
> > -EFI_STATUS
> > -EFIAPI
> > -AhciWaitMemSet (
> > - IN EFI_PHYSICAL_ADDRESS Address,
> > - IN UINT32 MaskValue,
> > - IN UINT32 TestValue,
> > - IN UINT64 Timeout
> > - )
> > -{
> > - UINT32 Value;
> > - UINT32 Delay;
> > -
> > - Delay = (UINT32) (DivU64x32 (Timeout, 1000) + 1);
> > -
> > - do {
> > - //
> > - // Access sytem memory to see if the Value is the tested one.
> > - //
> > - // The system memory pointed by Address will be updated by the
> > - // SATA Host Controller, "volatile" is introduced to prevent
> > - // compiler from optimizing the access to the memory address
> > - // to only read once.
> > - //
> > - Value = *(volatile UINT32 *) (UINTN) Address;
> > - Value &= MaskValue;
> > -
> > - if (Value == TestValue) {
> > - return EFI_SUCCESS;
> > - }
> > -
> > - //
> > - // Stall for 100 microseconds.
> > - //
> > - MicroSecondDelay (100);
> > -
> > - Delay--;
> > -
> > - } while (Delay > 0);
> > -
> > - return EFI_TIMEOUT;
> > -}
> > -
> > -/**
> > - Check the memory status to the test Value.
> > -
> > - @param[in] Address The memory address to test.
> > - @param[in] MaskValue The mask Value of memory.
> > - @param[in] TestValue The test Value of memory.
> > - @param[in, out] RetryTimes The retry times Value for waitting
> memory
> > set. If 0, then just try once.
> > -
> > - @retval EFI_NOTREADY The memory is not set.
> > - @retval EFI_TIMEOUT The memory setting retry times out.
> > - @retval EFI_SUCCESS The memory is correct set.
> > -
> > -**/
> > -EFI_STATUS
> > -EFIAPI
> > -AhciCheckMemSet (
> > - IN UINTN Address,
> > - IN UINT32 MaskValue,
> > - IN UINT32 TestValue,
> > - IN OUT UINTN *RetryTimes OPTIONAL
> > - )
> > -{
> > - UINT32 Value;
> > -
> > - if (RetryTimes != NULL) {
> > - (*RetryTimes)--;
> > - }
> > -
> > - Value = *(volatile UINT32 *) Address;
> > - Value &= MaskValue;
> > -
> > - if (Value == TestValue) {
> > - return EFI_SUCCESS;
> > - }
> > -
> > - if ((RetryTimes != NULL) && (*RetryTimes == 0)) {
> > - return EFI_TIMEOUT;
> > - } else {
> > - return EFI_NOT_READY;
> > - }
> > -}
> > -
> > -/**
> > - Clear the port interrupt and error status. It will also clear
> > - HBA interrupt status.
> > -
> > - @param AhciBar AHCI bar address.
> > - @param Port The number of port.
> > -
> > -**/
> > -VOID
> > -EFIAPI
> > -AhciClearPortStatus (
> > - IN UINT32 AhciBar,
> > - IN UINT8 Port
> > - )
> > -{
> > - UINT32 Offset;
> > -
> > - //
> > - // Clear any error status
> > - //
> > - Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH +
> > EFI_AHCI_PORT_SERR;
> > - AhciWriteReg (AhciBar, Offset, AhciReadReg (AhciBar, Offset));
> > -
> > - //
> > - // Clear any port interrupt status
> > - //
> > - Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH +
> > EFI_AHCI_PORT_IS;
> > - AhciWriteReg (AhciBar, Offset, AhciReadReg (AhciBar, Offset));
> > -
> > - //
> > - // Clear any HBA interrupt status
> > - //
> > - AhciWriteReg (AhciBar, EFI_AHCI_IS_OFFSET, AhciReadReg (AhciBar,
> > EFI_AHCI_IS_OFFSET));
> > -}
> > -
> > -/**
> > - Enable the FIS running for giving port.
> > -
> > - @param AhciBar AHCI bar address.
> > - @param Port The number of port.
> > - @param Timeout The timeout Value of enabling FIS.
> > -
> > - @retval EFI_DEVICE_ERROR The FIS enable setting fails.
> > - @retval EFI_TIMEOUT The FIS enable setting is time out.
> > - @retval EFI_SUCCESS The FIS enable successfully.
> > -
> > -**/
> > -EFI_STATUS
> > -EFIAPI
> > -AhciEnableFisReceive (
> > - IN UINT32 AhciBar,
> > - IN UINT8 Port,
> > - IN UINT64 Timeout
> > - )
> > -{
> > - UINT32 Offset;
> > -
> > - Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH +
> > EFI_AHCI_PORT_CMD;
> > - AhciOrReg (AhciBar, Offset, EFI_AHCI_PORT_CMD_FRE);
> > -
> > - return AhciWaitMmioSet (
> > - AhciBar,
> > - Offset,
> > - EFI_AHCI_PORT_CMD_FR,
> > - EFI_AHCI_PORT_CMD_FR,
> > - Timeout
> > - );
> > -}
> > -
> > -/**
> > - Disable the FIS running for giving port.
> > -
> > - @param AhciBar AHCI bar address.
> > - @param Port The number of port.
> > - @param Timeout The timeout Value of disabling FIS.
> > -
> > - @retval EFI_DEVICE_ERROR The FIS disable setting fails.
> > - @retval EFI_TIMEOUT The FIS disable setting is time out.
> > - @retval EFI_UNSUPPORTED The port is in running state.
> > - @retval EFI_SUCCESS The FIS disable successfully.
> > -
> > -**/
> > -EFI_STATUS
> > -EFIAPI
> > -AhciDisableFisReceive (
> > - IN UINT32 AhciBar,
> > - IN UINT8 Port,
> > - IN UINT64 Timeout
> > - )
> > -{
> > - UINT32 Offset;
> > - UINT32 Data;
> > -
> > - Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH +
> > EFI_AHCI_PORT_CMD;
> > - Data = AhciReadReg (AhciBar, Offset);
> > -
> > - //
> > - // Before disabling Fis receive, the DMA engine of the port should NOT
> be
> > in running status.
> > - //
> > - if ((Data & (EFI_AHCI_PORT_CMD_ST | EFI_AHCI_PORT_CMD_CR)) != 0) {
> > - return EFI_UNSUPPORTED;
> > - }
> > -
> > - //
> > - // Check if the Fis receive DMA engine for the port is running.
> > - //
> > - if ((Data & EFI_AHCI_PORT_CMD_FR) != EFI_AHCI_PORT_CMD_FR) {
> > - return EFI_SUCCESS;
> > - }
> > -
> > - AhciAndReg (AhciBar, Offset, (UINT32)~(EFI_AHCI_PORT_CMD_FRE));
> > -
> > - return AhciWaitMmioSet (
> > - AhciBar,
> > - Offset,
> > - EFI_AHCI_PORT_CMD_FR,
> > - 0,
> > - Timeout
> > - );
> > -}
> > -
> > -/**
> > - Build the command list, command table and prepare the fis receiver.
> > -
> > - @param AhciContext The pointer to the AHCI_CONTEXT.
> > - @param Port The number of port.
> > - @param PortMultiplier The timeout Value of stop.
> > - @param CommandFis The control fis will be used for the transfer.
> > - @param CommandList The command list will be used for the
> transfer.
> > - @param AtapiCommand The atapi command will be used for the
> > transfer.
> > - @param AtapiCommandLength The Length of the atapi command.
> > - @param CommandSlotNumber The command slot will be used for the
> > transfer.
> > - @param DataPhysicalAddr The pointer to the Data Buffer pci bus
> > master address.
> > - @param DataLength The Data count to be transferred.
> > -
> > -**/
> > -VOID
> > -EFIAPI
> > -AhciBuildCommand (
> > - IN AHCI_CONTEXT *AhciContext,
> > - IN UINT8 Port,
> > - IN UINT8 PortMultiplier,
> > - IN EFI_AHCI_COMMAND_FIS *CommandFis,
> > - IN EFI_AHCI_COMMAND_LIST *CommandList,
> > - IN EFI_AHCI_ATAPI_COMMAND *AtapiCommand OPTIONAL,
> > - IN UINT8 AtapiCommandLength,
> > - IN UINT8 CommandSlotNumber,
> > - IN OUT VOID *DataPhysicalAddr,
> > - IN UINT64 DataLength
> > - )
> > -{
> > - EFI_AHCI_REGISTERS *AhciRegisters;
> > - UINT32 AhciBar;
> > - UINT64 BaseAddr;
> > - UINT64 PrdtNumber;
> > - UINTN RemainedData;
> > - UINTN MemAddr;
> > - DATA_64 Data64;
> > - UINT32 Offset;
> > -
> > - AhciRegisters = &AhciContext->AhciRegisters;
> > - AhciBar = AhciContext->AhciBar;
> > -
> > - //
> > - // Filling the PRDT
> > - //
> > - PrdtNumber = DivU64x32 (DataLength +
> EFI_AHCI_MAX_DATA_PER_PRDT
> > - 1, EFI_AHCI_MAX_DATA_PER_PRDT);
> > -
> > - //
> > - // According to AHCI 1.3 spec, a PRDT entry can point to a maximum 4MB
> > Data block.
> > - // It also limits that the maximum amount of the PRDT entry in the
> > command table
> > - // is 65535.
> > - //
> > - ASSERT (PrdtNumber <= 1);
> > -
> > - Data64.Uint64 = (UINTN) (AhciRegisters->AhciRFis);
> > -
> > - BaseAddr = Data64.Uint64;
> > -
> > - ZeroMem ((VOID *)((UINTN) BaseAddr), sizeof
> (EFI_AHCI_RECEIVED_FIS));
> > -
> > - ZeroMem (AhciRegisters->AhciCommandTable, sizeof
> > (EFI_AHCI_COMMAND_TABLE));
> > -
> > - CommandFis->AhciCFisPmNum = PortMultiplier;
> > -
> > - CopyMem (&AhciRegisters->AhciCommandTable->CommandFis,
> > CommandFis, sizeof (EFI_AHCI_COMMAND_FIS));
> > -
> > - Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH +
> > EFI_AHCI_PORT_CMD;
> > - if (AtapiCommand != NULL) {
> > - CopyMem (
> > - &AhciRegisters->AhciCommandTable->AtapiCmd,
> > - AtapiCommand,
> > - AtapiCommandLength
> > - );
> > -
> > - CommandList->AhciCmdA = 1;
> > - CommandList->AhciCmdP = 1;
> > -
> > - AhciOrReg (AhciBar, Offset, (EFI_AHCI_PORT_CMD_DLAE |
> > EFI_AHCI_PORT_CMD_ATAPI));
> > - } else {
> > - AhciAndReg (AhciBar, Offset, (UINT32)~(EFI_AHCI_PORT_CMD_DLAE |
> > EFI_AHCI_PORT_CMD_ATAPI));
> > - }
> > -
> > - RemainedData = (UINTN) DataLength;
> > - MemAddr = (UINTN) DataPhysicalAddr;
> > - CommandList->AhciCmdPrdtl = (UINT32)PrdtNumber;
> > -
> > - AhciRegisters->AhciCommandTable->PrdtTable.AhciPrdtDbc =
> > (UINT32)RemainedData - 1;
> > -
> > - Data64.Uint64 = (UINT64)MemAddr;
> > - AhciRegisters->AhciCommandTable->PrdtTable.AhciPrdtDba =
> > Data64.Uint32.Lower32;
> > - AhciRegisters->AhciCommandTable->PrdtTable.AhciPrdtDbau =
> > Data64.Uint32.Upper32;
> > -
> > - //
> > - // Set the last PRDT to Interrupt On Complete
> > - //
> > - AhciRegisters->AhciCommandTable->PrdtTable.AhciPrdtIoc = 1;
> > -
> > - CopyMem (
> > - (VOID *) ((UINTN) AhciRegisters->AhciCmdList + (UINTN)
> > CommandSlotNumber * sizeof (EFI_AHCI_COMMAND_LIST)),
> > - CommandList,
> > - sizeof (EFI_AHCI_COMMAND_LIST)
> > - );
> > -
> > - Data64.Uint64 = (UINT64)(UINTN) AhciRegisters->AhciCommandTable;
> > - AhciRegisters->AhciCmdList[CommandSlotNumber].AhciCmdCtba =
> > Data64.Uint32.Lower32;
> > - AhciRegisters->AhciCmdList[CommandSlotNumber].AhciCmdCtbau =
> > Data64.Uint32.Upper32;
> > - AhciRegisters->AhciCmdList[CommandSlotNumber].AhciCmdPmp =
> > PortMultiplier;
> > -
> > -}
> > -
> > -/**
> > - Buid a command FIS.
> > -
> > - @param CmdFis A pointer to the EFI_AHCI_COMMAND_FIS Data
> > structure.
> > - @param AtaCommandBlock A pointer to the AhciBuildCommandFis
> Data
> > structure.
> > -
> > -**/
> > -VOID
> > -EFIAPI
> > -AhciBuildCommandFis (
> > - IN OUT EFI_AHCI_COMMAND_FIS *CmdFis,
> > - IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock
> > - )
> > -{
> > - ZeroMem (CmdFis, sizeof (EFI_AHCI_COMMAND_FIS));
> > -
> > - CmdFis->AhciCFisType = EFI_AHCI_FIS_REGISTER_H2D;
> > - //
> > - // Indicator it's a command
> > - //
> > - CmdFis->AhciCFisCmdInd = 0x1;
> > - CmdFis->AhciCFisCmd = AtaCommandBlock->AtaCommand;
> > -
> > - CmdFis->AhciCFisFeature = AtaCommandBlock->AtaFeatures;
> > - CmdFis->AhciCFisFeatureExp = AtaCommandBlock->AtaFeaturesExp;
> > -
> > - CmdFis->AhciCFisSecNum = AtaCommandBlock->AtaSectorNumber;
> > - CmdFis->AhciCFisSecNumExp = AtaCommandBlock-
> > >AtaSectorNumberExp;
> > -
> > - CmdFis->AhciCFisClyLow = AtaCommandBlock->AtaCylinderLow;
> > - CmdFis->AhciCFisClyLowExp = AtaCommandBlock->AtaCylinderLowExp;
> > -
> > - CmdFis->AhciCFisClyHigh = AtaCommandBlock->AtaCylinderHigh;
> > - CmdFis->AhciCFisClyHighExp = AtaCommandBlock->AtaCylinderHighExp;
> > -
> > - CmdFis->AhciCFisSecCount = AtaCommandBlock->AtaSectorCount;
> > - CmdFis->AhciCFisSecCountExp = AtaCommandBlock-
> >AtaSectorCountExp;
> > -
> > - CmdFis->AhciCFisDevHead = (UINT8) (AtaCommandBlock-
> > >AtaDeviceHead | 0xE0);
> > -}
> > -
> > -/**
> > - Start a PIO Data transfer on specific port.
> > -
> > - @param AhciContext The pointer to the AHCI_CONTEXT.
> > - @param Port The number of port.
> > - @param PortMultiplier The timeout Value of stop.
> > - @param AtapiCommand The atapi command will be used for the
> > transfer.
> > - @param AtapiCommandLength The Length of the atapi command.
> > - @param Read The transfer direction.
> > - @param AtaCommandBlock The EFI_ATA_COMMAND_BLOCK Data.
> > - @param AtaStatusBlock The EFI_ATA_STATUS_BLOCK Data.
> > - @param MemoryAddr The pointer to the Data Buffer.
> > - @param DataCount The Data count to be transferred.
> > - @param Timeout The timeout Value of non Data transfer.
> > -
> > - @retval EFI_DEVICE_ERROR The PIO Data transfer abort with error
> occurs.
> > - @retval EFI_TIMEOUT The operation is time out.
> > - @retval EFI_UNSUPPORTED The device is not ready for transfer.
> > - @retval EFI_SUCCESS The PIO Data transfer executes successfully.
> > -
> > -**/
> > -EFI_STATUS
> > -EFIAPI
> > -AhciPioTransfer (
> > - IN AHCI_CONTEXT *AhciContext,
> > - IN UINT8 Port,
> > - IN UINT8 PortMultiplier,
> > - IN EFI_AHCI_ATAPI_COMMAND *AtapiCommand OPTIONAL,
> > - IN UINT8 AtapiCommandLength,
> > - IN BOOLEAN Read,
> > - IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock,
> > - IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock,
> > - IN OUT VOID *MemoryAddr,
> > - IN UINT32 DataCount,
> > - IN UINT64 Timeout
> > - )
> > -{
> > - EFI_STATUS Status;
> > - EFI_AHCI_REGISTERS *AhciRegisters;
> > - UINT32 AhciBar;
> > - UINT32 FisBaseAddr;
> > - UINT32 Offset;
> > - UINT32 Delay;
> > - EFI_AHCI_COMMAND_FIS CFis;
> > - EFI_AHCI_COMMAND_LIST CmdList;
> > - UINT32 PortTfd;
> > - UINT32 PrdCount;
> > - UINT32 OldRfisLo;
> > - UINT32 OldRfisHi;
> > - UINT32 OldCmdListLo;
> > - UINT32 OldCmdListHi;
> > -
> > - AhciRegisters = &AhciContext->AhciRegisters;
> > - AhciBar = AhciContext->AhciBar;
> > -
> > - Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH
> +
> > EFI_AHCI_PORT_FB;
> > - OldRfisLo = AhciReadReg (AhciBar, Offset);
> > - Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH
> +
> > EFI_AHCI_PORT_FBU;
> > - OldRfisHi = AhciReadReg (AhciBar, Offset);
> > - Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH
> +
> > EFI_AHCI_PORT_FB;
> > - AhciWriteReg (AhciBar, Offset, (UINT32)(UINTN)AhciRegisters->AhciRFis);
> > - Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH
> +
> > EFI_AHCI_PORT_FBU;
> > - AhciWriteReg (AhciBar, Offset, 0);
> > -
> > - //
> > - // Single task envrionment, we only use one command table for all port
> > - //
> > - Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH +
> > EFI_AHCI_PORT_CLB;
> > - OldCmdListLo = AhciReadReg (AhciBar, Offset);
> > - Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH +
> > EFI_AHCI_PORT_CLBU;
> > - OldCmdListHi = AhciReadReg (AhciBar, Offset);
> > - Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH +
> > EFI_AHCI_PORT_CLB;
> > - AhciWriteReg (AhciBar, Offset, (UINT32)(UINTN)AhciRegisters-
> > >AhciCmdList);
> > - Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH +
> > EFI_AHCI_PORT_CLBU;
> > - AhciWriteReg (AhciBar, Offset, 0);
> > -
> > - //
> > - // Package read needed
> > - //
> > - AhciBuildCommandFis (&CFis, AtaCommandBlock);
> > -
> > - ZeroMem (&CmdList, sizeof (EFI_AHCI_COMMAND_LIST));
> > -
> > - CmdList.AhciCmdCfl = EFI_AHCI_FIS_REGISTER_H2D_LENGTH / 4;
> > - CmdList.AhciCmdW = Read ? 0 : 1;
> > -
> > - AhciBuildCommand (
> > - AhciContext,
> > - Port,
> > - PortMultiplier,
> > - &CFis,
> > - &CmdList,
> > - AtapiCommand,
> > - AtapiCommandLength,
> > - 0,
> > - MemoryAddr,
> > - DataCount
> > - );
> > -
> > - Status = AhciStartCommand (
> > - AhciBar,
> > - Port,
> > - 0,
> > - Timeout
> > - );
> > - if (EFI_ERROR (Status)) {
> > - goto Exit;
> > - }
> > -
> > - //
> > - // Checking the status and wait the driver sending Data
> > - //
> > - FisBaseAddr = (UINT32)(UINTN)AhciRegisters->AhciRFis;
> > - if (Read && (AtapiCommand == 0)) {
> > - //
> > - // Wait device sends the PIO setup fis before Data transfer
> > - //
> > - Status = EFI_TIMEOUT;
> > - Delay = (UINT32) (DivU64x32 (Timeout, 1000) + 1);
> > - do {
> > - Offset = FisBaseAddr + EFI_AHCI_PIO_FIS_OFFSET;
> > -
> > - Status = AhciCheckMemSet (Offset, EFI_AHCI_FIS_TYPE_MASK,
> > EFI_AHCI_FIS_PIO_SETUP, 0);
> > - if (!EFI_ERROR (Status)) {
> > - Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH
> +
> > EFI_AHCI_PORT_TFD;
> > - PortTfd = AhciReadReg (AhciBar, (UINT32) Offset);
> > - //
> > - // PxTFD will be updated if there is a D2H or SetupFIS received.
> > - // For PIO IN transfer, D2H means a device error. Therefore we only
> > need to check the TFD after receiving a SetupFIS.
> > - //
> > - if ((PortTfd & EFI_AHCI_PORT_TFD_ERR) != 0) {
> > - Status = EFI_DEVICE_ERROR;
> > - break;
> > - }
> > -
> > - PrdCount = *(volatile UINT32 *) (&(AhciRegisters-
> > >AhciCmdList[0].AhciCmdPrdbc));
> > - if (PrdCount == DataCount) {
> > - break;
> > - }
> > - }
> > -
> > - Offset = FisBaseAddr + EFI_AHCI_D2H_FIS_OFFSET;
> > - Status = AhciCheckMemSet (Offset, EFI_AHCI_FIS_TYPE_MASK,
> > EFI_AHCI_FIS_REGISTER_D2H, 0);
> > - if (!EFI_ERROR (Status)) {
> > - Status = EFI_DEVICE_ERROR;
> > - break;
> > - }
> > -
> > - //
> > - // Stall for 100 microseconds.
> > - //
> > - MicroSecondDelay(100);
> > -
> > - Delay--;
> > - } while (Delay > 0);
> > - } else {
> > - //
> > - // Wait for D2H Fis is received
> > - //
> > - Offset = FisBaseAddr + EFI_AHCI_D2H_FIS_OFFSET;
> > - Status = AhciWaitMemSet (
> > - Offset,
> > - EFI_AHCI_FIS_TYPE_MASK,
> > - EFI_AHCI_FIS_REGISTER_D2H,
> > - Timeout
> > - );
> > -
> > - if (EFI_ERROR (Status)) {
> > - goto Exit;
> > - }
> > -
> > - Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH +
> > EFI_AHCI_PORT_TFD;
> > - PortTfd = AhciReadReg (AhciBar, (UINT32) Offset);
> > - if ((PortTfd & EFI_AHCI_PORT_TFD_ERR) != 0) {
> > - Status = EFI_DEVICE_ERROR;
> > - }
> > - }
> > -
> > -Exit:
> > - AhciStopCommand (
> > - AhciBar,
> > - Port,
> > - Timeout
> > - );
> > -
> > - AhciDisableFisReceive (
> > - AhciBar,
> > - Port,
> > - Timeout
> > - );
> > -
> > - Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH
> +
> > EFI_AHCI_PORT_FB;
> > - AhciWriteReg (AhciBar, Offset, OldRfisLo);
> > - Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH
> +
> > EFI_AHCI_PORT_FBU;
> > - AhciWriteReg (AhciBar, Offset, OldRfisHi);
> > -
> > - Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH
> +
> > EFI_AHCI_PORT_CLB;
> > - AhciWriteReg (AhciBar, Offset, OldCmdListLo);
> > - Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH
> +
> > EFI_AHCI_PORT_CLBU;
> > - AhciWriteReg (AhciBar, Offset, OldCmdListHi);
> > -
> > - return Status;
> > -}
> > -
> > -/**
> > - Stop command running for giving port
> > -
> > - @param AhciBar AHCI bar address.
> > - @param Port The number of port.
> > - @param Timeout The timeout Value of stop.
> > -
> > - @retval EFI_DEVICE_ERROR The command stop unsuccessfully.
> > - @retval EFI_TIMEOUT The operation is time out.
> > - @retval EFI_SUCCESS The command stop successfully.
> > -
> > -**/
> > -EFI_STATUS
> > -EFIAPI
> > -AhciStopCommand (
> > - IN UINT32 AhciBar,
> > - IN UINT8 Port,
> > - IN UINT64 Timeout
> > - )
> > -{
> > - UINT32 Offset;
> > - UINT32 Data;
> > -
> > - Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH +
> > EFI_AHCI_PORT_CMD;
> > - Data = AhciReadReg (AhciBar, Offset);
> > -
> > - if ((Data & (EFI_AHCI_PORT_CMD_ST | EFI_AHCI_PORT_CMD_CR)) == 0)
> {
> > - return EFI_SUCCESS;
> > - }
> > -
> > - if ((Data & EFI_AHCI_PORT_CMD_ST) != 0) {
> > - AhciAndReg (AhciBar, Offset, (UINT32)~(EFI_AHCI_PORT_CMD_ST));
> > - }
> > -
> > - return AhciWaitMmioSet (
> > - AhciBar,
> > - Offset,
> > - EFI_AHCI_PORT_CMD_CR,
> > - 0,
> > - Timeout
> > - );
> > -}
> > -
> > -/**
> > - Start command for give slot on specific port.
> > -
> > - @param AhciBar AHCI bar address.
> > - @param Port The number of port.
> > - @param CommandSlot The number of CommandSlot.
> > - @param Timeout The timeout Value of start.
> > -
> > - @retval EFI_DEVICE_ERROR The command start unsuccessfully.
> > - @retval EFI_TIMEOUT The operation is time out.
> > - @retval EFI_SUCCESS The command start successfully.
> > -
> > -**/
> > -EFI_STATUS
> > -EFIAPI
> > -AhciStartCommand (
> > - IN UINT32 AhciBar,
> > - IN UINT8 Port,
> > - IN UINT8 CommandSlot,
> > - IN UINT64 Timeout
> > - )
> > -{
> > - UINT32 CmdSlotBit;
> > - EFI_STATUS Status;
> > - UINT32 PortStatus;
> > - UINT32 StartCmd;
> > - UINT32 PortTfd;
> > - UINT32 Offset;
> > - UINT32 Capability;
> > -
> > - //
> > - // Collect AHCI controller information
> > - //
> > - Capability = AhciReadReg(AhciBar, EFI_AHCI_CAPABILITY_OFFSET);
> > -
> > - CmdSlotBit = (UINT32) (1 << CommandSlot);
> > -
> > - AhciClearPortStatus (
> > - AhciBar,
> > - Port
> > - );
> > -
> > - Status = AhciEnableFisReceive (
> > - AhciBar,
> > - Port,
> > - Timeout
> > - );
> > -
> > - if (EFI_ERROR (Status)) {
> > - return Status;
> > - }
> > -
> > - Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH +
> > EFI_AHCI_PORT_CMD;
> > - PortStatus = AhciReadReg (AhciBar, Offset);
> > -
> > - StartCmd = 0;
> > - if ((PortStatus & EFI_AHCI_PORT_CMD_ALPE) != 0) {
> > - StartCmd = AhciReadReg (AhciBar, Offset);
> > - StartCmd &= ~EFI_AHCI_PORT_CMD_ICC_MASK;
> > - StartCmd |= EFI_AHCI_PORT_CMD_ACTIVE;
> > - }
> > -
> > - Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH +
> > EFI_AHCI_PORT_TFD;
> > - PortTfd = AhciReadReg (AhciBar, Offset);
> > -
> > - if ((PortTfd & (EFI_AHCI_PORT_TFD_BSY | EFI_AHCI_PORT_TFD_DRQ)) !=
> 0)
> > {
> > - if ((Capability & BIT24) != 0) {
> > - Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH
> +
> > EFI_AHCI_PORT_CMD;
> > - AhciOrReg (AhciBar, Offset, EFI_AHCI_PORT_CMD_COL);
> > -
> > - AhciWaitMmioSet (
> > - AhciBar,
> > - Offset,
> > - EFI_AHCI_PORT_CMD_COL,
> > - 0,
> > - Timeout
> > - );
> > - }
> > - }
> > -
> > - Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH +
> > EFI_AHCI_PORT_CMD;
> > - AhciOrReg (AhciBar, Offset, EFI_AHCI_PORT_CMD_ST | StartCmd);
> > -
> > - //
> > - // Setting the command
> > - //
> > - Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH +
> > EFI_AHCI_PORT_SACT;
> > - AhciAndReg (AhciBar, Offset, 0);
> > - AhciOrReg (AhciBar, Offset, CmdSlotBit);
> > -
> > - Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH +
> > EFI_AHCI_PORT_CI;
> > - AhciAndReg (AhciBar, Offset, 0);
> > - AhciOrReg (AhciBar, Offset, CmdSlotBit);
> > - return EFI_SUCCESS;
> > -}
> > -
> > -
> > -/**
> > - Do AHCI HBA reset.
> > -
> > - @param[in] AhciBar AHCI bar address.
> > - @param[in] Timeout The timeout Value of reset.
> > -
> > - @retval EFI_DEVICE_ERROR AHCI controller is failed to complete
> hardware
> > reset.
> > - @retval EFI_TIMEOUT The reset operation is time out.
> > - @retval EFI_SUCCESS AHCI controller is reset successfully.
> > -
> > -**/
> > -EFI_STATUS
> > -EFIAPI
> > -AhciReset (
> > - IN UINT32 AhciBar,
> > - IN UINT64 Timeout
> > - )
> > -{
> > - UINT32 Delay;
> > - UINT32 Value;
> > - UINT32 Capability;
> > -
> > - //
> > - // Collect AHCI controller information
> > - //
> > - Capability = AhciReadReg (AhciBar, EFI_AHCI_CAPABILITY_OFFSET);
> > -
> > - //
> > - // Enable AE before accessing any AHCI registers if Supports AHCI Mode
> > Only is not set
> > - //
> > - if ((Capability & EFI_AHCI_CAP_SAM) == 0) {
> > - AhciOrReg (AhciBar, EFI_AHCI_GHC_OFFSET, EFI_AHCI_GHC_ENABLE);
> > - }
> > -
> > - AhciOrReg (AhciBar, EFI_AHCI_GHC_OFFSET, EFI_AHCI_GHC_RESET);
> > -
> > - Delay = (UINT32) (DivU64x32(Timeout, 1000) + 1);
> > -
> > - do {
> > - Value = AhciReadReg(AhciBar, EFI_AHCI_GHC_OFFSET);
> > - if ((Value & EFI_AHCI_GHC_RESET) == 0) {
> > - return EFI_SUCCESS;
> > - }
> > -
> > - //
> > - // Stall for 100 microseconds.
> > - //
> > - MicroSecondDelay(100);
> > -
> > - Delay--;
> > - } while (Delay > 0);
> > -
> > - return EFI_TIMEOUT;
> > -
> > -
> > -}
> > -
> > -/**
> > - Allocate transfer-related data struct which is used at AHCI mode.
> > -
> > - @param[in, out] AhciContext The pointer to the AHCI_CONTEXT.
> > -
> > - @retval EFI_OUT_OF_RESOURCE No enough resource.
> > - @retval EFI_SUCCESS Successful to allocate resource.
> > -
> > -**/
> > -EFI_STATUS
> > -EFIAPI
> > -AhciAllocateResource (
> > - IN OUT AHCI_CONTEXT *AhciContext
> > - )
> > -{
> > - EFI_STATUS Status;
> > - EFI_AHCI_REGISTERS *AhciRegisters;
> > - EFI_PHYSICAL_ADDRESS DeviceAddress;
> > - VOID *Base;
> > - VOID *Mapping;
> > -
> > - AhciRegisters = &AhciContext->AhciRegisters;
> > -
> > - //
> > - // Allocate resources required by AHCI host controller.
> > - //
> > - Status = IoMmuAllocateBuffer (
> > - EFI_SIZE_TO_PAGES (sizeof (EFI_AHCI_RECEIVED_FIS)),
> > - &Base,
> > - &DeviceAddress,
> > - &Mapping
> > - );
> > - if (EFI_ERROR (Status)) {
> > - return EFI_OUT_OF_RESOURCES;
> > - }
> > - ASSERT (DeviceAddress == ((EFI_PHYSICAL_ADDRESS) (UINTN) Base));
> > - AhciRegisters->AhciRFisMapping = Mapping;
> > - AhciRegisters->AhciRFis = Base;
> > - ZeroMem (AhciRegisters->AhciRFis, EFI_PAGE_SIZE *
> EFI_SIZE_TO_PAGES
> > (sizeof (EFI_AHCI_RECEIVED_FIS)));
> > -
> > - Status = IoMmuAllocateBuffer (
> > - EFI_SIZE_TO_PAGES (sizeof (EFI_AHCI_COMMAND_LIST)),
> > - &Base,
> > - &DeviceAddress,
> > - &Mapping
> > - );
> > - if (EFI_ERROR (Status)) {
> > - IoMmuFreeBuffer (
> > - EFI_SIZE_TO_PAGES (sizeof (EFI_AHCI_RECEIVED_FIS)),
> > - AhciRegisters->AhciRFis,
> > - AhciRegisters->AhciRFisMapping
> > - );
> > - AhciRegisters->AhciRFis = NULL;
> > - return EFI_OUT_OF_RESOURCES;
> > - }
> > - ASSERT (DeviceAddress == ((EFI_PHYSICAL_ADDRESS) (UINTN) Base));
> > - AhciRegisters->AhciCmdListMapping = Mapping;
> > - AhciRegisters->AhciCmdList = Base;
> > - ZeroMem (AhciRegisters->AhciCmdList, EFI_PAGE_SIZE *
> > EFI_SIZE_TO_PAGES (sizeof (EFI_AHCI_COMMAND_LIST)));
> > -
> > - Status = IoMmuAllocateBuffer (
> > - EFI_SIZE_TO_PAGES (sizeof (EFI_AHCI_COMMAND_TABLE)),
> > - &Base,
> > - &DeviceAddress,
> > - &Mapping
> > - );
> > - if (EFI_ERROR (Status)) {
> > - IoMmuFreeBuffer (
> > - EFI_SIZE_TO_PAGES (sizeof (EFI_AHCI_COMMAND_LIST)),
> > - AhciRegisters->AhciCmdList,
> > - AhciRegisters->AhciCmdListMapping
> > - );
> > - AhciRegisters->AhciCmdList = NULL;
> > - IoMmuFreeBuffer (
> > - EFI_SIZE_TO_PAGES (sizeof (EFI_AHCI_RECEIVED_FIS)),
> > - AhciRegisters->AhciRFis,
> > - AhciRegisters->AhciRFisMapping
> > - );
> > - AhciRegisters->AhciRFis = NULL;
> > - return EFI_OUT_OF_RESOURCES;
> > - }
> > - ASSERT (DeviceAddress == ((EFI_PHYSICAL_ADDRESS) (UINTN) Base));
> > - AhciRegisters->AhciCommandTableMapping = Mapping;
> > - AhciRegisters->AhciCommandTable = Base;
> > - ZeroMem (AhciRegisters->AhciCommandTable, EFI_PAGE_SIZE *
> > EFI_SIZE_TO_PAGES (sizeof (EFI_AHCI_COMMAND_TABLE)));
> > -
> > - //
> > - // Allocate resources for data transfer.
> > - //
> > - Status = IoMmuAllocateBuffer (
> > - EFI_SIZE_TO_PAGES (HDD_PAYLOAD),
> > - &Base,
> > - &DeviceAddress,
> > - &Mapping
> > - );
> > - if (EFI_ERROR (Status)) {
> > - IoMmuFreeBuffer (
> > - EFI_SIZE_TO_PAGES (sizeof (EFI_AHCI_RECEIVED_FIS)),
> > - AhciRegisters->AhciCommandTable,
> > - AhciRegisters->AhciCommandTableMapping
> > - );
> > - AhciRegisters->AhciCommandTable = NULL;
> > - IoMmuFreeBuffer (
> > - EFI_SIZE_TO_PAGES (sizeof (EFI_AHCI_COMMAND_LIST)),
> > - AhciRegisters->AhciCmdList,
> > - AhciRegisters->AhciCmdListMapping
> > - );
> > - AhciRegisters->AhciCmdList = NULL;
> > - IoMmuFreeBuffer (
> > - EFI_SIZE_TO_PAGES (sizeof (EFI_AHCI_RECEIVED_FIS)),
> > - AhciRegisters->AhciRFis,
> > - AhciRegisters->AhciRFisMapping
> > - );
> > - AhciRegisters->AhciRFis = NULL;
> > - return EFI_OUT_OF_RESOURCES;
> > - }
> > - ASSERT (DeviceAddress == ((EFI_PHYSICAL_ADDRESS) (UINTN) Base));
> > - AhciContext->BufferMapping = Mapping;
> > - AhciContext->Buffer = Base;
> > - ZeroMem (AhciContext->Buffer, EFI_PAGE_SIZE * EFI_SIZE_TO_PAGES
> > (HDD_PAYLOAD));
> > -
> > - DEBUG ((
> > - DEBUG_INFO,
> > - "%a() AhciContext 0x%x 0x%x 0x%x 0x%x\n",
> > - __FUNCTION__,
> > - AhciContext->Buffer,
> > - AhciRegisters->AhciRFis,
> > - AhciRegisters->AhciCmdList,
> > - AhciRegisters->AhciCommandTable
> > - ));
> > - return EFI_SUCCESS;
> > -}
> > -
> > -/**
> > - Free allocated transfer-related data struct which is used at AHCI mode.
> > -
> > - @param[in, out] AhciContext The pointer to the AHCI_CONTEXT.
> > -
> > -**/
> > -VOID
> > -EFIAPI
> > -AhciFreeResource (
> > - IN OUT AHCI_CONTEXT *AhciContext
> > - )
> > -{
> > - EFI_AHCI_REGISTERS *AhciRegisters;
> > -
> > - AhciRegisters = &AhciContext->AhciRegisters;
> > -
> > - if (AhciContext->Buffer != NULL) {
> > - IoMmuFreeBuffer (
> > - EFI_SIZE_TO_PAGES (HDD_PAYLOAD),
> > - AhciContext->Buffer,
> > - AhciContext->BufferMapping
> > - );
> > - AhciContext->Buffer = NULL;
> > - }
> > -
> > - if (AhciRegisters->AhciCommandTable != NULL) {
> > - IoMmuFreeBuffer (
> > - EFI_SIZE_TO_PAGES (sizeof (EFI_AHCI_COMMAND_TABLE)),
> > - AhciRegisters->AhciCommandTable,
> > - AhciRegisters->AhciCommandTableMapping
> > - );
> > - AhciRegisters->AhciCommandTable = NULL;
> > - }
> > -
> > - if (AhciRegisters->AhciCmdList != NULL) {
> > - IoMmuFreeBuffer (
> > - EFI_SIZE_TO_PAGES (sizeof (EFI_AHCI_COMMAND_LIST)),
> > - AhciRegisters->AhciCmdList,
> > - AhciRegisters->AhciCmdListMapping
> > - );
> > - AhciRegisters->AhciCmdList = NULL;
> > - }
> > -
> > - if (AhciRegisters->AhciRFis != NULL) {
> > - IoMmuFreeBuffer (
> > - EFI_SIZE_TO_PAGES (sizeof (EFI_AHCI_RECEIVED_FIS)),
> > - AhciRegisters->AhciRFis,
> > - AhciRegisters->AhciRFisMapping
> > - );
> > - AhciRegisters->AhciRFis = NULL;
> > - }
> > -}
> > -
> > -/**
> > - Initialize ATA host controller at AHCI mode.
> > -
> > - The function is designed to initialize ATA host controller.
> > -
> > - @param[in] AhciContext The pointer to the AHCI_CONTEXT.
> > - @param[in] Port The port number to do initialization.
> > -
> > -**/
> > -EFI_STATUS
> > -EFIAPI
> > -AhciModeInitialize (
> > - IN AHCI_CONTEXT *AhciContext,
> > - IN UINT8 Port
> > - )
> > -{
> > - EFI_STATUS Status;
> > - EFI_AHCI_REGISTERS *AhciRegisters;
> > - UINT32 AhciBar;
> > - UINT32 Capability;
> > - UINT32 Offset;
> > - UINT32 Data;
> > - UINT32 PhyDetectDelay;
> > -
> > - AhciRegisters = &AhciContext->AhciRegisters;
> > - AhciBar = AhciContext->AhciBar;
> > -
> > - Status = AhciReset (AhciBar, ATA_TIMEOUT);
> > - if (EFI_ERROR (Status)) {
> > - return Status;
> > - }
> > -
> > - //
> > - // Collect AHCI controller information
> > - //
> > - Capability = AhciReadReg (AhciBar, EFI_AHCI_CAPABILITY_OFFSET);
> > -
> > - //
> > - // Enable AE before accessing any AHCI registers if Supports AHCI Mode
> > Only is not set
> > - //
> > - if ((Capability & EFI_AHCI_CAP_SAM) == 0) {
> > - AhciOrReg (AhciBar, EFI_AHCI_GHC_OFFSET, EFI_AHCI_GHC_ENABLE);
> > - }
> > -
> > - Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH +
> > EFI_AHCI_PORT_FB;
> > - AhciWriteReg (AhciBar, Offset, (UINT32)(UINTN)AhciRegisters->AhciRFis);
> > -
> > - //
> > - // Single task envrionment, we only use one command table for all port
> > - //
> > - Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH +
> > EFI_AHCI_PORT_CLB;
> > - AhciWriteReg (AhciBar, Offset, (UINT32)(UINTN)AhciRegisters-
> > >AhciCmdList);
> > -
> > - Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH +
> > EFI_AHCI_PORT_CMD;
> > - Data = AhciReadReg (AhciBar, Offset);
> > - if ((Data & EFI_AHCI_PORT_CMD_CPD) != 0) {
> > - AhciOrReg (AhciBar, Offset, EFI_AHCI_PORT_CMD_POD);
> > - }
> > -
> > - if ((Capability & BIT27) != 0) {
> > - AhciOrReg (AhciBar, Offset, EFI_AHCI_PORT_CMD_SUD);
> > - }
> > -
> > - //
> > - // Disable aggressive power management.
> > - //
> > - Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH +
> > EFI_AHCI_PORT_SCTL;
> > - AhciOrReg (AhciBar, Offset, EFI_AHCI_PORT_SCTL_IPM_INIT);
> > - //
> > - // Disable the reporting of the corresponding interrupt to system
> software.
> > - //
> > - Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH +
> > EFI_AHCI_PORT_IE;
> > - AhciAndReg (AhciBar, Offset, 0);
> > -
> > - Status = AhciEnableFisReceive (
> > - AhciBar,
> > - Port,
> > - 5000000
> > - );
> > - ASSERT_EFI_ERROR (Status);
> > - if (EFI_ERROR (Status)) {
> > - return Status;
> > - }
> > -
> > - //
> > - // According to SATA1.0a spec section 5.2, we need to wait for PxTFD.BSY
> > and PxTFD.DRQ
> > - // and PxTFD.ERR to be zero. The maximum wait time is 16s which is
> > defined at ATA spec.
> > - //
> > - PhyDetectDelay = 16 * 1000;
> > - do {
> > - Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH +
> > EFI_AHCI_PORT_SERR;
> > - if (AhciReadReg(AhciBar, Offset) != 0) {
> > - AhciWriteReg (AhciBar, Offset, AhciReadReg(AhciBar, Offset));
> > - }
> > - Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH +
> > EFI_AHCI_PORT_TFD;
> > -
> > - Data = AhciReadReg (AhciBar, Offset) & EFI_AHCI_PORT_TFD_MASK;
> > - if (Data == 0) {
> > - break;
> > - }
> > -
> > - MicroSecondDelay (1000);
> > - PhyDetectDelay--;
> > - } while (PhyDetectDelay > 0);
> > -
> > - if (PhyDetectDelay == 0) {
> > - return EFI_NOT_FOUND;
> > - }
> > -
> > - Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH +
> > EFI_AHCI_PORT_SIG;
> > - Status = AhciWaitMmioSet (
> > - AhciBar,
> > - Offset,
> > - 0x0000FFFF,
> > - 0x00000101,
> > - 160000000
> > - );
> > -
> > - if (EFI_ERROR (Status)) {
> > - return Status;
> > - }
> > -
> > - return Status;
> > -}
> > -
> > diff --git a/SecurityPkg/Tcg/Opal/OpalPassword/OpalDriver.c
> > b/SecurityPkg/Tcg/Opal/OpalPassword/OpalDriver.c
> > index b5317d82b8..40fd892bc1 100644
> > --- a/SecurityPkg/Tcg/Opal/OpalPassword/OpalDriver.c
> > +++ b/SecurityPkg/Tcg/Opal/OpalPassword/OpalDriver.c
> > @@ -21,40 +21,13 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF
> > ANY KIND, EITHER EXPRESS OR IMPLIED.
> > #include "OpalDriver.h"
> > #include "OpalHii.h"
> >
> > -EFI_GUID mOpalDeviceAtaGuid = OPAL_DEVICE_ATA_GUID;
> > -EFI_GUID mOpalDeviceNvmeGuid = OPAL_DEVICE_NVME_GUID;
> > +EFI_GUID mOpalDeviceLockBoxGuid = OPAL_DEVICE_LOCKBOX_GUID;
> >
> > BOOLEAN mOpalEndOfDxe = FALSE;
> > OPAL_REQUEST_VARIABLE *mOpalRequestVariable = NULL;
> > UINTN mOpalRequestVariableSize = 0;
> > CHAR16 mPopUpString[100];
> >
> > -typedef struct {
> > - UINT32 Address;
> > - S3_BOOT_SCRIPT_LIB_WIDTH Width;
> > -} OPAL_HC_PCI_REGISTER_SAVE;
> > -
> > -//
> > -// To unlock the Intel SATA controller at S3 Resume, restored the following
> > registers.
> > -//
> > -const OPAL_HC_PCI_REGISTER_SAVE mSataHcRegisterSaveTemplate[] = {
> > - {0x9, S3BootScriptWidthUint8},
> > - {0x10, S3BootScriptWidthUint32},
> > - {0x14, S3BootScriptWidthUint32},
> > - {0x18, S3BootScriptWidthUint32},
> > - {0x1C, S3BootScriptWidthUint32},
> > - {0x20, S3BootScriptWidthUint32},
> > - {0x24, S3BootScriptWidthUint32},
> > - {0x3c, S3BootScriptWidthUint8},
> > - {0x3d, S3BootScriptWidthUint8},
> > - {0x40, S3BootScriptWidthUint16},
> > - {0x42, S3BootScriptWidthUint16},
> > - {0x92, S3BootScriptWidthUint16},
> > - {0x94, S3BootScriptWidthUint32},
> > - {0x9C, S3BootScriptWidthUint32},
> > - {0x4, S3BootScriptWidthUint16},
> > -};
> > -
> > OPAL_DRIVER mOpalDriver;
> >
> > //
> > @@ -233,14 +206,12 @@ OpalSupportUpdatePassword (
> > @param[out] DevInfoLength Device information length needed.
> > @param[out] DevInfo Device information extracted.
> >
> > - @return Device type.
> > -
> > **/
> > -UINT8
> > +VOID
> > ExtractDeviceInfoFromDevicePath (
> > IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
> > - OUT UINT16 *DevInfoLength,
> > - OUT OPAL_DEVICE_COMMON *DevInfo OPTIONAL
> > + OUT UINT32 *DevInfoLength,
> > + OUT OPAL_DEVICE_LOCKBOX_DATA *DevInfo OPTIONAL
> > )
> > {
> > EFI_DEVICE_PATH_PROTOCOL *TmpDevPath;
> > @@ -249,10 +220,6 @@ ExtractDeviceInfoFromDevicePath (
> > UINT8 DeviceType;
> > UINT8 BusNum;
> > OPAL_PCI_DEVICE *PciDevice;
> > - OPAL_DEVICE_ATA *DevInfoAta;
> > - OPAL_DEVICE_NVME *DevInfoNvme;
> > - SATA_DEVICE_PATH *SataDevPath;
> > - NVME_NAMESPACE_DEVICE_PATH *NvmeDevPath;
> >
> > ASSERT (DevicePath != NULL);
> > ASSERT (DevInfoLength != NULL);
> > @@ -266,30 +233,15 @@ ExtractDeviceInfoFromDevicePath (
> > // Get device type.
> > //
> > while (!IsDevicePathEnd (TmpDevPath)) {
> > - if (TmpDevPath->Type == MESSAGING_DEVICE_PATH && TmpDevPath-
> > >SubType == MSG_SATA_DP) {
> > - //
> > - // SATA
> > - //
> > - if (DevInfo != NULL) {
> > - SataDevPath = (SATA_DEVICE_PATH *) TmpDevPath;
> > - DevInfoAta = (OPAL_DEVICE_ATA *) DevInfo;
> > - DevInfoAta->Port = SataDevPath->HBAPortNumber;
> > - DevInfoAta->PortMultiplierPort = SataDevPath-
> > >PortMultiplierPortNumber;
> > - }
> > - DeviceType = OPAL_DEVICE_TYPE_ATA;
> > - *DevInfoLength = sizeof (OPAL_DEVICE_ATA);
> > - break;
> > - } else if (TmpDevPath->Type == MESSAGING_DEVICE_PATH &&
> > TmpDevPath->SubType == MSG_NVME_NAMESPACE_DP) {
> > - //
> > - // NVMe
> > - //
> > + if ((TmpDevPath->Type == MESSAGING_DEVICE_PATH) &&
> > + (TmpDevPath->SubType == MSG_SATA_DP || TmpDevPath-
> >SubType
> > == MSG_NVME_NAMESPACE_DP)) {
> > if (DevInfo != NULL) {
> > - NvmeDevPath = (NVME_NAMESPACE_DEVICE_PATH *) TmpDevPath;
> > - DevInfoNvme = (OPAL_DEVICE_NVME *) DevInfo;
> > - DevInfoNvme->NvmeNamespaceId = NvmeDevPath->NamespaceId;
> > + DevInfo->DevicePathLength = (UINT32) GetDevicePathSize
> > (DevicePath);
> > + CopyMem (DevInfo->DevicePath, DevicePath, DevInfo-
> > >DevicePathLength);
> > }
> > - DeviceType = OPAL_DEVICE_TYPE_NVME;
> > - *DevInfoLength = sizeof (OPAL_DEVICE_NVME);
> > +
> > + DeviceType = (TmpDevPath->SubType == MSG_SATA_DP) ?
> > OPAL_DEVICE_TYPE_ATA : OPAL_DEVICE_TYPE_NVME;
> > + *DevInfoLength = sizeof (OPAL_DEVICE_LOCKBOX_DATA) + (UINT32)
> > GetDevicePathSize (DevicePath);
> > break;
> > }
> > TmpDevPath = NextDevicePathNode (TmpDevPath);
> > @@ -304,8 +256,8 @@ ExtractDeviceInfoFromDevicePath (
> > while (!IsDevicePathEnd (TmpDevPath2)) {
> > if (TmpDevPath->Type == HARDWARE_DEVICE_PATH && TmpDevPath-
> > >SubType == HW_PCI_DP) {
> > PciDevPath = (PCI_DEVICE_PATH *) TmpDevPath;
> > - if ((TmpDevPath2->Type == MESSAGING_DEVICE_PATH &&
> > TmpDevPath2->SubType == MSG_NVME_NAMESPACE_DP)||
> > - (TmpDevPath2->Type == MESSAGING_DEVICE_PATH &&
> > TmpDevPath2->SubType == MSG_SATA_DP)) {
> > + if ((TmpDevPath2->Type == MESSAGING_DEVICE_PATH) &&
> > + (TmpDevPath2->SubType == MSG_SATA_DP || TmpDevPath2-
> > >SubType == MSG_NVME_NAMESPACE_DP)) {
> > if (DevInfo != NULL) {
> > PciDevice = &DevInfo->Device;
> > PciDevice->Segment = 0;
> > @@ -314,14 +266,6 @@ ExtractDeviceInfoFromDevicePath (
> > PciDevice->Function = PciDevPath->Function;
> > }
> > } else {
> > - if (DevInfo != NULL) {
> > - PciDevice = (OPAL_PCI_DEVICE *) ((UINTN) DevInfo +
> *DevInfoLength);
> > - PciDevice->Segment = 0;
> > - PciDevice->Bus = BusNum;
> > - PciDevice->Device = PciDevPath->Device;
> > - PciDevice->Function = PciDevPath->Function;
> > - }
> > - *DevInfoLength += sizeof (OPAL_PCI_DEVICE);
> > if (TmpDevPath2->Type == HARDWARE_DEVICE_PATH &&
> > TmpDevPath2->SubType == HW_PCI_DP) {
> > BusNum = PciRead8 (PCI_LIB_ADDRESS (BusNum, PciDevPath-
> >Device,
> > PciDevPath->Function,
> PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET));
> > }
> > @@ -333,251 +277,159 @@ ExtractDeviceInfoFromDevicePath (
> > }
> >
> > ASSERT (DeviceType != OPAL_DEVICE_TYPE_UNKNOWN);
> > - return DeviceType;
> > -}
> > -
> > -/**
> > - Save boot script for ATA OPAL device.
> > -
> > - @param[in] DevInfo Pointer to ATA Opal device information.
> > -
> > - **/
> > -VOID
> > -OpalDeviceAtaSaveBootScript (
> > - IN OPAL_DEVICE_ATA *DevInfo
> > - )
> > -{
> > - UINTN Bus;
> > - UINTN Device;
> > - UINTN Function;
> > - UINTN Index;
> > - EFI_STATUS Status;
> > - UINTN Offset;
> > - UINT64 Address;
> > - S3_BOOT_SCRIPT_LIB_WIDTH Width;
> > - UINT32 Data;
> > - OPAL_HC_PCI_REGISTER_SAVE *HcRegisterSaveListPtr;
> > - UINTN Count;
> > -
> > - Data = 0;
> > -
> > - Bus = DevInfo->Device.Bus;
> > - Device = DevInfo->Device.Device;
> > - Function = DevInfo->Device.Function;
> > -
> > - HcRegisterSaveListPtr = (OPAL_HC_PCI_REGISTER_SAVE *)
> > mSataHcRegisterSaveTemplate;
> > - Count = sizeof (mSataHcRegisterSaveTemplate) / sizeof
> > (OPAL_HC_PCI_REGISTER_SAVE);
> > -
> > - for (Index = 0; Index < Count; Index++) {
> > - Offset = HcRegisterSaveListPtr[Index].Address;
> > - Width = HcRegisterSaveListPtr[Index].Width;
> > -
> > - switch (Width) {
> > - case S3BootScriptWidthUint8:
> > - Data = (UINT32)PciRead8
> > (PCI_LIB_ADDRESS(Bus,Device,Function,Offset));
> > - break;
> > - case S3BootScriptWidthUint16:
> > - Data = (UINT32)PciRead16
> > (PCI_LIB_ADDRESS(Bus,Device,Function,Offset));
> > - break;
> > - case S3BootScriptWidthUint32:
> > - Data = PciRead32 (PCI_LIB_ADDRESS(Bus,Device,Function,Offset));
> > - break;
> > - default:
> > - ASSERT (FALSE);
> > - break;
> > - }
> > -
> > - Address = S3_BOOT_SCRIPT_LIB_PCI_ADDRESS (Bus, Device, Function,
> > Offset);
> > - Status = S3BootScriptSavePciCfgWrite (Width, Address, 1, &Data);
> > - ASSERT_EFI_ERROR (Status);
> > - }
> > + return;
> > }
> >
> > /**
> > - Build ATA OPAL device info and save them to LockBox.
> > -
> > - @param[in] BarAddr Bar address allocated.
> > + Build OPAL device info and save them to LockBox.
> >
> > **/
> > VOID
> > -BuildOpalDeviceInfoAta (
> > - IN UINT32 BarAddr
> > +BuildOpalDeviceInfo (
> > + VOID
> > )
> > {
> > - EFI_STATUS Status;
> > - UINT8 DeviceType;
> > - OPAL_DEVICE_ATA *DevInfoAta;
> > - OPAL_DEVICE_ATA *TempDevInfoAta;
> > - UINTN DevInfoLengthAta;
> > - UINT16 DevInfoLength;
> > - OPAL_DRIVER_DEVICE *TmpDev;
> > + EFI_STATUS Status;
> > + OPAL_DEVICE_LOCKBOX_DATA *DevInfo;
> > + OPAL_DEVICE_LOCKBOX_DATA *TempDevInfo;
> > + UINTN TotalDevInfoLength;
> > + UINT32 DevInfoLength;
> > + OPAL_DRIVER_DEVICE *TmpDev;
> > + UINT8 DummyData;
> > + BOOLEAN S3InitDevicesExist;
> > + UINTN S3InitDevicesLength;
> > + EFI_DEVICE_PATH_PROTOCOL *S3InitDevices;
> > + EFI_DEVICE_PATH_PROTOCOL *S3InitDevicesBak;
> >
> > //
> > - // Build ATA OPAL device info and save them to LockBox.
> > + // Build OPAL device info and save them to LockBox.
> > //
> > - DevInfoLengthAta = 0;
> > + TotalDevInfoLength = 0;
> > TmpDev = mOpalDriver.DeviceList;
> > while (TmpDev != NULL) {
> > - DeviceType = ExtractDeviceInfoFromDevicePath (
> > - TmpDev->OpalDisk.OpalDevicePath,
> > - &DevInfoLength,
> > - NULL
> > - );
> > - if (DeviceType == OPAL_DEVICE_TYPE_ATA) {
> > - DevInfoLengthAta += DevInfoLength;
> > - }
> > -
> > + ExtractDeviceInfoFromDevicePath (
> > + TmpDev->OpalDisk.OpalDevicePath,
> > + &DevInfoLength,
> > + NULL
> > + );
> > + TotalDevInfoLength += DevInfoLength;
> > TmpDev = TmpDev->Next;
> > }
> >
> > - if (DevInfoLengthAta == 0) {
> > + if (TotalDevInfoLength == 0) {
> > return;
> > }
> >
> > - DevInfoAta = AllocateZeroPool (DevInfoLengthAta);
> > - ASSERT (DevInfoAta != NULL);
> > - if (DevInfoAta == NULL) {
> > - return;
> > - }
> > -
> > - TempDevInfoAta = DevInfoAta;
> > - TmpDev = mOpalDriver.DeviceList;
> > - while (TmpDev != NULL) {
> > - DeviceType = ExtractDeviceInfoFromDevicePath (
> > - TmpDev->OpalDisk.OpalDevicePath,
> > - &DevInfoLength,
> > - NULL
> > - );
> > - if (DeviceType == OPAL_DEVICE_TYPE_ATA) {
> > - ExtractDeviceInfoFromDevicePath (
> > - TmpDev->OpalDisk.OpalDevicePath,
> > - &DevInfoLength,
> > - (OPAL_DEVICE_COMMON *) TempDevInfoAta
> > - );
> > - TempDevInfoAta->Length = DevInfoLength;
> > - TempDevInfoAta->OpalBaseComId = TmpDev-
> >OpalDisk.OpalBaseComId;
> > - TempDevInfoAta->BarAddr = BarAddr;
> > - CopyMem (
> > - TempDevInfoAta->Password,
> > - TmpDev->OpalDisk.Password,
> > - TmpDev->OpalDisk.PasswordLength
> > - );
> > - TempDevInfoAta->PasswordLength = TmpDev-
> > >OpalDisk.PasswordLength;
> > - OpalDeviceAtaSaveBootScript (TempDevInfoAta);
> > - TempDevInfoAta = (OPAL_DEVICE_ATA *) ((UINTN) TempDevInfoAta +
> > DevInfoLength);
> > - }
> > -
> > - TmpDev = TmpDev->Next;
> > - }
> > -
> > - Status = SaveLockBox (
> > - &mOpalDeviceAtaGuid,
> > - DevInfoAta,
> > - DevInfoLengthAta
> > + S3InitDevicesLength = sizeof (DummyData);
> > + Status = RestoreLockBox (
> > + &gS3StorageDeviceInitListGuid,
> > + &DummyData,
> > + &S3InitDevicesLength
> > );
> > - ASSERT_EFI_ERROR (Status);
> > -
> > - Status = SetLockBoxAttributes (
> > - &mOpalDeviceAtaGuid,
> > - LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY
> > - );
> > - ASSERT_EFI_ERROR (Status);
> > -
> > - ZeroMem (DevInfoAta, DevInfoLengthAta);
> > - FreePool (DevInfoAta);
> > -}
> > -
> > -/**
> > - Build NVMe OPAL device info and save them to LockBox.
> > -
> > - @param[in] BarAddr Bar address allocated.
> > -
> > - **/
> > -VOID
> > -BuildOpalDeviceInfoNvme (
> > - IN UINT32 BarAddr
> > - )
> > -{
> > - EFI_STATUS Status;
> > - UINT8 DeviceType;
> > - OPAL_DEVICE_NVME *DevInfoNvme;
> > - OPAL_DEVICE_NVME *TempDevInfoNvme;
> > - UINTN DevInfoLengthNvme;
> > - UINT16 DevInfoLength;
> > - OPAL_DRIVER_DEVICE *TmpDev;
> > -
> > - //
> > - // Build NVMe OPAL device info and save them to LockBox.
> > - //
> > - DevInfoLengthNvme = 0;
> > - TmpDev = mOpalDriver.DeviceList;
> > - while (TmpDev != NULL) {
> > - DeviceType = ExtractDeviceInfoFromDevicePath (
> > - TmpDev->OpalDisk.OpalDevicePath,
> > - &DevInfoLength,
> > - NULL
> > - );
> > - if (DeviceType == OPAL_DEVICE_TYPE_NVME) {
> > - DevInfoLengthNvme += DevInfoLength;
> > + ASSERT ((Status == EFI_NOT_FOUND) || (Status ==
> > EFI_BUFFER_TOO_SMALL));
> > + if (Status == EFI_NOT_FOUND) {
> > + S3InitDevices = NULL;
> > + S3InitDevicesExist = FALSE;
> > + } else if (Status == EFI_BUFFER_TOO_SMALL) {
> > + S3InitDevices = AllocatePool (S3InitDevicesLength);
> > + ASSERT (S3InitDevices != NULL);
> > + if (S3InitDevices == NULL) {
> > + return;
> > }
> >
> > - TmpDev = TmpDev->Next;
> > - }
> > -
> > - if (DevInfoLengthNvme == 0) {
> > + Status = RestoreLockBox (
> > + &gS3StorageDeviceInitListGuid,
> > + S3InitDevices,
> > + &S3InitDevicesLength
> > + );
> > + ASSERT_EFI_ERROR (Status);
> > + S3InitDevicesExist = TRUE;
> > + } else {
> > return;
> > }
> >
> > - DevInfoNvme = AllocateZeroPool (DevInfoLengthNvme);
> > - ASSERT (DevInfoNvme != NULL);
> > - if (DevInfoNvme == NULL) {
> > + DevInfo = AllocateZeroPool (TotalDevInfoLength);
> > + ASSERT (DevInfo != NULL);
> > + if (DevInfo == NULL) {
> > return;
> > }
> >
> > - TempDevInfoNvme = DevInfoNvme;
> > - TmpDev = mOpalDriver.DeviceList;
> > + TempDevInfo = DevInfo;
> > + TmpDev = mOpalDriver.DeviceList;
> > while (TmpDev != NULL) {
> > - DeviceType = ExtractDeviceInfoFromDevicePath (
> > - TmpDev->OpalDisk.OpalDevicePath,
> > - &DevInfoLength,
> > - NULL
> > - );
> > - if (DeviceType == OPAL_DEVICE_TYPE_NVME) {
> > - ExtractDeviceInfoFromDevicePath (
> > - TmpDev->OpalDisk.OpalDevicePath,
> > - &DevInfoLength,
> > - (OPAL_DEVICE_COMMON *) TempDevInfoNvme
> > - );
> > - TempDevInfoNvme->Length = DevInfoLength;
> > - TempDevInfoNvme->OpalBaseComId = TmpDev-
> > >OpalDisk.OpalBaseComId;
> > - TempDevInfoNvme->BarAddr = BarAddr;
> > - CopyMem (
> > - TempDevInfoNvme->Password,
> > - TmpDev->OpalDisk.Password,
> > - TmpDev->OpalDisk.PasswordLength
> > - );
> > - TempDevInfoNvme->PasswordLength = TmpDev-
> > >OpalDisk.PasswordLength;
> > - TempDevInfoNvme = (OPAL_DEVICE_NVME *) ((UINTN)
> > TempDevInfoNvme + DevInfoLength);
> > + ExtractDeviceInfoFromDevicePath (
> > + TmpDev->OpalDisk.OpalDevicePath,
> > + &DevInfoLength,
> > + TempDevInfo
> > + );
> > + TempDevInfo->Length = DevInfoLength;
> > + TempDevInfo->OpalBaseComId = TmpDev->OpalDisk.OpalBaseComId;
> > + CopyMem (
> > + TempDevInfo->Password,
> > + TmpDev->OpalDisk.Password,
> > + TmpDev->OpalDisk.PasswordLength
> > + );
> > + TempDevInfo->PasswordLength = TmpDev->OpalDisk.PasswordLength;
> > +
> > + S3InitDevicesBak = S3InitDevices;
> > + S3InitDevices = AppendDevicePathInstance (
> > + S3InitDevicesBak,
> > + TmpDev->OpalDisk.OpalDevicePath
> > + );
> > + if (S3InitDevicesBak != NULL) {
> > + ZeroMem (S3InitDevicesBak, GetDevicePathSize (S3InitDevicesBak));
> > + FreePool (S3InitDevicesBak);
> > + }
> > + ASSERT (S3InitDevices != NULL);
> > + if (S3InitDevices == NULL) {
> > + return;
> > }
> >
> > + TempDevInfo = (OPAL_DEVICE_LOCKBOX_DATA *) ((UINTN)
> > TempDevInfo + DevInfoLength);
> > TmpDev = TmpDev->Next;
> > }
> >
> > Status = SaveLockBox (
> > - &mOpalDeviceNvmeGuid,
> > - DevInfoNvme,
> > - DevInfoLengthNvme
> > + &mOpalDeviceLockBoxGuid,
> > + DevInfo,
> > + TotalDevInfoLength
> > );
> > ASSERT_EFI_ERROR (Status);
> >
> > Status = SetLockBoxAttributes (
> > - &mOpalDeviceNvmeGuid,
> > + &mOpalDeviceLockBoxGuid,
> > LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY
> > );
> > ASSERT_EFI_ERROR (Status);
> >
> > - ZeroMem (DevInfoNvme, DevInfoLengthNvme);
> > - FreePool (DevInfoNvme);
> > + S3InitDevicesLength = GetDevicePathSize (S3InitDevices);
> > + if (S3InitDevicesExist) {
> > + Status = UpdateLockBox (
> > + &gS3StorageDeviceInitListGuid,
> > + 0,
> > + S3InitDevices,
> > + S3InitDevicesLength
> > + );
> > + ASSERT_EFI_ERROR (Status);
> > + } else {
> > + Status = SaveLockBox (
> > + &gS3StorageDeviceInitListGuid,
> > + S3InitDevices,
> > + S3InitDevicesLength
> > + );
> > + ASSERT_EFI_ERROR (Status);
> > +
> > + Status = SetLockBoxAttributes (
> > + &gS3StorageDeviceInitListGuid,
> > + LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY
> > + );
> > + ASSERT_EFI_ERROR (Status);
> > + }
> > +
> > + ZeroMem (DevInfo, TotalDevInfoLength);
> > + FreePool (DevInfo);
> > + ZeroMem (S3InitDevices, S3InitDevicesLength);
> > + FreePool (S3InitDevices);
> > }
> >
> > /**
> > @@ -596,9 +448,6 @@ OpalEndOfDxeEventNotify (
> > VOID *Context
> > )
> > {
> > - EFI_STATUS Status;
> > - EFI_PHYSICAL_ADDRESS Address;
> > - UINT64 Length;
> > OPAL_DRIVER_DEVICE *TmpDev;
> >
> > DEBUG ((DEBUG_INFO, "%a() - enter\n", __FUNCTION__));
> > @@ -623,24 +472,7 @@ OpalEndOfDxeEventNotify (
> > return;
> > }
> >
> > - //
> > - // Assume 64K size and alignment are enough.
> > - //
> > - Length = 0x10000;
> > - Address = 0xFFFFFFFF;
> > - Status = gDS->AllocateMemorySpace (
> > - EfiGcdAllocateMaxAddressSearchBottomUp,
> > - EfiGcdMemoryTypeMemoryMappedIo,
> > - 16, // 2^16: 64K Alignment
> > - Length,
> > - &Address,
> > - gImageHandle,
> > - NULL
> > - );
> > - ASSERT_EFI_ERROR (Status);
> > -
> > - BuildOpalDeviceInfoAta ((UINT32) Address);
> > - BuildOpalDeviceInfoNvme ((UINT32) Address);
> > + BuildOpalDeviceInfo ();
> >
> > //
> > // Zero passsword.
> > diff --git a/SecurityPkg/Tcg/Opal/OpalPassword/OpalNvmeMode.c
> > b/SecurityPkg/Tcg/Opal/OpalPassword/OpalNvmeMode.c
> > deleted file mode 100644
> > index 01c316d597..0000000000
> > --- a/SecurityPkg/Tcg/Opal/OpalPassword/OpalNvmeMode.c
> > +++ /dev/null
> > @@ -1,1823 +0,0 @@
> > -/** @file
> > - Provide functions to initialize NVME controller and perform NVME
> > commands
> > -
> > -Copyright (c) 2016 - 2018, 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 "OpalPasswordPei.h"
> > -
> > -
> > -#define ALIGN(v, a) (UINTN)((((v) - 1) | ((a) - 1)) + 1)
> > -
> > -///
> > -/// NVME Host controller registers operation
> > -///
> > -#define NVME_GET_CAP(Nvme, Cap) NvmeMmioRead (Cap,
> Nvme-
> > >Nbar + NVME_CAP_OFFSET, sizeof (NVME_CAP))
> > -#define NVME_GET_CC(Nvme, Cc) NvmeMmioRead (Cc, Nvme-
> > >Nbar + NVME_CC_OFFSET, sizeof (NVME_CC))
> > -#define NVME_SET_CC(Nvme, Cc) NvmeMmioWrite (Nvme->Nbar
> +
> > NVME_CC_OFFSET, Cc, sizeof (NVME_CC))
> > -#define NVME_GET_CSTS(Nvme, Csts) NvmeMmioRead (Csts,
> Nvme-
> > >Nbar + NVME_CSTS_OFFSET, sizeof (NVME_CSTS))
> > -#define NVME_GET_AQA(Nvme, Aqa) NvmeMmioRead (Aqa,
> Nvme-
> > >Nbar + NVME_AQA_OFFSET, sizeof (NVME_AQA))
> > -#define NVME_SET_AQA(Nvme, Aqa) NvmeMmioWrite (Nvme-
> > >Nbar + NVME_AQA_OFFSET, Aqa, sizeof (NVME_AQA))
> > -#define NVME_GET_ASQ(Nvme, Asq) NvmeMmioRead (Asq,
> Nvme-
> > >Nbar + NVME_ASQ_OFFSET, sizeof (NVME_ASQ))
> > -#define NVME_SET_ASQ(Nvme, Asq) NvmeMmioWrite (Nvme-
> >Nbar
> > + NVME_ASQ_OFFSET, Asq, sizeof (NVME_ASQ))
> > -#define NVME_GET_ACQ(Nvme, Acq) NvmeMmioRead (Acq,
> Nvme-
> > >Nbar + NVME_ACQ_OFFSET, sizeof (NVME_ACQ))
> > -#define NVME_SET_ACQ(Nvme, Acq) NvmeMmioWrite (Nvme-
> >Nbar
> > + NVME_ACQ_OFFSET, Acq, sizeof (NVME_ACQ))
> > -#define NVME_GET_VER(Nvme, Ver) NvmeMmioRead (Ver,
> Nvme-
> > >Nbar + NVME_VER_OFFSET, sizeof (NVME_VER))
> > -#define NVME_SET_SQTDBL(Nvme, Qid, Sqtdbl) NvmeMmioWrite
> (Nvme-
> > >Nbar + NVME_SQTDBL_OFFSET(Qid, Nvme->Cap.Dstrd), Sqtdbl, sizeof
> > (NVME_SQTDBL))
> > -#define NVME_SET_CQHDBL(Nvme, Qid, Cqhdbl) NvmeMmioWrite
> (Nvme-
> > >Nbar + NVME_CQHDBL_OFFSET(Qid, Nvme->Cap.Dstrd), Cqhdbl, sizeof
> > (NVME_CQHDBL))
> > -
> > -///
> > -/// Base memory address
> > -///
> > -enum {
> > - BASEMEM_CONTROLLER_DATA,
> > - BASEMEM_IDENTIFY_DATA,
> > - BASEMEM_ASQ,
> > - BASEMEM_ACQ,
> > - BASEMEM_SQ,
> > - BASEMEM_CQ,
> > - BASEMEM_PRP,
> > - BASEMEM_SECURITY,
> > - MAX_BASEMEM_COUNT
> > -};
> > -
> > -///
> > -/// All of base memories are 4K(0x1000) alignment
> > -///
> > -#define NVME_MEM_BASE(Nvme) ((UINTN)(Nvme->BaseMem))
> > -#define NVME_CONTROL_DATA_BASE(Nvme) (ALIGN
> > (NVME_MEM_BASE(Nvme) + ((NvmeGetBaseMemPages
> > (BASEMEM_CONTROLLER_DATA)) * EFI_PAGE_SIZE),
> > EFI_PAGE_SIZE))
> > -#define NVME_NAMESPACE_DATA_BASE(Nvme) (ALIGN
> > (NVME_MEM_BASE(Nvme) + ((NvmeGetBaseMemPages
> > (BASEMEM_IDENTIFY_DATA)) * EFI_PAGE_SIZE),
> > EFI_PAGE_SIZE))
> > -#define NVME_ASQ_BASE(Nvme) (ALIGN
> > (NVME_MEM_BASE(Nvme) + ((NvmeGetBaseMemPages
> (BASEMEM_ASQ))
> > * EFI_PAGE_SIZE), EFI_PAGE_SIZE))
> > -#define NVME_ACQ_BASE(Nvme) (ALIGN
> > (NVME_MEM_BASE(Nvme) + ((NvmeGetBaseMemPages
> (BASEMEM_ACQ))
> > * EFI_PAGE_SIZE), EFI_PAGE_SIZE))
> > -#define NVME_SQ_BASE(Nvme, index) (ALIGN
> > (NVME_MEM_BASE(Nvme) + ((NvmeGetBaseMemPages (BASEMEM_SQ)
> +
> > ((index)*(NVME_MAX_IO_QUEUES-1))) * EFI_PAGE_SIZE),
> EFI_PAGE_SIZE))
> > -#define NVME_CQ_BASE(Nvme, index) (ALIGN
> > (NVME_MEM_BASE(Nvme) + ((NvmeGetBaseMemPages (BASEMEM_CQ)
> +
> > ((index)*(NVME_MAX_IO_QUEUES-1))) * EFI_PAGE_SIZE),
> EFI_PAGE_SIZE))
> > -#define NVME_PRP_BASE(Nvme, index) (ALIGN
> > (NVME_MEM_BASE(Nvme) + ((NvmeGetBaseMemPages (BASEMEM_PRP)
> > + ((index)*NVME_PRP_SIZE)) * EFI_PAGE_SIZE), EFI_PAGE_SIZE))
> > -#define NVME_SEC_BASE(Nvme) (ALIGN
> > (NVME_MEM_BASE(Nvme) + ((NvmeGetBaseMemPages
> > (BASEMEM_SECURITY)) * EFI_PAGE_SIZE), EFI_PAGE_SIZE))
> > -
> > -/**
> > - Transfer MMIO Data to memory.
> > -
> > - @param[in,out] MemBuffer - Destination: Memory address
> > - @param[in] MmioAddr - Source: MMIO address
> > - @param[in] Size - Size for read
> > -
> > - @retval EFI_SUCCESS - MMIO read sucessfully
> > -**/
> > -EFI_STATUS
> > -NvmeMmioRead (
> > - IN OUT VOID *MemBuffer,
> > - IN UINTN MmioAddr,
> > - IN UINTN Size
> > - )
> > -{
> > - UINTN Offset;
> > - UINT8 Data;
> > - UINT8 *Ptr;
> > -
> > - // priority has adjusted
> > - switch (Size) {
> > - case 4:
> > - *((UINT32 *)MemBuffer) = MmioRead32 (MmioAddr);
> > - break;
> > -
> > - case 8:
> > - *((UINT64 *)MemBuffer) = MmioRead64 (MmioAddr);
> > - break;
> > -
> > - case 2:
> > - *((UINT16 *)MemBuffer) = MmioRead16 (MmioAddr);
> > - break;
> > -
> > - case 1:
> > - *((UINT8 *)MemBuffer) = MmioRead8 (MmioAddr);
> > - break;
> > -
> > - default:
> > - Ptr = (UINT8 *)MemBuffer;
> > - for (Offset = 0; Offset < Size; Offset += 1) {
> > - Data = MmioRead8 (MmioAddr + Offset);
> > - Ptr[Offset] = Data;
> > - }
> > - break;
> > - }
> > -
> > - return EFI_SUCCESS;
> > -}
> > -
> > -/**
> > - Transfer memory data to MMIO.
> > -
> > - @param[in,out] MmioAddr - Destination: MMIO address
> > - @param[in] MemBuffer - Source: Memory address
> > - @param[in] Size - Size for write
> > -
> > - @retval EFI_SUCCESS - MMIO write sucessfully
> > -**/
> > -EFI_STATUS
> > -NvmeMmioWrite (
> > - IN OUT UINTN MmioAddr,
> > - IN VOID *MemBuffer,
> > - IN UINTN Size
> > - )
> > -{
> > - UINTN Offset;
> > - UINT8 Data;
> > - UINT8 *Ptr;
> > -
> > - // priority has adjusted
> > - switch (Size) {
> > - case 4:
> > - MmioWrite32 (MmioAddr, *((UINT32 *)MemBuffer));
> > - break;
> > -
> > - case 8:
> > - MmioWrite64 (MmioAddr, *((UINT64 *)MemBuffer));
> > - break;
> > -
> > - case 2:
> > - MmioWrite16 (MmioAddr, *((UINT16 *)MemBuffer));
> > - break;
> > -
> > - case 1:
> > - MmioWrite8 (MmioAddr, *((UINT8 *)MemBuffer));
> > - break;
> > -
> > - default:
> > - Ptr = (UINT8 *)MemBuffer;
> > - for (Offset = 0; Offset < Size; Offset += 1) {
> > - Data = Ptr[Offset];
> > - MmioWrite8 (MmioAddr + Offset, Data);
> > - }
> > - break;
> > - }
> > -
> > - return EFI_SUCCESS;
> > -}
> > -
> > -/**
> > - Transfer MMIO data to memory.
> > -
> > - @param[in,out] MemBuffer - Destination: Memory address
> > - @param[in] MmioAddr - Source: MMIO address
> > - @param[in] Size - Size for read
> > -
> > - @retval EFI_SUCCESS - MMIO read sucessfully
> > -**/
> > -EFI_STATUS
> > -OpalPciRead (
> > - IN OUT VOID *MemBuffer,
> > - IN UINTN MmioAddr,
> > - IN UINTN Size
> > - )
> > -{
> > - UINTN Offset;
> > - UINT8 Data;
> > - UINT8 *Ptr;
> > -
> > - // priority has adjusted
> > - switch (Size) {
> > - case 4:
> > - *((UINT32 *)MemBuffer) = PciRead32 (MmioAddr);
> > - break;
> > -
> > - case 2:
> > - *((UINT16 *)MemBuffer) = PciRead16 (MmioAddr);
> > - break;
> > -
> > - case 1:
> > - *((UINT8 *)MemBuffer) = PciRead8 (MmioAddr);
> > - break;
> > -
> > - default:
> > - Ptr = (UINT8 *)MemBuffer;
> > - for (Offset = 0; Offset < Size; Offset += 1) {
> > - Data = PciRead8 (MmioAddr + Offset);
> > - Ptr[Offset] = Data;
> > - }
> > - break;
> > - }
> > -
> > - return EFI_SUCCESS;
> > -}
> > -
> > -/**
> > - Transfer memory data to MMIO.
> > -
> > - @param[in,out] MmioAddr - Destination: MMIO address
> > - @param[in] MemBuffer - Source: Memory address
> > - @param[in] Size - Size for write
> > -
> > - @retval EFI_SUCCESS - MMIO write sucessfully
> > -**/
> > -EFI_STATUS
> > -OpalPciWrite (
> > - IN OUT UINTN MmioAddr,
> > - IN VOID *MemBuffer,
> > - IN UINTN Size
> > - )
> > -{
> > - UINTN Offset;
> > - UINT8 Data;
> > - UINT8 *Ptr;
> > -
> > - // priority has adjusted
> > - switch (Size) {
> > - case 4:
> > - PciWrite32 (MmioAddr, *((UINT32 *)MemBuffer));
> > - break;
> > -
> > - case 2:
> > - PciWrite16 (MmioAddr, *((UINT16 *)MemBuffer));
> > - break;
> > -
> > - case 1:
> > - PciWrite8 (MmioAddr, *((UINT8 *)MemBuffer));
> > - break;
> > -
> > - default:
> > - Ptr = (UINT8 *)MemBuffer;
> > - for (Offset = 0; Offset < Size; Offset += 1) {
> > - Data = Ptr[Offset];
> > - PciWrite8 (MmioAddr + Offset, Data);
> > - }
> > - break;
> > - }
> > -
> > - return EFI_SUCCESS;
> > -}
> > -
> > -/**
> > - Get total pages for specific NVME based memory.
> > -
> > - @param[in] BaseMemIndex - The Index of BaseMem (0-based).
> > -
> > - @retval - The page count for specific BaseMem Index
> > -
> > -**/
> > -UINT32
> > -NvmeGetBaseMemPages (
> > - IN UINTN BaseMemIndex
> > - )
> > -{
> > - UINT32 Pages;
> > - UINTN Index;
> > - UINT32 PageSizeList[8];
> > -
> > - PageSizeList[0] = 1; /* Controller Data */
> > - PageSizeList[1] = 1; /* Identify Data */
> > - PageSizeList[2] = 1; /* ASQ */
> > - PageSizeList[3] = 1; /* ACQ */
> > - PageSizeList[4] = 1; /* SQs */
> > - PageSizeList[5] = 1; /* CQs */
> > - PageSizeList[6] = NVME_PRP_SIZE * NVME_CSQ_DEPTH; /* PRPs */
> > - PageSizeList[7] = 1; /* Security Commands */
> > -
> > - if (BaseMemIndex > MAX_BASEMEM_COUNT) {
> > - ASSERT (FALSE);
> > - return 0;
> > - }
> > -
> > - Pages = 0;
> > - for (Index = 0; Index < BaseMemIndex; Index++) {
> > - Pages += PageSizeList[Index];
> > - }
> > -
> > - return Pages;
> > -}
> > -
> > -/**
> > - Wait for NVME controller status to be ready or not.
> > -
> > - @param[in] Nvme - The pointer to the NVME_CONTEXT Data
> > structure.
> > - @param[in] WaitReady - Flag for waitting status ready or not
> > -
> > - @return EFI_SUCCESS - Successfully to wait specific status.
> > - @return others - Fail to wait for specific controller status.
> > -
> > -**/
> > -STATIC
> > -EFI_STATUS
> > -NvmeWaitController (
> > - IN NVME_CONTEXT *Nvme,
> > - IN BOOLEAN WaitReady
> > - )
> > -{
> > - NVME_CSTS Csts;
> > - EFI_STATUS Status;
> > - UINT32 Index;
> > - UINT8 Timeout;
> > -
> > - //
> > - // Cap.To specifies max delay time in 500ms increments for Csts.Rdy to
> set
> > after
> > - // Cc.Enable. Loop produces a 1 millisecond delay per itteration, up to 500
> *
> > Cap.To.
> > - //
> > - if (Nvme->Cap.To == 0) {
> > - Timeout = 1;
> > - } else {
> > - Timeout = Nvme->Cap.To;
> > - }
> > -
> > - Status = EFI_SUCCESS;
> > - for(Index = (Timeout * 500); Index != 0; --Index) {
> > - MicroSecondDelay (1000);
> > -
> > - //
> > - // Check if the controller is initialized
> > - //
> > - Status = NVME_GET_CSTS (Nvme, &Csts);
> > - if (EFI_ERROR(Status)) {
> > - DEBUG ((DEBUG_ERROR, "NVME_GET_CSTS fail, Status = %r\n",
> Status));
> > - return Status;
> > - }
> > -
> > - if ((BOOLEAN) Csts.Rdy == WaitReady) {
> > - break;
> > - }
> > - }
> > -
> > - if (Index == 0) {
> > - Status = EFI_TIMEOUT;
> > - }
> > -
> > - return Status;
> > -}
> > -
> > -/**
> > - Disable the Nvm Express controller.
> > -
> > - @param[in] Nvme - The pointer to the NVME_CONTEXT Data
> > structure.
> > -
> > - @return EFI_SUCCESS - Successfully disable the controller.
> > - @return others - Fail to disable the controller.
> > -
> > -**/
> > -STATIC
> > -EFI_STATUS
> > -NvmeDisableController (
> > - IN NVME_CONTEXT *Nvme
> > - )
> > -{
> > - NVME_CC Cc;
> > - NVME_CSTS Csts;
> > - EFI_STATUS Status;
> > -
> > - Status = NVME_GET_CSTS (Nvme, &Csts);
> > -
> > - ///
> > - /// Read Controller Configuration Register.
> > - ///
> > - Status = NVME_GET_CC (Nvme, &Cc);
> > - if (EFI_ERROR(Status)) {
> > - DEBUG ((DEBUG_ERROR, "NVME_GET_CC fail, Status = %r\n", Status));
> > - goto Done;
> > - }
> > -
> > - if (Cc.En == 1) {
> > - Cc.En = 0;
> > - ///
> > - /// Disable the controller.
> > - ///
> > - Status = NVME_SET_CC (Nvme, &Cc);
> > - if (EFI_ERROR(Status)) {
> > - DEBUG ((DEBUG_ERROR, "NVME_SET_CC fail, Status = %r\n", Status));
> > - goto Done;
> > - }
> > - }
> > -
> > - Status = NvmeWaitController (Nvme, FALSE);
> > - if (EFI_ERROR(Status)) {
> > - DEBUG ((DEBUG_ERROR, "NvmeWaitController fail, Status = %r\n",
> > Status));
> > - goto Done;
> > - }
> > -
> > - return EFI_SUCCESS;
> > -
> > -Done:
> > - DEBUG ((DEBUG_INFO, "NvmeDisableController fail, Status: %r\n",
> Status));
> > - return Status;
> > -}
> > -
> > -/**
> > - Enable the Nvm Express controller.
> > -
> > - @param[in] Nvme - The pointer to the NVME_CONTEXT Data
> > structure.
> > -
> > - @return EFI_SUCCESS - Successfully enable the controller.
> > - @return EFI_DEVICE_ERROR - Fail to enable the controller.
> > - @return EFI_TIMEOUT - Fail to enable the controller in given time
> > slot.
> > -
> > -**/
> > -STATIC
> > -EFI_STATUS
> > -NvmeEnableController (
> > - IN NVME_CONTEXT *Nvme
> > - )
> > -{
> > - NVME_CC Cc;
> > - EFI_STATUS Status;
> > -
> > - //
> > - // Enable the controller
> > - //
> > - ZeroMem (&Cc, sizeof (NVME_CC));
> > - Cc.En = 1;
> > - Cc.Iosqes = 6;
> > - Cc.Iocqes = 4;
> > - Status = NVME_SET_CC (Nvme, &Cc);
> > - if (EFI_ERROR(Status)) {
> > - DEBUG ((DEBUG_ERROR, "NVME_SET_CC fail, Status = %r\n", Status));
> > - goto Done;
> > - }
> > -
> > - Status = NvmeWaitController (Nvme, TRUE);
> > - if (EFI_ERROR(Status)) {
> > - DEBUG ((DEBUG_ERROR, "NvmeWaitController fail, Status = %r\n",
> > Status));
> > - goto Done;
> > - }
> > -
> > - return EFI_SUCCESS;
> > -
> > -Done:
> > - DEBUG ((DEBUG_INFO, "NvmeEnableController fail, Status: %r\n",
> Status));
> > - return Status;
> > -}
> > -
> > -/**
> > - Shutdown the Nvm Express controller.
> > -
> > - @param[in] Nvme - The pointer to the NVME_CONTEXT Data
> > structure.
> > -
> > - @return EFI_SUCCESS - Successfully shutdown the controller.
> > - @return EFI_DEVICE_ERROR - Fail to shutdown the controller.
> > - @return EFI_TIMEOUT - Fail to shutdown the controller in given
> > time slot.
> > -
> > -**/
> > -STATIC
> > -EFI_STATUS
> > -NvmeShutdownController (
> > - IN NVME_CONTEXT *Nvme
> > - )
> > -{
> > - NVME_CC Cc;
> > - NVME_CSTS Csts;
> > - EFI_STATUS Status;
> > - UINT32 Index;
> > - UINTN Timeout;
> > -
> > - Status = NVME_GET_CC (Nvme, &Cc);
> > - if (EFI_ERROR(Status)) {
> > - DEBUG ((DEBUG_ERROR, "NVME_GET_CC fail, Status = %r\n", Status));
> > - return Status;
> > - }
> > -
> > - Cc.Shn = 1; // Normal shutdown
> > -
> > - Status = NVME_SET_CC (Nvme, &Cc);
> > - if (EFI_ERROR(Status)) {
> > - DEBUG ((DEBUG_ERROR, "NVME_SET_CC fail, Status = %r\n", Status));
> > - return Status;
> > - }
> > -
> > - Timeout = NVME_GENERIC_TIMEOUT/1000; // ms
> > - for(Index = (UINT32)(Timeout); Index != 0; --Index) {
> > - MicroSecondDelay (1000);
> > -
> > - Status = NVME_GET_CSTS (Nvme, &Csts);
> > - if (EFI_ERROR(Status)) {
> > - DEBUG ((DEBUG_ERROR, "NVME_GET_CSTS fail, Status = %r\n",
> Status));
> > - return Status;
> > - }
> > -
> > - if (Csts.Shst == 2) { // Shutdown processing complete
> > - break;
> > - }
> > - }
> > -
> > - if (Index == 0) {
> > - Status = EFI_TIMEOUT;
> > - }
> > -
> > - return Status;
> > -}
> > -
> > -/**
> > - Check the execution status from a given completion queue entry.
> > -
> > - @param[in] Cq - A pointer to the NVME_CQ item.
> > -
> > -**/
> > -EFI_STATUS
> > -NvmeCheckCqStatus (
> > - IN NVME_CQ *Cq
> > - )
> > -{
> > - if (Cq->Sct == 0x0 && Cq->Sc == 0x0) {
> > - return EFI_SUCCESS;
> > - }
> > -
> > - DEBUG ((DEBUG_INFO, "Dump NVMe Completion Entry Status from
> > [0x%x]:\n", (UINTN)Cq));
> > - DEBUG ((DEBUG_INFO, " SQ Identifier : [0x%x], Phase Tag : [%d], Cmd
> > Identifier : [0x%x]\n", Cq->Sqid, Cq->Pt, Cq->Cid));
> > - DEBUG ((DEBUG_INFO, " NVMe Cmd Execution Result - "));
> > -
> > - switch (Cq->Sct) {
> > - case 0x0:
> > - switch (Cq->Sc) {
> > - case 0x0:
> > - DEBUG ((DEBUG_INFO, "Successful Completion\n"));
> > - return EFI_SUCCESS;
> > - case 0x1:
> > - DEBUG ((DEBUG_INFO, "Invalid Command Opcode\n"));
> > - break;
> > - case 0x2:
> > - DEBUG ((DEBUG_INFO, "Invalid Field in Command\n"));
> > - break;
> > - case 0x3:
> > - DEBUG ((DEBUG_INFO, "Command ID Conflict\n"));
> > - break;
> > - case 0x4:
> > - DEBUG ((DEBUG_INFO, "Data Transfer Error\n"));
> > - break;
> > - case 0x5:
> > - DEBUG ((DEBUG_INFO, "Commands Aborted due to Power Loss
> > Notification\n"));
> > - break;
> > - case 0x6:
> > - DEBUG ((DEBUG_INFO, "Internal Device Error\n"));
> > - break;
> > - case 0x7:
> > - DEBUG ((DEBUG_INFO, "Command Abort Requested\n"));
> > - break;
> > - case 0x8:
> > - DEBUG ((DEBUG_INFO, "Command Aborted due to SQ Deletion\n"));
> > - break;
> > - case 0x9:
> > - DEBUG ((DEBUG_INFO, "Command Aborted due to Failed Fused
> > Command\n"));
> > - break;
> > - case 0xA:
> > - DEBUG ((DEBUG_INFO, "Command Aborted due to Missing Fused
> > Command\n"));
> > - break;
> > - case 0xB:
> > - DEBUG ((DEBUG_INFO, "Invalid Namespace or Format\n"));
> > - break;
> > - case 0xC:
> > - DEBUG ((DEBUG_INFO, "Command Sequence Error\n"));
> > - break;
> > - case 0xD:
> > - DEBUG ((DEBUG_INFO, "Invalid SGL Last Segment Descriptor\n"));
> > - break;
> > - case 0xE:
> > - DEBUG ((DEBUG_INFO, "Invalid Number of SGL Descriptors\n"));
> > - break;
> > - case 0xF:
> > - DEBUG ((DEBUG_INFO, "Data SGL Length Invalid\n"));
> > - break;
> > - case 0x10:
> > - DEBUG ((DEBUG_INFO, "Metadata SGL Length Invalid\n"));
> > - break;
> > - case 0x11:
> > - DEBUG ((DEBUG_INFO, "SGL Descriptor Type Invalid\n"));
> > - break;
> > - case 0x80:
> > - DEBUG ((DEBUG_INFO, "LBA Out of Range\n"));
> > - break;
> > - case 0x81:
> > - DEBUG ((DEBUG_INFO, "Capacity Exceeded\n"));
> > - break;
> > - case 0x82:
> > - DEBUG ((DEBUG_INFO, "Namespace Not Ready\n"));
> > - break;
> > - case 0x83:
> > - DEBUG ((DEBUG_INFO, "Reservation Conflict\n"));
> > - break;
> > - }
> > - break;
> > -
> > - case 0x1:
> > - switch (Cq->Sc) {
> > - case 0x0:
> > - DEBUG ((DEBUG_INFO, "Completion Queue Invalid\n"));
> > - break;
> > - case 0x1:
> > - DEBUG ((DEBUG_INFO, "Invalid Queue Identifier\n"));
> > - break;
> > - case 0x2:
> > - DEBUG ((DEBUG_INFO, "Maximum Queue Size Exceeded\n"));
> > - break;
> > - case 0x3:
> > - DEBUG ((DEBUG_INFO, "Abort Command Limit Exceeded\n"));
> > - break;
> > - case 0x5:
> > - DEBUG ((DEBUG_INFO, "Asynchronous Event Request Limit
> > Exceeded\n"));
> > - break;
> > - case 0x6:
> > - DEBUG ((DEBUG_INFO, "Invalid Firmware Slot\n"));
> > - break;
> > - case 0x7:
> > - DEBUG ((DEBUG_INFO, "Invalid Firmware Image\n"));
> > - break;
> > - case 0x8:
> > - DEBUG ((DEBUG_INFO, "Invalid Interrupt Vector\n"));
> > - break;
> > - case 0x9:
> > - DEBUG ((DEBUG_INFO, "Invalid Log Page\n"));
> > - break;
> > - case 0xA:
> > - DEBUG ((DEBUG_INFO, "Invalid Format\n"));
> > - break;
> > - case 0xB:
> > - DEBUG ((DEBUG_INFO, "Firmware Application Requires Conventional
> > Reset\n"));
> > - break;
> > - case 0xC:
> > - DEBUG ((DEBUG_INFO, "Invalid Queue Deletion\n"));
> > - break;
> > - case 0xD:
> > - DEBUG ((DEBUG_INFO, "Feature Identifier Not Saveable\n"));
> > - break;
> > - case 0xE:
> > - DEBUG ((DEBUG_INFO, "Feature Not Changeable\n"));
> > - break;
> > - case 0xF:
> > - DEBUG ((DEBUG_INFO, "Feature Not Namespace Specific\n"));
> > - break;
> > - case 0x10:
> > - DEBUG ((DEBUG_INFO, "Firmware Application Requires NVM
> > Subsystem Reset\n"));
> > - break;
> > - case 0x80:
> > - DEBUG ((DEBUG_INFO, "Conflicting Attributes\n"));
> > - break;
> > - case 0x81:
> > - DEBUG ((DEBUG_INFO, "Invalid Protection Information\n"));
> > - break;
> > - case 0x82:
> > - DEBUG ((DEBUG_INFO, "Attempted Write to Read Only Range\n"));
> > - break;
> > - }
> > - break;
> > -
> > - case 0x2:
> > - switch (Cq->Sc) {
> > - case 0x80:
> > - DEBUG ((DEBUG_INFO, "Write Fault\n"));
> > - break;
> > - case 0x81:
> > - DEBUG ((DEBUG_INFO, "Unrecovered Read Error\n"));
> > - break;
> > - case 0x82:
> > - DEBUG ((DEBUG_INFO, "End-to-end Guard Check Error\n"));
> > - break;
> > - case 0x83:
> > - DEBUG ((DEBUG_INFO, "End-to-end Application Tag Check Error\n"));
> > - break;
> > - case 0x84:
> > - DEBUG ((DEBUG_INFO, "End-to-end Reference Tag Check Error\n"));
> > - break;
> > - case 0x85:
> > - DEBUG ((DEBUG_INFO, "Compare Failure\n"));
> > - break;
> > - case 0x86:
> > - DEBUG ((DEBUG_INFO, "Access Denied\n"));
> > - break;
> > - }
> > - break;
> > -
> > - default:
> > - DEBUG ((DEBUG_INFO, "Unknown error\n"));
> > - break;
> > - }
> > -
> > - return EFI_DEVICE_ERROR;
> > -}
> > -
> > -/**
> > - Create PRP lists for Data transfer which is larger than 2 memory pages.
> > - Note here we calcuate the number of required PRP lists and allocate
> them
> > at one time.
> > -
> > - @param[in] Nvme - The pointer to the NVME_CONTEXT Data
> > structure.
> > - @param[in] SqId - The SQ index for this PRP
> > - @param[in] PhysicalAddr - The physical base address of Data Buffer.
> > - @param[in] Pages - The number of pages to be transfered.
> > - @param[out] PrpListHost - The host base address of PRP lists.
> > - @param[in,out] PrpListNo - The number of PRP List.
> > -
> > - @retval The pointer Value to the first PRP List of the PRP lists.
> > -
> > -**/
> > -STATIC
> > -UINT64
> > -NvmeCreatePrpList (
> > - IN NVME_CONTEXT *Nvme,
> > - IN UINT16 SqId,
> > - IN EFI_PHYSICAL_ADDRESS PhysicalAddr,
> > - IN UINTN Pages,
> > - OUT VOID **PrpListHost,
> > - IN OUT UINTN *PrpListNo
> > - )
> > -{
> > - UINTN PrpEntryNo;
> > - UINT64 PrpListBase;
> > - UINTN PrpListIndex;
> > - UINTN PrpEntryIndex;
> > - UINT64 Remainder;
> > - EFI_PHYSICAL_ADDRESS PrpListPhyAddr;
> > - UINTN Bytes;
> > - UINT8 *PrpEntry;
> > - EFI_PHYSICAL_ADDRESS NewPhyAddr;
> > -
> > - ///
> > - /// The number of Prp Entry in a memory page.
> > - ///
> > - PrpEntryNo = EFI_PAGE_SIZE / sizeof (UINT64);
> > -
> > - ///
> > - /// Calculate total PrpList number.
> > - ///
> > - *PrpListNo = (UINTN) DivU64x64Remainder ((UINT64)Pages,
> > (UINT64)PrpEntryNo, &Remainder);
> > - if (Remainder != 0) {
> > - *PrpListNo += 1;
> > - }
> > -
> > - if (*PrpListNo > NVME_PRP_SIZE) {
> > - DEBUG ((DEBUG_INFO, "NvmeCreatePrpList (PhysicalAddr: %lx,
> > Pages: %x) PrpEntryNo: %x\n",
> > - PhysicalAddr, Pages, PrpEntryNo));
> > - DEBUG ((DEBUG_INFO, "*PrpListNo: %x, Remainder: %lx", *PrpListNo,
> > Remainder));
> > - ASSERT (FALSE);
> > - }
> > - *PrpListHost = (VOID *)(UINTN) NVME_PRP_BASE (Nvme, SqId);
> > -
> > - Bytes = EFI_PAGES_TO_SIZE (*PrpListNo);
> > - PrpListPhyAddr = (UINT64)(UINTN)(*PrpListHost);
> > -
> > - ///
> > - /// Fill all PRP lists except of last one.
> > - ///
> > - ZeroMem (*PrpListHost, Bytes);
> > - for (PrpListIndex = 0; PrpListIndex < *PrpListNo - 1; ++PrpListIndex) {
> > - PrpListBase = *(UINT64*)PrpListHost + PrpListIndex * EFI_PAGE_SIZE;
> > -
> > - for (PrpEntryIndex = 0; PrpEntryIndex < PrpEntryNo; ++PrpEntryIndex) {
> > - PrpEntry = (UINT8 *)(UINTN) (PrpListBase + PrpEntryIndex *
> > sizeof(UINT64));
> > - if (PrpEntryIndex != PrpEntryNo - 1) {
> > - ///
> > - /// Fill all PRP entries except of last one.
> > - ///
> > - CopyMem (PrpEntry, (VOID *)(UINTN) (&PhysicalAddr), sizeof
> > (UINT64));
> > - PhysicalAddr += EFI_PAGE_SIZE;
> > - } else {
> > - ///
> > - /// Fill last PRP entries with next PRP List pointer.
> > - ///
> > - NewPhyAddr = (PrpListPhyAddr + (PrpListIndex + 1) * EFI_PAGE_SIZE);
> > - CopyMem (PrpEntry, (VOID *)(UINTN) (&NewPhyAddr), sizeof
> > (UINT64));
> > - }
> > - }
> > - }
> > -
> > - ///
> > - /// Fill last PRP list.
> > - ///
> > - PrpListBase = *(UINT64*)PrpListHost + PrpListIndex * EFI_PAGE_SIZE;
> > - for (PrpEntryIndex = 0; PrpEntryIndex < ((Remainder != 0) ? Remainder :
> > PrpEntryNo); ++PrpEntryIndex) {
> > - PrpEntry = (UINT8 *)(UINTN) (PrpListBase + PrpEntryIndex *
> > sizeof(UINT64));
> > - CopyMem (PrpEntry, (VOID *)(UINTN) (&PhysicalAddr), sizeof
> (UINT64));
> > -
> > - PhysicalAddr += EFI_PAGE_SIZE;
> > - }
> > -
> > - return PrpListPhyAddr;
> > -}
> > -
> > -/**
> > - Waits until all NVME commands completed.
> > -
> > - @param[in] Nvme - The pointer to the NVME_CONTEXT Data
> > structure.
> > - @param[in] Qid - Queue index
> > -
> > - @retval EFI_SUCCESS - All NVME commands have completed
> > - @retval EFI_TIMEOUT - Timeout occured
> > - @retval EFI_NOT_READY - Not all NVME commands have
> completed
> > - @retval others - Error occurred on device side.
> > -**/
> > -EFI_STATUS
> > -NvmeWaitAllComplete (
> > - IN NVME_CONTEXT *Nvme,
> > - IN UINT8 Qid
> > - )
> > -{
> > - return EFI_SUCCESS;
> > -}
> > -
> > -/**
> > - Sends an NVM Express Command Packet to an NVM Express controller or
> > namespace. This function supports
> > - both blocking I/O and nonblocking I/O. The blocking I/O functionality is
> > required, and the nonblocking
> > - I/O functionality is optional.
> > -
> > - @param[in] Nvme - The pointer to the NVME_CONTEXT Data
> > structure.
> > - @param[in] NamespaceId - Is a 32 bit Namespace ID to which the
> > Express HCI command packet will be sent.
> > - A Value of 0 denotes the NVM Express controller, a
> Value
> > of all 0FFh in the namespace
> > - ID specifies that the command packet should be sent to
> > all valid namespaces.
> > - @param[in] NamespaceUuid - Is a 64 bit Namespace UUID to which
> > the Express HCI command packet will be sent.
> > - A Value of 0 denotes the NVM Express controller, a
> Value
> > of all 0FFh in the namespace
> > - UUID specifies that the command packet should be
> sent
> > to all valid namespaces.
> > - @param[in,out] Packet - A pointer to the NVM Express HCI
> > Command Packet to send to the NVMe namespace specified
> > - by NamespaceId.
> > -
> > - @retval EFI_SUCCESS - The NVM Express Command Packet was
> sent
> > by the host. TransferLength bytes were transferred
> > - to, or from DataBuffer.
> > - @retval EFI_NOT_READY - The NVM Express Command Packet
> could
> > not be sent because the controller is not ready. The caller
> > - may retry again later.
> > - @retval EFI_DEVICE_ERROR - A device error occurred while
> attempting
> > to send the NVM Express Command Packet.
> > - @retval EFI_INVALID_PARAMETER - Namespace, or the contents of
> > NVM_EXPRESS_PASS_THRU_COMMAND_PACKET are invalid. The NVM
> > - Express Command Packet was not sent, so no
> additional
> > status information is available.
> > - @retval EFI_UNSUPPORTED - The command described by the NVM
> > Express Command Packet is not supported by the host adapter.
> > - The NVM Express Command Packet was not sent, so no
> > additional status information is available.
> > - @retval EFI_TIMEOUT - A timeout occurred while waiting for the
> > NVM Express Command Packet to execute.
> > -
> > -**/
> > -EFI_STATUS
> > -NvmePassThru (
> > - IN NVME_CONTEXT *Nvme,
> > - IN UINT32 NamespaceId,
> > - IN UINT64 NamespaceUuid,
> > - IN OUT NVM_EXPRESS_PASS_THRU_COMMAND_PACKET *Packet
> > - )
> > -{
> > - EFI_STATUS Status;
> > - NVME_SQ *Sq;
> > - NVME_CQ *Cq;
> > - UINT8 Qid;
> > - UINT32 Bytes;
> > - UINT32 Offset;
> > - EFI_PHYSICAL_ADDRESS PhyAddr;
> > - VOID *PrpListHost;
> > - UINTN PrpListNo;
> > - UINT32 Timer;
> > - UINTN SqSize;
> > - UINTN CqSize;
> > -
> > - ///
> > - /// check the Data fields in Packet parameter.
> > - ///
> > - if ((Nvme == NULL) || (Packet == NULL)) {
> > - DEBUG ((DEBUG_ERROR, "NvmePassThru, invalid parameter:
> > Nvme(%x)/Packet(%x)\n",
> > - (UINTN)Nvme, (UINTN)Packet));
> > - return EFI_INVALID_PARAMETER;
> > - }
> > -
> > - if ((Packet->NvmeCmd == NULL) || (Packet->NvmeResponse == NULL)) {
> > - DEBUG ((DEBUG_ERROR, "NvmePassThru, invalid parameter:
> > NvmeCmd(%x)/NvmeResponse(%x)\n",
> > - (UINTN)Packet->NvmeCmd, (UINTN)Packet->NvmeResponse));
> > - return EFI_INVALID_PARAMETER;
> > - }
> > -
> > - if (Packet->QueueId != NVME_ADMIN_QUEUE && Packet->QueueId !=
> > NVME_IO_QUEUE) {
> > - DEBUG ((DEBUG_ERROR, "NvmePassThru, invalid parameter:
> > QueueId(%x)\n",
> > - Packet->QueueId));
> > - return EFI_INVALID_PARAMETER;
> > - }
> > -
> > - PrpListHost = NULL;
> > - PrpListNo = 0;
> > - Status = EFI_SUCCESS;
> > -
> > - Qid = Packet->QueueId;
> > - Sq = Nvme->SqBuffer[Qid] + Nvme->SqTdbl[Qid].Sqt;
> > - Cq = Nvme->CqBuffer[Qid] + Nvme->CqHdbl[Qid].Cqh;
> > - if (Qid == NVME_ADMIN_QUEUE) {
> > - SqSize = NVME_ASQ_SIZE + 1;
> > - CqSize = NVME_ACQ_SIZE + 1;
> > - } else {
> > - SqSize = NVME_CSQ_DEPTH;
> > - CqSize = NVME_CCQ_DEPTH;
> > - }
> > -
> > - if (Packet->NvmeCmd->Nsid != NamespaceId) {
> > - DEBUG ((DEBUG_ERROR, "NvmePassThru: Nsid mismatch (%x, %x)\n",
> > - Packet->NvmeCmd->Nsid, NamespaceId));
> > - return EFI_INVALID_PARAMETER;
> > - }
> > -
> > - ZeroMem (Sq, sizeof (NVME_SQ));
> > - Sq->Opc = Packet->NvmeCmd->Cdw0.Opcode;
> > - Sq->Fuse = Packet->NvmeCmd->Cdw0.FusedOperation;
> > - Sq->Cid = Packet->NvmeCmd->Cdw0.Cid;
> > - Sq->Nsid = Packet->NvmeCmd->Nsid;
> > -
> > - ///
> > - /// Currently we only support PRP for Data transfer, SGL is NOT
> supported.
> > - ///
> > - ASSERT (Sq->Psdt == 0);
> > - if (Sq->Psdt != 0) {
> > - DEBUG ((DEBUG_ERROR, "NvmePassThru: doesn't support SGL
> > mechanism\n"));
> > - return EFI_UNSUPPORTED;
> > - }
> > -
> > - Sq->Prp[0] = Packet->TransferBuffer;
> > - Sq->Prp[1] = 0;
> > -
> > - if(Packet->MetadataBuffer != (UINT64)(UINTN)NULL) {
> > - Sq->Mptr = Packet->MetadataBuffer;
> > - }
> > -
> > - ///
> > - /// If the Buffer Size spans more than two memory pages (page Size as
> > defined in CC.Mps),
> > - /// then build a PRP list in the second PRP submission queue entry.
> > - ///
> > - Offset = ((UINT32)Sq->Prp[0]) & (EFI_PAGE_SIZE - 1);
> > - Bytes = Packet->TransferLength;
> > -
> > - if ((Offset + Bytes) > (EFI_PAGE_SIZE * 2)) {
> > - ///
> > - /// Create PrpList for remaining Data Buffer.
> > - ///
> > - PhyAddr = (Sq->Prp[0] + EFI_PAGE_SIZE) & ~(EFI_PAGE_SIZE - 1);
> > - Sq->Prp[1] = NvmeCreatePrpList (Nvme, Nvme->SqTdbl[Qid].Sqt,
> > PhyAddr, EFI_SIZE_TO_PAGES(Offset + Bytes) - 1, &PrpListHost,
> &PrpListNo);
> > - if (Sq->Prp[1] == 0) {
> > - Status = EFI_OUT_OF_RESOURCES;
> > - DEBUG ((DEBUG_ERROR, "NvmeCreatePrpList fail, Status: %r\n",
> Status));
> > - goto EXIT;
> > - }
> > -
> > - } else if ((Offset + Bytes) > EFI_PAGE_SIZE) {
> > - Sq->Prp[1] = (Sq->Prp[0] + EFI_PAGE_SIZE) & ~(EFI_PAGE_SIZE - 1);
> > - }
> > -
> > - if(Packet->NvmeCmd->Flags & CDW10_VALID) {
> > - Sq->Payload.Raw.Cdw10 = Packet->NvmeCmd->Cdw10;
> > - }
> > - if(Packet->NvmeCmd->Flags & CDW11_VALID) {
> > - Sq->Payload.Raw.Cdw11 = Packet->NvmeCmd->Cdw11;
> > - }
> > - if(Packet->NvmeCmd->Flags & CDW12_VALID) {
> > - Sq->Payload.Raw.Cdw12 = Packet->NvmeCmd->Cdw12;
> > - }
> > - if(Packet->NvmeCmd->Flags & CDW13_VALID) {
> > - Sq->Payload.Raw.Cdw13 = Packet->NvmeCmd->Cdw13;
> > - }
> > - if(Packet->NvmeCmd->Flags & CDW14_VALID) {
> > - Sq->Payload.Raw.Cdw14 = Packet->NvmeCmd->Cdw14;
> > - }
> > - if(Packet->NvmeCmd->Flags & CDW15_VALID) {
> > - Sq->Payload.Raw.Cdw15 = Packet->NvmeCmd->Cdw15;
> > - }
> > -
> > - ///
> > - /// Ring the submission queue doorbell.
> > - ///
> > - Nvme->SqTdbl[Qid].Sqt++;
> > - if(Nvme->SqTdbl[Qid].Sqt == SqSize) {
> > - Nvme->SqTdbl[Qid].Sqt = 0;
> > - }
> > - Status = NVME_SET_SQTDBL (Nvme, Qid, &Nvme->SqTdbl[Qid]);
> > - if (EFI_ERROR(Status)) {
> > - DEBUG ((DEBUG_ERROR, "NVME_SET_SQTDBL fail, Status: %r\n",
> Status));
> > - goto EXIT;
> > - }
> > -
> > - ///
> > - /// Wait for completion queue to get filled in.
> > - ///
> > - Status = EFI_TIMEOUT;
> > - Timer = 0;
> > - while (Timer < NVME_CMD_TIMEOUT) {
> > - //DEBUG ((DEBUG_VERBOSE, "Timer: %x, Cq:\n", Timer));
> > - //DumpMem (Cq, sizeof (NVME_CQ));
> > - if (Cq->Pt != Nvme->Pt[Qid]) {
> > - Status = EFI_SUCCESS;
> > - break;
> > - }
> > -
> > - MicroSecondDelay (NVME_CMD_WAIT);
> > - Timer += NVME_CMD_WAIT;
> > - }
> > -
> > - Nvme->CqHdbl[Qid].Cqh++;
> > - if (Nvme->CqHdbl[Qid].Cqh == CqSize) {
> > - Nvme->CqHdbl[Qid].Cqh = 0;
> > - Nvme->Pt[Qid] ^= 1;
> > - }
> > -
> > - ///
> > - /// Copy the Respose Queue entry for this command to the callers
> > response Buffer
> > - ///
> > - CopyMem (Packet->NvmeResponse, Cq,
> > sizeof(NVM_EXPRESS_RESPONSE));
> > -
> > - if (!EFI_ERROR(Status)) { // We still need to check CQ status if no timeout
> > error occured
> > - Status = NvmeCheckCqStatus (Cq);
> > - }
> > - NVME_SET_CQHDBL (Nvme, Qid, &Nvme->CqHdbl[Qid]);
> > -
> > -EXIT:
> > - return Status;
> > -}
> > -
> > -/**
> > - Get identify controller Data.
> > -
> > - @param[in] Nvme - The pointer to the NVME_CONTEXT Data
> > structure.
> > - @param[in] Buffer - The Buffer used to store the identify
> controller
> > Data.
> > -
> > - @return EFI_SUCCESS - Successfully get the identify controller
> Data.
> > - @return others - Fail to get the identify controller Data.
> > -
> > -**/
> > -STATIC
> > -EFI_STATUS
> > -NvmeIdentifyController (
> > - IN NVME_CONTEXT *Nvme,
> > - IN VOID *Buffer
> > - )
> > -{
> > - NVM_EXPRESS_PASS_THRU_COMMAND_PACKET CommandPacket;
> > - NVM_EXPRESS_COMMAND Command;
> > - NVM_EXPRESS_RESPONSE Response;
> > - EFI_STATUS Status;
> > -
> > - ZeroMem (&CommandPacket,
> > sizeof(NVM_EXPRESS_PASS_THRU_COMMAND_PACKET));
> > - ZeroMem (&Command, sizeof(NVM_EXPRESS_COMMAND));
> > - ZeroMem (&Response, sizeof(NVM_EXPRESS_RESPONSE));
> > -
> > - Command.Cdw0.Opcode = NVME_ADMIN_IDENTIFY_OPC;
> > - Command.Cdw0.Cid = Nvme->Cid[NVME_ADMIN_QUEUE]++;
> > - //
> > - // According to Nvm Express 1.1 spec Figure 38, When not used, the field
> > shall be cleared to 0h.
> > - // For the Identify command, the Namespace Identifier is only used for
> the
> > Namespace Data structure.
> > - //
> > - Command.Nsid = 0;
> > -
> > - CommandPacket.NvmeCmd = &Command;
> > - CommandPacket.NvmeResponse = &Response;
> > - CommandPacket.TransferBuffer = (UINT64)(UINTN)Buffer;
> > - CommandPacket.TransferLength = sizeof
> > (NVME_ADMIN_CONTROLLER_DATA);
> > - CommandPacket.CommandTimeout = NVME_GENERIC_TIMEOUT;
> > - CommandPacket.QueueId = NVME_ADMIN_QUEUE;
> > - //
> > - // Set bit 0 (Cns bit) to 1 to identify a controller
> > - //
> > - Command.Cdw10 = 1;
> > - Command.Flags = CDW10_VALID;
> > -
> > - Status = NvmePassThru (
> > - Nvme,
> > - NVME_CONTROLLER_ID,
> > - 0,
> > - &CommandPacket
> > - );
> > - if (!EFI_ERROR (Status)) {
> > - Status = NvmeWaitAllComplete (Nvme, CommandPacket.QueueId);
> > - }
> > -
> > - return Status;
> > -}
> > -
> > -/**
> > - Get specified identify namespace Data.
> > -
> > - @param[in] Nvme - The pointer to the NVME_CONTEXT Data
> > structure.
> > - @param[in] NamespaceId - The specified namespace identifier.
> > - @param[in] Buffer - The Buffer used to store the identify
> > namespace Data.
> > -
> > - @return EFI_SUCCESS - Successfully get the identify namespace
> > Data.
> > - @return others - Fail to get the identify namespace Data.
> > -
> > -**/
> > -STATIC
> > -EFI_STATUS
> > -NvmeIdentifyNamespace (
> > - IN NVME_CONTEXT *Nvme,
> > - IN UINT32 NamespaceId,
> > - IN VOID *Buffer
> > - )
> > -{
> > - NVM_EXPRESS_PASS_THRU_COMMAND_PACKET CommandPacket;
> > - NVM_EXPRESS_COMMAND Command;
> > - NVM_EXPRESS_RESPONSE Response;
> > - EFI_STATUS Status;
> > -
> > - ZeroMem (&CommandPacket,
> > sizeof(NVM_EXPRESS_PASS_THRU_COMMAND_PACKET));
> > - ZeroMem (&Command, sizeof(NVM_EXPRESS_COMMAND));
> > - ZeroMem (&Response, sizeof(NVM_EXPRESS_RESPONSE));
> > -
> > - CommandPacket.NvmeCmd = &Command;
> > - CommandPacket.NvmeResponse = &Response;
> > -
> > - Command.Cdw0.Opcode = NVME_ADMIN_IDENTIFY_OPC;
> > - Command.Cdw0.Cid = Nvme->Cid[NVME_ADMIN_QUEUE]++;
> > - Command.Nsid = NamespaceId;
> > - CommandPacket.TransferBuffer = (UINT64)(UINTN)Buffer;
> > - CommandPacket.TransferLength = sizeof
> > (NVME_ADMIN_NAMESPACE_DATA);
> > - CommandPacket.CommandTimeout = NVME_GENERIC_TIMEOUT;
> > - CommandPacket.QueueId = NVME_ADMIN_QUEUE;
> > - //
> > - // Set bit 0 (Cns bit) to 1 to identify a namespace
> > - //
> > - CommandPacket.NvmeCmd->Cdw10 = 0;
> > - CommandPacket.NvmeCmd->Flags = CDW10_VALID;
> > -
> > - Status = NvmePassThru (
> > - Nvme,
> > - NamespaceId,
> > - 0,
> > - &CommandPacket
> > - );
> > - if (!EFI_ERROR (Status)) {
> > - Status = NvmeWaitAllComplete (Nvme, CommandPacket.QueueId);
> > - }
> > -
> > - return Status;
> > -}
> > -
> > -/**
> > - Get Block Size for specific namespace of NVME.
> > -
> > - @param[in] Nvme - The pointer to the NVME_CONTEXT Data
> > structure.
> > -
> > - @return - Block Size in bytes
> > -
> > -**/
> > -STATIC
> > -UINT32
> > -NvmeGetBlockSize (
> > - IN NVME_CONTEXT *Nvme
> > - )
> > -{
> > - UINT32 BlockSize;
> > - UINT32 Lbads;
> > - UINT32 Flbas;
> > - UINT32 LbaFmtIdx;
> > -
> > - Flbas = Nvme->NamespaceData->Flbas;
> > - LbaFmtIdx = Flbas & 3;
> > - Lbads = Nvme->NamespaceData->LbaFormat[LbaFmtIdx].Lbads;
> > -
> > - BlockSize = (UINT32)1 << Lbads;
> > - return BlockSize;
> > -}
> > -
> > -/**
> > - Get last LBA for specific namespace of NVME.
> > -
> > - @param[in] Nvme - The pointer to the NVME_CONTEXT Data
> > structure.
> > -
> > - @return - Last LBA address
> > -
> > -**/
> > -STATIC
> > -EFI_LBA
> > -NvmeGetLastLba (
> > - IN NVME_CONTEXT *Nvme
> > - )
> > -{
> > - EFI_LBA LastBlock;
> > - LastBlock = Nvme->NamespaceData->Nsze - 1;
> > - return LastBlock;
> > -}
> > -
> > -/**
> > - Create io completion queue.
> > -
> > - @param[in] Nvme - The pointer to the NVME_CONTEXT Data
> > structure.
> > -
> > - @return EFI_SUCCESS - Successfully create io completion queue.
> > - @return others - Fail to create io completion queue.
> > -
> > -**/
> > -STATIC
> > -EFI_STATUS
> > -NvmeCreateIoCompletionQueue (
> > - IN NVME_CONTEXT *Nvme
> > - )
> > -{
> > - NVM_EXPRESS_PASS_THRU_COMMAND_PACKET CommandPacket;
> > - NVM_EXPRESS_COMMAND Command;
> > - NVM_EXPRESS_RESPONSE Response;
> > - EFI_STATUS Status;
> > - NVME_ADMIN_CRIOCQ CrIoCq;
> > -
> > - ZeroMem (&CommandPacket,
> > sizeof(NVM_EXPRESS_PASS_THRU_COMMAND_PACKET));
> > - ZeroMem (&Command, sizeof(NVM_EXPRESS_COMMAND));
> > - ZeroMem (&Response, sizeof(NVM_EXPRESS_RESPONSE));
> > - ZeroMem (&CrIoCq, sizeof(NVME_ADMIN_CRIOCQ));
> > -
> > - CommandPacket.NvmeCmd = &Command;
> > - CommandPacket.NvmeResponse = &Response;
> > -
> > - Command.Cdw0.Opcode = NVME_ADMIN_CRIOCQ_OPC;
> > - Command.Cdw0.Cid = Nvme->Cid[NVME_ADMIN_QUEUE]++;
> > - CommandPacket.TransferBuffer = (UINT64)(UINTN)Nvme-
> > >CqBuffer[NVME_IO_QUEUE];
> > - CommandPacket.TransferLength = EFI_PAGE_SIZE;
> > - CommandPacket.CommandTimeout = NVME_GENERIC_TIMEOUT;
> > - CommandPacket.QueueId = NVME_ADMIN_QUEUE;
> > -
> > - CrIoCq.Qid = NVME_IO_QUEUE;
> > - CrIoCq.Qsize = NVME_CCQ_SIZE;
> > - CrIoCq.Pc = 1;
> > - CopyMem (&CommandPacket.NvmeCmd->Cdw10, &CrIoCq, sizeof
> > (NVME_ADMIN_CRIOCQ));
> > - CommandPacket.NvmeCmd->Flags = CDW10_VALID | CDW11_VALID;
> > -
> > - Status = NvmePassThru (
> > - Nvme,
> > - NVME_CONTROLLER_ID,
> > - 0,
> > - &CommandPacket
> > - );
> > - if (!EFI_ERROR (Status)) {
> > - Status = NvmeWaitAllComplete (Nvme, CommandPacket.QueueId);
> > - }
> > -
> > - return Status;
> > -}
> > -
> > -/**
> > - Create io submission queue.
> > -
> > - @param[in] Nvme - The pointer to the NVME_CONTEXT Data
> > structure.
> > -
> > - @return EFI_SUCCESS - Successfully create io submission queue.
> > - @return others - Fail to create io submission queue.
> > -
> > -**/
> > -STATIC
> > -EFI_STATUS
> > -NvmeCreateIoSubmissionQueue (
> > - IN NVME_CONTEXT *Nvme
> > - )
> > -{
> > - NVM_EXPRESS_PASS_THRU_COMMAND_PACKET CommandPacket;
> > - NVM_EXPRESS_COMMAND Command;
> > - NVM_EXPRESS_RESPONSE Response;
> > - EFI_STATUS Status;
> > - NVME_ADMIN_CRIOSQ CrIoSq;
> > -
> > - ZeroMem (&CommandPacket,
> > sizeof(NVM_EXPRESS_PASS_THRU_COMMAND_PACKET));
> > - ZeroMem (&Command, sizeof(NVM_EXPRESS_COMMAND));
> > - ZeroMem (&Response, sizeof(NVM_EXPRESS_RESPONSE));
> > - ZeroMem (&CrIoSq, sizeof(NVME_ADMIN_CRIOSQ));
> > -
> > - CommandPacket.NvmeCmd = &Command;
> > - CommandPacket.NvmeResponse = &Response;
> > -
> > - Command.Cdw0.Opcode = NVME_ADMIN_CRIOSQ_OPC;
> > - Command.Cdw0.Cid = Nvme->Cid[NVME_ADMIN_QUEUE]++;
> > - CommandPacket.TransferBuffer = (UINT64)(UINTN)Nvme-
> > >SqBuffer[NVME_IO_QUEUE];
> > - CommandPacket.TransferLength = EFI_PAGE_SIZE;
> > - CommandPacket.CommandTimeout = NVME_GENERIC_TIMEOUT;
> > - CommandPacket.QueueId = NVME_ADMIN_QUEUE;
> > -
> > - CrIoSq.Qid = NVME_IO_QUEUE;
> > - CrIoSq.Qsize = NVME_CSQ_SIZE;
> > - CrIoSq.Pc = 1;
> > - CrIoSq.Cqid = NVME_IO_QUEUE;
> > - CrIoSq.Qprio = 0;
> > - CopyMem (&CommandPacket.NvmeCmd->Cdw10, &CrIoSq, sizeof
> > (NVME_ADMIN_CRIOSQ));
> > - CommandPacket.NvmeCmd->Flags = CDW10_VALID | CDW11_VALID;
> > -
> > - Status = NvmePassThru (
> > - Nvme,
> > - NVME_CONTROLLER_ID,
> > - 0,
> > - &CommandPacket
> > - );
> > - if (!EFI_ERROR (Status)) {
> > - Status = NvmeWaitAllComplete (Nvme, CommandPacket.QueueId);
> > - }
> > -
> > - return Status;
> > -}
> > -
> > -/**
> > - Security send and receive commands.
> > -
> > - @param[in] Nvme - The pointer to the NVME_CONTEXT Data
> > structure.
> > - @param[in] SendCommand - The flag to indicate the command
> > type, TRUE for Send command and FALSE for receive command
> > - @param[in] SecurityProtocol - Security Protocol
> > - @param[in] SpSpecific - Security Protocol Specific
> > - @param[in] TransferLength - Transfer Length of Buffer (in bytes) -
> > always a multiple of 512
> > - @param[in,out] TransferBuffer - Address of Data to transfer
> > -
> > - @return EFI_SUCCESS - Successfully create io submission queue.
> > - @return others - Fail to send/receive commands.
> > -
> > -**/
> > -EFI_STATUS
> > -NvmeSecuritySendReceive (
> > - IN NVME_CONTEXT *Nvme,
> > - IN BOOLEAN SendCommand,
> > - IN UINT8 SecurityProtocol,
> > - IN UINT16 SpSpecific,
> > - IN UINTN TransferLength,
> > - IN OUT VOID *TransferBuffer
> > - )
> > -{
> > - NVM_EXPRESS_PASS_THRU_COMMAND_PACKET CommandPacket;
> > - NVM_EXPRESS_COMMAND Command;
> > - NVM_EXPRESS_RESPONSE Response;
> > - EFI_STATUS Status;
> > - NVME_ADMIN_SECSEND SecSend;
> > - OACS *Oacs;
> > - UINT8 Opcode;
> > - VOID* *SecBuff;
> > -
> > - Oacs = (OACS *)&Nvme->ControllerData->Oacs;
> > -
> > - //
> > - // Verify security bit for Security Send/Receive commands
> > - //
> > - if (Oacs->Security == 0) {
> > - DEBUG ((DEBUG_ERROR, "Security command doesn't support.\n"));
> > - return EFI_NOT_READY;
> > - }
> > -
> > - SecBuff = (VOID *)(UINTN) NVME_SEC_BASE (Nvme);
> > -
> > - //
> > - // Actions for sending security command
> > - //
> > - if (SendCommand) {
> > - CopyMem (SecBuff, TransferBuffer, TransferLength);
> > - }
> > -
> > - ZeroMem (&CommandPacket,
> > sizeof(NVM_EXPRESS_PASS_THRU_COMMAND_PACKET));
> > - ZeroMem (&Command, sizeof(NVM_EXPRESS_COMMAND));
> > - ZeroMem (&Response, sizeof(NVM_EXPRESS_RESPONSE));
> > - ZeroMem (&SecSend, sizeof(NVME_ADMIN_SECSEND));
> > -
> > - CommandPacket.NvmeCmd = &Command;
> > - CommandPacket.NvmeResponse = &Response;
> > -
> > - Opcode = (UINT8)(SendCommand ?
> NVME_ADMIN_SECURITY_SEND_OPC :
> > NVME_ADMIN_SECURITY_RECV_OPC);
> > - Command.Cdw0.Opcode = Opcode;
> > - Command.Cdw0.Cid = Nvme->Cid[NVME_ADMIN_QUEUE]++;
> > - CommandPacket.TransferBuffer = (UINT64)(UINTN)SecBuff;
> > - CommandPacket.TransferLength = (UINT32)TransferLength;
> > - CommandPacket.CommandTimeout = NVME_GENERIC_TIMEOUT;
> > - CommandPacket.QueueId = NVME_ADMIN_QUEUE;
> > -
> > - SecSend.Spsp = SpSpecific;
> > - SecSend.Secp = SecurityProtocol;
> > - SecSend.Tl = (UINT32)TransferLength;
> > -
> > - CopyMem (&CommandPacket.NvmeCmd->Cdw10, &SecSend, sizeof
> > (NVME_ADMIN_SECSEND));
> > - CommandPacket.NvmeCmd->Flags = CDW10_VALID | CDW11_VALID;
> > -
> > - Status = NvmePassThru (
> > - Nvme,
> > - NVME_CONTROLLER_ID,
> > - 0,
> > - &CommandPacket
> > - );
> > - if (!EFI_ERROR (Status)) {
> > - Status = NvmeWaitAllComplete (Nvme, CommandPacket.QueueId);
> > - }
> > -
> > - //
> > - // Actions for receiving security command
> > - //
> > - if (!SendCommand) {
> > - CopyMem (TransferBuffer, SecBuff, TransferLength);
> > - }
> > -
> > - return Status;
> > -}
> > -
> > -/**
> > - Destroy io completion queue.
> > -
> > - @param[in] Nvme - The pointer to the NVME_CONTEXT Data
> > structure.
> > -
> > - @return EFI_SUCCESS - Successfully destroy io completion queue.
> > - @return others - Fail to destroy io completion queue.
> > -
> > -**/
> > -STATIC
> > -EFI_STATUS
> > -NvmeDestroyIoCompletionQueue (
> > - IN NVME_CONTEXT *Nvme
> > - )
> > -{
> > - NVM_EXPRESS_PASS_THRU_COMMAND_PACKET CommandPacket;
> > - NVM_EXPRESS_COMMAND Command;
> > - NVM_EXPRESS_RESPONSE Response;
> > - EFI_STATUS Status;
> > - NVME_ADMIN_DEIOCQ DelIoCq;
> > -
> > - ZeroMem (&CommandPacket,
> > sizeof(NVM_EXPRESS_PASS_THRU_COMMAND_PACKET));
> > - ZeroMem (&Command, sizeof(NVM_EXPRESS_COMMAND));
> > - ZeroMem (&Response, sizeof(NVM_EXPRESS_RESPONSE));
> > - ZeroMem (&DelIoCq, sizeof(NVME_ADMIN_DEIOCQ));
> > -
> > - CommandPacket.NvmeCmd = &Command;
> > - CommandPacket.NvmeResponse = &Response;
> > -
> > - Command.Cdw0.Opcode = NVME_ADMIN_DELIOCQ_OPC;
> > - Command.Cdw0.Cid = Nvme->Cid[NVME_ADMIN_QUEUE]++;
> > - CommandPacket.TransferBuffer = (UINT64)(UINTN)Nvme-
> > >CqBuffer[NVME_IO_QUEUE];
> > - CommandPacket.TransferLength = EFI_PAGE_SIZE;
> > - CommandPacket.CommandTimeout = NVME_GENERIC_TIMEOUT;
> > - CommandPacket.QueueId = NVME_ADMIN_QUEUE;
> > -
> > - DelIoCq.Qid = NVME_IO_QUEUE;
> > - CopyMem (&CommandPacket.NvmeCmd->Cdw10, &DelIoCq, sizeof
> > (NVME_ADMIN_DEIOCQ));
> > - CommandPacket.NvmeCmd->Flags = CDW10_VALID | CDW11_VALID;
> > -
> > - Status = NvmePassThru (
> > - Nvme,
> > - NVME_CONTROLLER_ID,
> > - 0,
> > - &CommandPacket
> > - );
> > - if (!EFI_ERROR (Status)) {
> > - Status = NvmeWaitAllComplete (Nvme, CommandPacket.QueueId);
> > - }
> > -
> > - return Status;
> > -}
> > -
> > -/**
> > - Destroy io submission queue.
> > -
> > - @param[in] Nvme - The pointer to the NVME_CONTEXT Data
> > structure.
> > -
> > - @return EFI_SUCCESS - Successfully destroy io submission queue.
> > - @return others - Fail to destroy io submission queue.
> > -
> > -**/
> > -STATIC
> > -EFI_STATUS
> > -NvmeDestroyIoSubmissionQueue (
> > - IN NVME_CONTEXT *Nvme
> > - )
> > -{
> > - NVM_EXPRESS_PASS_THRU_COMMAND_PACKET CommandPacket;
> > - NVM_EXPRESS_COMMAND Command;
> > - NVM_EXPRESS_RESPONSE Response;
> > - EFI_STATUS Status;
> > - NVME_ADMIN_DEIOSQ DelIoSq;
> > -
> > - ZeroMem (&CommandPacket,
> > sizeof(NVM_EXPRESS_PASS_THRU_COMMAND_PACKET));
> > - ZeroMem (&Command, sizeof(NVM_EXPRESS_COMMAND));
> > - ZeroMem (&Response, sizeof(NVM_EXPRESS_RESPONSE));
> > - ZeroMem (&DelIoSq, sizeof(NVME_ADMIN_DEIOSQ));
> > -
> > - CommandPacket.NvmeCmd = &Command;
> > - CommandPacket.NvmeResponse = &Response;
> > -
> > - Command.Cdw0.Opcode = NVME_ADMIN_DELIOSQ_OPC;
> > - Command.Cdw0.Cid = Nvme->Cid[NVME_ADMIN_QUEUE]++;
> > - CommandPacket.TransferBuffer = (UINT64)(UINTN)Nvme-
> > >SqBuffer[NVME_IO_QUEUE];
> > - CommandPacket.TransferLength = EFI_PAGE_SIZE;
> > - CommandPacket.CommandTimeout = NVME_GENERIC_TIMEOUT;
> > - CommandPacket.QueueId = NVME_ADMIN_QUEUE;
> > -
> > - DelIoSq.Qid = NVME_IO_QUEUE;
> > - CopyMem (&CommandPacket.NvmeCmd->Cdw10, &DelIoSq, sizeof
> > (NVME_ADMIN_DEIOSQ));
> > - CommandPacket.NvmeCmd->Flags = CDW10_VALID | CDW11_VALID;
> > -
> > - Status = NvmePassThru (
> > - Nvme,
> > - NVME_CONTROLLER_ID,
> > - 0,
> > - &CommandPacket
> > - );
> > - if (!EFI_ERROR (Status)) {
> > - Status = NvmeWaitAllComplete (Nvme, CommandPacket.QueueId);
> > - }
> > -
> > - return Status;
> > -}
> > -
> > -/**
> > - Allocate transfer-related Data struct which is used at Nvme.
> > -
> > - @param[in, out] Nvme The pointer to the NVME_CONTEXT Data
> > structure.
> > -
> > - @retval EFI_OUT_OF_RESOURCE No enough resource.
> > - @retval EFI_SUCCESS Successful to allocate resource.
> > -
> > -**/
> > -EFI_STATUS
> > -EFIAPI
> > -NvmeAllocateResource (
> > - IN OUT NVME_CONTEXT *Nvme
> > - )
> > -{
> > - EFI_STATUS Status;
> > - EFI_PHYSICAL_ADDRESS DeviceAddress;
> > - VOID *Base;
> > - VOID *Mapping;
> > -
> > - //
> > - // Allocate resources for DMA.
> > - //
> > - Status = IoMmuAllocateBuffer (
> > - EFI_SIZE_TO_PAGES (NVME_MEM_MAX_SIZE),
> > - &Base,
> > - &DeviceAddress,
> > - &Mapping
> > - );
> > - if (EFI_ERROR (Status)) {
> > - return EFI_OUT_OF_RESOURCES;
> > - }
> > - ASSERT (DeviceAddress == ((EFI_PHYSICAL_ADDRESS) (UINTN) Base));
> > - Nvme->BaseMemMapping = Mapping;
> > - Nvme->BaseMem = Base;
> > - ZeroMem (Nvme->BaseMem, EFI_PAGE_SIZE * EFI_SIZE_TO_PAGES
> > (NVME_MEM_MAX_SIZE));
> > -
> > - DEBUG ((
> > - DEBUG_INFO,
> > - "%a() NvmeContext 0x%x\n",
> > - __FUNCTION__,
> > - Nvme->BaseMem
> > - ));
> > -
> > - return EFI_SUCCESS;
> > -}
> > -
> > -/**
> > - Free allocated transfer-related Data struct which is used at NVMe.
> > -
> > - @param[in, out] Nvme The pointer to the NVME_CONTEXT Data
> > structure.
> > -
> > -**/
> > -VOID
> > -EFIAPI
> > -NvmeFreeResource (
> > - IN OUT NVME_CONTEXT *Nvme
> > - )
> > -{
> > - if (Nvme->BaseMem != NULL) {
> > - IoMmuFreeBuffer (
> > - EFI_SIZE_TO_PAGES (NVME_MEM_MAX_SIZE),
> > - Nvme->BaseMem,
> > - Nvme->BaseMemMapping
> > - );
> > - Nvme->BaseMem = NULL;
> > - }
> > -}
> > -
> > -/**
> > - Initialize the Nvm Express controller.
> > -
> > - @param[in] Nvme - The pointer to the NVME_CONTEXT Data
> > structure.
> > -
> > - @retval EFI_SUCCESS - The NVM Express Controller is initialized
> > successfully.
> > - @retval Others - A device error occurred while initializing the
> > controller.
> > -
> > -**/
> > -EFI_STATUS
> > -NvmeControllerInit (
> > - IN NVME_CONTEXT *Nvme
> > - )
> > -{
> > - EFI_STATUS Status;
> > - NVME_AQA Aqa;
> > - NVME_ASQ Asq;
> > - NVME_ACQ Acq;
> > - NVME_VER Ver;
> > -
> > - UINT32 MlBAR;
> > - UINT32 MuBAR;
> > -
> > - ///
> > - /// Update PCIE BAR0/1 for NVME device
> > - ///
> > - MlBAR = Nvme->Nbar;
> > - MuBAR = 0;
> > - PciWrite32 (Nvme->PciBase + 0x10, MlBAR); // MLBAR (BAR0)
> > - PciWrite32 (Nvme->PciBase + 0x14, MuBAR); // MUBAR (BAR1)
> > -
> > - ///
> > - /// Enable PCIE decode
> > - ///
> > - PciWrite8 (Nvme->PciBase + NVME_PCIE_PCICMD, 0x6);
> > -
> > - // Version
> > - NVME_GET_VER (Nvme, &Ver);
> > - if (!(Ver.Mjr == 0x0001) && (Ver.Mnr == 0x0000)) {
> > - DEBUG ((DEBUG_INFO, "\n!!!\n!!! NVME Version mismatch for the
> > implementation !!!\n!!!\n"));
> > - }
> > -
> > - ///
> > - /// Read the Controller Capabilities register and verify that the NVM
> > command set is supported
> > - ///
> > - Status = NVME_GET_CAP (Nvme, &Nvme->Cap);
> > - if (EFI_ERROR (Status)) {
> > - DEBUG ((DEBUG_ERROR, "NVME_GET_CAP fail, Status: %r\n", Status));
> > - goto Done;
> > - }
> > -
> > - if (Nvme->Cap.Css != 0x01) {
> > - DEBUG ((DEBUG_ERROR, "NvmeControllerInit fail: the controller doesn't
> > support NVMe command set\n"));
> > - Status = EFI_UNSUPPORTED;
> > - goto Done;
> > - }
> > -
> > - ///
> > - /// Currently the driver only supports 4k page Size.
> > - ///
> > - if ((Nvme->Cap.Mpsmin + 12) > EFI_PAGE_SHIFT) {
> > - DEBUG ((DEBUG_ERROR, "NvmeControllerInit fail: only supports 4k page
> > Size\n"));
> > - ASSERT (FALSE);
> > - Status = EFI_UNSUPPORTED;
> > - goto Done;
> > - }
> > -
> > - Nvme->Cid[0] = 0;
> > - Nvme->Cid[1] = 0;
> > -
> > - Nvme->Pt[0] = 0;
> > - Nvme->Pt[1] = 0;
> > -
> > - ZeroMem ((VOID *)(UINTN)(&(Nvme->SqTdbl[0])), sizeof
> (NVME_SQTDBL)
> > * NVME_MAX_IO_QUEUES);
> > - ZeroMem ((VOID *)(UINTN)(&(Nvme->CqHdbl[0])), sizeof
> > (NVME_CQHDBL) * NVME_MAX_IO_QUEUES);
> > -
> > - ZeroMem (Nvme->BaseMem, NVME_MEM_MAX_SIZE);
> > -
> > - Status = NvmeDisableController (Nvme);
> > - if (EFI_ERROR(Status)) {
> > - DEBUG ((DEBUG_ERROR, "NvmeDisableController fail, Status: %r\n",
> > Status));
> > - goto Done;
> > - }
> > -
> > - ///
> > - /// set number of entries admin submission & completion queues.
> > - ///
> > - Aqa.Asqs = NVME_ASQ_SIZE;
> > - Aqa.Rsvd1 = 0;
> > - Aqa.Acqs = NVME_ACQ_SIZE;
> > - Aqa.Rsvd2 = 0;
> > -
> > - ///
> > - /// Address of admin submission queue.
> > - ///
> > - Asq = (UINT64)(UINTN)(NVME_ASQ_BASE (Nvme) & ~0xFFF);
> > -
> > - ///
> > - /// Address of admin completion queue.
> > - ///
> > - Acq = (UINT64)(UINTN)(NVME_ACQ_BASE (Nvme) & ~0xFFF);
> > -
> > - ///
> > - /// Address of I/O submission & completion queue.
> > - ///
> > - Nvme->SqBuffer[0] = (NVME_SQ *)(UINTN)NVME_ASQ_BASE (Nvme);
> //
> > NVME_ADMIN_QUEUE
> > - Nvme->CqBuffer[0] = (NVME_CQ *)(UINTN)NVME_ACQ_BASE (Nvme);
> > // NVME_ADMIN_QUEUE
> > - Nvme->SqBuffer[1] = (NVME_SQ *)(UINTN)NVME_SQ_BASE (Nvme, 0);
> //
> > NVME_IO_QUEUE
> > - Nvme->CqBuffer[1] = (NVME_CQ *)(UINTN)NVME_CQ_BASE (Nvme, 0);
> > // NVME_IO_QUEUE
> > -
> > - DEBUG ((DEBUG_INFO, "Admin Submission Queue Size (Aqa.Asqs) =
> > [%08X]\n", Aqa.Asqs));
> > - DEBUG ((DEBUG_INFO, "Admin Completion Queue Size (Aqa.Acqs) =
> > [%08X]\n", Aqa.Acqs));
> > - DEBUG ((DEBUG_INFO, "Admin Submission Queue (SqBuffer[0]) =
> > [%08X]\n", Nvme->SqBuffer[0]));
> > - DEBUG ((DEBUG_INFO, "Admin Completion Queue (CqBuffer[0]) =
> > [%08X]\n", Nvme->CqBuffer[0]));
> > - DEBUG ((DEBUG_INFO, "I/O Submission Queue (SqBuffer[1]) =
> > [%08X]\n", Nvme->SqBuffer[1]));
> > - DEBUG ((DEBUG_INFO, "I/O Completion Queue (CqBuffer[1]) =
> > [%08X]\n", Nvme->CqBuffer[1]));
> > -
> > - ///
> > - /// Program admin queue attributes.
> > - ///
> > - Status = NVME_SET_AQA (Nvme, &Aqa);
> > - if (EFI_ERROR(Status)) {
> > - goto Done;
> > - }
> > -
> > - ///
> > - /// Program admin submission queue address.
> > - ///
> > - Status = NVME_SET_ASQ (Nvme, &Asq);
> > - if (EFI_ERROR(Status)) {
> > - goto Done;
> > - }
> > -
> > - ///
> > - /// Program admin completion queue address.
> > - ///
> > - Status = NVME_SET_ACQ (Nvme, &Acq);
> > - if (EFI_ERROR(Status)) {
> > - goto Done;
> > - }
> > -
> > - Status = NvmeEnableController (Nvme);
> > - if (EFI_ERROR(Status)) {
> > - goto Done;
> > - }
> > -
> > - ///
> > - /// Create one I/O completion queue.
> > - ///
> > - Status = NvmeCreateIoCompletionQueue (Nvme);
> > - if (EFI_ERROR(Status)) {
> > - goto Done;
> > - }
> > -
> > - ///
> > - /// Create one I/O Submission queue.
> > - ///
> > - Status = NvmeCreateIoSubmissionQueue (Nvme);
> > - if (EFI_ERROR(Status)) {
> > - goto Done;
> > - }
> > -
> > - ///
> > - /// Get current Identify Controller Data
> > - ///
> > - Nvme->ControllerData = (NVME_ADMIN_CONTROLLER_DATA *)(UINTN)
> > NVME_CONTROL_DATA_BASE (Nvme);
> > - Status = NvmeIdentifyController (Nvme, Nvme->ControllerData);
> > - if (EFI_ERROR(Status)) {
> > - goto Done;
> > - }
> > -
> > - ///
> > - /// Dump NvmExpress Identify Controller Data
> > - ///
> > - Nvme->ControllerData->Sn[19] = 0;
> > - Nvme->ControllerData->Mn[39] = 0;
> > - //NvmeDumpIdentifyController (Nvme->ControllerData);
> > -
> > - ///
> > - /// Get current Identify Namespace Data
> > - ///
> > - Nvme->NamespaceData = (NVME_ADMIN_NAMESPACE_DATA
> > *)NVME_NAMESPACE_DATA_BASE (Nvme);
> > - Status = NvmeIdentifyNamespace (Nvme, Nvme->Nsid, Nvme-
> > >NamespaceData);
> > - if (EFI_ERROR(Status)) {
> > - DEBUG ((DEBUG_ERROR, "NvmeIdentifyNamespace fail, Status = %r\n",
> > Status));
> > - goto Done;
> > - }
> > -
> > - ///
> > - /// Dump NvmExpress Identify Namespace Data
> > - ///
> > - if (Nvme->NamespaceData->Ncap == 0) {
> > - DEBUG ((DEBUG_ERROR, "Invalid Namespace, Ncap: %lx\n", Nvme-
> > >NamespaceData->Ncap));
> > - Status = EFI_DEVICE_ERROR;
> > - goto Done;
> > - }
> > -
> > - Nvme->BlockSize = NvmeGetBlockSize (Nvme);
> > - Nvme->LastBlock = NvmeGetLastLba (Nvme);
> > -
> > - Nvme->State = NvmeStatusInit;
> > -
> > - return EFI_SUCCESS;
> > -
> > -Done:
> > - return Status;
> > -}
> > -
> > -/**
> > - Un-initialize the Nvm Express controller.
> > -
> > - @param[in] Nvme - The pointer to the NVME_CONTEXT Data
> > structure.
> > -
> > - @retval EFI_SUCCESS - The NVM Express Controller is un-
> initialized
> > successfully.
> > - @retval Others - A device error occurred while un-initializing the
> > controller.
> > -
> > -**/
> > -EFI_STATUS
> > -NvmeControllerExit (
> > - IN NVME_CONTEXT *Nvme
> > - )
> > -{
> > - EFI_STATUS Status;
> > -
> > - Status = EFI_SUCCESS;
> > - if (Nvme->State == NvmeStatusInit || Nvme->State == NvmeStatusMax)
> {
> > - ///
> > - /// Destroy I/O Submission queue.
> > - ///
> > - Status = NvmeDestroyIoSubmissionQueue (Nvme);
> > - if (EFI_ERROR(Status)) {
> > - DEBUG ((DEBUG_ERROR, "NvmeDestroyIoSubmissionQueue fail,
> Status
> > = %r\n", Status));
> > - return Status;
> > - }
> > -
> > - ///
> > - /// Destroy I/O completion queue.
> > - ///
> > - Status = NvmeDestroyIoCompletionQueue (Nvme);
> > - if (EFI_ERROR(Status)) {
> > - DEBUG ((DEBUG_ERROR, "NvmeDestroyIoCompletionQueue fail,
> Status
> > = %r\n", Status));
> > - return Status;
> > - }
> > -
> > - Status = NvmeShutdownController (Nvme);
> > - if (EFI_ERROR(Status)) {
> > - DEBUG ((DEBUG_ERROR, "NvmeShutdownController fail, Status: %r\n",
> > Status));
> > - }
> > - }
> > -
> > - ///
> > - /// Disable PCIE decode
> > - ///
> > - PciWrite8 (Nvme->PciBase + NVME_PCIE_PCICMD, 0x0);
> > - PciWrite32 (Nvme->PciBase + 0x10, 0); // MLBAR (BAR0)
> > - PciWrite32 (Nvme->PciBase + 0x14, 0); // MUBAR (BAR1)
> > -
> > - Nvme->State = NvmeStatusUnknown;
> > - return Status;
> > -}
> > diff --git a/SecurityPkg/Tcg/Opal/OpalPassword/OpalPasswordPei.c
> > b/SecurityPkg/Tcg/Opal/OpalPassword/OpalPasswordPei.c
> > index edb47ca8bc..4d78a6a4ed 100644
> > --- a/SecurityPkg/Tcg/Opal/OpalPassword/OpalPasswordPei.c
> > +++ b/SecurityPkg/Tcg/Opal/OpalPassword/OpalPasswordPei.c
> > @@ -1,7 +1,7 @@
> > /** @file
> > Opal Password PEI driver which is used to unlock Opal Password for S3.
> >
> > -Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
> > +Copyright (c) 2016 - 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
> > @@ -14,249 +14,34 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF
> > ANY KIND, EITHER EXPRESS OR IMPLIED.
> >
> > #include "OpalPasswordPei.h"
> >
> > -EFI_GUID mOpalDeviceAtaGuid = OPAL_DEVICE_ATA_GUID;
> > -EFI_GUID mOpalDeviceNvmeGuid = OPAL_DEVICE_NVME_GUID;
> > -
> > -#define OPAL_PCIE_ROOTPORT_SAVESIZE (0x40)
> > -#define STORE_INVALID_ROOTPORT_INDEX ((UINT8) -1)
> > +EFI_GUID mOpalDeviceLockBoxGuid = OPAL_DEVICE_LOCKBOX_GUID;
> >
> > /**
> > - Get IOMMU PPI.
> > + Tell whether the input EDKII_PEI_STORAGE_SECURITY_CMD_PPI
> instance
> > has already
> > + been handled by the Opal PEI driver.
> >
> > - @return Pointer to IOMMU PPI.
> > + @param[in] Private Pointer to the Opal PEI driver private data.
> > + @param[in] SscInstance Pointer to the
> > EDKII_PEI_STORAGE_SECURITY_CMD_PPI.
> >
> > -**/
> > -EDKII_IOMMU_PPI *
> > -GetIoMmu (
> > - VOID
> > - )
> > -{
> > - EFI_STATUS Status;
> > - EDKII_IOMMU_PPI *IoMmu;
> > -
> > - IoMmu = NULL;
> > - Status = PeiServicesLocatePpi (
> > - &gEdkiiIoMmuPpiGuid,
> > - 0,
> > - NULL,
> > - (VOID **) &IoMmu
> > - );
> > - if (!EFI_ERROR (Status) && (IoMmu != NULL)) {
> > - return IoMmu;
> > - }
> > -
> > - return NULL;
> > -}
> > -
> > -/**
> > - Allocates pages that are suitable for an
> > OperationBusMasterCommonBuffer or
> > - OperationBusMasterCommonBuffer64 mapping.
> > -
> > - @param Pages The number of pages to allocate.
> > - @param HostAddress A pointer to store the base system memory
> > address of the
> > - allocated range.
> > - @param DeviceAddress The resulting map address for the bus
> master
> > PCI controller to use to
> > - access the hosts HostAddress.
> > - @param Mapping A resulting value to pass to Unmap().
> > -
> > - @retval EFI_SUCCESS The requested memory pages were allocated.
> > - @retval EFI_UNSUPPORTED Attributes is unsupported. The only legal
> > attribute bits are
> > - MEMORY_WRITE_COMBINE and MEMORY_CACHED.
> > - @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
> > - @retval EFI_OUT_OF_RESOURCES The memory pages could not be
> > allocated.
> > + @retval TRUE The PPI instance has already been handled.
> > + @retval FALSE The PPI instance has not been handled before.
> >
> > **/
> > -EFI_STATUS
> > -IoMmuAllocateBuffer (
> > - IN UINTN Pages,
> > - OUT VOID **HostAddress,
> > - OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,
> > - OUT VOID **Mapping
> > - )
> > -{
> > - EFI_STATUS Status;
> > - UINTN NumberOfBytes;
> > - EFI_PHYSICAL_ADDRESS HostPhyAddress;
> > - EDKII_IOMMU_PPI *IoMmu;
> > -
> > - *HostAddress = NULL;
> > - *DeviceAddress = 0;
> > - *Mapping = NULL;
> > -
> > - IoMmu = GetIoMmu ();
> > -
> > - if (IoMmu != NULL) {
> > - Status = IoMmu->AllocateBuffer (
> > - IoMmu,
> > - EfiBootServicesData,
> > - Pages,
> > - HostAddress,
> > - 0
> > - );
> > - if (EFI_ERROR (Status)) {
> > - return EFI_OUT_OF_RESOURCES;
> > - }
> > -
> > - NumberOfBytes = EFI_PAGES_TO_SIZE (Pages);
> > - Status = IoMmu->Map (
> > - IoMmu,
> > - EdkiiIoMmuOperationBusMasterCommonBuffer,
> > - *HostAddress,
> > - &NumberOfBytes,
> > - DeviceAddress,
> > - Mapping
> > - );
> > - if (EFI_ERROR (Status)) {
> > - IoMmu->FreeBuffer (IoMmu, Pages, *HostAddress);
> > - *HostAddress = NULL;
> > - return EFI_OUT_OF_RESOURCES;
> > - }
> > - Status = IoMmu->SetAttribute (
> > - IoMmu,
> > - *Mapping,
> > - EDKII_IOMMU_ACCESS_READ |
> EDKII_IOMMU_ACCESS_WRITE
> > - );
> > - if (EFI_ERROR (Status)) {
> > - IoMmu->Unmap (IoMmu, *Mapping);
> > - IoMmu->FreeBuffer (IoMmu, Pages, *HostAddress);
> > - *Mapping = NULL;
> > - *HostAddress = NULL;
> > - return Status;
> > - }
> > - } else {
> > - Status = PeiServicesAllocatePages (
> > - EfiBootServicesData,
> > - Pages,
> > - &HostPhyAddress
> > - );
> > - if (EFI_ERROR (Status)) {
> > - return EFI_OUT_OF_RESOURCES;
> > - }
> > - *HostAddress = (VOID *) (UINTN) HostPhyAddress;
> > - *DeviceAddress = HostPhyAddress;
> > - *Mapping = NULL;
> > - }
> > - return Status;
> > -}
> > -
> > -/**
> > - Frees memory that was allocated with AllocateBuffer().
> > -
> > - @param Pages The number of pages to free.
> > - @param HostAddress The base system memory address of the
> > allocated range.
> > - @param Mapping The mapping value returned from Map().
> > -
> > -**/
> > -VOID
> > -IoMmuFreeBuffer (
> > - IN UINTN Pages,
> > - IN VOID *HostAddress,
> > - IN VOID *Mapping
> > - )
> > -{
> > - EDKII_IOMMU_PPI *IoMmu;
> > -
> > - IoMmu = GetIoMmu ();
> > -
> > - if (IoMmu != NULL) {
> > - IoMmu->SetAttribute (IoMmu, Mapping, 0);
> > - IoMmu->Unmap (IoMmu, Mapping);
> > - IoMmu->FreeBuffer (IoMmu, Pages, HostAddress);
> > - } else {
> > - PeiServicesFreePages (
> > - (EFI_PHYSICAL_ADDRESS) (UINTN) HostAddress,
> > - Pages
> > - );
> > - }
> > -}
> > -
> > -/**
> > - Provide IO action support.
> > -
> > - @param[in] PeiDev The opal device need to perform trusted IO.
> > - @param[in] IoType OPAL_IO_TYPE indicating whether to perform
> a
> > Trusted Send or Trusted Receive.
> > - @param[in] SecurityProtocol Security Protocol
> > - @param[in] SpSpecific Security Protocol Specific
> > - @param[in] TransferLength Transfer Length of Buffer (in bytes) -
> > always a multiple of 512
> > - @param[in] Buffer Address of Data to transfer
> > -
> > - @retval EFI_SUCCESS Perform the IO action success.
> > - @retval Others Perform the IO action failed.
> > -
> > -**/
> > -EFI_STATUS
> > -PerformTrustedIo (
> > - OPAL_PEI_DEVICE *PeiDev,
> > - OPAL_IO_TYPE IoType,
> > - UINT8 SecurityProtocol,
> > - UINT16 SpSpecific,
> > - UINTN TransferLength,
> > - VOID *Buffer
> > +BOOLEAN
> > +IsSscInstanceHandled (
> > + IN OPAL_PEI_DRIVER_PRIVATE_DATA *Private,
> > + IN EDKII_PEI_STORAGE_SECURITY_CMD_PPI *SscInstance
> > )
> > {
> > - EFI_STATUS Status;
> > - UINTN BufferSizeBlocks;
> > - EFI_ATA_COMMAND_BLOCK AtaCommandBlock;
> > - OPAL_DEVICE_ATA *DevInfoAta;
> > - AHCI_CONTEXT *AhciContext;
> > - NVME_CONTEXT *NvmeContext;
> > -
> > - Status = EFI_DEVICE_ERROR;
> > - if (PeiDev->DeviceType == OPAL_DEVICE_TYPE_ATA) {
> > - DevInfoAta = (OPAL_DEVICE_ATA *) PeiDev->Device;
> > - AhciContext = (AHCI_CONTEXT *) PeiDev->Context;
> > -
> > - BufferSizeBlocks = TransferLength / 512;
> > -
> > - ZeroMem( &AtaCommandBlock, sizeof( EFI_ATA_COMMAND_BLOCK ) );
> > - AtaCommandBlock.AtaCommand = ( IoType == OpalSend ) ?
> > ATA_COMMAND_TRUSTED_SEND : ATA_COMMAND_TRUSTED_RECEIVE;
> > - AtaCommandBlock.AtaSectorCount = ( UINT8 )BufferSizeBlocks;
> > - AtaCommandBlock.AtaSectorNumber = ( UINT8 )( BufferSizeBlocks >>
> 8 );
> > - AtaCommandBlock.AtaFeatures = SecurityProtocol;
> > - AtaCommandBlock.AtaCylinderLow = ( UINT8 )( SpSpecific >> 8 );
> > - AtaCommandBlock.AtaCylinderHigh = ( UINT8 )( SpSpecific );
> > - AtaCommandBlock.AtaDeviceHead = ATA_DEVICE_LBA;
> > -
> > -
> > - ZeroMem( AhciContext->Buffer, HDD_PAYLOAD );
> > - ASSERT( TransferLength <= HDD_PAYLOAD );
> > -
> > - if (IoType == OpalSend) {
> > - CopyMem( AhciContext->Buffer, Buffer, TransferLength );
> > - }
> > + UINTN Index;
> >
> > - Status = AhciPioTransfer(
> > - AhciContext,
> > - (UINT8) DevInfoAta->Port,
> > - (UINT8) DevInfoAta->PortMultiplierPort,
> > - NULL,
> > - 0,
> > - ( IoType == OpalSend ) ? FALSE : TRUE, // i/o direction
> > - &AtaCommandBlock,
> > - NULL,
> > - AhciContext->Buffer,
> > - (UINT32)TransferLength,
> > - ATA_TIMEOUT
> > - );
> > -
> > - if (IoType == OpalRecv) {
> > - CopyMem( Buffer, AhciContext->Buffer, TransferLength );
> > + for (Index = 0; Index < Private->SscPpiInstanceNum; Index++) {
> > + if ((UINTN)SscInstance == Private->SscPpiInstances[Index]) {
> > + return TRUE;
> > }
> > - } else if (PeiDev->DeviceType == OPAL_DEVICE_TYPE_NVME) {
> > - NvmeContext = (NVME_CONTEXT *) PeiDev->Context;
> > - Status = NvmeSecuritySendReceive (
> > - NvmeContext,
> > - IoType == OpalSend,
> > - SecurityProtocol,
> > - SwapBytes16(SpSpecific),
> > - TransferLength,
> > - Buffer
> > - );
> > - } else {
> > - DEBUG((DEBUG_ERROR, "DeviceType(%x) not support.\n", PeiDev-
> > >DeviceType));
> > }
> >
> > - return Status;
> > + return FALSE;
> > }
> >
> > /**
> > @@ -351,14 +136,16 @@ SecurityReceiveData (
> > return EFI_DEVICE_ERROR;
> > }
> >
> > - return PerformTrustedIo (
> > - PeiDev,
> > - OpalRecv,
> > - SecurityProtocolId,
> > - SecurityProtocolSpecificData,
> > - PayloadBufferSize,
> > - PayloadBuffer
> > - );
> > + return PeiDev->SscPpi->ReceiveData (
> > + PeiDev->SscPpi,
> > + PeiDev->DeviceIndex,
> > + SSC_PPI_GENERIC_TIMEOUT,
> > + SecurityProtocolId,
> > + SecurityProtocolSpecificData,
> > + PayloadBufferSize,
> > + PayloadBuffer,
> > + PayloadTransferSize
> > + );
> > }
> >
> > /**
> > @@ -441,111 +228,15 @@ SecuritySendData (
> > return EFI_DEVICE_ERROR;
> > }
> >
> > - return PerformTrustedIo (
> > - PeiDev,
> > - OpalSend,
> > - SecurityProtocolId,
> > - SecurityProtocolSpecificData,
> > - PayloadBufferSize,
> > - PayloadBuffer
> > - );
> > -
> > -}
> > -
> > -/**
> > - Save/Restore RootPort configuration space.
> > -
> > - @param[in] DevInfoNvme Pointer to NVMe device info.
> > - @param[in] SaveAction TRUE: Save, FALSE: Restore
> > - @param[in,out] PcieConfBufferList Configuration space data buffer for
> > save/restore
> > -
> > - @return PCIE base address of this RootPort
> > -**/
> > -UINTN
> > -SaveRestoreRootportConfSpace (
> > - IN OPAL_DEVICE_NVME *DevInfoNvme,
> > - IN BOOLEAN SaveAction,
> > - IN OUT UINT8 **PcieConfBufferList
> > - )
> > -{
> > - UINTN RpBase;
> > - UINTN Length;
> > - OPAL_PCI_DEVICE *DevNode;
> > - UINT8 *StorePcieConfData;
> > - UINTN Index;
> > -
> > - Length = 0;
> > - Index = 0;
> > - RpBase = 0;
> > -
> > - while (sizeof (OPAL_DEVICE_NVME) + Length < DevInfoNvme->Length) {
> > - DevNode = (OPAL_PCI_DEVICE *)((UINT8*)DevInfoNvme-
> > >PciBridgeNode + Length);
> > - RpBase = PCI_LIB_ADDRESS (DevNode->Bus, DevNode->Device,
> > DevNode->Function, 0x0);
> > -
> > - if (PcieConfBufferList != NULL) {
> > - if (SaveAction) {
> > - StorePcieConfData = (UINT8 *) AllocateZeroPool
> > (OPAL_PCIE_ROOTPORT_SAVESIZE);
> > - ASSERT (StorePcieConfData != NULL);
> > - OpalPciRead (StorePcieConfData, RpBase,
> > OPAL_PCIE_ROOTPORT_SAVESIZE);
> > - PcieConfBufferList[Index] = StorePcieConfData;
> > - } else {
> > - // Skip PCIe Command & Status registers
> > - StorePcieConfData = PcieConfBufferList[Index];
> > - OpalPciWrite (RpBase, StorePcieConfData, 4);
> > - OpalPciWrite (RpBase + 8, StorePcieConfData + 8,
> > OPAL_PCIE_ROOTPORT_SAVESIZE - 8);
> > -
> > - FreePool (StorePcieConfData);
> > - }
> > - }
> > -
> > - Length += sizeof (OPAL_PCI_DEVICE);
> > - Index ++;
> > - }
> > -
> > - return RpBase;
> > -}
> > -
> > -/**
> > - Configure RootPort for downstream PCIe NAND devices.
> > -
> > - @param[in] RpBase - PCIe configuration space address of this
> > RootPort
> > - @param[in] BusNumber - Bus number
> > - @param[in] MemoryBase - Memory base address
> > - @param[in] MemoryLength - Memory size
> > -
> > -**/
> > -VOID
> > -ConfigureRootPortForPcieNand (
> > - IN UINTN RpBase,
> > - IN UINTN BusNumber,
> > - IN UINT32 MemoryBase,
> > - IN UINT32 MemoryLength
> > - )
> > -{
> > - UINT32 MemoryLimit;
> > -
> > - DEBUG ((DEBUG_INFO, "ConfigureRootPortForPcieNand,
> BusNumber: %x,
> > MemoryBase: %x, MemoryLength: %x\n",
> > - BusNumber, MemoryBase, MemoryLength));
> > -
> > - if (MemoryLength == 0) {
> > - MemoryLimit = MemoryBase;
> > - } else {
> > - MemoryLimit = MemoryBase + MemoryLength + 0xFFFFF; // 1M
> > - }
> > -
> > - ///
> > - /// Configue PCIE configuration space for RootPort
> > - ///
> > - PciWrite8 (RpBase + NVME_PCIE_BNUM + 1, (UINT8) BusNumber);
> > // Secondary Bus Number registers
> > - PciWrite8 (RpBase + NVME_PCIE_BNUM + 2, (UINT8) BusNumber);
> > // Subordinate Bus Number registers
> > - PciWrite8 (RpBase + NVME_PCIE_IOBL, 0xFF); // I/O Base
> > registers
> > - PciWrite8 (RpBase + NVME_PCIE_IOBL + 1, 0x00); // I/O Limit
> > registers
> > - PciWrite16 (RpBase + NVME_PCIE_MBL, (UINT16) RShiftU64
> > ((UINTN)MemoryBase, 16)); // Memory Base register
> > - PciWrite16 (RpBase + NVME_PCIE_MBL + 2, (UINT16) RShiftU64
> > ((UINTN)MemoryLimit, 16)); // Memory Limit register
> > - PciWrite16 (RpBase + NVME_PCIE_PMBL, 0xFFFF); //
> > Prefetchable Memory Base registers
> > - PciWrite16 (RpBase + NVME_PCIE_PMBL + 2, 0x0000); //
> > Prefetchable Memory Limit registers
> > - PciWrite32 (RpBase + NVME_PCIE_PMBU32, 0xFFFFFFFF); //
> > Prefetchable Memory Upper Base registers
> > - PciWrite32 (RpBase + NVME_PCIE_PMLU32, 0x00000000); //
> > Prefetchable Memory Upper Limit registers
> > + return PeiDev->SscPpi->SendData (
> > + PeiDev->SscPpi,
> > + PeiDev->DeviceIndex,
> > + SSC_PPI_GENERIC_TIMEOUT,
> > + SecurityProtocolId,
> > + SecurityProtocolSpecificData,
> > + PayloadBufferSize,
> > + PayloadBuffer
> > + );
> > }
> >
> > /**
> > @@ -651,272 +342,178 @@ UnlockOpalPassword (
> > }
> >
> > /**
> > - Unlock ATA OPAL password for S3.
> > + Unlock the OPAL NVM Express and ATA devices for S3.
> > +
> > + @param[in] Private Pointer to the Opal PEI driver private data.
> >
> > **/
> > VOID
> > -UnlockOpalPasswordAta (
> > - VOID
> > +UnlockOpalPasswordDevices (
> > + IN OPAL_PEI_DRIVER_PRIVATE_DATA *Private
> > )
> > {
> > - EFI_STATUS Status;
> > - UINT8 *DevInfo;
> > - OPAL_DEVICE_ATA TempDevInfoAta;
> > - OPAL_DEVICE_ATA *DevInfoAta;
> > - UINTN DevInfoLengthAta;
> > - UINT8 Bus;
> > - UINT8 Device;
> > - UINT8 Function;
> > - OPAL_PEI_DEVICE OpalDev;
> > - UINT8 BaseClassCode;
> > - UINT8 SubClassCode;
> > - UINT8 SataCmdSt;
> > - AHCI_CONTEXT AhciContext;
> > - UINT32 AhciBar;
> > -
> > - DEBUG ((DEBUG_INFO, "%a() - enter\n", __FUNCTION__));
> > + EFI_STATUS Status;
> > + UINT8 *DevInfoBuffer;
> > + UINT8 DummyData;
> > + OPAL_DEVICE_LOCKBOX_DATA *DevInfo;
> > + UINTN DevInfoLength;
> > + EFI_PEI_PPI_DESCRIPTOR *TempPpiDescriptor;
> > + UINTN SscPpiInstance;
> > + EDKII_PEI_STORAGE_SECURITY_CMD_PPI *SscPpi;
> > + EFI_DEVICE_PATH_PROTOCOL *SscDevicePath;
> > + UINTN SscDevicePathLength;
> > + UINTN SscDeviceNum;
> > + UINTN SscDeviceIndex;
> > + OPAL_PEI_DEVICE OpalDev;
> >
> > //
> > - // Get ATA OPAL device info from LockBox.
> > + // Get OPAL devices info from LockBox.
> > //
> > - DevInfo = (UINT8 *) &TempDevInfoAta;
> > - DevInfoLengthAta = sizeof (OPAL_DEVICE_ATA);
> > - Status = RestoreLockBox (&mOpalDeviceAtaGuid, DevInfo,
> > &DevInfoLengthAta);
> > + DevInfoBuffer = &DummyData;
> > + DevInfoLength = sizeof (DummyData);
> > + Status = RestoreLockBox (&mOpalDeviceLockBoxGuid, DevInfoBuffer,
> > &DevInfoLength);
> > if (Status == EFI_BUFFER_TOO_SMALL) {
> > - DevInfo = AllocatePages (EFI_SIZE_TO_PAGES (DevInfoLengthAta));
> > - if (DevInfo != NULL) {
> > - Status = RestoreLockBox (&mOpalDeviceAtaGuid, DevInfo,
> > &DevInfoLengthAta);
> > + DevInfoBuffer = AllocatePages (EFI_SIZE_TO_PAGES (DevInfoLength));
> > + if (DevInfoBuffer != NULL) {
> > + Status = RestoreLockBox (&mOpalDeviceLockBoxGuid, DevInfoBuffer,
> > &DevInfoLength);
> > }
> > }
> > - if (EFI_ERROR (Status) || (DevInfo == NULL)) {
> > + if (DevInfoBuffer == NULL || DevInfoBuffer == &DummyData) {
> > + return;
> > + } else if (EFI_ERROR (Status)) {
> > + FreePages (DevInfoBuffer, EFI_SIZE_TO_PAGES (DevInfoLength));
> > return;
> > }
> >
> > - for (DevInfoAta = (OPAL_DEVICE_ATA *) DevInfo;
> > - (UINTN) DevInfoAta < ((UINTN) DevInfo + DevInfoLengthAta);
> > - DevInfoAta = (OPAL_DEVICE_ATA *) ((UINTN) DevInfoAta +
> DevInfoAta-
> > >Length)) {
> > - Bus = DevInfoAta->Device.Bus;
> > - Device = DevInfoAta->Device.Device;
> > - Function = DevInfoAta->Device.Function;
> > -
> > - SataCmdSt = PciRead8 (PCI_LIB_ADDRESS (Bus, Device, Function,
> > PCI_COMMAND_OFFSET));
> > - PciWrite8 (PCI_LIB_ADDRESS (Bus, Device, Function,
> > PCI_COMMAND_OFFSET), 0x6);
> > -
> > - BaseClassCode = PciRead8 (PCI_LIB_ADDRESS (Bus, Device, Function,
> > 0x0B));
> > - SubClassCode = PciRead8 (PCI_LIB_ADDRESS (Bus, Device, Function,
> > 0x0A));
> > - if ((BaseClassCode != PCI_CLASS_MASS_STORAGE) ||
> > - ((SubClassCode != PCI_CLASS_MASS_STORAGE_SATADPA) &&
> > (SubClassCode != PCI_CLASS_MASS_STORAGE_RAID))) {
> > - DEBUG ((DEBUG_ERROR, "%a() ClassCode/SubClassCode are not
> > supported\n", __FUNCTION__));
> > - } else {
> > - AhciBar = PciRead32 (PCI_LIB_ADDRESS (Bus, Device, Function, 0x24));
> > - PciWrite32 (PCI_LIB_ADDRESS (Bus, Device, Function, 0x24),
> DevInfoAta-
> > >BarAddr);
> > -
> > - ZeroMem (&AhciContext, sizeof (AHCI_CONTEXT));
> > - AhciContext.AhciBar = DevInfoAta->BarAddr;
> > - AhciAllocateResource (&AhciContext);
> > - Status = AhciModeInitialize (&AhciContext, (UINT8)DevInfoAta->Port);
> > - ASSERT_EFI_ERROR (Status);
> > - if (EFI_ERROR (Status)) {
> > - DEBUG ((DEBUG_ERROR, "%a() AhciModeInitialize() error,
> Status: %r\n",
> > __FUNCTION__, Status));
> > - } else {
> > - OpalDev.Signature = OPAL_PEI_DEVICE_SIGNATURE;
> > - OpalDev.Sscp.ReceiveData = SecurityReceiveData;
> > - OpalDev.Sscp.SendData = SecuritySendData;
> > - OpalDev.DeviceType = OPAL_DEVICE_TYPE_ATA;
> > - OpalDev.Device = (OPAL_DEVICE_COMMON *) DevInfoAta;
> > - OpalDev.Context = &AhciContext;
> > -
> > - UnlockOpalPassword (&OpalDev);
> > - }
> > - AhciFreeResource (&AhciContext);
> > - PciWrite32 (PCI_LIB_ADDRESS (Bus, Device, Function, 0x24), AhciBar);
> > - }
> > - PciWrite8 (PCI_LIB_ADDRESS (Bus, Device, Function,
> > PCI_COMMAND_OFFSET), SataCmdSt);
> > - }
> > -
> > - ZeroMem (DevInfo, DevInfoLengthAta);
> > - if ((UINTN) DevInfo != (UINTN) &TempDevInfoAta) {
> > - FreePages (DevInfo, EFI_SIZE_TO_PAGES (DevInfoLengthAta));
> > - }
> > -
> > - DEBUG ((DEBUG_INFO, "%a() - exit\n", __FUNCTION__));
> > -}
> > -
> > -/**
> > - Unlock NVMe OPAL password for S3.
> > -
> > -**/
> > -VOID
> > -UnlockOpalPasswordNvme (
> > - VOID
> > - )
> > -{
> > - EFI_STATUS Status;
> > - UINT8 *DevInfo;
> > - OPAL_DEVICE_NVME TempDevInfoNvme;
> > - OPAL_DEVICE_NVME *DevInfoNvme;
> > - UINTN DevInfoLengthNvme;
> > - UINT8 Bus;
> > - UINT8 Device;
> > - UINT8 Function;
> > - OPAL_PEI_DEVICE OpalDev;
> > - UINT8 BaseClassCode;
> > - UINT8 SubClassCode;
> > - UINT8 ProgInt;
> > - UINT8 NvmeCmdSt;
> > - UINT8 *StorePcieConfDataList[16];
> > - UINTN RpBase;
> > - UINTN MemoryBase;
> > - UINTN MemoryLength;
> > - NVME_CONTEXT NvmeContext;
> > -
> > - DEBUG ((DEBUG_INFO, "%a() - enter\n", __FUNCTION__));
> > -
> > //
> > - // Get NVMe OPAL device info from LockBox.
> > + // Go through the Storage Security Command PPI instances within
> system.
> > //
> > - DevInfo = (UINT8 *) &TempDevInfoNvme;
> > - DevInfoLengthNvme = sizeof (OPAL_DEVICE_NVME);
> > - Status = RestoreLockBox (&mOpalDeviceNvmeGuid, DevInfo,
> > &DevInfoLengthNvme);
> > - if (Status == EFI_BUFFER_TOO_SMALL) {
> > - DevInfo = AllocatePages (EFI_SIZE_TO_PAGES (DevInfoLengthNvme));
> > - if (DevInfo != NULL) {
> > - Status = RestoreLockBox (&mOpalDeviceNvmeGuid, DevInfo,
> > &DevInfoLengthNvme);
> > + for (SscPpiInstance = 0;
> > + SscPpiInstance < OPAL_PEI_MAX_STORAGE_SECURITY_CMD_PPI;
> > + SscPpiInstance++) {
> > + Status = PeiServicesLocatePpi (
> > + &gEdkiiPeiStorageSecurityCommandPpiGuid,
> > + SscPpiInstance,
> > + &TempPpiDescriptor,
> > + (VOID **) &SscPpi
> > + );
> > + if (EFI_ERROR (Status)) {
> > + break;
> > }
> > - }
> > - if (EFI_ERROR (Status) || (DevInfo == NULL)) {
> > - return;
> > - }
> >
> > - for (DevInfoNvme = (OPAL_DEVICE_NVME *) DevInfo;
> > - (UINTN) DevInfoNvme < ((UINTN) DevInfo + DevInfoLengthNvme);
> > - DevInfoNvme = (OPAL_DEVICE_NVME *) ((UINTN) DevInfoNvme +
> > DevInfoNvme->Length)) {
> > - Bus = DevInfoNvme->Device.Bus;
> > - Device = DevInfoNvme->Device.Device;
> > - Function = DevInfoNvme->Device.Function;
> > -
> > - RpBase = 0;
> > - NvmeCmdSt = 0;
> > -
> > - ///
> > - /// Save original RootPort configuration space to heap
> > - ///
> > - RpBase = SaveRestoreRootportConfSpace (
> > - DevInfoNvme,
> > - TRUE, // save
> > - StorePcieConfDataList
> > - );
> > - MemoryBase = DevInfoNvme->BarAddr;
> > - MemoryLength = 0;
> > - ConfigureRootPortForPcieNand (RpBase, Bus, (UINT32) MemoryBase,
> > (UINT32) MemoryLength);
> > -
> > - ///
> > - /// Enable PCIE decode for RootPort
> > - ///
> > - NvmeCmdSt = PciRead8 (RpBase + NVME_PCIE_PCICMD);
> > - PciWrite8 (RpBase + NVME_PCIE_PCICMD, 0x6);
> > -
> > - BaseClassCode = PciRead8 (PCI_LIB_ADDRESS (Bus, Device, Function,
> > 0x0B));
> > - SubClassCode = PciRead8 (PCI_LIB_ADDRESS (Bus, Device, Function,
> > 0x0A));
> > - ProgInt = PciRead8 (PCI_LIB_ADDRESS (Bus, Device, Function, 0x09));
> > - if ((BaseClassCode != PCI_CLASS_MASS_STORAGE) ||
> > - (SubClassCode != PCI_CLASS_MASS_STORAGE_NVM) ||
> > - (ProgInt != PCI_IF_NVMHCI)) {
> > - DEBUG ((DEBUG_ERROR, "%a() ClassCode/SubClassCode/PI are not
> > supported\n", __FUNCTION__));
> > + //
> > + // Check whether this PPI instance has been handled previously.
> > + //
> > + if (IsSscInstanceHandled (Private, SscPpi)) {
> > + DEBUG ((
> > + DEBUG_INFO, "%a: Ssc PPI instance (0x%p) already handled.\n",
> > + __FUNCTION__, (UINTN)SscPpi
> > + ));
> > + continue;
> > } else {
> > - ZeroMem (&NvmeContext, sizeof (NVME_CONTEXT));
> > - NvmeContext.Nbar = DevInfoNvme->BarAddr;
> > - NvmeContext.PciBase = PCI_LIB_ADDRESS (Bus, Device, Function, 0x0);
> > - NvmeContext.NvmeInitWaitTime = 0;
> > - NvmeContext.Nsid = DevInfoNvme->NvmeNamespaceId;
> > - NvmeAllocateResource (&NvmeContext);
> > - Status = NvmeControllerInit (&NvmeContext);
> > -
> > - OpalDev.Signature = OPAL_PEI_DEVICE_SIGNATURE;
> > - OpalDev.Sscp.ReceiveData = SecurityReceiveData;
> > - OpalDev.Sscp.SendData = SecuritySendData;
> > - OpalDev.DeviceType = OPAL_DEVICE_TYPE_NVME;
> > - OpalDev.Device = (OPAL_DEVICE_COMMON *) DevInfoNvme;
> > - OpalDev.Context = &NvmeContext;
> > -
> > - UnlockOpalPassword (&OpalDev);
> > -
> > - Status = NvmeControllerExit (&NvmeContext);
> > - NvmeFreeResource (&NvmeContext);
> > + DEBUG ((
> > + DEBUG_INFO, "%a: New Ssc PPI instance (0x%p) found.\n",
> > + __FUNCTION__, (UINTN)SscPpi
> > + ));
> > + Private->SscPpiInstances[Private->SscPpiInstanceNum] =
> (UINTN)SscPpi;
> > + Private->SscPpiInstanceNum++;
> > }
> >
> > - ASSERT (RpBase != 0);
> > - PciWrite8 (RpBase + NVME_PCIE_PCICMD, 0);
> > - RpBase = SaveRestoreRootportConfSpace (
> > - DevInfoNvme,
> > - FALSE, // restore
> > - StorePcieConfDataList
> > - );
> > - PciWrite8 (RpBase + NVME_PCIE_PCICMD, NvmeCmdSt);
> > - }
> > + //
> > + // Go through all the devices managed by this PPI instance.
> > + //
> > + Status = SscPpi->GetNumberofDevices (SscPpi, &SscDeviceNum);
> > + if (EFI_ERROR (Status)) {
> > + continue;
> > + }
> > + for (SscDeviceIndex = 1; SscDeviceIndex <= SscDeviceNum;
> > SscDeviceIndex++) {
> > + Status = SscPpi->GetDevicePath (
> > + SscPpi,
> > + SscDeviceIndex,
> > + &SscDevicePathLength,
> > + &SscDevicePath
> > + );
> > + if (SscDevicePathLength <= sizeof (EFI_DEVICE_PATH_PROTOCOL)) {
> > + //
> > + // Device path validity check.
> > + //
> > + continue;
> > + }
> >
> > - ZeroMem (DevInfo, DevInfoLengthNvme);
> > - if ((UINTN) DevInfo != (UINTN) &TempDevInfoNvme) {
> > - FreePages (DevInfo, EFI_SIZE_TO_PAGES (DevInfoLengthNvme));
> > + //
> > + // Search the device in the restored LockBox.
> > + //
> > + for (DevInfo = (OPAL_DEVICE_LOCKBOX_DATA *) DevInfoBuffer;
> > + (UINTN) DevInfo < ((UINTN) DevInfoBuffer + DevInfoLength);
> > + DevInfo = (OPAL_DEVICE_LOCKBOX_DATA *) ((UINTN) DevInfo +
> > DevInfo->Length)) {
> > + //
> > + // Find the matching device.
> > + //
> > + if ((DevInfo->DevicePathLength >= SscDevicePathLength) &&
> > + (CompareMem (
> > + DevInfo->DevicePath,
> > + SscDevicePath,
> > + SscDevicePathLength - sizeof (EFI_DEVICE_PATH_PROTOCOL)) ==
> 0))
> > {
> > + OpalDev.Signature = OPAL_PEI_DEVICE_SIGNATURE;
> > + OpalDev.Sscp.ReceiveData = SecurityReceiveData;
> > + OpalDev.Sscp.SendData = SecuritySendData;
> > + OpalDev.Device = DevInfo;
> > + OpalDev.Context = NULL;
> > + OpalDev.SscPpi = SscPpi;
> > + OpalDev.DeviceIndex = SscDeviceIndex;
> > + UnlockOpalPassword (&OpalDev);
> > + break;
> > + }
> > + }
> > + }
> > }
> >
> > - DEBUG ((DEBUG_INFO, "%a() - exit\n", __FUNCTION__));
> > -}
> > -
> > -/**
> > - Unlock OPAL password for S3.
> > + ZeroMem (DevInfoBuffer, DevInfoLength);
> > + FreePages (DevInfoBuffer, EFI_SIZE_TO_PAGES (DevInfoLength));
> >
> > -**/
> > -VOID
> > -OpalPasswordS3 (
> > - VOID
> > - )
> > -{
> > - UnlockOpalPasswordAta ();
> > - UnlockOpalPasswordNvme ();
> > }
> >
> > /**
> > - Entry point of the notification callback function itself within the PEIM.
> > + One notified function at the installation of
> > EDKII_PEI_STORAGE_SECURITY_CMD_PPI.
> > It is to unlock OPAL password for S3.
> >
> > - @param PeiServices Indirect reference to the PEI Services Table.
> > - @param NotifyDescriptor Address of the notification descriptor data
> > structure.
> > - @param Ppi Address of the PPI that was installed.
> > + @param[in] PeiServices Indirect reference to the PEI Services Table.
> > + @param[in] NotifyDescriptor Address of the notification descriptor
> data
> > structure.
> > + @param[in] Ppi Address of the PPI that was installed.
> >
> > @return Status of the notification.
> > The status code returned from this function is ignored.
> > +
> > **/
> > EFI_STATUS
> > EFIAPI
> > -OpalPasswordEndOfPeiNotify(
> > - IN EFI_PEI_SERVICES **PeiServices,
> > - IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc,
> > - IN VOID *Ppi
> > +OpalPasswordStorageSecurityPpiNotify (
> > + IN EFI_PEI_SERVICES **PeiServices,
> > + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc,
> > + IN VOID *Ppi
> > )
> > {
> > - EFI_STATUS Status;
> > - EFI_BOOT_MODE BootMode;
> > + OPAL_PEI_DRIVER_PRIVATE_DATA *Private;
> >
> > - Status = PeiServicesGetBootMode (&BootMode);
> > - ASSERT_EFI_ERROR (Status);
> > - if (BootMode != BOOT_ON_S3_RESUME) {
> > - return EFI_UNSUPPORTED;
> > - }
> > + DEBUG ((DEBUG_INFO, "%a entered at S3 resume!\n",
> __FUNCTION__));
> >
> > - DEBUG ((DEBUG_INFO, "%a() - enter at S3 resume\n", __FUNCTION__));
> > + Private = OPAL_PEI_PRIVATE_DATA_FROM_THIS_NOTIFY (NotifyDesc);
> > + UnlockOpalPasswordDevices (Private);
> >
> > - OpalPasswordS3 ();
> > -
> > - DEBUG ((DEBUG_INFO, "%a() - exit at S3 resume\n", __FUNCTION__));
> > + DEBUG ((DEBUG_INFO, "%a exit at S3 resume!\n", __FUNCTION__));
> >
> > return EFI_SUCCESS;
> > }
> >
> > -EFI_PEI_NOTIFY_DESCRIPTOR mOpalPasswordEndOfPeiNotifyDesc = {
> > - (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK |
> > EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
> > - &gEfiEndOfPeiSignalPpiGuid,
> > - OpalPasswordEndOfPeiNotify
> > +OPAL_PEI_DRIVER_PRIVATE_DATA mOpalPeiDriverPrivateTemplate = {
> > + OPAL_PEI_DRIVER_SIGNATURE, // Signature
> > + { // SscPpiNotifyList
> > + (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK |
> > EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
> > + &gEdkiiPeiStorageSecurityCommandPpiGuid,
> > + OpalPasswordStorageSecurityPpiNotify
> > + },
> > + 0, // SscPpiInstanceNum
> > + {0} // SscPpiInstances
> > };
> >
> > /**
> > @@ -935,10 +532,32 @@ OpalPasswordPeiInit (
> > IN CONST EFI_PEI_SERVICES **PeiServices
> > )
> > {
> > - EFI_STATUS Status;
> > + EFI_STATUS Status;
> > + EFI_BOOT_MODE BootMode;
> > + OPAL_PEI_DRIVER_PRIVATE_DATA *Private;
> >
> > - Status = PeiServicesNotifyPpi (&mOpalPasswordEndOfPeiNotifyDesc);
> > + Status = PeiServicesGetBootMode (&BootMode);
> > + if ((EFI_ERROR (Status)) || (BootMode != BOOT_ON_S3_RESUME)) {
> > + return EFI_UNSUPPORTED;
> > + }
> > +
> > + DEBUG ((DEBUG_INFO, "%a: Enters in S3 path.\n", __FUNCTION__));
> > +
> > + Private = (OPAL_PEI_DRIVER_PRIVATE_DATA *)
> > + AllocateCopyPool (
> > + sizeof (OPAL_PEI_DRIVER_PRIVATE_DATA),
> > + &mOpalPeiDriverPrivateTemplate
> > + );
> > + if (Private == NULL) {
> > + DEBUG ((
> > + DEBUG_ERROR,
> > + "%a: Failed to allocate memory for
> > OPAL_PEI_DRIVER_PRIVATE_DATA.\n",
> > + __FUNCTION__
> > + ));
> > + return EFI_OUT_OF_RESOURCES;
> > + }
> > +
> > + Status = PeiServicesNotifyPpi (&Private->SscPpiNotifyList);
> > ASSERT_EFI_ERROR (Status);
> > return Status;
> > }
> > -
> > --
> > 2.12.0.windows.1
next prev parent reply other threads:[~2019-02-19 2:50 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
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 [this message]
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=B80AF82E9BFB8E4FBD8C89DA810C6A093C897E4D@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