From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=192.55.52.115; helo=mga14.intel.com; envelope-from=hao.a.wu@intel.com; receiver=edk2-devel@lists.01.org Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 8EF72208D613B for ; Mon, 18 Feb 2019 18:50:36 -0800 (PST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga007.jf.intel.com ([10.7.209.58]) by fmsmga103.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 18 Feb 2019 18:50:36 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.58,385,1544515200"; d="scan'208";a="115965285" Received: from fmsmsx105.amr.corp.intel.com ([10.18.124.203]) by orsmga007.jf.intel.com with ESMTP; 18 Feb 2019 18:50:34 -0800 Received: from fmsmsx113.amr.corp.intel.com (10.18.116.7) by FMSMSX105.amr.corp.intel.com (10.18.124.203) with Microsoft SMTP Server (TLS) id 14.3.408.0; Mon, 18 Feb 2019 18:50:30 -0800 Received: from shsmsx151.ccr.corp.intel.com (10.239.6.50) by FMSMSX113.amr.corp.intel.com (10.18.116.7) with Microsoft SMTP Server (TLS) id 14.3.408.0; Mon, 18 Feb 2019 18:50:28 -0800 Received: from shsmsx104.ccr.corp.intel.com ([169.254.5.102]) by SHSMSX151.ccr.corp.intel.com ([169.254.3.172]) with mapi id 14.03.0415.000; Tue, 19 Feb 2019 10:50:26 +0800 From: "Wu, Hao A" To: "Dong, Eric" , "edk2-devel@lists.01.org" CC: "Zhang, Chao B" , "Yao, Jiewen" , "Ni, Ray" Thread-Topic: [PATCH v5 13/13] SecurityPkg/OpalPassword: Remove HW init codes and consume SSC PPI Thread-Index: AQHUxPcXi/RzqU/G9E+FI5j5iYj5qqXklA8AgAHdKwA= Date: Tue, 19 Feb 2019 02:50:24 +0000 Message-ID: References: <20190215062338.19412-1-hao.a.wu@intel.com> <20190215062338.19412-14-hao.a.wu@intel.com> In-Reply-To: Accept-Language: zh-CN, en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [10.239.127.40] MIME-Version: 1.0 Subject: Re: [PATCH v5 13/13] SecurityPkg/OpalPassword: Remove HW init codes and consume SSC PPI X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 19 Feb 2019 02:50:36 -0000 Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable > -----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 >=20 > Hi Hao, >=20 > 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 >=20 > With above changes, Reviewed-by: Eric Dong >=20 > Thanks, > Eric >=20 > > -----Original Message----- > > From: Wu, Hao A > > Sent: Friday, February 15, 2019 2:24 PM > > To: edk2-devel@lists.01.org > > Cc: Wu, Hao A ; Zhang, Chao B > > ; Yao, Jiewen ; Ni, Ray > > ; Dong, Eric > > Subject: [PATCH v5 13/13] SecurityPkg/OpalPassword: Remove HW init > codes > > and consume SSC PPI > > > > REF:https://bugzilla.tianocore.org/show_bug.cgi?id=3D1409 > > > > For the current implementation of OpalPassword drivers, it has a featur= e > > to support devices being automatically unlocked in the S3 resume. For t= his > > 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 f= or > > 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 AT= A > > 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 fro= m > > the OpalPassword drivers. The hardware initialization will be covered b= y > > 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 managin= g > > 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 > > Cc: Jiewen Yao > > Cc: Ray Ni > > Cc: Eric Dong > > Contributed-under: TianoCore Contribution Agreement 1.1 > > Signed-off-by: Hao Wu > > --- > > 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. > > +# Copyright (c) 2016 - 2019, Intel Corporation. All rights reserved. > > # This program and the accompanying materials > > # are licensed and made available under the terms and conditions of th= e > BSD > > License > > # which accompanies this distribution. The full text of the license ma= y 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. > > +# Copyright (c) 2016 - 2019, Intel Corporation. All rights reserved. > > # This program and the accompanying materials > > # are licensed and made available under the terms and conditions of th= e > BSD > > License > > # which accompanies this distribution. The full text of the license ma= y 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.
> > -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 co= mmands 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 FI= S - Host > to > > Device > > -#define EFI_AHCI_FIS_REGISTER_H2D_LENGTH 20 > > -#define EFI_AHCI_FIS_REGISTER_D2H 0x34 //Register FI= S - > Device > > to Host > > -#define EFI_AHCI_FIS_REGISTER_D2H_LENGTH 20 > > -#define EFI_AHCI_FIS_DMA_ACTIVATE 0x39 //DMA Activat= e FIS - > > Device to Host > > -#define EFI_AHCI_FIS_DMA_ACTIVATE_LENGTH 4 > > -#define EFI_AHCI_FIS_DMA_SETUP 0x41 //DMA Setup F= IS - 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 Activa= te FIS - Bi- > > directional > > -#define EFI_AHCI_FIS_BIST_LENGTH 12 > > -#define EFI_AHCI_FIS_PIO_SETUP 0x5F //PIO Setup F= IS - 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 Lengt= h > > - 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 a= s > > -// 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 constructe= d > > FIS. > > - EFI_AHCI_ATAPI_COMMAND AtapiCmd; // 12 or 16 bytes ATAPI > cmd. > > - UINT8 Reserved[0x30]; > > - EFI_AHCI_COMMAND_PRDT PrdtTable; // The scatter/gather list f= or > > Data transfer > > -} EFI_AHCI_COMMAND_TABLE; > > - > > -// > > -// Received FIS structure > > -// > > -typedef struct { > > - UINT8 AhciDmaSetupFis[0x1C]; // Dma Setup Fis: offset 0x0= 0 > > - UINT8 AhciDmaSetupFisRsvd[0x04]; > > - UINT8 AhciPioSetupFis[0x14]; // Pio Setup Fis: offset 0x2= 0 > > - UINT8 AhciPioSetupFisRsvd[0x0C]; > > - UINT8 AhciD2HRegisterFis[0x14]; // D2H Register Fis: offset = 0x40 > > - UINT8 AhciD2HRegisterFisRsvd[0x04]; > > - UINT64 AhciSetDeviceBitsFis; // Set Device Bits Fix: offs= et 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 mo= de. > > - > > - @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 successfu= lly. > > - > > -**/ > > -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.
> > +Copyright (c) 2016 - 2019, Intel Corporation. All rights reserved.
> > This program and the accompanying materials > > are licensed and made available under the terms and conditions of the = BSD > > License > > which accompanies this distribution. The full text of the license may= be > > found at > > @@ -28,6 +28,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF > ANY > > KIND, EITHER EXPRESS OR IMPLIED. > > #include > > > > #include > > +#include > > > > #include > > #include > > @@ -42,7 +43,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF > ANY > > KIND, EITHER EXPRESS OR IMPLIED. > > #include > > #include > > #include > > -#include > > #include > > #include > > #include > > 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.
> > -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 functionalit= y 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 whic= h the > > Express HCI command packet will be sent. > > - A Value of 0 denotes the NVM Exp= ress controller, a > Value > > of all 0FFh in the namespace > > - ID specifies that the command pa= cket should be sent to > > all valid namespaces. > > - @param[in] NamespaceUuid - Is a 64 bit Namespace UUID to wh= ich > > the Express HCI command packet will be sent. > > - A Value of 0 denotes the NVM Exp= ress 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 w= as > 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 s= ent, 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 w= as 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 in= itialized > > successfully. > > - @retval Others - A device error occurred while in= itializing 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_CONT= EXT Data > > structure. > > - @param[in] SendCommand - The flag to indicate the com= mand > > 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 (i= n bytes) - > > always a multiple of 512 > > - @param[in,out] TransferBuffer - Address of Data to transfer > > - > > - @return EFI_SUCCESS - Successfully create io submissio= n 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.
> > -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 storag= e > > sub-class non-volatile memory. > > -#define PCI_IF_NVMHCI 0x02 // mass storag= e programming > > interface NVMHCI. > > - > > -#define NVME_ASQ_SIZE 1 // Numb= er of admin > > submission queue entries, which is 0-based > > -#define NVME_ACQ_SIZE 1 // Numb= er of admin > > completion queue entries, which is 0-based > > - > > -#define NVME_CSQ_SIZE 63 // Num= ber of I/O > > submission queue entries, which is 0-based > > -#define NVME_CCQ_SIZE 63 // Num= ber of I/O > > completion queue entries, which is 0-based > > - > > -#define NVME_MAX_IO_QUEUES 2 // Numb= er of I/O > > queues supported by the driver, 1 for AQ, 1 for CQ > > - > > -#define NVME_CSQ_DEPTH (NVME_CSQ_SIZ= E+1) > > -#define NVME_CCQ_DEPTH (NVME_CCQ_SIZ= E+1) > > -#define NVME_PRP_SIZE (4) // Pag= es 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 capabil= ities. > > -// > > -#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 - Submis= sion > > 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 Refere= nce Tag */ > > - // > > - // CDW 15 > > - // > > - UINT16 Elbat; /* Expected Logical Block Application Ta= g */ > > - UINT16 Elbatm; /* Expected Logical Block Application Ta= g 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 Refere= nce Tag */ > > - // > > - // CDW 15 > > - // > > - UINT16 Elbat; /* Expected Logical Block Application Ta= g */ > > - UINT16 Elbatm; /* Expected Logical Block Application Ta= g 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 Configu= ration > */ > > - UINT8 Apsta; /* Autonomous Power State Transition Att= ributes */ > > - 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 Configura= tion */ > > - 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 co= mmands */ > > - UINT16 Format : 1; /* supports format nvm command */ > > - UINT16 Firmware : 1; /* supports firmware activate/downlo= ad > > 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 block= s in > > formatted namespace) */ > > - UINT64 Ncap; /* Namespace Capacity (max number of log= ical > 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 capabiliti= es */ > > - UINT8 Dps; /* End-to-end Data Protection Type Setti= ngs */ > > - UINT8 Nmic; /* Namespace Multi-path I/O and Namespac= e > 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.
> > +Copyright (c) 2018 - 2019, Intel Corporation. All rights reserved.
> > This program and the accompanying materials > > are licensed and made available under the terms and conditions of the = BSD > > License > > which accompanies this distribution. The full text of the license may= be > > found at > > @@ -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 S= 3. > > > > -Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.
> > +Copyright (c) 2016 - 2019, Intel Corporation. All rights reserved.
> > This program and the accompanying materials > > are licensed and made available under the terms and conditions of the = BSD > > License > > which accompanies this distribution. The full text of the license may= be > > found at > > @@ -16,8 +16,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF > ANY > > KIND, EITHER EXPRESS OR IMPLIED. > > #define _OPAL_PASSWORD_PEI_H_ > > > > #include > > -#include > > -#include > > > > #include > > #include > > @@ -27,107 +25,63 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF > > ANY KIND, EITHER EXPRESS OR IMPLIED. > > #include > > #include > > #include > > -#include > > -#include > > #include > > #include > > #include > > +#include > > > > #include > > > > #include > > +#include > > > > #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 mem= ory > > 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 alloca= ted. > > - @retval EFI_UNSUPPORTED Attributes is unsupported. The only le= gal > > 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.
> > -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 =3D 0; > > - > > - Data =3D 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 =3D AhciReadReg (AhciBar, Offset); > > - > > - Data &=3D 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 =3D AhciReadReg (AhciBar, Offset); > > - > > - Data |=3D 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 =3D (UINT32) (DivU64x32(Timeout, 1000) + 1); > > - > > - do { > > - Value =3D AhciReadReg (AhciBar, Offset) & MaskValue; > > - > > - if (Value =3D=3D 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 Va= lue. > > - > > - @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, us= es > 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 =3D (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 =3D *(volatile UINT32 *) (UINTN) Address; > > - Value &=3D MaskValue; > > - > > - if (Value =3D=3D 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 waittin= g > 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 !=3D NULL) { > > - (*RetryTimes)--; > > - } > > - > > - Value =3D *(volatile UINT32 *) Address; > > - Value &=3D MaskValue; > > - > > - if (Value =3D=3D TestValue) { > > - return EFI_SUCCESS; > > - } > > - > > - if ((RetryTimes !=3D NULL) && (*RetryTimes =3D=3D 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 =3D 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 =3D 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 =3D 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 =3D EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + > > EFI_AHCI_PORT_CMD; > > - Data =3D AhciReadReg (AhciBar, Offset); > > - > > - // > > - // Before disabling Fis receive, the DMA engine of the port should N= OT > be > > in running status. > > - // > > - if ((Data & (EFI_AHCI_PORT_CMD_ST | EFI_AHCI_PORT_CMD_CR)) !=3D 0) { > > - return EFI_UNSUPPORTED; > > - } > > - > > - // > > - // Check if the Fis receive DMA engine for the port is running. > > - // > > - if ((Data & EFI_AHCI_PORT_CMD_FR) !=3D 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 th= e > transfer. > > - @param AtapiCommand The atapi command will be used for t= he > > transfer. > > - @param AtapiCommandLength The Length of the atapi command. > > - @param CommandSlotNumber The command slot will be used for th= e > > transfer. > > - @param DataPhysicalAddr The pointer to the Data Buffer pci b= us > > 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 =3D &AhciContext->AhciRegisters; > > - AhciBar =3D AhciContext->AhciBar; > > - > > - // > > - // Filling the PRDT > > - // > > - PrdtNumber =3D 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 4= MB > > Data block. > > - // It also limits that the maximum amount of the PRDT entry in the > > command table > > - // is 65535. > > - // > > - ASSERT (PrdtNumber <=3D 1); > > - > > - Data64.Uint64 =3D (UINTN) (AhciRegisters->AhciRFis); > > - > > - BaseAddr =3D Data64.Uint64; > > - > > - ZeroMem ((VOID *)((UINTN) BaseAddr), sizeof > (EFI_AHCI_RECEIVED_FIS)); > > - > > - ZeroMem (AhciRegisters->AhciCommandTable, sizeof > > (EFI_AHCI_COMMAND_TABLE)); > > - > > - CommandFis->AhciCFisPmNum =3D PortMultiplier; > > - > > - CopyMem (&AhciRegisters->AhciCommandTable->CommandFis, > > CommandFis, sizeof (EFI_AHCI_COMMAND_FIS)); > > - > > - Offset =3D EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + > > EFI_AHCI_PORT_CMD; > > - if (AtapiCommand !=3D NULL) { > > - CopyMem ( > > - &AhciRegisters->AhciCommandTable->AtapiCmd, > > - AtapiCommand, > > - AtapiCommandLength > > - ); > > - > > - CommandList->AhciCmdA =3D 1; > > - CommandList->AhciCmdP =3D 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 =3D (UINTN) DataLength; > > - MemAddr =3D (UINTN) DataPhysicalAddr; > > - CommandList->AhciCmdPrdtl =3D (UINT32)PrdtNumber; > > - > > - AhciRegisters->AhciCommandTable->PrdtTable.AhciPrdtDbc =3D > > (UINT32)RemainedData - 1; > > - > > - Data64.Uint64 =3D (UINT64)MemAddr; > > - AhciRegisters->AhciCommandTable->PrdtTable.AhciPrdtDba =3D > > Data64.Uint32.Lower32; > > - AhciRegisters->AhciCommandTable->PrdtTable.AhciPrdtDbau =3D > > Data64.Uint32.Upper32; > > - > > - // > > - // Set the last PRDT to Interrupt On Complete > > - // > > - AhciRegisters->AhciCommandTable->PrdtTable.AhciPrdtIoc =3D 1; > > - > > - CopyMem ( > > - (VOID *) ((UINTN) AhciRegisters->AhciCmdList + (UINTN) > > CommandSlotNumber * sizeof (EFI_AHCI_COMMAND_LIST)), > > - CommandList, > > - sizeof (EFI_AHCI_COMMAND_LIST) > > - ); > > - > > - Data64.Uint64 =3D (UINT64)(UINTN) AhciRegisters->AhciCommandTable; > > - AhciRegisters->AhciCmdList[CommandSlotNumber].AhciCmdCtba =3D > > Data64.Uint32.Lower32; > > - AhciRegisters->AhciCmdList[CommandSlotNumber].AhciCmdCtbau =3D > > Data64.Uint32.Upper32; > > - AhciRegisters->AhciCmdList[CommandSlotNumber].AhciCmdPmp =3D > > 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 =3D EFI_AHCI_FIS_REGISTER_H2D; > > - // > > - // Indicator it's a command > > - // > > - CmdFis->AhciCFisCmdInd =3D 0x1; > > - CmdFis->AhciCFisCmd =3D AtaCommandBlock->AtaCommand; > > - > > - CmdFis->AhciCFisFeature =3D AtaCommandBlock->AtaFeatures; > > - CmdFis->AhciCFisFeatureExp =3D AtaCommandBlock->AtaFeaturesExp; > > - > > - CmdFis->AhciCFisSecNum =3D AtaCommandBlock->AtaSectorNumber; > > - CmdFis->AhciCFisSecNumExp =3D AtaCommandBlock- > > >AtaSectorNumberExp; > > - > > - CmdFis->AhciCFisClyLow =3D AtaCommandBlock->AtaCylinderLow; > > - CmdFis->AhciCFisClyLowExp =3D AtaCommandBlock->AtaCylinderLowExp; > > - > > - CmdFis->AhciCFisClyHigh =3D AtaCommandBlock->AtaCylinderHigh; > > - CmdFis->AhciCFisClyHighExp =3D AtaCommandBlock->AtaCylinderHighExp; > > - > > - CmdFis->AhciCFisSecCount =3D AtaCommandBlock->AtaSectorCount; > > - CmdFis->AhciCFisSecCountExp =3D AtaCommandBlock- > >AtaSectorCountExp; > > - > > - CmdFis->AhciCFisDevHead =3D (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 successfu= lly. > > - > > -**/ > > -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 =3D &AhciContext->AhciRegisters; > > - AhciBar =3D AhciContext->AhciBar; > > - > > - Offset =3D EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH > + > > EFI_AHCI_PORT_FB; > > - OldRfisLo =3D AhciReadReg (AhciBar, Offset); > > - Offset =3D EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH > + > > EFI_AHCI_PORT_FBU; > > - OldRfisHi =3D AhciReadReg (AhciBar, Offset); > > - Offset =3D EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH > + > > EFI_AHCI_PORT_FB; > > - AhciWriteReg (AhciBar, Offset, (UINT32)(UINTN)AhciRegisters->AhciRFi= s); > > - Offset =3D 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 po= rt > > - // > > - Offset =3D EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + > > EFI_AHCI_PORT_CLB; > > - OldCmdListLo =3D AhciReadReg (AhciBar, Offset); > > - Offset =3D EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + > > EFI_AHCI_PORT_CLBU; > > - OldCmdListHi =3D AhciReadReg (AhciBar, Offset); > > - Offset =3D EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + > > EFI_AHCI_PORT_CLB; > > - AhciWriteReg (AhciBar, Offset, (UINT32)(UINTN)AhciRegisters- > > >AhciCmdList); > > - Offset =3D 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 =3D EFI_AHCI_FIS_REGISTER_H2D_LENGTH / 4; > > - CmdList.AhciCmdW =3D Read ? 0 : 1; > > - > > - AhciBuildCommand ( > > - AhciContext, > > - Port, > > - PortMultiplier, > > - &CFis, > > - &CmdList, > > - AtapiCommand, > > - AtapiCommandLength, > > - 0, > > - MemoryAddr, > > - DataCount > > - ); > > - > > - Status =3D AhciStartCommand ( > > - AhciBar, > > - Port, > > - 0, > > - Timeout > > - ); > > - if (EFI_ERROR (Status)) { > > - goto Exit; > > - } > > - > > - // > > - // Checking the status and wait the driver sending Data > > - // > > - FisBaseAddr =3D (UINT32)(UINTN)AhciRegisters->AhciRFis; > > - if (Read && (AtapiCommand =3D=3D 0)) { > > - // > > - // Wait device sends the PIO setup fis before Data transfer > > - // > > - Status =3D EFI_TIMEOUT; > > - Delay =3D (UINT32) (DivU64x32 (Timeout, 1000) + 1); > > - do { > > - Offset =3D FisBaseAddr + EFI_AHCI_PIO_FIS_OFFSET; > > - > > - Status =3D AhciCheckMemSet (Offset, EFI_AHCI_FIS_TYPE_MASK, > > EFI_AHCI_FIS_PIO_SETUP, 0); > > - if (!EFI_ERROR (Status)) { > > - Offset =3D EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDT= H > + > > EFI_AHCI_PORT_TFD; > > - PortTfd =3D AhciReadReg (AhciBar, (UINT32) Offset); > > - // > > - // PxTFD will be updated if there is a D2H or SetupFIS receive= d. > > - // 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) !=3D 0) { > > - Status =3D EFI_DEVICE_ERROR; > > - break; > > - } > > - > > - PrdCount =3D *(volatile UINT32 *) (&(AhciRegisters- > > >AhciCmdList[0].AhciCmdPrdbc)); > > - if (PrdCount =3D=3D DataCount) { > > - break; > > - } > > - } > > - > > - Offset =3D FisBaseAddr + EFI_AHCI_D2H_FIS_OFFSET; > > - Status =3D AhciCheckMemSet (Offset, EFI_AHCI_FIS_TYPE_MASK, > > EFI_AHCI_FIS_REGISTER_D2H, 0); > > - if (!EFI_ERROR (Status)) { > > - Status =3D EFI_DEVICE_ERROR; > > - break; > > - } > > - > > - // > > - // Stall for 100 microseconds. > > - // > > - MicroSecondDelay(100); > > - > > - Delay--; > > - } while (Delay > 0); > > - } else { > > - // > > - // Wait for D2H Fis is received > > - // > > - Offset =3D FisBaseAddr + EFI_AHCI_D2H_FIS_OFFSET; > > - Status =3D AhciWaitMemSet ( > > - Offset, > > - EFI_AHCI_FIS_TYPE_MASK, > > - EFI_AHCI_FIS_REGISTER_D2H, > > - Timeout > > - ); > > - > > - if (EFI_ERROR (Status)) { > > - goto Exit; > > - } > > - > > - Offset =3D EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + > > EFI_AHCI_PORT_TFD; > > - PortTfd =3D AhciReadReg (AhciBar, (UINT32) Offset); > > - if ((PortTfd & EFI_AHCI_PORT_TFD_ERR) !=3D 0) { > > - Status =3D EFI_DEVICE_ERROR; > > - } > > - } > > - > > -Exit: > > - AhciStopCommand ( > > - AhciBar, > > - Port, > > - Timeout > > - ); > > - > > - AhciDisableFisReceive ( > > - AhciBar, > > - Port, > > - Timeout > > - ); > > - > > - Offset =3D EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH > + > > EFI_AHCI_PORT_FB; > > - AhciWriteReg (AhciBar, Offset, OldRfisLo); > > - Offset =3D EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH > + > > EFI_AHCI_PORT_FBU; > > - AhciWriteReg (AhciBar, Offset, OldRfisHi); > > - > > - Offset =3D EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH > + > > EFI_AHCI_PORT_CLB; > > - AhciWriteReg (AhciBar, Offset, OldCmdListLo); > > - Offset =3D 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 =3D EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + > > EFI_AHCI_PORT_CMD; > > - Data =3D AhciReadReg (AhciBar, Offset); > > - > > - if ((Data & (EFI_AHCI_PORT_CMD_ST | EFI_AHCI_PORT_CMD_CR)) =3D=3D 0= ) > { > > - return EFI_SUCCESS; > > - } > > - > > - if ((Data & EFI_AHCI_PORT_CMD_ST) !=3D 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 =3D AhciReadReg(AhciBar, EFI_AHCI_CAPABILITY_OFFSET); > > - > > - CmdSlotBit =3D (UINT32) (1 << CommandSlot); > > - > > - AhciClearPortStatus ( > > - AhciBar, > > - Port > > - ); > > - > > - Status =3D AhciEnableFisReceive ( > > - AhciBar, > > - Port, > > - Timeout > > - ); > > - > > - if (EFI_ERROR (Status)) { > > - return Status; > > - } > > - > > - Offset =3D EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + > > EFI_AHCI_PORT_CMD; > > - PortStatus =3D AhciReadReg (AhciBar, Offset); > > - > > - StartCmd =3D 0; > > - if ((PortStatus & EFI_AHCI_PORT_CMD_ALPE) !=3D 0) { > > - StartCmd =3D AhciReadReg (AhciBar, Offset); > > - StartCmd &=3D ~EFI_AHCI_PORT_CMD_ICC_MASK; > > - StartCmd |=3D EFI_AHCI_PORT_CMD_ACTIVE; > > - } > > - > > - Offset =3D EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + > > EFI_AHCI_PORT_TFD; > > - PortTfd =3D AhciReadReg (AhciBar, Offset); > > - > > - if ((PortTfd & (EFI_AHCI_PORT_TFD_BSY | EFI_AHCI_PORT_TFD_DRQ)) !=3D > 0) > > { > > - if ((Capability & BIT24) !=3D 0) { > > - Offset =3D 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 =3D 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 =3D EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + > > EFI_AHCI_PORT_SACT; > > - AhciAndReg (AhciBar, Offset, 0); > > - AhciOrReg (AhciBar, Offset, CmdSlotBit); > > - > > - Offset =3D 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 =3D AhciReadReg (AhciBar, EFI_AHCI_CAPABILITY_OFFSET); > > - > > - // > > - // Enable AE before accessing any AHCI registers if Supports AHCI Mo= de > > Only is not set > > - // > > - if ((Capability & EFI_AHCI_CAP_SAM) =3D=3D 0) { > > - AhciOrReg (AhciBar, EFI_AHCI_GHC_OFFSET, EFI_AHCI_GHC_ENABLE); > > - } > > - > > - AhciOrReg (AhciBar, EFI_AHCI_GHC_OFFSET, EFI_AHCI_GHC_RESET); > > - > > - Delay =3D (UINT32) (DivU64x32(Timeout, 1000) + 1); > > - > > - do { > > - Value =3D AhciReadReg(AhciBar, EFI_AHCI_GHC_OFFSET); > > - if ((Value & EFI_AHCI_GHC_RESET) =3D=3D 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 =3D &AhciContext->AhciRegisters; > > - > > - // > > - // Allocate resources required by AHCI host controller. > > - // > > - Status =3D IoMmuAllocateBuffer ( > > - EFI_SIZE_TO_PAGES (sizeof (EFI_AHCI_RECEIVED_FIS)), > > - &Base, > > - &DeviceAddress, > > - &Mapping > > - ); > > - if (EFI_ERROR (Status)) { > > - return EFI_OUT_OF_RESOURCES; > > - } > > - ASSERT (DeviceAddress =3D=3D ((EFI_PHYSICAL_ADDRESS) (UINTN) Base)); > > - AhciRegisters->AhciRFisMapping =3D Mapping; > > - AhciRegisters->AhciRFis =3D Base; > > - ZeroMem (AhciRegisters->AhciRFis, EFI_PAGE_SIZE * > EFI_SIZE_TO_PAGES > > (sizeof (EFI_AHCI_RECEIVED_FIS))); > > - > > - Status =3D 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 =3D NULL; > > - return EFI_OUT_OF_RESOURCES; > > - } > > - ASSERT (DeviceAddress =3D=3D ((EFI_PHYSICAL_ADDRESS) (UINTN) Base)); > > - AhciRegisters->AhciCmdListMapping =3D Mapping; > > - AhciRegisters->AhciCmdList =3D Base; > > - ZeroMem (AhciRegisters->AhciCmdList, EFI_PAGE_SIZE * > > EFI_SIZE_TO_PAGES (sizeof (EFI_AHCI_COMMAND_LIST))); > > - > > - Status =3D 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 =3D NULL; > > - IoMmuFreeBuffer ( > > - EFI_SIZE_TO_PAGES (sizeof (EFI_AHCI_RECEIVED_FIS)), > > - AhciRegisters->AhciRFis, > > - AhciRegisters->AhciRFisMapping > > - ); > > - AhciRegisters->AhciRFis =3D NULL; > > - return EFI_OUT_OF_RESOURCES; > > - } > > - ASSERT (DeviceAddress =3D=3D ((EFI_PHYSICAL_ADDRESS) (UINTN) Base)); > > - AhciRegisters->AhciCommandTableMapping =3D Mapping; > > - AhciRegisters->AhciCommandTable =3D Base; > > - ZeroMem (AhciRegisters->AhciCommandTable, EFI_PAGE_SIZE * > > EFI_SIZE_TO_PAGES (sizeof (EFI_AHCI_COMMAND_TABLE))); > > - > > - // > > - // Allocate resources for data transfer. > > - // > > - Status =3D 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 =3D NULL; > > - IoMmuFreeBuffer ( > > - EFI_SIZE_TO_PAGES (sizeof (EFI_AHCI_COMMAND_LIST)), > > - AhciRegisters->AhciCmdList, > > - AhciRegisters->AhciCmdListMapping > > - ); > > - AhciRegisters->AhciCmdList =3D NULL; > > - IoMmuFreeBuffer ( > > - EFI_SIZE_TO_PAGES (sizeof (EFI_AHCI_RECEIVED_FIS)), > > - AhciRegisters->AhciRFis, > > - AhciRegisters->AhciRFisMapping > > - ); > > - AhciRegisters->AhciRFis =3D NULL; > > - return EFI_OUT_OF_RESOURCES; > > - } > > - ASSERT (DeviceAddress =3D=3D ((EFI_PHYSICAL_ADDRESS) (UINTN) Base)); > > - AhciContext->BufferMapping =3D Mapping; > > - AhciContext->Buffer =3D 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 mo= de. > > - > > - @param[in, out] AhciContext The pointer to the AHCI_CONTEXT. > > - > > -**/ > > -VOID > > -EFIAPI > > -AhciFreeResource ( > > - IN OUT AHCI_CONTEXT *AhciContext > > - ) > > -{ > > - EFI_AHCI_REGISTERS *AhciRegisters; > > - > > - AhciRegisters =3D &AhciContext->AhciRegisters; > > - > > - if (AhciContext->Buffer !=3D NULL) { > > - IoMmuFreeBuffer ( > > - EFI_SIZE_TO_PAGES (HDD_PAYLOAD), > > - AhciContext->Buffer, > > - AhciContext->BufferMapping > > - ); > > - AhciContext->Buffer =3D NULL; > > - } > > - > > - if (AhciRegisters->AhciCommandTable !=3D NULL) { > > - IoMmuFreeBuffer ( > > - EFI_SIZE_TO_PAGES (sizeof (EFI_AHCI_COMMAND_TABLE)), > > - AhciRegisters->AhciCommandTable, > > - AhciRegisters->AhciCommandTableMapping > > - ); > > - AhciRegisters->AhciCommandTable =3D NULL; > > - } > > - > > - if (AhciRegisters->AhciCmdList !=3D NULL) { > > - IoMmuFreeBuffer ( > > - EFI_SIZE_TO_PAGES (sizeof (EFI_AHCI_COMMAND_LIST)), > > - AhciRegisters->AhciCmdList, > > - AhciRegisters->AhciCmdListMapping > > - ); > > - AhciRegisters->AhciCmdList =3D NULL; > > - } > > - > > - if (AhciRegisters->AhciRFis !=3D NULL) { > > - IoMmuFreeBuffer ( > > - EFI_SIZE_TO_PAGES (sizeof (EFI_AHCI_RECEIVED_FIS)), > > - AhciRegisters->AhciRFis, > > - AhciRegisters->AhciRFisMapping > > - ); > > - AhciRegisters->AhciRFis =3D 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 =3D &AhciContext->AhciRegisters; > > - AhciBar =3D AhciContext->AhciBar; > > - > > - Status =3D AhciReset (AhciBar, ATA_TIMEOUT); > > - if (EFI_ERROR (Status)) { > > - return Status; > > - } > > - > > - // > > - // Collect AHCI controller information > > - // > > - Capability =3D AhciReadReg (AhciBar, EFI_AHCI_CAPABILITY_OFFSET); > > - > > - // > > - // Enable AE before accessing any AHCI registers if Supports AHCI Mo= de > > Only is not set > > - // > > - if ((Capability & EFI_AHCI_CAP_SAM) =3D=3D 0) { > > - AhciOrReg (AhciBar, EFI_AHCI_GHC_OFFSET, EFI_AHCI_GHC_ENABLE); > > - } > > - > > - Offset =3D EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + > > EFI_AHCI_PORT_FB; > > - AhciWriteReg (AhciBar, Offset, (UINT32)(UINTN)AhciRegisters->AhciRFi= s); > > - > > - // > > - // Single task envrionment, we only use one command table for all po= rt > > - // > > - Offset =3D EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + > > EFI_AHCI_PORT_CLB; > > - AhciWriteReg (AhciBar, Offset, (UINT32)(UINTN)AhciRegisters- > > >AhciCmdList); > > - > > - Offset =3D EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + > > EFI_AHCI_PORT_CMD; > > - Data =3D AhciReadReg (AhciBar, Offset); > > - if ((Data & EFI_AHCI_PORT_CMD_CPD) !=3D 0) { > > - AhciOrReg (AhciBar, Offset, EFI_AHCI_PORT_CMD_POD); > > - } > > - > > - if ((Capability & BIT27) !=3D 0) { > > - AhciOrReg (AhciBar, Offset, EFI_AHCI_PORT_CMD_SUD); > > - } > > - > > - // > > - // Disable aggressive power management. > > - // > > - Offset =3D 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 =3D EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + > > EFI_AHCI_PORT_IE; > > - AhciAndReg (AhciBar, Offset, 0); > > - > > - Status =3D 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 =3D 16 * 1000; > > - do { > > - Offset =3D EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + > > EFI_AHCI_PORT_SERR; > > - if (AhciReadReg(AhciBar, Offset) !=3D 0) { > > - AhciWriteReg (AhciBar, Offset, AhciReadReg(AhciBar, Offset)); > > - } > > - Offset =3D EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + > > EFI_AHCI_PORT_TFD; > > - > > - Data =3D AhciReadReg (AhciBar, Offset) & EFI_AHCI_PORT_TFD_MASK; > > - if (Data =3D=3D 0) { > > - break; > > - } > > - > > - MicroSecondDelay (1000); > > - PhyDetectDelay--; > > - } while (PhyDetectDelay > 0); > > - > > - if (PhyDetectDelay =3D=3D 0) { > > - return EFI_NOT_FOUND; > > - } > > - > > - Offset =3D EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + > > EFI_AHCI_PORT_SIG; > > - Status =3D 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 =3D OPAL_DEVICE_ATA_GUID; > > -EFI_GUID mOpalDeviceNvmeGuid =3D OPAL_DEVICE_NVME_GUID; > > +EFI_GUID mOpalDeviceLockBoxGuid =3D OPAL_DEVICE_LOCKBOX_GUID; > > > > BOOLEAN mOpalEndOfDxe =3D FALSE; > > OPAL_REQUEST_VARIABLE *mOpalRequestVariable =3D NULL; > > UINTN mOpalRequestVariableSize =3D 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 foll= owing > > registers. > > -// > > -const OPAL_HC_PCI_REGISTER_SAVE mSataHcRegisterSaveTemplate[] =3D { > > - {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 !=3D NULL); > > ASSERT (DevInfoLength !=3D NULL); > > @@ -266,30 +233,15 @@ ExtractDeviceInfoFromDevicePath ( > > // Get device type. > > // > > while (!IsDevicePathEnd (TmpDevPath)) { > > - if (TmpDevPath->Type =3D=3D MESSAGING_DEVICE_PATH && TmpDevPath- > > >SubType =3D=3D MSG_SATA_DP) { > > - // > > - // SATA > > - // > > - if (DevInfo !=3D NULL) { > > - SataDevPath =3D (SATA_DEVICE_PATH *) TmpDevPath; > > - DevInfoAta =3D (OPAL_DEVICE_ATA *) DevInfo; > > - DevInfoAta->Port =3D SataDevPath->HBAPortNumber; > > - DevInfoAta->PortMultiplierPort =3D SataDevPath- > > >PortMultiplierPortNumber; > > - } > > - DeviceType =3D OPAL_DEVICE_TYPE_ATA; > > - *DevInfoLength =3D sizeof (OPAL_DEVICE_ATA); > > - break; > > - } else if (TmpDevPath->Type =3D=3D MESSAGING_DEVICE_PATH && > > TmpDevPath->SubType =3D=3D MSG_NVME_NAMESPACE_DP) { > > - // > > - // NVMe > > - // > > + if ((TmpDevPath->Type =3D=3D MESSAGING_DEVICE_PATH) && > > + (TmpDevPath->SubType =3D=3D MSG_SATA_DP || TmpDevPath- > >SubType > > =3D=3D MSG_NVME_NAMESPACE_DP)) { > > if (DevInfo !=3D NULL) { > > - NvmeDevPath =3D (NVME_NAMESPACE_DEVICE_PATH *) TmpDevPath; > > - DevInfoNvme =3D (OPAL_DEVICE_NVME *) DevInfo; > > - DevInfoNvme->NvmeNamespaceId =3D NvmeDevPath->NamespaceId; > > + DevInfo->DevicePathLength =3D (UINT32) GetDevicePathSize > > (DevicePath); > > + CopyMem (DevInfo->DevicePath, DevicePath, DevInfo- > > >DevicePathLength); > > } > > - DeviceType =3D OPAL_DEVICE_TYPE_NVME; > > - *DevInfoLength =3D sizeof (OPAL_DEVICE_NVME); > > + > > + DeviceType =3D (TmpDevPath->SubType =3D=3D MSG_SATA_DP) ? > > OPAL_DEVICE_TYPE_ATA : OPAL_DEVICE_TYPE_NVME; > > + *DevInfoLength =3D sizeof (OPAL_DEVICE_LOCKBOX_DATA) + (UINT32) > > GetDevicePathSize (DevicePath); > > break; > > } > > TmpDevPath =3D NextDevicePathNode (TmpDevPath); > > @@ -304,8 +256,8 @@ ExtractDeviceInfoFromDevicePath ( > > while (!IsDevicePathEnd (TmpDevPath2)) { > > if (TmpDevPath->Type =3D=3D HARDWARE_DEVICE_PATH && TmpDevPath- > > >SubType =3D=3D HW_PCI_DP) { > > PciDevPath =3D (PCI_DEVICE_PATH *) TmpDevPath; > > - if ((TmpDevPath2->Type =3D=3D MESSAGING_DEVICE_PATH && > > TmpDevPath2->SubType =3D=3D MSG_NVME_NAMESPACE_DP)|| > > - (TmpDevPath2->Type =3D=3D MESSAGING_DEVICE_PATH && > > TmpDevPath2->SubType =3D=3D MSG_SATA_DP)) { > > + if ((TmpDevPath2->Type =3D=3D MESSAGING_DEVICE_PATH) && > > + (TmpDevPath2->SubType =3D=3D MSG_SATA_DP || TmpDevPath2- > > >SubType =3D=3D MSG_NVME_NAMESPACE_DP)) { > > if (DevInfo !=3D NULL) { > > PciDevice =3D &DevInfo->Device; > > PciDevice->Segment =3D 0; > > @@ -314,14 +266,6 @@ ExtractDeviceInfoFromDevicePath ( > > PciDevice->Function =3D PciDevPath->Function; > > } > > } else { > > - if (DevInfo !=3D NULL) { > > - PciDevice =3D (OPAL_PCI_DEVICE *) ((UINTN) DevInfo + > *DevInfoLength); > > - PciDevice->Segment =3D 0; > > - PciDevice->Bus =3D BusNum; > > - PciDevice->Device =3D PciDevPath->Device; > > - PciDevice->Function =3D PciDevPath->Function; > > - } > > - *DevInfoLength +=3D sizeof (OPAL_PCI_DEVICE); > > if (TmpDevPath2->Type =3D=3D HARDWARE_DEVICE_PATH && > > TmpDevPath2->SubType =3D=3D HW_PCI_DP) { > > BusNum =3D PciRead8 (PCI_LIB_ADDRESS (BusNum, PciDevPath- > >Device, > > PciDevPath->Function, > PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET)); > > } > > @@ -333,251 +277,159 @@ ExtractDeviceInfoFromDevicePath ( > > } > > > > ASSERT (DeviceType !=3D 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 =3D 0; > > - > > - Bus =3D DevInfo->Device.Bus; > > - Device =3D DevInfo->Device.Device; > > - Function =3D DevInfo->Device.Function; > > - > > - HcRegisterSaveListPtr =3D (OPAL_HC_PCI_REGISTER_SAVE *) > > mSataHcRegisterSaveTemplate; > > - Count =3D sizeof (mSataHcRegisterSaveTemplate) / sizeof > > (OPAL_HC_PCI_REGISTER_SAVE); > > - > > - for (Index =3D 0; Index < Count; Index++) { > > - Offset =3D HcRegisterSaveListPtr[Index].Address; > > - Width =3D HcRegisterSaveListPtr[Index].Width; > > - > > - switch (Width) { > > - case S3BootScriptWidthUint8: > > - Data =3D (UINT32)PciRead8 > > (PCI_LIB_ADDRESS(Bus,Device,Function,Offset)); > > - break; > > - case S3BootScriptWidthUint16: > > - Data =3D (UINT32)PciRead16 > > (PCI_LIB_ADDRESS(Bus,Device,Function,Offset)); > > - break; > > - case S3BootScriptWidthUint32: > > - Data =3D PciRead32 (PCI_LIB_ADDRESS(Bus,Device,Function,Offset= )); > > - break; > > - default: > > - ASSERT (FALSE); > > - break; > > - } > > - > > - Address =3D S3_BOOT_SCRIPT_LIB_PCI_ADDRESS (Bus, Device, Function, > > Offset); > > - Status =3D 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 =3D 0; > > + TotalDevInfoLength =3D 0; > > TmpDev =3D mOpalDriver.DeviceList; > > while (TmpDev !=3D NULL) { > > - DeviceType =3D ExtractDeviceInfoFromDevicePath ( > > - TmpDev->OpalDisk.OpalDevicePath, > > - &DevInfoLength, > > - NULL > > - ); > > - if (DeviceType =3D=3D OPAL_DEVICE_TYPE_ATA) { > > - DevInfoLengthAta +=3D DevInfoLength; > > - } > > - > > + ExtractDeviceInfoFromDevicePath ( > > + TmpDev->OpalDisk.OpalDevicePath, > > + &DevInfoLength, > > + NULL > > + ); > > + TotalDevInfoLength +=3D DevInfoLength; > > TmpDev =3D TmpDev->Next; > > } > > > > - if (DevInfoLengthAta =3D=3D 0) { > > + if (TotalDevInfoLength =3D=3D 0) { > > return; > > } > > > > - DevInfoAta =3D AllocateZeroPool (DevInfoLengthAta); > > - ASSERT (DevInfoAta !=3D NULL); > > - if (DevInfoAta =3D=3D NULL) { > > - return; > > - } > > - > > - TempDevInfoAta =3D DevInfoAta; > > - TmpDev =3D mOpalDriver.DeviceList; > > - while (TmpDev !=3D NULL) { > > - DeviceType =3D ExtractDeviceInfoFromDevicePath ( > > - TmpDev->OpalDisk.OpalDevicePath, > > - &DevInfoLength, > > - NULL > > - ); > > - if (DeviceType =3D=3D OPAL_DEVICE_TYPE_ATA) { > > - ExtractDeviceInfoFromDevicePath ( > > - TmpDev->OpalDisk.OpalDevicePath, > > - &DevInfoLength, > > - (OPAL_DEVICE_COMMON *) TempDevInfoAta > > - ); > > - TempDevInfoAta->Length =3D DevInfoLength; > > - TempDevInfoAta->OpalBaseComId =3D TmpDev- > >OpalDisk.OpalBaseComId; > > - TempDevInfoAta->BarAddr =3D BarAddr; > > - CopyMem ( > > - TempDevInfoAta->Password, > > - TmpDev->OpalDisk.Password, > > - TmpDev->OpalDisk.PasswordLength > > - ); > > - TempDevInfoAta->PasswordLength =3D TmpDev- > > >OpalDisk.PasswordLength; > > - OpalDeviceAtaSaveBootScript (TempDevInfoAta); > > - TempDevInfoAta =3D (OPAL_DEVICE_ATA *) ((UINTN) TempDevInfoAta + > > DevInfoLength); > > - } > > - > > - TmpDev =3D TmpDev->Next; > > - } > > - > > - Status =3D SaveLockBox ( > > - &mOpalDeviceAtaGuid, > > - DevInfoAta, > > - DevInfoLengthAta > > + S3InitDevicesLength =3D sizeof (DummyData); > > + Status =3D RestoreLockBox ( > > + &gS3StorageDeviceInitListGuid, > > + &DummyData, > > + &S3InitDevicesLength > > ); > > - ASSERT_EFI_ERROR (Status); > > - > > - Status =3D 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 =3D 0; > > - TmpDev =3D mOpalDriver.DeviceList; > > - while (TmpDev !=3D NULL) { > > - DeviceType =3D ExtractDeviceInfoFromDevicePath ( > > - TmpDev->OpalDisk.OpalDevicePath, > > - &DevInfoLength, > > - NULL > > - ); > > - if (DeviceType =3D=3D OPAL_DEVICE_TYPE_NVME) { > > - DevInfoLengthNvme +=3D DevInfoLength; > > + ASSERT ((Status =3D=3D EFI_NOT_FOUND) || (Status =3D=3D > > EFI_BUFFER_TOO_SMALL)); > > + if (Status =3D=3D EFI_NOT_FOUND) { > > + S3InitDevices =3D NULL; > > + S3InitDevicesExist =3D FALSE; > > + } else if (Status =3D=3D EFI_BUFFER_TOO_SMALL) { > > + S3InitDevices =3D AllocatePool (S3InitDevicesLength); > > + ASSERT (S3InitDevices !=3D NULL); > > + if (S3InitDevices =3D=3D NULL) { > > + return; > > } > > > > - TmpDev =3D TmpDev->Next; > > - } > > - > > - if (DevInfoLengthNvme =3D=3D 0) { > > + Status =3D RestoreLockBox ( > > + &gS3StorageDeviceInitListGuid, > > + S3InitDevices, > > + &S3InitDevicesLength > > + ); > > + ASSERT_EFI_ERROR (Status); > > + S3InitDevicesExist =3D TRUE; > > + } else { > > return; > > } > > > > - DevInfoNvme =3D AllocateZeroPool (DevInfoLengthNvme); > > - ASSERT (DevInfoNvme !=3D NULL); > > - if (DevInfoNvme =3D=3D NULL) { > > + DevInfo =3D AllocateZeroPool (TotalDevInfoLength); > > + ASSERT (DevInfo !=3D NULL); > > + if (DevInfo =3D=3D NULL) { > > return; > > } > > > > - TempDevInfoNvme =3D DevInfoNvme; > > - TmpDev =3D mOpalDriver.DeviceList; > > + TempDevInfo =3D DevInfo; > > + TmpDev =3D mOpalDriver.DeviceList; > > while (TmpDev !=3D NULL) { > > - DeviceType =3D ExtractDeviceInfoFromDevicePath ( > > - TmpDev->OpalDisk.OpalDevicePath, > > - &DevInfoLength, > > - NULL > > - ); > > - if (DeviceType =3D=3D OPAL_DEVICE_TYPE_NVME) { > > - ExtractDeviceInfoFromDevicePath ( > > - TmpDev->OpalDisk.OpalDevicePath, > > - &DevInfoLength, > > - (OPAL_DEVICE_COMMON *) TempDevInfoNvme > > - ); > > - TempDevInfoNvme->Length =3D DevInfoLength; > > - TempDevInfoNvme->OpalBaseComId =3D TmpDev- > > >OpalDisk.OpalBaseComId; > > - TempDevInfoNvme->BarAddr =3D BarAddr; > > - CopyMem ( > > - TempDevInfoNvme->Password, > > - TmpDev->OpalDisk.Password, > > - TmpDev->OpalDisk.PasswordLength > > - ); > > - TempDevInfoNvme->PasswordLength =3D TmpDev- > > >OpalDisk.PasswordLength; > > - TempDevInfoNvme =3D (OPAL_DEVICE_NVME *) ((UINTN) > > TempDevInfoNvme + DevInfoLength); > > + ExtractDeviceInfoFromDevicePath ( > > + TmpDev->OpalDisk.OpalDevicePath, > > + &DevInfoLength, > > + TempDevInfo > > + ); > > + TempDevInfo->Length =3D DevInfoLength; > > + TempDevInfo->OpalBaseComId =3D TmpDev->OpalDisk.OpalBaseComId; > > + CopyMem ( > > + TempDevInfo->Password, > > + TmpDev->OpalDisk.Password, > > + TmpDev->OpalDisk.PasswordLength > > + ); > > + TempDevInfo->PasswordLength =3D TmpDev->OpalDisk.PasswordLength; > > + > > + S3InitDevicesBak =3D S3InitDevices; > > + S3InitDevices =3D AppendDevicePathInstance ( > > + S3InitDevicesBak, > > + TmpDev->OpalDisk.OpalDevicePath > > + ); > > + if (S3InitDevicesBak !=3D NULL) { > > + ZeroMem (S3InitDevicesBak, GetDevicePathSize (S3InitDevicesBak))= ; > > + FreePool (S3InitDevicesBak); > > + } > > + ASSERT (S3InitDevices !=3D NULL); > > + if (S3InitDevices =3D=3D NULL) { > > + return; > > } > > > > + TempDevInfo =3D (OPAL_DEVICE_LOCKBOX_DATA *) ((UINTN) > > TempDevInfo + DevInfoLength); > > TmpDev =3D TmpDev->Next; > > } > > > > Status =3D SaveLockBox ( > > - &mOpalDeviceNvmeGuid, > > - DevInfoNvme, > > - DevInfoLengthNvme > > + &mOpalDeviceLockBoxGuid, > > + DevInfo, > > + TotalDevInfoLength > > ); > > ASSERT_EFI_ERROR (Status); > > > > Status =3D SetLockBoxAttributes ( > > - &mOpalDeviceNvmeGuid, > > + &mOpalDeviceLockBoxGuid, > > LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY > > ); > > ASSERT_EFI_ERROR (Status); > > > > - ZeroMem (DevInfoNvme, DevInfoLengthNvme); > > - FreePool (DevInfoNvme); > > + S3InitDevicesLength =3D GetDevicePathSize (S3InitDevices); > > + if (S3InitDevicesExist) { > > + Status =3D UpdateLockBox ( > > + &gS3StorageDeviceInitListGuid, > > + 0, > > + S3InitDevices, > > + S3InitDevicesLength > > + ); > > + ASSERT_EFI_ERROR (Status); > > + } else { > > + Status =3D SaveLockBox ( > > + &gS3StorageDeviceInitListGuid, > > + S3InitDevices, > > + S3InitDevicesLength > > + ); > > + ASSERT_EFI_ERROR (Status); > > + > > + Status =3D 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 =3D 0x10000; > > - Address =3D 0xFFFFFFFF; > > - Status =3D gDS->AllocateMemorySpace ( > > - EfiGcdAllocateMaxAddressSearchBottomUp, > > - EfiGcdMemoryTypeMemoryMappedIo, > > - 16, // 2^16: 64K Alignme= nt > > - 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.
> > -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) =3D MmioRead32 (MmioAddr); > > - break; > > - > > - case 8: > > - *((UINT64 *)MemBuffer) =3D MmioRead64 (MmioAddr); > > - break; > > - > > - case 2: > > - *((UINT16 *)MemBuffer) =3D MmioRead16 (MmioAddr); > > - break; > > - > > - case 1: > > - *((UINT8 *)MemBuffer) =3D MmioRead8 (MmioAddr); > > - break; > > - > > - default: > > - Ptr =3D (UINT8 *)MemBuffer; > > - for (Offset =3D 0; Offset < Size; Offset +=3D 1) { > > - Data =3D MmioRead8 (MmioAddr + Offset); > > - Ptr[Offset] =3D 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 =3D (UINT8 *)MemBuffer; > > - for (Offset =3D 0; Offset < Size; Offset +=3D 1) { > > - Data =3D 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) =3D PciRead32 (MmioAddr); > > - break; > > - > > - case 2: > > - *((UINT16 *)MemBuffer) =3D PciRead16 (MmioAddr); > > - break; > > - > > - case 1: > > - *((UINT8 *)MemBuffer) =3D PciRead8 (MmioAddr); > > - break; > > - > > - default: > > - Ptr =3D (UINT8 *)MemBuffer; > > - for (Offset =3D 0; Offset < Size; Offset +=3D 1) { > > - Data =3D PciRead8 (MmioAddr + Offset); > > - Ptr[Offset] =3D 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 =3D (UINT8 *)MemBuffer; > > - for (Offset =3D 0; Offset < Size; Offset +=3D 1) { > > - Data =3D 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] =3D 1; /* Controller Data */ > > - PageSizeList[1] =3D 1; /* Identify Data */ > > - PageSizeList[2] =3D 1; /* ASQ */ > > - PageSizeList[3] =3D 1; /* ACQ */ > > - PageSizeList[4] =3D 1; /* SQs */ > > - PageSizeList[5] =3D 1; /* CQs */ > > - PageSizeList[6] =3D NVME_PRP_SIZE * NVME_CSQ_DEPTH; /* PRPs */ > > - PageSizeList[7] =3D 1; /* Security Commands */ > > - > > - if (BaseMemIndex > MAX_BASEMEM_COUNT) { > > - ASSERT (FALSE); > > - return 0; > > - } > > - > > - Pages =3D 0; > > - for (Index =3D 0; Index < BaseMemIndex; Index++) { > > - Pages +=3D 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 o= r not > > - > > - @return EFI_SUCCESS - Successfully to wait specific st= atus. > > - @return others - Fail to wait for specific contro= ller 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 =3D=3D 0) { > > - Timeout =3D 1; > > - } else { > > - Timeout =3D Nvme->Cap.To; > > - } > > - > > - Status =3D EFI_SUCCESS; > > - for(Index =3D (Timeout * 500); Index !=3D 0; --Index) { > > - MicroSecondDelay (1000); > > - > > - // > > - // Check if the controller is initialized > > - // > > - Status =3D NVME_GET_CSTS (Nvme, &Csts); > > - if (EFI_ERROR(Status)) { > > - DEBUG ((DEBUG_ERROR, "NVME_GET_CSTS fail, Status =3D %r\n", > Status)); > > - return Status; > > - } > > - > > - if ((BOOLEAN) Csts.Rdy =3D=3D WaitReady) { > > - break; > > - } > > - } > > - > > - if (Index =3D=3D 0) { > > - Status =3D 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 control= ler. > > - @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 =3D NVME_GET_CSTS (Nvme, &Csts); > > - > > - /// > > - /// Read Controller Configuration Register. > > - /// > > - Status =3D NVME_GET_CC (Nvme, &Cc); > > - if (EFI_ERROR(Status)) { > > - DEBUG ((DEBUG_ERROR, "NVME_GET_CC fail, Status =3D %r\n", Status))= ; > > - goto Done; > > - } > > - > > - if (Cc.En =3D=3D 1) { > > - Cc.En =3D 0; > > - /// > > - /// Disable the controller. > > - /// > > - Status =3D NVME_SET_CC (Nvme, &Cc); > > - if (EFI_ERROR(Status)) { > > - DEBUG ((DEBUG_ERROR, "NVME_SET_CC fail, Status =3D %r\n", Status= )); > > - goto Done; > > - } > > - } > > - > > - Status =3D NvmeWaitController (Nvme, FALSE); > > - if (EFI_ERROR(Status)) { > > - DEBUG ((DEBUG_ERROR, "NvmeWaitController fail, Status =3D %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 controll= er. > > - @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 =3D 1; > > - Cc.Iosqes =3D 6; > > - Cc.Iocqes =3D 4; > > - Status =3D NVME_SET_CC (Nvme, &Cc); > > - if (EFI_ERROR(Status)) { > > - DEBUG ((DEBUG_ERROR, "NVME_SET_CC fail, Status =3D %r\n", Status))= ; > > - goto Done; > > - } > > - > > - Status =3D NvmeWaitController (Nvme, TRUE); > > - if (EFI_ERROR(Status)) { > > - DEBUG ((DEBUG_ERROR, "NvmeWaitController fail, Status =3D %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 contro= ller. > > - @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 =3D NVME_GET_CC (Nvme, &Cc); > > - if (EFI_ERROR(Status)) { > > - DEBUG ((DEBUG_ERROR, "NVME_GET_CC fail, Status =3D %r\n", Status))= ; > > - return Status; > > - } > > - > > - Cc.Shn =3D 1; // Normal shutdown > > - > > - Status =3D NVME_SET_CC (Nvme, &Cc); > > - if (EFI_ERROR(Status)) { > > - DEBUG ((DEBUG_ERROR, "NVME_SET_CC fail, Status =3D %r\n", Status))= ; > > - return Status; > > - } > > - > > - Timeout =3D NVME_GENERIC_TIMEOUT/1000; // ms > > - for(Index =3D (UINT32)(Timeout); Index !=3D 0; --Index) { > > - MicroSecondDelay (1000); > > - > > - Status =3D NVME_GET_CSTS (Nvme, &Csts); > > - if (EFI_ERROR(Status)) { > > - DEBUG ((DEBUG_ERROR, "NVME_GET_CSTS fail, Status =3D %r\n", > Status)); > > - return Status; > > - } > > - > > - if (Csts.Shst =3D=3D 2) { // Shutdown processing complete > > - break; > > - } > > - } > > - > > - if (Index =3D=3D 0) { > > - Status =3D 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 =3D=3D 0x0 && Cq->Sc =3D=3D 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 Conventio= nal > > 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 pag= es. > > - 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 Dat= a Buffer. > > - @param[in] Pages - The number of pages to be transf= ered. > > - @param[out] PrpListHost - The host base address of PRP lis= ts. > > - @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 =3D EFI_PAGE_SIZE / sizeof (UINT64); > > - > > - /// > > - /// Calculate total PrpList number. > > - /// > > - *PrpListNo =3D (UINTN) DivU64x64Remainder ((UINT64)Pages, > > (UINT64)PrpEntryNo, &Remainder); > > - if (Remainder !=3D 0) { > > - *PrpListNo +=3D 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 =3D (VOID *)(UINTN) NVME_PRP_BASE (Nvme, SqId); > > - > > - Bytes =3D EFI_PAGES_TO_SIZE (*PrpListNo); > > - PrpListPhyAddr =3D (UINT64)(UINTN)(*PrpListHost); > > - > > - /// > > - /// Fill all PRP lists except of last one. > > - /// > > - ZeroMem (*PrpListHost, Bytes); > > - for (PrpListIndex =3D 0; PrpListIndex < *PrpListNo - 1; ++PrpListInd= ex) { > > - PrpListBase =3D *(UINT64*)PrpListHost + PrpListIndex * EFI_PAGE_SI= ZE; > > - > > - for (PrpEntryIndex =3D 0; PrpEntryIndex < PrpEntryNo; ++PrpEntryIn= dex) { > > - PrpEntry =3D (UINT8 *)(UINTN) (PrpListBase + PrpEntryIndex * > > sizeof(UINT64)); > > - if (PrpEntryIndex !=3D PrpEntryNo - 1) { > > - /// > > - /// Fill all PRP entries except of last one. > > - /// > > - CopyMem (PrpEntry, (VOID *)(UINTN) (&PhysicalAddr), sizeof > > (UINT64)); > > - PhysicalAddr +=3D EFI_PAGE_SIZE; > > - } else { > > - /// > > - /// Fill last PRP entries with next PRP List pointer. > > - /// > > - NewPhyAddr =3D (PrpListPhyAddr + (PrpListIndex + 1) * EFI_PAGE= _SIZE); > > - CopyMem (PrpEntry, (VOID *)(UINTN) (&NewPhyAddr), sizeof > > (UINT64)); > > - } > > - } > > - } > > - > > - /// > > - /// Fill last PRP list. > > - /// > > - PrpListBase =3D *(UINT64*)PrpListHost + PrpListIndex * EFI_PAGE_SIZE= ; > > - for (PrpEntryIndex =3D 0; PrpEntryIndex < ((Remainder !=3D 0) ? Rema= inder : > > PrpEntryNo); ++PrpEntryIndex) { > > - PrpEntry =3D (UINT8 *)(UINTN) (PrpListBase + PrpEntryIndex * > > sizeof(UINT64)); > > - CopyMem (PrpEntry, (VOID *)(UINTN) (&PhysicalAddr), sizeof > (UINT64)); > > - > > - PhysicalAddr +=3D 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 functionalit= y 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 whic= h the > > Express HCI command packet will be sent. > > - A Value of 0 denotes the NVM Exp= ress controller, a > Value > > of all 0FFh in the namespace > > - ID specifies that the command pa= cket should be sent to > > all valid namespaces. > > - @param[in] NamespaceUuid - Is a 64 bit Namespace UUID to wh= ich > > the Express HCI command packet will be sent. > > - A Value of 0 denotes the NVM Exp= ress 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 w= as > 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 s= ent, 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 w= as 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 =3D=3D NULL) || (Packet =3D=3D NULL)) { > > - DEBUG ((DEBUG_ERROR, "NvmePassThru, invalid parameter: > > Nvme(%x)/Packet(%x)\n", > > - (UINTN)Nvme, (UINTN)Packet)); > > - return EFI_INVALID_PARAMETER; > > - } > > - > > - if ((Packet->NvmeCmd =3D=3D NULL) || (Packet->NvmeResponse =3D=3D NU= LL)) { > > - DEBUG ((DEBUG_ERROR, "NvmePassThru, invalid parameter: > > NvmeCmd(%x)/NvmeResponse(%x)\n", > > - (UINTN)Packet->NvmeCmd, (UINTN)Packet->NvmeResponse)); > > - return EFI_INVALID_PARAMETER; > > - } > > - > > - if (Packet->QueueId !=3D NVME_ADMIN_QUEUE && Packet->QueueId !=3D > > NVME_IO_QUEUE) { > > - DEBUG ((DEBUG_ERROR, "NvmePassThru, invalid parameter: > > QueueId(%x)\n", > > - Packet->QueueId)); > > - return EFI_INVALID_PARAMETER; > > - } > > - > > - PrpListHost =3D NULL; > > - PrpListNo =3D 0; > > - Status =3D EFI_SUCCESS; > > - > > - Qid =3D Packet->QueueId; > > - Sq =3D Nvme->SqBuffer[Qid] + Nvme->SqTdbl[Qid].Sqt; > > - Cq =3D Nvme->CqBuffer[Qid] + Nvme->CqHdbl[Qid].Cqh; > > - if (Qid =3D=3D NVME_ADMIN_QUEUE) { > > - SqSize =3D NVME_ASQ_SIZE + 1; > > - CqSize =3D NVME_ACQ_SIZE + 1; > > - } else { > > - SqSize =3D NVME_CSQ_DEPTH; > > - CqSize =3D NVME_CCQ_DEPTH; > > - } > > - > > - if (Packet->NvmeCmd->Nsid !=3D 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 =3D Packet->NvmeCmd->Cdw0.Opcode; > > - Sq->Fuse =3D Packet->NvmeCmd->Cdw0.FusedOperation; > > - Sq->Cid =3D Packet->NvmeCmd->Cdw0.Cid; > > - Sq->Nsid =3D Packet->NvmeCmd->Nsid; > > - > > - /// > > - /// Currently we only support PRP for Data transfer, SGL is NOT > supported. > > - /// > > - ASSERT (Sq->Psdt =3D=3D 0); > > - if (Sq->Psdt !=3D 0) { > > - DEBUG ((DEBUG_ERROR, "NvmePassThru: doesn't support SGL > > mechanism\n")); > > - return EFI_UNSUPPORTED; > > - } > > - > > - Sq->Prp[0] =3D Packet->TransferBuffer; > > - Sq->Prp[1] =3D 0; > > - > > - if(Packet->MetadataBuffer !=3D (UINT64)(UINTN)NULL) { > > - Sq->Mptr =3D Packet->MetadataBuffer; > > - } > > - > > - /// > > - /// If the Buffer Size spans more than two memory pages (page Size a= s > > defined in CC.Mps), > > - /// then build a PRP list in the second PRP submission queue entry. > > - /// > > - Offset =3D ((UINT32)Sq->Prp[0]) & (EFI_PAGE_SIZE - 1); > > - Bytes =3D Packet->TransferLength; > > - > > - if ((Offset + Bytes) > (EFI_PAGE_SIZE * 2)) { > > - /// > > - /// Create PrpList for remaining Data Buffer. > > - /// > > - PhyAddr =3D (Sq->Prp[0] + EFI_PAGE_SIZE) & ~(EFI_PAGE_SIZE - 1); > > - Sq->Prp[1] =3D NvmeCreatePrpList (Nvme, Nvme->SqTdbl[Qid].Sqt, > > PhyAddr, EFI_SIZE_TO_PAGES(Offset + Bytes) - 1, &PrpListHost, > &PrpListNo); > > - if (Sq->Prp[1] =3D=3D 0) { > > - Status =3D 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] =3D (Sq->Prp[0] + EFI_PAGE_SIZE) & ~(EFI_PAGE_SIZE - 1)= ; > > - } > > - > > - if(Packet->NvmeCmd->Flags & CDW10_VALID) { > > - Sq->Payload.Raw.Cdw10 =3D Packet->NvmeCmd->Cdw10; > > - } > > - if(Packet->NvmeCmd->Flags & CDW11_VALID) { > > - Sq->Payload.Raw.Cdw11 =3D Packet->NvmeCmd->Cdw11; > > - } > > - if(Packet->NvmeCmd->Flags & CDW12_VALID) { > > - Sq->Payload.Raw.Cdw12 =3D Packet->NvmeCmd->Cdw12; > > - } > > - if(Packet->NvmeCmd->Flags & CDW13_VALID) { > > - Sq->Payload.Raw.Cdw13 =3D Packet->NvmeCmd->Cdw13; > > - } > > - if(Packet->NvmeCmd->Flags & CDW14_VALID) { > > - Sq->Payload.Raw.Cdw14 =3D Packet->NvmeCmd->Cdw14; > > - } > > - if(Packet->NvmeCmd->Flags & CDW15_VALID) { > > - Sq->Payload.Raw.Cdw15 =3D Packet->NvmeCmd->Cdw15; > > - } > > - > > - /// > > - /// Ring the submission queue doorbell. > > - /// > > - Nvme->SqTdbl[Qid].Sqt++; > > - if(Nvme->SqTdbl[Qid].Sqt =3D=3D SqSize) { > > - Nvme->SqTdbl[Qid].Sqt =3D 0; > > - } > > - Status =3D 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 =3D EFI_TIMEOUT; > > - Timer =3D 0; > > - while (Timer < NVME_CMD_TIMEOUT) { > > - //DEBUG ((DEBUG_VERBOSE, "Timer: %x, Cq:\n", Timer)); > > - //DumpMem (Cq, sizeof (NVME_CQ)); > > - if (Cq->Pt !=3D Nvme->Pt[Qid]) { > > - Status =3D EFI_SUCCESS; > > - break; > > - } > > - > > - MicroSecondDelay (NVME_CMD_WAIT); > > - Timer +=3D NVME_CMD_WAIT; > > - } > > - > > - Nvme->CqHdbl[Qid].Cqh++; > > - if (Nvme->CqHdbl[Qid].Cqh =3D=3D CqSize) { > > - Nvme->CqHdbl[Qid].Cqh =3D 0; > > - Nvme->Pt[Qid] ^=3D 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 =3D 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 ide= ntify > controller > > Data. > > - > > - @return EFI_SUCCESS - Successfully get the identify co= ntroller > Data. > > - @return others - Fail to get the identify control= ler 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 =3D NVME_ADMIN_IDENTIFY_OPC; > > - Command.Cdw0.Cid =3D Nvme->Cid[NVME_ADMIN_QUEUE]++; > > - // > > - // According to Nvm Express 1.1 spec Figure 38, When not used, the f= ield > > shall be cleared to 0h. > > - // For the Identify command, the Namespace Identifier is only used f= or > the > > Namespace Data structure. > > - // > > - Command.Nsid =3D 0; > > - > > - CommandPacket.NvmeCmd =3D &Command; > > - CommandPacket.NvmeResponse =3D &Response; > > - CommandPacket.TransferBuffer =3D (UINT64)(UINTN)Buffer; > > - CommandPacket.TransferLength =3D sizeof > > (NVME_ADMIN_CONTROLLER_DATA); > > - CommandPacket.CommandTimeout =3D NVME_GENERIC_TIMEOUT; > > - CommandPacket.QueueId =3D NVME_ADMIN_QUEUE; > > - // > > - // Set bit 0 (Cns bit) to 1 to identify a controller > > - // > > - Command.Cdw10 =3D 1; > > - Command.Flags =3D CDW10_VALID; > > - > > - Status =3D NvmePassThru ( > > - Nvme, > > - NVME_CONTROLLER_ID, > > - 0, > > - &CommandPacket > > - ); > > - if (!EFI_ERROR (Status)) { > > - Status =3D 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 identifi= er. > > - @param[in] Buffer - The Buffer used to store the ide= ntify > > namespace Data. > > - > > - @return EFI_SUCCESS - Successfully get the identify na= mespace > > Data. > > - @return others - Fail to get the identify namespa= ce 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 =3D &Command; > > - CommandPacket.NvmeResponse =3D &Response; > > - > > - Command.Cdw0.Opcode =3D NVME_ADMIN_IDENTIFY_OPC; > > - Command.Cdw0.Cid =3D Nvme->Cid[NVME_ADMIN_QUEUE]++; > > - Command.Nsid =3D NamespaceId; > > - CommandPacket.TransferBuffer =3D (UINT64)(UINTN)Buffer; > > - CommandPacket.TransferLength =3D sizeof > > (NVME_ADMIN_NAMESPACE_DATA); > > - CommandPacket.CommandTimeout =3D NVME_GENERIC_TIMEOUT; > > - CommandPacket.QueueId =3D NVME_ADMIN_QUEUE; > > - // > > - // Set bit 0 (Cns bit) to 1 to identify a namespace > > - // > > - CommandPacket.NvmeCmd->Cdw10 =3D 0; > > - CommandPacket.NvmeCmd->Flags =3D CDW10_VALID; > > - > > - Status =3D NvmePassThru ( > > - Nvme, > > - NamespaceId, > > - 0, > > - &CommandPacket > > - ); > > - if (!EFI_ERROR (Status)) { > > - Status =3D 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 =3D Nvme->NamespaceData->Flbas; > > - LbaFmtIdx =3D Flbas & 3; > > - Lbads =3D Nvme->NamespaceData->LbaFormat[LbaFmtIdx].Lbads; > > - > > - BlockSize =3D (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 =3D 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 completio= n queue. > > - @return others - Fail to create io completion que= ue. > > - > > -**/ > > -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 =3D &Command; > > - CommandPacket.NvmeResponse =3D &Response; > > - > > - Command.Cdw0.Opcode =3D NVME_ADMIN_CRIOCQ_OPC; > > - Command.Cdw0.Cid =3D Nvme->Cid[NVME_ADMIN_QUEUE]++; > > - CommandPacket.TransferBuffer =3D (UINT64)(UINTN)Nvme- > > >CqBuffer[NVME_IO_QUEUE]; > > - CommandPacket.TransferLength =3D EFI_PAGE_SIZE; > > - CommandPacket.CommandTimeout =3D NVME_GENERIC_TIMEOUT; > > - CommandPacket.QueueId =3D NVME_ADMIN_QUEUE; > > - > > - CrIoCq.Qid =3D NVME_IO_QUEUE; > > - CrIoCq.Qsize =3D NVME_CCQ_SIZE; > > - CrIoCq.Pc =3D 1; > > - CopyMem (&CommandPacket.NvmeCmd->Cdw10, &CrIoCq, sizeof > > (NVME_ADMIN_CRIOCQ)); > > - CommandPacket.NvmeCmd->Flags =3D CDW10_VALID | CDW11_VALID; > > - > > - Status =3D NvmePassThru ( > > - Nvme, > > - NVME_CONTROLLER_ID, > > - 0, > > - &CommandPacket > > - ); > > - if (!EFI_ERROR (Status)) { > > - Status =3D 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 submissio= n queue. > > - @return others - Fail to create io submission que= ue. > > - > > -**/ > > -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 =3D &Command; > > - CommandPacket.NvmeResponse =3D &Response; > > - > > - Command.Cdw0.Opcode =3D NVME_ADMIN_CRIOSQ_OPC; > > - Command.Cdw0.Cid =3D Nvme->Cid[NVME_ADMIN_QUEUE]++; > > - CommandPacket.TransferBuffer =3D (UINT64)(UINTN)Nvme- > > >SqBuffer[NVME_IO_QUEUE]; > > - CommandPacket.TransferLength =3D EFI_PAGE_SIZE; > > - CommandPacket.CommandTimeout =3D NVME_GENERIC_TIMEOUT; > > - CommandPacket.QueueId =3D NVME_ADMIN_QUEUE; > > - > > - CrIoSq.Qid =3D NVME_IO_QUEUE; > > - CrIoSq.Qsize =3D NVME_CSQ_SIZE; > > - CrIoSq.Pc =3D 1; > > - CrIoSq.Cqid =3D NVME_IO_QUEUE; > > - CrIoSq.Qprio =3D 0; > > - CopyMem (&CommandPacket.NvmeCmd->Cdw10, &CrIoSq, sizeof > > (NVME_ADMIN_CRIOSQ)); > > - CommandPacket.NvmeCmd->Flags =3D CDW10_VALID | CDW11_VALID; > > - > > - Status =3D NvmePassThru ( > > - Nvme, > > - NVME_CONTROLLER_ID, > > - 0, > > - &CommandPacket > > - ); > > - if (!EFI_ERROR (Status)) { > > - Status =3D NvmeWaitAllComplete (Nvme, CommandPacket.QueueId); > > - } > > - > > - return Status; > > -} > > - > > -/** > > - Security send and receive commands. > > - > > - @param[in] Nvme - The pointer to the NVME_CONT= EXT Data > > structure. > > - @param[in] SendCommand - The flag to indicate the com= mand > > 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 (i= n bytes) - > > always a multiple of 512 > > - @param[in,out] TransferBuffer - Address of Data to transfer > > - > > - @return EFI_SUCCESS - Successfully create io submissio= n 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 =3D (OACS *)&Nvme->ControllerData->Oacs; > > - > > - // > > - // Verify security bit for Security Send/Receive commands > > - // > > - if (Oacs->Security =3D=3D 0) { > > - DEBUG ((DEBUG_ERROR, "Security command doesn't support.\n")); > > - return EFI_NOT_READY; > > - } > > - > > - SecBuff =3D (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 =3D &Command; > > - CommandPacket.NvmeResponse =3D &Response; > > - > > - Opcode =3D (UINT8)(SendCommand ? > NVME_ADMIN_SECURITY_SEND_OPC : > > NVME_ADMIN_SECURITY_RECV_OPC); > > - Command.Cdw0.Opcode =3D Opcode; > > - Command.Cdw0.Cid =3D Nvme->Cid[NVME_ADMIN_QUEUE]++; > > - CommandPacket.TransferBuffer =3D (UINT64)(UINTN)SecBuff; > > - CommandPacket.TransferLength =3D (UINT32)TransferLength; > > - CommandPacket.CommandTimeout =3D NVME_GENERIC_TIMEOUT; > > - CommandPacket.QueueId =3D NVME_ADMIN_QUEUE; > > - > > - SecSend.Spsp =3D SpSpecific; > > - SecSend.Secp =3D SecurityProtocol; > > - SecSend.Tl =3D (UINT32)TransferLength; > > - > > - CopyMem (&CommandPacket.NvmeCmd->Cdw10, &SecSend, sizeof > > (NVME_ADMIN_SECSEND)); > > - CommandPacket.NvmeCmd->Flags =3D CDW10_VALID | CDW11_VALID; > > - > > - Status =3D NvmePassThru ( > > - Nvme, > > - NVME_CONTROLLER_ID, > > - 0, > > - &CommandPacket > > - ); > > - if (!EFI_ERROR (Status)) { > > - Status =3D 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 completi= on queue. > > - @return others - Fail to destroy io completion qu= eue. > > - > > -**/ > > -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 =3D &Command; > > - CommandPacket.NvmeResponse =3D &Response; > > - > > - Command.Cdw0.Opcode =3D NVME_ADMIN_DELIOCQ_OPC; > > - Command.Cdw0.Cid =3D Nvme->Cid[NVME_ADMIN_QUEUE]++; > > - CommandPacket.TransferBuffer =3D (UINT64)(UINTN)Nvme- > > >CqBuffer[NVME_IO_QUEUE]; > > - CommandPacket.TransferLength =3D EFI_PAGE_SIZE; > > - CommandPacket.CommandTimeout =3D NVME_GENERIC_TIMEOUT; > > - CommandPacket.QueueId =3D NVME_ADMIN_QUEUE; > > - > > - DelIoCq.Qid =3D NVME_IO_QUEUE; > > - CopyMem (&CommandPacket.NvmeCmd->Cdw10, &DelIoCq, sizeof > > (NVME_ADMIN_DEIOCQ)); > > - CommandPacket.NvmeCmd->Flags =3D CDW10_VALID | CDW11_VALID; > > - > > - Status =3D NvmePassThru ( > > - Nvme, > > - NVME_CONTROLLER_ID, > > - 0, > > - &CommandPacket > > - ); > > - if (!EFI_ERROR (Status)) { > > - Status =3D 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 submissi= on queue. > > - @return others - Fail to destroy io submission qu= eue. > > - > > -**/ > > -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 =3D &Command; > > - CommandPacket.NvmeResponse =3D &Response; > > - > > - Command.Cdw0.Opcode =3D NVME_ADMIN_DELIOSQ_OPC; > > - Command.Cdw0.Cid =3D Nvme->Cid[NVME_ADMIN_QUEUE]++; > > - CommandPacket.TransferBuffer =3D (UINT64)(UINTN)Nvme- > > >SqBuffer[NVME_IO_QUEUE]; > > - CommandPacket.TransferLength =3D EFI_PAGE_SIZE; > > - CommandPacket.CommandTimeout =3D NVME_GENERIC_TIMEOUT; > > - CommandPacket.QueueId =3D NVME_ADMIN_QUEUE; > > - > > - DelIoSq.Qid =3D NVME_IO_QUEUE; > > - CopyMem (&CommandPacket.NvmeCmd->Cdw10, &DelIoSq, sizeof > > (NVME_ADMIN_DEIOSQ)); > > - CommandPacket.NvmeCmd->Flags =3D CDW10_VALID | CDW11_VALID; > > - > > - Status =3D NvmePassThru ( > > - Nvme, > > - NVME_CONTROLLER_ID, > > - 0, > > - &CommandPacket > > - ); > > - if (!EFI_ERROR (Status)) { > > - Status =3D 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 =3D IoMmuAllocateBuffer ( > > - EFI_SIZE_TO_PAGES (NVME_MEM_MAX_SIZE), > > - &Base, > > - &DeviceAddress, > > - &Mapping > > - ); > > - if (EFI_ERROR (Status)) { > > - return EFI_OUT_OF_RESOURCES; > > - } > > - ASSERT (DeviceAddress =3D=3D ((EFI_PHYSICAL_ADDRESS) (UINTN) Base)); > > - Nvme->BaseMemMapping =3D Mapping; > > - Nvme->BaseMem =3D 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 !=3D NULL) { > > - IoMmuFreeBuffer ( > > - EFI_SIZE_TO_PAGES (NVME_MEM_MAX_SIZE), > > - Nvme->BaseMem, > > - Nvme->BaseMemMapping > > - ); > > - Nvme->BaseMem =3D 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 in= itialized > > successfully. > > - @retval Others - A device error occurred while in= itializing 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 =3D Nvme->Nbar; > > - MuBAR =3D 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 =3D=3D 0x0001) && (Ver.Mnr =3D=3D 0x0000)) { > > - DEBUG ((DEBUG_INFO, "\n!!!\n!!! NVME Version mismatch for the > > implementation !!!\n!!!\n")); > > - } > > - > > - /// > > - /// Read the Controller Capabilities register and verify that the NV= M > > command set is supported > > - /// > > - Status =3D 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 !=3D 0x01) { > > - DEBUG ((DEBUG_ERROR, "NvmeControllerInit fail: the controller does= n't > > support NVMe command set\n")); > > - Status =3D 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 pa= ge > > Size\n")); > > - ASSERT (FALSE); > > - Status =3D EFI_UNSUPPORTED; > > - goto Done; > > - } > > - > > - Nvme->Cid[0] =3D 0; > > - Nvme->Cid[1] =3D 0; > > - > > - Nvme->Pt[0] =3D 0; > > - Nvme->Pt[1] =3D 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 =3D 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 =3D NVME_ASQ_SIZE; > > - Aqa.Rsvd1 =3D 0; > > - Aqa.Acqs =3D NVME_ACQ_SIZE; > > - Aqa.Rsvd2 =3D 0; > > - > > - /// > > - /// Address of admin submission queue. > > - /// > > - Asq =3D (UINT64)(UINTN)(NVME_ASQ_BASE (Nvme) & ~0xFFF); > > - > > - /// > > - /// Address of admin completion queue. > > - /// > > - Acq =3D (UINT64)(UINTN)(NVME_ACQ_BASE (Nvme) & ~0xFFF); > > - > > - /// > > - /// Address of I/O submission & completion queue. > > - /// > > - Nvme->SqBuffer[0] =3D (NVME_SQ *)(UINTN)NVME_ASQ_BASE (Nvme); > // > > NVME_ADMIN_QUEUE > > - Nvme->CqBuffer[0] =3D (NVME_CQ *)(UINTN)NVME_ACQ_BASE (Nvme); > > // NVME_ADMIN_QUEUE > > - Nvme->SqBuffer[1] =3D (NVME_SQ *)(UINTN)NVME_SQ_BASE (Nvme, 0); > // > > NVME_IO_QUEUE > > - Nvme->CqBuffer[1] =3D (NVME_CQ *)(UINTN)NVME_CQ_BASE (Nvme, 0); > > // NVME_IO_QUEUE > > - > > - DEBUG ((DEBUG_INFO, "Admin Submission Queue Size (Aqa.Asqs) =3D > > [%08X]\n", Aqa.Asqs)); > > - DEBUG ((DEBUG_INFO, "Admin Completion Queue Size (Aqa.Acqs) =3D > > [%08X]\n", Aqa.Acqs)); > > - DEBUG ((DEBUG_INFO, "Admin Submission Queue (SqBuffer[0]) =3D > > [%08X]\n", Nvme->SqBuffer[0])); > > - DEBUG ((DEBUG_INFO, "Admin Completion Queue (CqBuffer[0]) =3D > > [%08X]\n", Nvme->CqBuffer[0])); > > - DEBUG ((DEBUG_INFO, "I/O Submission Queue (SqBuffer[1]) =3D > > [%08X]\n", Nvme->SqBuffer[1])); > > - DEBUG ((DEBUG_INFO, "I/O Completion Queue (CqBuffer[1]) =3D > > [%08X]\n", Nvme->CqBuffer[1])); > > - > > - /// > > - /// Program admin queue attributes. > > - /// > > - Status =3D NVME_SET_AQA (Nvme, &Aqa); > > - if (EFI_ERROR(Status)) { > > - goto Done; > > - } > > - > > - /// > > - /// Program admin submission queue address. > > - /// > > - Status =3D NVME_SET_ASQ (Nvme, &Asq); > > - if (EFI_ERROR(Status)) { > > - goto Done; > > - } > > - > > - /// > > - /// Program admin completion queue address. > > - /// > > - Status =3D NVME_SET_ACQ (Nvme, &Acq); > > - if (EFI_ERROR(Status)) { > > - goto Done; > > - } > > - > > - Status =3D NvmeEnableController (Nvme); > > - if (EFI_ERROR(Status)) { > > - goto Done; > > - } > > - > > - /// > > - /// Create one I/O completion queue. > > - /// > > - Status =3D NvmeCreateIoCompletionQueue (Nvme); > > - if (EFI_ERROR(Status)) { > > - goto Done; > > - } > > - > > - /// > > - /// Create one I/O Submission queue. > > - /// > > - Status =3D NvmeCreateIoSubmissionQueue (Nvme); > > - if (EFI_ERROR(Status)) { > > - goto Done; > > - } > > - > > - /// > > - /// Get current Identify Controller Data > > - /// > > - Nvme->ControllerData =3D (NVME_ADMIN_CONTROLLER_DATA *)(UINTN) > > NVME_CONTROL_DATA_BASE (Nvme); > > - Status =3D NvmeIdentifyController (Nvme, Nvme->ControllerData); > > - if (EFI_ERROR(Status)) { > > - goto Done; > > - } > > - > > - /// > > - /// Dump NvmExpress Identify Controller Data > > - /// > > - Nvme->ControllerData->Sn[19] =3D 0; > > - Nvme->ControllerData->Mn[39] =3D 0; > > - //NvmeDumpIdentifyController (Nvme->ControllerData); > > - > > - /// > > - /// Get current Identify Namespace Data > > - /// > > - Nvme->NamespaceData =3D (NVME_ADMIN_NAMESPACE_DATA > > *)NVME_NAMESPACE_DATA_BASE (Nvme); > > - Status =3D NvmeIdentifyNamespace (Nvme, Nvme->Nsid, Nvme- > > >NamespaceData); > > - if (EFI_ERROR(Status)) { > > - DEBUG ((DEBUG_ERROR, "NvmeIdentifyNamespace fail, Status =3D %r\n"= , > > Status)); > > - goto Done; > > - } > > - > > - /// > > - /// Dump NvmExpress Identify Namespace Data > > - /// > > - if (Nvme->NamespaceData->Ncap =3D=3D 0) { > > - DEBUG ((DEBUG_ERROR, "Invalid Namespace, Ncap: %lx\n", Nvme- > > >NamespaceData->Ncap)); > > - Status =3D EFI_DEVICE_ERROR; > > - goto Done; > > - } > > - > > - Nvme->BlockSize =3D NvmeGetBlockSize (Nvme); > > - Nvme->LastBlock =3D NvmeGetLastLba (Nvme); > > - > > - Nvme->State =3D 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 =3D EFI_SUCCESS; > > - if (Nvme->State =3D=3D NvmeStatusInit || Nvme->State =3D=3D NvmeStat= usMax) > { > > - /// > > - /// Destroy I/O Submission queue. > > - /// > > - Status =3D NvmeDestroyIoSubmissionQueue (Nvme); > > - if (EFI_ERROR(Status)) { > > - DEBUG ((DEBUG_ERROR, "NvmeDestroyIoSubmissionQueue fail, > Status > > =3D %r\n", Status)); > > - return Status; > > - } > > - > > - /// > > - /// Destroy I/O completion queue. > > - /// > > - Status =3D NvmeDestroyIoCompletionQueue (Nvme); > > - if (EFI_ERROR(Status)) { > > - DEBUG ((DEBUG_ERROR, "NvmeDestroyIoCompletionQueue fail, > Status > > =3D %r\n", Status)); > > - return Status; > > - } > > - > > - Status =3D 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 =3D 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 S= 3. > > > > -Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.
> > +Copyright (c) 2016 - 2019, Intel Corporation. All rights reserved.
> > This program and the accompanying materials > > are licensed and made available under the terms and conditions of the = BSD > > License > > which accompanies this distribution. The full text of the license may= be > > found at > > @@ -14,249 +14,34 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF > > ANY KIND, EITHER EXPRESS OR IMPLIED. > > > > #include "OpalPasswordPei.h" > > > > -EFI_GUID mOpalDeviceAtaGuid =3D OPAL_DEVICE_ATA_GUID; > > -EFI_GUID mOpalDeviceNvmeGuid =3D OPAL_DEVICE_NVME_GUID; > > - > > -#define OPAL_PCIE_ROOTPORT_SAVESIZE (0x40) > > -#define STORE_INVALID_ROOTPORT_INDEX ((UINT8) -1) > > +EFI_GUID mOpalDeviceLockBoxGuid =3D 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 dat= a. > > + @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 =3D NULL; > > - Status =3D PeiServicesLocatePpi ( > > - &gEdkiiIoMmuPpiGuid, > > - 0, > > - NULL, > > - (VOID **) &IoMmu > > - ); > > - if (!EFI_ERROR (Status) && (IoMmu !=3D 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 mem= ory > > 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 alloca= ted. > > - @retval EFI_UNSUPPORTED Attributes is unsupported. The only le= gal > > 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 =3D NULL; > > - *DeviceAddress =3D 0; > > - *Mapping =3D NULL; > > - > > - IoMmu =3D GetIoMmu (); > > - > > - if (IoMmu !=3D NULL) { > > - Status =3D IoMmu->AllocateBuffer ( > > - IoMmu, > > - EfiBootServicesData, > > - Pages, > > - HostAddress, > > - 0 > > - ); > > - if (EFI_ERROR (Status)) { > > - return EFI_OUT_OF_RESOURCES; > > - } > > - > > - NumberOfBytes =3D EFI_PAGES_TO_SIZE (Pages); > > - Status =3D IoMmu->Map ( > > - IoMmu, > > - EdkiiIoMmuOperationBusMasterCommonBuffer, > > - *HostAddress, > > - &NumberOfBytes, > > - DeviceAddress, > > - Mapping > > - ); > > - if (EFI_ERROR (Status)) { > > - IoMmu->FreeBuffer (IoMmu, Pages, *HostAddress); > > - *HostAddress =3D NULL; > > - return EFI_OUT_OF_RESOURCES; > > - } > > - Status =3D 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 =3D NULL; > > - *HostAddress =3D NULL; > > - return Status; > > - } > > - } else { > > - Status =3D PeiServicesAllocatePages ( > > - EfiBootServicesData, > > - Pages, > > - &HostPhyAddress > > - ); > > - if (EFI_ERROR (Status)) { > > - return EFI_OUT_OF_RESOURCES; > > - } > > - *HostAddress =3D (VOID *) (UINTN) HostPhyAddress; > > - *DeviceAddress =3D HostPhyAddress; > > - *Mapping =3D 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 =3D GetIoMmu (); > > - > > - if (IoMmu !=3D 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 tr= usted 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 byte= s) - > > 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 =3D EFI_DEVICE_ERROR; > > - if (PeiDev->DeviceType =3D=3D OPAL_DEVICE_TYPE_ATA) { > > - DevInfoAta =3D (OPAL_DEVICE_ATA *) PeiDev->Device; > > - AhciContext =3D (AHCI_CONTEXT *) PeiDev->Context; > > - > > - BufferSizeBlocks =3D TransferLength / 512; > > - > > - ZeroMem( &AtaCommandBlock, sizeof( EFI_ATA_COMMAND_BLOCK ) ); > > - AtaCommandBlock.AtaCommand =3D ( IoType =3D=3D OpalSend ) ? > > ATA_COMMAND_TRUSTED_SEND : ATA_COMMAND_TRUSTED_RECEIVE; > > - AtaCommandBlock.AtaSectorCount =3D ( UINT8 )BufferSizeBlocks; > > - AtaCommandBlock.AtaSectorNumber =3D ( UINT8 )( BufferSizeBlocks >> > 8 ); > > - AtaCommandBlock.AtaFeatures =3D SecurityProtocol; > > - AtaCommandBlock.AtaCylinderLow =3D ( UINT8 )( SpSpecific >> 8 ); > > - AtaCommandBlock.AtaCylinderHigh =3D ( UINT8 )( SpSpecific ); > > - AtaCommandBlock.AtaDeviceHead =3D ATA_DEVICE_LBA; > > - > > - > > - ZeroMem( AhciContext->Buffer, HDD_PAYLOAD ); > > - ASSERT( TransferLength <=3D HDD_PAYLOAD ); > > - > > - if (IoType =3D=3D OpalSend) { > > - CopyMem( AhciContext->Buffer, Buffer, TransferLength ); > > - } > > + UINTN Index; > > > > - Status =3D AhciPioTransfer( > > - AhciContext, > > - (UINT8) DevInfoAta->Port, > > - (UINT8) DevInfoAta->PortMultiplierPort, > > - NULL, > > - 0, > > - ( IoType =3D=3D OpalSend ) ? FALSE : TRUE, // i/o di= rection > > - &AtaCommandBlock, > > - NULL, > > - AhciContext->Buffer, > > - (UINT32)TransferLength, > > - ATA_TIMEOUT > > - ); > > - > > - if (IoType =3D=3D OpalRecv) { > > - CopyMem( Buffer, AhciContext->Buffer, TransferLength ); > > + for (Index =3D 0; Index < Private->SscPpiInstanceNum; Index++) { > > + if ((UINTN)SscInstance =3D=3D Private->SscPpiInstances[Index]) { > > + return TRUE; > > } > > - } else if (PeiDev->DeviceType =3D=3D OPAL_DEVICE_TYPE_NVME) { > > - NvmeContext =3D (NVME_CONTEXT *) PeiDev->Context; > > - Status =3D NvmeSecuritySendReceive ( > > - NvmeContext, > > - IoType =3D=3D 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 =3D 0; > > - Index =3D 0; > > - RpBase =3D 0; > > - > > - while (sizeof (OPAL_DEVICE_NVME) + Length < DevInfoNvme->Length) { > > - DevNode =3D (OPAL_PCI_DEVICE *)((UINT8*)DevInfoNvme- > > >PciBridgeNode + Length); > > - RpBase =3D PCI_LIB_ADDRESS (DevNode->Bus, DevNode->Device, > > DevNode->Function, 0x0); > > - > > - if (PcieConfBufferList !=3D NULL) { > > - if (SaveAction) { > > - StorePcieConfData =3D (UINT8 *) AllocateZeroPool > > (OPAL_PCIE_ROOTPORT_SAVESIZE); > > - ASSERT (StorePcieConfData !=3D NULL); > > - OpalPciRead (StorePcieConfData, RpBase, > > OPAL_PCIE_ROOTPORT_SAVESIZE); > > - PcieConfBufferList[Index] =3D StorePcieConfData; > > - } else { > > - // Skip PCIe Command & Status registers > > - StorePcieConfData =3D PcieConfBufferList[Index]; > > - OpalPciWrite (RpBase, StorePcieConfData, 4); > > - OpalPciWrite (RpBase + 8, StorePcieConfData + 8, > > OPAL_PCIE_ROOTPORT_SAVESIZE - 8); > > - > > - FreePool (StorePcieConfData); > > - } > > - } > > - > > - Length +=3D 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 =3D=3D 0) { > > - MemoryLimit =3D MemoryBase; > > - } else { > > - MemoryLimit =3D 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 =3D (UINT8 *) &TempDevInfoAta; > > - DevInfoLengthAta =3D sizeof (OPAL_DEVICE_ATA); > > - Status =3D RestoreLockBox (&mOpalDeviceAtaGuid, DevInfo, > > &DevInfoLengthAta); > > + DevInfoBuffer =3D &DummyData; > > + DevInfoLength =3D sizeof (DummyData); > > + Status =3D RestoreLockBox (&mOpalDeviceLockBoxGuid, DevInfoBuffer, > > &DevInfoLength); > > if (Status =3D=3D EFI_BUFFER_TOO_SMALL) { > > - DevInfo =3D AllocatePages (EFI_SIZE_TO_PAGES (DevInfoLengthAta)); > > - if (DevInfo !=3D NULL) { > > - Status =3D RestoreLockBox (&mOpalDeviceAtaGuid, DevInfo, > > &DevInfoLengthAta); > > + DevInfoBuffer =3D AllocatePages (EFI_SIZE_TO_PAGES (DevInfoLength)= ); > > + if (DevInfoBuffer !=3D NULL) { > > + Status =3D RestoreLockBox (&mOpalDeviceLockBoxGuid, DevInfoBuffe= r, > > &DevInfoLength); > > } > > } > > - if (EFI_ERROR (Status) || (DevInfo =3D=3D NULL)) { > > + if (DevInfoBuffer =3D=3D NULL || DevInfoBuffer =3D=3D &DummyData) { > > + return; > > + } else if (EFI_ERROR (Status)) { > > + FreePages (DevInfoBuffer, EFI_SIZE_TO_PAGES (DevInfoLength)); > > return; > > } > > > > - for (DevInfoAta =3D (OPAL_DEVICE_ATA *) DevInfo; > > - (UINTN) DevInfoAta < ((UINTN) DevInfo + DevInfoLengthAta); > > - DevInfoAta =3D (OPAL_DEVICE_ATA *) ((UINTN) DevInfoAta + > DevInfoAta- > > >Length)) { > > - Bus =3D DevInfoAta->Device.Bus; > > - Device =3D DevInfoAta->Device.Device; > > - Function =3D DevInfoAta->Device.Function; > > - > > - SataCmdSt =3D PciRead8 (PCI_LIB_ADDRESS (Bus, Device, Function, > > PCI_COMMAND_OFFSET)); > > - PciWrite8 (PCI_LIB_ADDRESS (Bus, Device, Function, > > PCI_COMMAND_OFFSET), 0x6); > > - > > - BaseClassCode =3D PciRead8 (PCI_LIB_ADDRESS (Bus, Device, Function= , > > 0x0B)); > > - SubClassCode =3D PciRead8 (PCI_LIB_ADDRESS (Bus, Device, Function= , > > 0x0A)); > > - if ((BaseClassCode !=3D PCI_CLASS_MASS_STORAGE) || > > - ((SubClassCode !=3D PCI_CLASS_MASS_STORAGE_SATADPA) && > > (SubClassCode !=3D PCI_CLASS_MASS_STORAGE_RAID))) { > > - DEBUG ((DEBUG_ERROR, "%a() ClassCode/SubClassCode are not > > supported\n", __FUNCTION__)); > > - } else { > > - AhciBar =3D PciRead32 (PCI_LIB_ADDRESS (Bus, Device, Function, 0= x24)); > > - PciWrite32 (PCI_LIB_ADDRESS (Bus, Device, Function, 0x24), > DevInfoAta- > > >BarAddr); > > - > > - ZeroMem (&AhciContext, sizeof (AHCI_CONTEXT)); > > - AhciContext.AhciBar =3D DevInfoAta->BarAddr; > > - AhciAllocateResource (&AhciContext); > > - Status =3D 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 =3D OPAL_PEI_DEVICE_SIGNATURE; > > - OpalDev.Sscp.ReceiveData =3D SecurityReceiveData; > > - OpalDev.Sscp.SendData =3D SecuritySendData; > > - OpalDev.DeviceType =3D OPAL_DEVICE_TYPE_ATA; > > - OpalDev.Device =3D (OPAL_DEVICE_COMMON *) DevInfoAta; > > - OpalDev.Context =3D &AhciContext; > > - > > - UnlockOpalPassword (&OpalDev); > > - } > > - AhciFreeResource (&AhciContext); > > - PciWrite32 (PCI_LIB_ADDRESS (Bus, Device, Function, 0x24), AhciB= ar); > > - } > > - PciWrite8 (PCI_LIB_ADDRESS (Bus, Device, Function, > > PCI_COMMAND_OFFSET), SataCmdSt); > > - } > > - > > - ZeroMem (DevInfo, DevInfoLengthAta); > > - if ((UINTN) DevInfo !=3D (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 =3D (UINT8 *) &TempDevInfoNvme; > > - DevInfoLengthNvme =3D sizeof (OPAL_DEVICE_NVME); > > - Status =3D RestoreLockBox (&mOpalDeviceNvmeGuid, DevInfo, > > &DevInfoLengthNvme); > > - if (Status =3D=3D EFI_BUFFER_TOO_SMALL) { > > - DevInfo =3D AllocatePages (EFI_SIZE_TO_PAGES (DevInfoLengthNvme)); > > - if (DevInfo !=3D NULL) { > > - Status =3D RestoreLockBox (&mOpalDeviceNvmeGuid, DevInfo, > > &DevInfoLengthNvme); > > + for (SscPpiInstance =3D 0; > > + SscPpiInstance < OPAL_PEI_MAX_STORAGE_SECURITY_CMD_PPI; > > + SscPpiInstance++) { > > + Status =3D PeiServicesLocatePpi ( > > + &gEdkiiPeiStorageSecurityCommandPpiGuid, > > + SscPpiInstance, > > + &TempPpiDescriptor, > > + (VOID **) &SscPpi > > + ); > > + if (EFI_ERROR (Status)) { > > + break; > > } > > - } > > - if (EFI_ERROR (Status) || (DevInfo =3D=3D NULL)) { > > - return; > > - } > > > > - for (DevInfoNvme =3D (OPAL_DEVICE_NVME *) DevInfo; > > - (UINTN) DevInfoNvme < ((UINTN) DevInfo + DevInfoLengthNvme); > > - DevInfoNvme =3D (OPAL_DEVICE_NVME *) ((UINTN) DevInfoNvme + > > DevInfoNvme->Length)) { > > - Bus =3D DevInfoNvme->Device.Bus; > > - Device =3D DevInfoNvme->Device.Device; > > - Function =3D DevInfoNvme->Device.Function; > > - > > - RpBase =3D 0; > > - NvmeCmdSt =3D 0; > > - > > - /// > > - /// Save original RootPort configuration space to heap > > - /// > > - RpBase =3D SaveRestoreRootportConfSpace ( > > - DevInfoNvme, > > - TRUE, // save > > - StorePcieConfDataList > > - ); > > - MemoryBase =3D DevInfoNvme->BarAddr; > > - MemoryLength =3D 0; > > - ConfigureRootPortForPcieNand (RpBase, Bus, (UINT32) MemoryBase, > > (UINT32) MemoryLength); > > - > > - /// > > - /// Enable PCIE decode for RootPort > > - /// > > - NvmeCmdSt =3D PciRead8 (RpBase + NVME_PCIE_PCICMD); > > - PciWrite8 (RpBase + NVME_PCIE_PCICMD, 0x6); > > - > > - BaseClassCode =3D PciRead8 (PCI_LIB_ADDRESS (Bus, Device, Function= , > > 0x0B)); > > - SubClassCode =3D PciRead8 (PCI_LIB_ADDRESS (Bus, Device, Function= , > > 0x0A)); > > - ProgInt =3D PciRead8 (PCI_LIB_ADDRESS (Bus, Device, Function= , 0x09)); > > - if ((BaseClassCode !=3D PCI_CLASS_MASS_STORAGE) || > > - (SubClassCode !=3D PCI_CLASS_MASS_STORAGE_NVM) || > > - (ProgInt !=3D 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 =3D DevInfoNvme->BarAddr; > > - NvmeContext.PciBase =3D PCI_LIB_ADDRESS (Bus, Device, Function, = 0x0); > > - NvmeContext.NvmeInitWaitTime =3D 0; > > - NvmeContext.Nsid =3D DevInfoNvme->NvmeNamespaceId; > > - NvmeAllocateResource (&NvmeContext); > > - Status =3D NvmeControllerInit (&NvmeContext); > > - > > - OpalDev.Signature =3D OPAL_PEI_DEVICE_SIGNATURE; > > - OpalDev.Sscp.ReceiveData =3D SecurityReceiveData; > > - OpalDev.Sscp.SendData =3D SecuritySendData; > > - OpalDev.DeviceType =3D OPAL_DEVICE_TYPE_NVME; > > - OpalDev.Device =3D (OPAL_DEVICE_COMMON *) DevInfoNvme; > > - OpalDev.Context =3D &NvmeContext; > > - > > - UnlockOpalPassword (&OpalDev); > > - > > - Status =3D NvmeControllerExit (&NvmeContext); > > - NvmeFreeResource (&NvmeContext); > > + DEBUG (( > > + DEBUG_INFO, "%a: New Ssc PPI instance (0x%p) found.\n", > > + __FUNCTION__, (UINTN)SscPpi > > + )); > > + Private->SscPpiInstances[Private->SscPpiInstanceNum] =3D > (UINTN)SscPpi; > > + Private->SscPpiInstanceNum++; > > } > > > > - ASSERT (RpBase !=3D 0); > > - PciWrite8 (RpBase + NVME_PCIE_PCICMD, 0); > > - RpBase =3D SaveRestoreRootportConfSpace ( > > - DevInfoNvme, > > - FALSE, // restore > > - StorePcieConfDataList > > - ); > > - PciWrite8 (RpBase + NVME_PCIE_PCICMD, NvmeCmdSt); > > - } > > + // > > + // Go through all the devices managed by this PPI instance. > > + // > > + Status =3D SscPpi->GetNumberofDevices (SscPpi, &SscDeviceNum); > > + if (EFI_ERROR (Status)) { > > + continue; > > + } > > + for (SscDeviceIndex =3D 1; SscDeviceIndex <=3D SscDeviceNum; > > SscDeviceIndex++) { > > + Status =3D SscPpi->GetDevicePath ( > > + SscPpi, > > + SscDeviceIndex, > > + &SscDevicePathLength, > > + &SscDevicePath > > + ); > > + if (SscDevicePathLength <=3D sizeof (EFI_DEVICE_PATH_PROTOCOL)) = { > > + // > > + // Device path validity check. > > + // > > + continue; > > + } > > > > - ZeroMem (DevInfo, DevInfoLengthNvme); > > - if ((UINTN) DevInfo !=3D (UINTN) &TempDevInfoNvme) { > > - FreePages (DevInfo, EFI_SIZE_TO_PAGES (DevInfoLengthNvme)); > > + // > > + // Search the device in the restored LockBox. > > + // > > + for (DevInfo =3D (OPAL_DEVICE_LOCKBOX_DATA *) DevInfoBuffer; > > + (UINTN) DevInfo < ((UINTN) DevInfoBuffer + DevInfoLength); > > + DevInfo =3D (OPAL_DEVICE_LOCKBOX_DATA *) ((UINTN) DevInfo + > > DevInfo->Length)) { > > + // > > + // Find the matching device. > > + // > > + if ((DevInfo->DevicePathLength >=3D SscDevicePathLength) && > > + (CompareMem ( > > + DevInfo->DevicePath, > > + SscDevicePath, > > + SscDevicePathLength - sizeof (EFI_DEVICE_PATH_PROTOCOL)= ) =3D=3D > 0)) > > { > > + OpalDev.Signature =3D OPAL_PEI_DEVICE_SIGNATURE; > > + OpalDev.Sscp.ReceiveData =3D SecurityReceiveData; > > + OpalDev.Sscp.SendData =3D SecuritySendData; > > + OpalDev.Device =3D DevInfo; > > + OpalDev.Context =3D NULL; > > + OpalDev.SscPpi =3D SscPpi; > > + OpalDev.DeviceIndex =3D 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 Tabl= e. > > - @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 Service= s Table. > > + @param[in] NotifyDescriptor Address of the notification descripto= r > 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 =3D PeiServicesGetBootMode (&BootMode); > > - ASSERT_EFI_ERROR (Status); > > - if (BootMode !=3D 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 =3D 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 =3D { > > - (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | > > EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), > > - &gEfiEndOfPeiSignalPpiGuid, > > - OpalPasswordEndOfPeiNotify > > +OPAL_PEI_DRIVER_PRIVATE_DATA mOpalPeiDriverPrivateTemplate =3D { > > + 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 =3D PeiServicesNotifyPpi (&mOpalPasswordEndOfPeiNotifyDesc); > > + Status =3D PeiServicesGetBootMode (&BootMode); > > + if ((EFI_ERROR (Status)) || (BootMode !=3D BOOT_ON_S3_RESUME)) { > > + return EFI_UNSUPPORTED; > > + } > > + > > + DEBUG ((DEBUG_INFO, "%a: Enters in S3 path.\n", __FUNCTION__)); > > + > > + Private =3D (OPAL_PEI_DRIVER_PRIVATE_DATA *) > > + AllocateCopyPool ( > > + sizeof (OPAL_PEI_DRIVER_PRIVATE_DATA), > > + &mOpalPeiDriverPrivateTemplate > > + ); > > + if (Private =3D=3D NULL) { > > + DEBUG (( > > + DEBUG_ERROR, > > + "%a: Failed to allocate memory for > > OPAL_PEI_DRIVER_PRIVATE_DATA.\n", > > + __FUNCTION__ > > + )); > > + return EFI_OUT_OF_RESOURCES; > > + } > > + > > + Status =3D PeiServicesNotifyPpi (&Private->SscPpiNotifyList); > > ASSERT_EFI_ERROR (Status); > > return Status; > > } > > - > > -- > > 2.12.0.windows.1