From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=134.134.136.20; helo=mga02.intel.com; envelope-from=eric.dong@intel.com; receiver=edk2-devel@lists.01.org Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) (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 B35FD202E53B0 for ; Sun, 17 Feb 2019 22:20:39 -0800 (PST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by orsmga101.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 17 Feb 2019 22:20:38 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.58,383,1544515200"; d="scan'208";a="147684997" Received: from fmsmsx104.amr.corp.intel.com ([10.18.124.202]) by fmsmga001.fm.intel.com with ESMTP; 17 Feb 2019 22:20:37 -0800 Received: from fmsmsx155.amr.corp.intel.com (10.18.116.71) by fmsmsx104.amr.corp.intel.com (10.18.124.202) with Microsoft SMTP Server (TLS) id 14.3.408.0; Sun, 17 Feb 2019 22:20:37 -0800 Received: from shsmsx101.ccr.corp.intel.com (10.239.4.153) by FMSMSX155.amr.corp.intel.com (10.18.116.71) with Microsoft SMTP Server (TLS) id 14.3.408.0; Sun, 17 Feb 2019 22:20:35 -0800 Received: from shsmsx102.ccr.corp.intel.com ([169.254.2.207]) by SHSMSX101.ccr.corp.intel.com ([169.254.1.110]) with mapi id 14.03.0415.000; Mon, 18 Feb 2019 14:20:33 +0800 From: "Dong, Eric" To: "Wu, Hao A" , "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: AQHUxPcX9X0o7ANGbkGjbiTPYPlcu6Xk72PA Date: Mon, 18 Feb 2019 06:20:32 +0000 Message-ID: References: <20190215062338.19412-1-hao.a.wu@intel.com> <20190215062338.19412-14-hao.a.wu@intel.com> In-Reply-To: <20190215062338.19412-14-hao.a.wu@intel.com> Accept-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [10.239.127.40] MIME-Version: 1.0 Subject: Re: [PATCH v5 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: Mon, 18 Feb 2019 06:20:41 -0000 Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Hi Hao, Only one minor change that below zero action is not needed. > + ZeroMem (S3InitDevices, S3InitDevicesLength); With above changes, Reviewed-by: Eric Dong Thanks, Eric > -----Original Message----- > From: Wu, Hao A > Sent: Friday, February 15, 2019 2:24 PM > To: edk2-devel@lists.01.org > Cc: Wu, Hao A ; Zhang, Chao B > ; Yao, Jiewen ; Ni, Ray > ; Dong, Eric > Subject: [PATCH v5 13/13] SecurityPkg/OpalPassword: Remove HW init codes > and consume SSC PPI >=20 > REF:https://bugzilla.tianocore.org/show_bug.cgi?id=3D1409 >=20 > For the current implementation of OpalPassword drivers, it has a feature > to support devices being automatically unlocked in the S3 resume. For thi= s > feature, two types of devices are supported: >=20 > * ATA hard disks working under AHCI mode > * NVM Express devices >=20 > 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. >=20 > More specifically, the OpalPasswordDxe will handle: >=20 > * Pre-allocate MMIO resource and save it in a driver internal LockBox for > OpalPasswordPei to retrieve; > * Save the PCI configuration space of ATA controllers into boot script. >=20 > Meanwhile, the OpalPasswordPei will handle: >=20 > * Rely on the boot script for the PCI configuration space program of ATA > controllers; > * Restore the driver internal LockBox to get the MMIO resource; > * Complete the PCI configuration space program for ATA and NVME > controllers; > * Initialize ATA and NVME controllers and devices. >=20 > This commit will remove these hardware initialization related codes from > the OpalPassword drivers. The hardware initialization will be covered by > PEI storage device drivers (e.g. NvmExpressPei & AhciPei in the > MdeModulePkg). >=20 > After such codes removal, the OpalPasswordDxe will only handle: >=20 > * Construct/update the S3StorageDeviceInitList LockBox with the managing > ATA and NVME devices. >=20 > And the OpalPasswordPei will only handle: >=20 > * Locate Storage Security Command PPI instances to perform the device > automatic unlock during the S3 resume. >=20 > 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(-) >=20 > 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 the = BSD > License > # which accompanies this distribution. The full text of the license may = be > found at > @@ -62,7 +62,6 @@ > TcgStorageOpalLib > Tcg2PhysicalPresenceLib > PciLib > - S3BootScriptLib > LockBoxLib >=20 > [Protocols] > @@ -73,7 +72,8 @@ > gEfiBlockIoProtocolGuid ## CONSUMES >=20 > [Guids] > - gEfiEndOfDxeEventGroupGuid ## CONSUMES = ## Event > + gEfiEndOfDxeEventGroupGuid ## CONSUMES ## Event > + gS3StorageDeviceInitListGuid ## SOMETIMES_PRODUCES ## > UNDEFINED >=20 > [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 the = BSD > License > # which accompanies this distribution. The full text of the license may = be > found at > @@ -29,11 +29,6 @@ > OpalPasswordPei.c > OpalPasswordPei.h > OpalPasswordCommon.h > - OpalAhciMode.c > - OpalAhciMode.h > - OpalNvmeMode.c > - OpalNvmeMode.h > - OpalNvmeReg.h >=20 > [Packages] > MdePkg/MdePkg.dec > @@ -49,14 +44,13 @@ > BaseLib > BaseMemoryLib > MemoryAllocationLib > - TimerLib > LockBoxLib > TcgStorageOpalLib > Tcg2PhysicalPresenceLib > + PeiServicesTablePointerLib >=20 > [Ppis] > - gEdkiiIoMmuPpiGuid ## SOMETIMES_CONSUMES > - gEfiEndOfPeiSignalPpiGuid ## NOTIFY > + gEdkiiPeiStorageSecurityCommandPpiGuid ## NOTIFY >=20 > [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 BS= D > License > -which accompanies this distribution. The full text of the license may b= e > 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 comm= ands with > LBA (rather than CHS) addresses > - > - > -#define EFI_AHCI_BAR_INDEX 0x05 > - > -#define EFI_AHCI_CAPABILITY_OFFSET 0x0000 > -#define EFI_AHCI_CAP_SAM BIT18 > -#define EFI_AHCI_GHC_OFFSET 0x0004 > -#define EFI_AHCI_GHC_RESET BIT0 > -#define EFI_AHCI_GHC_IE BIT1 > -#define EFI_AHCI_GHC_ENABLE BIT31 > -#define EFI_AHCI_IS_OFFSET 0x0008 > -#define EFI_AHCI_PI_OFFSET 0x000C > - > -typedef struct { > - UINT32 Lower32; > - UINT32 Upper32; > -} DATA_32; > - > -typedef union { > - DATA_32 Uint32; > - UINT64 Uint64; > -} DATA_64; > - > -// > -// Each PRDT entry can point to a memory block up to 4M byte > -// > -#define EFI_AHCI_MAX_DATA_PER_PRDT 0x400000 > - > -#define EFI_AHCI_FIS_REGISTER_H2D 0x27 //Register FIS = - Host to > Device > -#define EFI_AHCI_FIS_REGISTER_H2D_LENGTH 20 > -#define EFI_AHCI_FIS_REGISTER_D2H 0x34 //Register FIS = - Device > to Host > -#define EFI_AHCI_FIS_REGISTER_D2H_LENGTH 20 > -#define EFI_AHCI_FIS_DMA_ACTIVATE 0x39 //DMA Activate = FIS - > Device to Host > -#define EFI_AHCI_FIS_DMA_ACTIVATE_LENGTH 4 > -#define EFI_AHCI_FIS_DMA_SETUP 0x41 //DMA Setup FIS= - Bi- > directional > -#define EFI_AHCI_FIS_DMA_SETUP_LENGTH 28 > -#define EFI_AHCI_FIS_DATA 0x46 //Data FIS - Bi= -directional > -#define EFI_AHCI_FIS_BIST 0x58 //BIST Activate= FIS - Bi- > directional > -#define EFI_AHCI_FIS_BIST_LENGTH 12 > -#define EFI_AHCI_FIS_PIO_SETUP 0x5F //PIO Setup FIS= - Device > to Host > -#define EFI_AHCI_FIS_PIO_SETUP_LENGTH 20 > -#define EFI_AHCI_FIS_SET_DEVICE 0xA1 //Set Device Bi= ts FIS - > Device to Host > -#define EFI_AHCI_FIS_SET_DEVICE_LENGTH 8 > - > -#define EFI_AHCI_D2H_FIS_OFFSET 0x40 > -#define EFI_AHCI_DMA_FIS_OFFSET 0x00 > -#define EFI_AHCI_PIO_FIS_OFFSET 0x20 > -#define EFI_AHCI_SDB_FIS_OFFSET 0x58 > -#define EFI_AHCI_FIS_TYPE_MASK 0xFF > -#define EFI_AHCI_U_FIS_OFFSET 0x60 > - > -// > -// Port register > -// > -#define EFI_AHCI_PORT_START 0x0100 > -#define EFI_AHCI_PORT_REG_WIDTH 0x0080 > -#define EFI_AHCI_PORT_CLB 0x0000 > -#define EFI_AHCI_PORT_CLBU 0x0004 > -#define EFI_AHCI_PORT_FB 0x0008 > -#define EFI_AHCI_PORT_FBU 0x000C > -#define EFI_AHCI_PORT_IS 0x0010 > -#define EFI_AHCI_PORT_IS_DHRS BIT0 > -#define EFI_AHCI_PORT_IS_PSS BIT1 > -#define EFI_AHCI_PORT_IS_SSS BIT2 > -#define EFI_AHCI_PORT_IS_SDBS BIT3 > -#define EFI_AHCI_PORT_IS_UFS BIT4 > -#define EFI_AHCI_PORT_IS_DPS BIT5 > -#define EFI_AHCI_PORT_IS_PCS BIT6 > -#define EFI_AHCI_PORT_IS_DIS BIT7 > -#define EFI_AHCI_PORT_IS_PRCS BIT22 > -#define EFI_AHCI_PORT_IS_IPMS BIT23 > -#define EFI_AHCI_PORT_IS_OFS BIT24 > -#define EFI_AHCI_PORT_IS_INFS BIT26 > -#define EFI_AHCI_PORT_IS_IFS BIT27 > -#define EFI_AHCI_PORT_IS_HBDS BIT28 > -#define EFI_AHCI_PORT_IS_HBFS BIT29 > -#define EFI_AHCI_PORT_IS_TFES BIT30 > -#define EFI_AHCI_PORT_IS_CPDS BIT31 > -#define EFI_AHCI_PORT_IS_CLEAR 0xFFFFFFFF > -#define EFI_AHCI_PORT_IS_FIS_CLEAR 0x0000000F > - > -#define EFI_AHCI_PORT_IE 0x0014 > -#define EFI_AHCI_PORT_CMD 0x0018 > -#define EFI_AHCI_PORT_CMD_ST_MASK 0xFFFFFFFE > -#define EFI_AHCI_PORT_CMD_ST BIT0 > -#define EFI_AHCI_PORT_CMD_SUD BIT1 > -#define EFI_AHCI_PORT_CMD_POD BIT2 > -#define EFI_AHCI_PORT_CMD_COL BIT3 > -#define EFI_AHCI_PORT_CMD_CR BIT15 > -#define EFI_AHCI_PORT_CMD_FRE BIT4 > -#define EFI_AHCI_PORT_CMD_FR BIT14 > -#define EFI_AHCI_PORT_CMD_MASK ~(EFI_AHCI_PORT_CMD_ST | > EFI_AHCI_PORT_CMD_FRE | EFI_AHCI_PORT_CMD_COL) > -#define EFI_AHCI_PORT_CMD_PMA BIT17 > -#define EFI_AHCI_PORT_CMD_HPCP BIT18 > -#define EFI_AHCI_PORT_CMD_MPSP BIT19 > -#define EFI_AHCI_PORT_CMD_CPD BIT20 > -#define EFI_AHCI_PORT_CMD_ESP BIT21 > -#define EFI_AHCI_PORT_CMD_ATAPI BIT24 > -#define EFI_AHCI_PORT_CMD_DLAE BIT25 > -#define EFI_AHCI_PORT_CMD_ALPE BIT26 > -#define EFI_AHCI_PORT_CMD_ASP BIT27 > -#define EFI_AHCI_PORT_CMD_ICC_MASK (BIT28 | BIT29 | BIT30 | > BIT31) > -#define EFI_AHCI_PORT_CMD_ACTIVE (1 << 28 ) > -#define EFI_AHCI_PORT_TFD 0x0020 > -#define EFI_AHCI_PORT_TFD_MASK (BIT7 | BIT3 | BIT0) > -#define EFI_AHCI_PORT_TFD_BSY BIT7 > -#define EFI_AHCI_PORT_TFD_DRQ BIT3 > -#define EFI_AHCI_PORT_TFD_ERR BIT0 > -#define EFI_AHCI_PORT_TFD_ERR_MASK 0x00FF00 > -#define EFI_AHCI_PORT_SIG 0x0024 > -#define EFI_AHCI_PORT_SSTS 0x0028 > -#define EFI_AHCI_PORT_SSTS_DET_MASK 0x000F > -#define EFI_AHCI_PORT_SSTS_DET 0x0001 > -#define EFI_AHCI_PORT_SSTS_DET_PCE 0x0003 > -#define EFI_AHCI_PORT_SSTS_SPD_MASK 0x00F0 > -#define EFI_AHCI_PORT_SCTL 0x002C > -#define EFI_AHCI_PORT_SCTL_DET_MASK 0x000F > -#define EFI_AHCI_PORT_SCTL_MASK > (~EFI_AHCI_PORT_SCTL_DET_MASK) > -#define EFI_AHCI_PORT_SCTL_DET_INIT 0x0001 > -#define EFI_AHCI_PORT_SCTL_DET_PHYCOMM 0x0003 > -#define EFI_AHCI_PORT_SCTL_SPD_MASK 0x00F0 > -#define EFI_AHCI_PORT_SCTL_IPM_MASK 0x0F00 > -#define EFI_AHCI_PORT_SCTL_IPM_INIT 0x0300 > -#define EFI_AHCI_PORT_SCTL_IPM_PSD 0x0100 > -#define EFI_AHCI_PORT_SCTL_IPM_SSD 0x0200 > -#define EFI_AHCI_PORT_SERR 0x0030 > -#define EFI_AHCI_PORT_SERR_RDIE BIT0 > -#define EFI_AHCI_PORT_SERR_RCE BIT1 > -#define EFI_AHCI_PORT_SERR_TDIE BIT8 > -#define EFI_AHCI_PORT_SERR_PCDIE BIT9 > -#define EFI_AHCI_PORT_SERR_PE BIT10 > -#define EFI_AHCI_PORT_SERR_IE BIT11 > -#define EFI_AHCI_PORT_SERR_PRC BIT16 > -#define EFI_AHCI_PORT_SERR_PIE BIT17 > -#define EFI_AHCI_PORT_SERR_CW BIT18 > -#define EFI_AHCI_PORT_SERR_BDE BIT19 > -#define EFI_AHCI_PORT_SERR_DE BIT20 > -#define EFI_AHCI_PORT_SERR_CRCE BIT21 > -#define EFI_AHCI_PORT_SERR_HE BIT22 > -#define EFI_AHCI_PORT_SERR_LSE BIT23 > -#define EFI_AHCI_PORT_SERR_TSTE BIT24 > -#define EFI_AHCI_PORT_SERR_UFT BIT25 > -#define EFI_AHCI_PORT_SERR_EX BIT26 > -#define EFI_AHCI_PORT_ERR_CLEAR 0xFFFFFFFF > -#define EFI_AHCI_PORT_SACT 0x0034 > -#define EFI_AHCI_PORT_CI 0x0038 > -#define EFI_AHCI_PORT_SNTF 0x003C > - > - > -#pragma pack(1) > -// > -// Command List structure includes total 32 entries. > -// The entry Data structure is listed at the following. > -// > -typedef struct { > - UINT32 AhciCmdCfl:5; //Command FIS Length > - UINT32 AhciCmdA:1; //ATAPI > - UINT32 AhciCmdW:1; //Write > - UINT32 AhciCmdP:1; //Prefetchable > - UINT32 AhciCmdR:1; //Reset > - UINT32 AhciCmdB:1; //BIST > - UINT32 AhciCmdC:1; //Clear Busy upon R_OK > - UINT32 AhciCmdRsvd:1; > - UINT32 AhciCmdPmp:4; //Port Multiplier Port > - UINT32 AhciCmdPrdtl:16; //Physical Region Descriptor Table Length > - UINT32 AhciCmdPrdbc; //Physical Region Descriptor Byte Count > - UINT32 AhciCmdCtba; //Command Table Descriptor Base Address > - UINT32 AhciCmdCtbau; //Command Table Descriptor Base Address > Upper 32-BITs > - UINT32 AhciCmdRsvd1[4]; > -} EFI_AHCI_COMMAND_LIST; > - > -// > -// This is a software constructed FIS. > -// For Data transfer operations, this is the H2D Register FIS format as > -// specified in the Serial ATA Revision 2.6 specification. > -// > -typedef struct { > - UINT8 AhciCFisType; > - UINT8 AhciCFisPmNum:4; > - UINT8 AhciCFisRsvd:1; > - UINT8 AhciCFisRsvd1:1; > - UINT8 AhciCFisRsvd2:1; > - UINT8 AhciCFisCmdInd:1; > - UINT8 AhciCFisCmd; > - UINT8 AhciCFisFeature; > - UINT8 AhciCFisSecNum; > - UINT8 AhciCFisClyLow; > - UINT8 AhciCFisClyHigh; > - UINT8 AhciCFisDevHead; > - UINT8 AhciCFisSecNumExp; > - UINT8 AhciCFisClyLowExp; > - UINT8 AhciCFisClyHighExp; > - UINT8 AhciCFisFeatureExp; > - UINT8 AhciCFisSecCount; > - UINT8 AhciCFisSecCountExp; > - UINT8 AhciCFisRsvd3; > - UINT8 AhciCFisControl; > - UINT8 AhciCFisRsvd4[4]; > - UINT8 AhciCFisRsvd5[44]; > -} EFI_AHCI_COMMAND_FIS; > - > -// > -// ACMD: ATAPI command (12 or 16 bytes) > -// > -typedef struct { > - UINT8 AtapiCmd[0x10]; > -} EFI_AHCI_ATAPI_COMMAND; > - > -// > -// Physical Region Descriptor Table includes up to 65535 entries > -// The entry Data structure is listed at the following. > -// the actual entry number comes from the PRDTL field in the command > -// list entry for this command slot. > -// > -typedef struct { > - UINT32 AhciPrdtDba; //Data Base Address > - UINT32 AhciPrdtDbau; //Data Base Address Upper 32-BITs > - UINT32 AhciPrdtRsvd; > - UINT32 AhciPrdtDbc:22; //Data Byte Count > - UINT32 AhciPrdtRsvd1:9; > - UINT32 AhciPrdtIoc:1; //Interrupt on Completion > -} EFI_AHCI_COMMAND_PRDT; > - > -// > -// Command table Data strucute which is pointed to by the entry in the > command list > -// > -typedef struct { > - EFI_AHCI_COMMAND_FIS CommandFis; // A software constructed > FIS. > - EFI_AHCI_ATAPI_COMMAND AtapiCmd; // 12 or 16 bytes ATAPI cm= d. > - UINT8 Reserved[0x30]; > - EFI_AHCI_COMMAND_PRDT PrdtTable; // The scatter/gather list for > Data transfer > -} EFI_AHCI_COMMAND_TABLE; > - > -// > -// Received FIS structure > -// > -typedef struct { > - UINT8 AhciDmaSetupFis[0x1C]; // Dma Setup Fis: offset 0x00 > - UINT8 AhciDmaSetupFisRsvd[0x04]; > - UINT8 AhciPioSetupFis[0x14]; // Pio Setup Fis: offset 0x20 > - UINT8 AhciPioSetupFisRsvd[0x0C]; > - UINT8 AhciD2HRegisterFis[0x14]; // D2H Register Fis: offset 0x= 40 > - UINT8 AhciD2HRegisterFisRsvd[0x04]; > - UINT64 AhciSetDeviceBitsFis; // Set Device Bits Fix: offset= 0x58 > - UINT8 AhciUnknownFis[0x40]; // Unkonwn Fis: offset 0x60 > - UINT8 AhciUnknownFisRsvd[0x60]; > -} EFI_AHCI_RECEIVED_FIS; > - > -#pragma pack() > - > -typedef struct { > - EFI_AHCI_RECEIVED_FIS *AhciRFis; > - VOID *AhciRFisMapping; > - EFI_AHCI_COMMAND_LIST *AhciCmdList; > - VOID *AhciCmdListMapping; > - EFI_AHCI_COMMAND_TABLE *AhciCommandTable; > - VOID *AhciCommandTableMapping; > -} EFI_AHCI_REGISTERS; > - > -typedef struct { > - VOID *Buffer; > - VOID *BufferMapping; > - EFI_AHCI_REGISTERS AhciRegisters; > - UINT32 AhciBar; > -} AHCI_CONTEXT; > - > -/** > - Allocate transfer-related data struct which is used at AHCI mode. > - > - @param[in, out] AhciContext The pointer to the AHCI_CONTEXT. > - > - @retval EFI_OUT_OF_RESOURCE No enough resource. > - @retval EFI_SUCCESS Successful to allocate resource. > - > -**/ > -EFI_STATUS > -EFIAPI > -AhciAllocateResource ( > - IN OUT AHCI_CONTEXT *AhciContext > - ); > - > -/** > - Free allocated transfer-related data struct which is used at AHCI mode= . > - > - @param[in, out] AhciContext The pointer to the AHCI_CONTEXT. > - > -**/ > -VOID > -EFIAPI > -AhciFreeResource ( > - IN OUT AHCI_CONTEXT *AhciContext > - ); > - > -/** > - Initialize ATA host controller at AHCI mode. > - > - The function is designed to initialize ATA host controller. > - > - @param[in] AhciContext The pointer to the AHCI_CONTEXT. > - @param[in] Port The port number to do initialization. > - > -**/ > -EFI_STATUS > -EFIAPI > -AhciModeInitialize ( > - IN AHCI_CONTEXT *AhciContext, > - IN UINT8 Port > - ); > - > -typedef struct _EFI_ATA_COMMAND_BLOCK { > - UINT8 Reserved1[2]; > - UINT8 AtaCommand; > - UINT8 AtaFeatures; > - UINT8 AtaSectorNumber; > - UINT8 AtaCylinderLow; > - UINT8 AtaCylinderHigh; > - UINT8 AtaDeviceHead; > - UINT8 AtaSectorNumberExp; > - UINT8 AtaCylinderLowExp; > - UINT8 AtaCylinderHighExp; > - UINT8 AtaFeaturesExp; > - UINT8 AtaSectorCount; > - UINT8 AtaSectorCountExp; > - UINT8 Reserved2[6]; > -} EFI_ATA_COMMAND_BLOCK; > - > -typedef struct _EFI_ATA_STATUS_BLOCK { > - UINT8 Reserved1[2]; > - UINT8 AtaStatus; > - UINT8 AtaError; > - UINT8 AtaSectorNumber; > - UINT8 AtaCylinderLow; > - UINT8 AtaCylinderHigh; > - UINT8 AtaDeviceHead; > - UINT8 AtaSectorNumberExp; > - UINT8 AtaCylinderLowExp; > - UINT8 AtaCylinderHighExp; > - UINT8 Reserved2; > - UINT8 AtaSectorCount; > - UINT8 AtaSectorCountExp; > - UINT8 Reserved3[6]; > -} EFI_ATA_STATUS_BLOCK; > - > -/** > - Start a PIO Data transfer on specific port. > - > - @param AhciContext The pointer to the AHCI_CONTEXT. > - @param Port The number of port. > - @param PortMultiplier The timeout Value of stop. > - @param AtapiCommand The atapi command will be used for the > transfer. > - @param AtapiCommandLength The Length of the atapi command. > - @param Read The transfer direction. > - @param AtaCommandBlock The EFI_ATA_COMMAND_BLOCK Data. > - @param AtaStatusBlock The EFI_ATA_STATUS_BLOCK Data. > - @param MemoryAddr The pointer to the Data Buffer. > - @param DataCount The Data count to be transferred. > - @param Timeout The timeout Value of non Data transfer. > - > - @retval EFI_DEVICE_ERROR The PIO Data transfer abort with error occ= urs. > - @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 successfull= y. > - > -**/ > -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. >=20 > -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 BS= D > License > which accompanies this distribution. The full text of the license may b= e > found at > @@ -28,6 +28,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY > KIND, EITHER EXPRESS OR IMPLIED. > #include >=20 > #include > +#include >=20 > #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 BS= D > License > -which accompanies this distribution. The full text of the license may b= e > found at > -http://opensource.org/licenses/bsd-license.php > - > -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > EXPRESS OR IMPLIED. > - > -**/ > - > -#ifndef __OPAL_PASSWORD_NVME_MODE_H__ > -#define __OPAL_PASSWORD_NVME_MODE_H__ > - > - > -#include "OpalNvmeReg.h" > - > -#define NVME_MAX_SECTORS 0x10000 > -// > -// QueueId > -// > -#define NVME_ADMIN_QUEUE 0x00 > -#define NVME_IO_QUEUE 0x01 > - > -typedef struct { > - UINT8 Opcode; > - UINT8 FusedOperation; > - #define NORMAL_CMD 0x00 > - #define FUSED_FIRST_CMD 0x01 > - #define FUSED_SECOND_CMD 0x02 > - UINT16 Cid; > -} NVME_CDW0; > - > -typedef struct { > - NVME_CDW0 Cdw0; > - UINT8 Flags; > - #define CDW10_VALID 0x01 > - #define CDW11_VALID 0x02 > - #define CDW12_VALID 0x04 > - #define CDW13_VALID 0x08 > - #define CDW14_VALID 0x10 > - #define CDW15_VALID 0x20 > - UINT32 Nsid; > - UINT32 Cdw10; > - UINT32 Cdw11; > - UINT32 Cdw12; > - UINT32 Cdw13; > - UINT32 Cdw14; > - UINT32 Cdw15; > -} NVM_EXPRESS_COMMAND; > - > -typedef struct { > - UINT32 Cdw0; > - UINT32 Cdw1; > - UINT32 Cdw2; > - UINT32 Cdw3; > -} NVM_EXPRESS_RESPONSE; > - > -typedef struct { > - UINT64 CommandTimeout; > - UINT64 TransferBuffer; > - UINT32 TransferLength; > - UINT64 MetadataBuffer; > - UINT32 MetadataLength; > - UINT8 QueueId; > - NVM_EXPRESS_COMMAND *NvmeCmd; > - NVM_EXPRESS_RESPONSE *NvmeResponse; > -} NVM_EXPRESS_PASS_THRU_COMMAND_PACKET; > - > - > -#pragma pack(1) > - > -// Internal fields > -typedef enum { > - NvmeStatusUnknown, > - NvmeStatusInit, > - NvmeStatusInuse, > - NvmeStatusMax, > -} NVME_STATUS; > - > -typedef struct { > - UINT32 Nbar; > - VOID *BaseMem; > - VOID *BaseMemMapping; > - BOOLEAN PollCancellation; > - UINT16 NvmeInitWaitTime; > - > - NVME_STATUS State; > - UINT8 BusID; > - UINT8 DeviceID; > - UINT8 FuncID; > - UINTN PciBase; > - > - UINT32 Nsid; > - UINT64 Nsuuid; > - UINT32 BlockSize; > - EFI_LBA LastBlock; > - > - // > - // Pointers to 4kB aligned submission & completion queues. > - // > - NVME_SQ *SqBuffer[NVME_MAX_IO_QUEUES]; > - NVME_CQ *CqBuffer[NVME_MAX_IO_QUEUES]; > - UINT16 Cid[NVME_MAX_IO_QUEUES]; > - > - // > - // Submission and completion queue indices. > - // > - NVME_SQTDBL SqTdbl[NVME_MAX_IO_QUEUES]; > - NVME_CQHDBL CqHdbl[NVME_MAX_IO_QUEUES]; > - UINT8 Pt[NVME_MAX_IO_QUEUES]; > - > - UINTN SqeCount[NVME_MAX_IO_QUEUES]; > - > - // > - // Nvme controller capabilities > - // > - NVME_CAP Cap; > - > - // > - // pointer to identify controller Data > - // > - NVME_ADMIN_CONTROLLER_DATA *ControllerData; > - NVME_ADMIN_NAMESPACE_DATA *NamespaceData; > -} NVME_CONTEXT; > - > -#pragma pack() > - > -/** > - Transfer MMIO Data to memory. > - > - @param[in,out] MemBuffer - Destination: Memory address > - @param[in] MmioAddr - Source: MMIO address > - @param[in] Size - Size for read > - > - @retval EFI_SUCCESS - MMIO read sucessfully > -**/ > -EFI_STATUS > -NvmeMmioRead ( > - IN OUT VOID *MemBuffer, > - IN UINTN MmioAddr, > - IN UINTN Size > - ); > - > -/** > - Transfer memory Data to MMIO. > - > - @param[in,out] MmioAddr - Destination: MMIO address > - @param[in] MemBuffer - Source: Memory address > - @param[in] Size - Size for write > - > - @retval EFI_SUCCESS - MMIO write sucessfully > -**/ > -EFI_STATUS > -NvmeMmioWrite ( > - IN OUT UINTN MmioAddr, > - IN VOID *MemBuffer, > - IN UINTN Size > - ); > - > -/** > - Transfer memory data to MMIO. > - > - @param[in,out] MmioAddr - Destination: MMIO address > - @param[in] MemBuffer - Source: Memory address > - @param[in] Size - Size for write > - > - @retval EFI_SUCCESS - MMIO write sucessfully > -**/ > -EFI_STATUS > -OpalPciWrite ( > - IN OUT UINTN MmioAddr, > - IN VOID *MemBuffer, > - IN UINTN Size > - ); > - > -/** > - Transfer MMIO data to memory. > - > - @param[in,out] MemBuffer - Destination: Memory address > - @param[in] MmioAddr - Source: MMIO address > - @param[in] Size - Size for read > - > - @retval EFI_SUCCESS - MMIO read sucessfully > -**/ > -EFI_STATUS > -OpalPciRead ( > - IN OUT VOID *MemBuffer, > - IN UINTN MmioAddr, > - IN UINTN Size > - ); > - > -/** > - Allocate transfer-related Data struct which is used at Nvme. > - > - @param[in, out] Nvme The pointer to the NVME_CONTEXT Data > structure. > - > - @retval EFI_OUT_OF_RESOURCE No enough resource. > - @retval EFI_SUCCESS Successful to allocate resource. > - > -**/ > -EFI_STATUS > -EFIAPI > -NvmeAllocateResource ( > - IN OUT NVME_CONTEXT *Nvme > - ); > - > -/** > - Free allocated transfer-related Data struct which is used at NVMe. > - > - @param[in, out] Nvme The pointer to the NVME_CONTEXT Data > structure. > - > -**/ > -VOID > -EFIAPI > -NvmeFreeResource ( > - IN OUT NVME_CONTEXT *Nvme > - ); > - > -/** > - Sends an NVM Express Command Packet to an NVM Express controller or > namespace. This function supports > - both blocking I/O and nonblocking I/O. The blocking I/O functionality = is > required, and the nonblocking > - I/O functionality is optional. > - > - @param[in] Nvme - The pointer to the NVME_CONTEXT Da= ta > structure. > - @param[in] NamespaceId - Is a 32 bit Namespace ID to which = the > Express HCI command packet will be sent. > - A Value of 0 denotes the NVM Expre= ss controller, a Value > of all 0FFh in the namespace > - ID specifies that the command pack= et should be sent to > all valid namespaces. > - @param[in] NamespaceUuid - Is a 64 bit Namespace UUID to whic= h > the Express HCI command packet will be sent. > - A Value of 0 denotes the NVM Expre= ss controller, a Value > of all 0FFh in the namespace > - UUID specifies that the command pa= cket should be sent > to all valid namespaces. > - @param[in,out] Packet - A pointer to the NVM Express HCI > Command Packet to send to the NVMe namespace specified > - by NamespaceId. > - > - @retval EFI_SUCCESS - The NVM Express Command Packet was= sent > by the host. TransferLength bytes were transferred > - to, or from DataBuffer. > - @retval EFI_NOT_READY - The NVM Express Command Packet cou= ld > not be sent because the controller is not ready. The caller > - may retry again later. > - @retval EFI_DEVICE_ERROR - A device error occurred while atte= mpting > 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 sen= t, so no additional > status information is available. > - @retval EFI_UNSUPPORTED - The command described by the NVM > Express Command Packet is not supported by the host adapter. > - The NVM Express Command Packet was= not sent, so no > additional status information is available. > - @retval EFI_TIMEOUT - A timeout occurred while waiting f= or 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 Da= ta > 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 complet= ed > - @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 Da= ta > structure. > - > - @retval EFI_SUCCESS - The NVM Express Controller is init= ialized > successfully. > - @retval Others - A device error occurred while init= ializing the > controller. > - > -**/ > -EFI_STATUS > -NvmeControllerInit ( > - IN NVME_CONTEXT *Nvme > - ); > - > -/** > - Un-initialize the Nvm Express controller. > - > - @param[in] Nvme - The pointer to the NVME_CONTEXT Da= ta > structure. > - > - @retval EFI_SUCCESS - The NVM Express Controller is un-i= nitialized > successfully. > - @retval Others - A device error occurred while un-i= nitializing the > controller. > - > -**/ > -EFI_STATUS > -NvmeControllerExit ( > - IN NVME_CONTEXT *Nvme > - ); > - > -/** > - Security send and receive commands. > - > - @param[in] Nvme - The pointer to the NVME_CONTEX= T Data > structure. > - @param[in] SendCommand - The flag to indicate the comma= nd > type, TRUE for Send command and FALSE for receive command > - @param[in] SecurityProtocol - Security Protocol > - @param[in] SpSpecific - Security Protocol Specific > - @param[in] TransferLength - Transfer Length of Buffer (in = bytes) - > always a multiple of 512 > - @param[in,out] TransferBuffer - Address of Data to transfer > - > - @return EFI_SUCCESS - Successfully create io submission = queue. > - @return others - Fail to send/receive commands. > - > -**/ > -EFI_STATUS > -NvmeSecuritySendReceive ( > - IN NVME_CONTEXT *Nvme, > - IN BOOLEAN SendCommand, > - IN UINT8 SecurityProtocol, > - IN UINT16 SpSpecific, > - IN UINTN TransferLength, > - IN OUT VOID *TransferBuffer > - ); > - > -#endif > diff --git a/SecurityPkg/Tcg/Opal/OpalPassword/OpalNvmeReg.h > b/SecurityPkg/Tcg/Opal/OpalPassword/OpalNvmeReg.h > deleted file mode 100644 > index 03376b9e6c..0000000000 > --- a/SecurityPkg/Tcg/Opal/OpalPassword/OpalNvmeReg.h > +++ /dev/null > @@ -1,815 +0,0 @@ > -/** @file > - Header file for Registers and Structure definitions > - > -Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.
> -This program and the accompanying materials > -are licensed and made available under the terms and conditions of the BS= D > License > -which accompanies this distribution. The full text of the license may b= e > found at > -http://opensource.org/licenses/bsd-license.php > - > -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > EXPRESS OR IMPLIED. > - > -**/ > -#ifndef __OPAL_PASSWORD_NVME_REG_H__ > -#define __OPAL_PASSWORD_NVME_REG_H__ > - > -// > -// PCI Header for PCIe root port configuration > -// > -#define NVME_PCIE_PCICMD 0x04 > -#define NVME_PCIE_BNUM 0x18 > -#define NVME_PCIE_SEC_BNUM 0x19 > -#define NVME_PCIE_IOBL 0x1C > -#define NVME_PCIE_MBL 0x20 > -#define NVME_PCIE_PMBL 0x24 > -#define NVME_PCIE_PMBU32 0x28 > -#define NVME_PCIE_PMLU32 0x2C > -#define NVME_PCIE_INTR 0x3C > - > -// > -// NVMe related definitions > -// > -#define PCI_CLASS_MASS_STORAGE_NVM 0x08 // mass storage > sub-class non-volatile memory. > -#define PCI_IF_NVMHCI 0x02 // mass storage = programming > interface NVMHCI. > - > -#define NVME_ASQ_SIZE 1 // Number= of admin > submission queue entries, which is 0-based > -#define NVME_ACQ_SIZE 1 // Number= of admin > completion queue entries, which is 0-based > - > -#define NVME_CSQ_SIZE 63 // Numbe= r of I/O > submission queue entries, which is 0-based > -#define NVME_CCQ_SIZE 63 // Numbe= r of I/O > completion queue entries, which is 0-based > - > -#define NVME_MAX_IO_QUEUES 2 // Number= of I/O > queues supported by the driver, 1 for AQ, 1 for CQ > - > -#define NVME_CSQ_DEPTH (NVME_CSQ_SIZE+= 1) > -#define NVME_CCQ_DEPTH (NVME_CCQ_SIZE+= 1) > -#define NVME_PRP_SIZE (4) // Pages= of PRP list > - > -#define NVME_CONTROLLER_ID 0 > - > -// > -// Time out Value for Nvme transaction execution > -// > -#define NVME_GENERIC_TIMEOUT 5000000 ///< = us > -#define NVME_CMD_WAIT 100 ///< = us > -#define NVME_CMD_TIMEOUT 20000000 ///< = us > - > - > - > -#define NVME_MEM_MAX_SIZE \ > - (( \ > - 1 /* Controller Data */ + \ > - 1 /* Identify Data */ + \ > - 1 /* ASQ */ + \ > - 1 /* ACQ */ + \ > - 1 /* SQs */ + \ > - 1 /* CQs */ + \ > - NVME_PRP_SIZE * NVME_CSQ_DEPTH /* PRPs */ + \ > - 1 /* SECURITY */ \ > - ) * EFI_PAGE_SIZE) > - > - > -// > -// controller register offsets > -// > -#define NVME_CAP_OFFSET 0x0000 // Controller Capabilities > -#define NVME_VER_OFFSET 0x0008 // Version > -#define NVME_INTMS_OFFSET 0x000c // Interrupt Mask Set > -#define NVME_INTMC_OFFSET 0x0010 // Interrupt Mask Clear > -#define NVME_CC_OFFSET 0x0014 // Controller Configuration > -#define NVME_CSTS_OFFSET 0x001c // Controller Status > -#define NVME_AQA_OFFSET 0x0024 // Admin Queue Attributes > -#define NVME_ASQ_OFFSET 0x0028 // Admin Submission Queue Base > Address > -#define NVME_ACQ_OFFSET 0x0030 // Admin Completion Queue Base > Address > -#define NVME_SQ0_OFFSET 0x1000 // Submission Queue 0 (admin) > Tail Doorbell > -#define NVME_CQ0_OFFSET 0x1004 // Completion Queue 0 (admin) > Head Doorbell > - > -// > -// These register offsets are defined as 0x1000 + (N * (4 << CAP.DSTRD)) > -// Get the doorbell stride bit shift Value from the controller capabilit= ies. > -// > -#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 - Submissi= on > 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 Referenc= e Tag */ > - // > - // CDW 15 > - // > - UINT16 Elbat; /* Expected Logical Block Application Tag = */ > - UINT16 Elbatm; /* Expected Logical Block Application Tag = Mask */ > -} NVME_READ; > - > -// > -// Write Command > -// > -typedef struct { > - // > - // CDW 10, 11 > - // > - UINT64 Slba; /* Starting Sector Address */ > - // > - // CDW 12 > - // > - UINT16 Nlb; /* Number of Sectors */ > - UINT16 Rsvd1:10; > - UINT16 Prinfo:4; /* Protection Info Check */ > - UINT16 Fua:1; /* Force Unit Access */ > - UINT16 Lr:1; /* Limited Retry */ > - // > - // CDW 13 > - // > - UINT32 Af:4; /* Access Frequency */ > - UINT32 Al:2; /* Access Latency */ > - UINT32 Sr:1; /* Sequential Request */ > - UINT32 In:1; /* Incompressible */ > - UINT32 Rsvd2:24; > - // > - // CDW 14 > - // > - UINT32 Ilbrt; /* Initial Logical Block Reference Tag */ > - // > - // CDW 15 > - // > - UINT16 Lbat; /* Logical Block Application Tag */ > - UINT16 Lbatm; /* Logical Block Application Tag Mask */ > -} NVME_WRITE; > - > -// > -// Flush > -// > -typedef struct { > - // > - // CDW 10 > - // > - UINT32 Flush; /* Flush */ > -} NVME_FLUSH; > - > -// > -// Write Uncorrectable command > -// > -typedef struct { > - // > - // CDW 10, 11 > - // > - UINT64 Slba; /* Starting LBA */ > - // > - // CDW 12 > - // > - UINT32 Nlb:16; /* Number of Logical Blocks */ > - UINT32 Rsvd1:16; > -} NVME_WRITE_UNCORRECTABLE; > - > -// > -// Write Zeroes command > -// > -typedef struct { > - // > - // CDW 10, 11 > - // > - UINT64 Slba; /* Starting LBA */ > - // > - // CDW 12 > - // > - UINT16 Nlb; /* Number of Logical Blocks */ > - UINT16 Rsvd1:10; > - UINT16 Prinfo:4; /* Protection Info Check */ > - UINT16 Fua:1; /* Force Unit Access */ > - UINT16 Lr:1; /* Limited Retry */ > - // > - // CDW 13 > - // > - UINT32 Rsvd2; > - // > - // CDW 14 > - // > - UINT32 Ilbrt; /* Initial Logical Block Reference Tag */ > - // > - // CDW 15 > - // > - UINT16 Lbat; /* Logical Block Application Tag */ > - UINT16 Lbatm; /* Logical Block Application Tag Mask */ > -} NVME_WRITE_ZEROES; > - > -// > -// Compare command > -// > -typedef struct { > - // > - // CDW 10, 11 > - // > - UINT64 Slba; /* Starting LBA */ > - // > - // CDW 12 > - // > - UINT16 Nlb; /* Number of Logical Blocks */ > - UINT16 Rsvd1:10; > - UINT16 Prinfo:4; /* Protection Info Check */ > - UINT16 Fua:1; /* Force Unit Access */ > - UINT16 Lr:1; /* Limited Retry */ > - // > - // CDW 13 > - // > - UINT32 Rsvd2; > - // > - // CDW 14 > - // > - UINT32 Eilbrt; /* Expected Initial Logical Block Referenc= e Tag */ > - // > - // CDW 15 > - // > - UINT16 Elbat; /* Expected Logical Block Application Tag = */ > - UINT16 Elbatm; /* Expected Logical Block Application Tag = Mask */ > -} NVME_COMPARE; > - > -typedef union { > - NVME_READ Read; > - NVME_WRITE Write; > - NVME_FLUSH Flush; > - NVME_WRITE_UNCORRECTABLE WriteUncorrectable; > - NVME_WRITE_ZEROES WriteZeros; > - NVME_COMPARE Compare; > -} NVME_CMD; > - > -typedef struct { > - UINT16 Mp; /* Maximum Power */ > - UINT8 Rsvd1; /* Reserved as of Nvm Express 1.1 Spec */ > - UINT8 Mps:1; /* Max Power Scale */ > - UINT8 Nops:1; /* Non-Operational State */ > - UINT8 Rsvd2:6; /* Reserved as of Nvm Express 1.1 Spec */ > - UINT32 Enlat; /* Entry Latency */ > - UINT32 Exlat; /* Exit Latency */ > - UINT8 Rrt:5; /* Relative Read Throughput */ > - UINT8 Rsvd3:3; /* Reserved as of Nvm Express 1.1 Spec */ > - UINT8 Rrl:5; /* Relative Read Leatency */ > - UINT8 Rsvd4:3; /* Reserved as of Nvm Express 1.1 Spec */ > - UINT8 Rwt:5; /* Relative Write Throughput */ > - UINT8 Rsvd5:3; /* Reserved as of Nvm Express 1.1 Spec */ > - UINT8 Rwl:5; /* Relative Write Leatency */ > - UINT8 Rsvd6:3; /* Reserved as of Nvm Express 1.1 Spec */ > - UINT8 Rsvd7[16]; /* Reserved as of Nvm Express 1.1 Spec */ > -} NVME_PSDESCRIPTOR; > - > -// > -// Identify Controller Data > -// > -typedef struct { > - // > - // Controller Capabilities and Features 0-255 > - // > - UINT16 Vid; /* PCI Vendor ID */ > - UINT16 Ssvid; /* PCI sub-system vendor ID */ > - UINT8 Sn[20]; /* Produce serial number */ > - > - UINT8 Mn[40]; /* Proeduct model number */ > - UINT8 Fr[8]; /* Firmware Revision */ > - UINT8 Rab; /* Recommended Arbitration Burst */ > - UINT8 Ieee_oiu[3]; /* Organization Unique Identifier */ > - UINT8 Cmic; /* Multi-interface Capabilities */ > - UINT8 Mdts; /* Maximum Data Transfer Size */ > - UINT8 Cntlid[2]; /* Controller ID */ > - UINT8 Rsvd1[176]; /* Reserved as of Nvm Express 1.1 Spec */ > - // > - // Admin Command Set Attributes > - // > - UINT16 Oacs; /* Optional Admin Command Support */ > - UINT8 Acl; /* Abort Command Limit */ > - UINT8 Aerl; /* Async Event Request Limit */ > - UINT8 Frmw; /* Firmware updates */ > - UINT8 Lpa; /* Log Page Attributes */ > - UINT8 Elpe; /* Error Log Page Entries */ > - UINT8 Npss; /* Number of Power States Support */ > - UINT8 Avscc; /* Admin Vendor Specific Command Configura= tion */ > - UINT8 Apsta; /* Autonomous Power State Transition Attri= butes */ > - 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 Configurati= on */ > - 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 comm= ands */ > - UINT16 Format : 1; /* supports format nvm command */ > - UINT16 Firmware : 1; /* supports firmware activate/download > commands */ > - UINT16 Oacs_rsvd : 13; > - } OACS; // optional admin command support: > NVME_ADMIN_CONTROLLER_DATA.Oacs > - > -typedef struct { > - UINT16 Ms; /* Metadata Size */ > - UINT8 Lbads; /* LBA Data Size */ > - UINT8 Rp:2; /* Relative Performance */ > - #define LBAF_RP_BEST 00b > - #define LBAF_RP_BETTER 01b > - #define LBAF_RP_GOOD 10b > - #define LBAF_RP_DEGRADED 11b > - UINT8 Rsvd1:6; /* Reserved as of Nvm Express 1.1 Spec */ > -} NVME_LBAFORMAT; > - > -// > -// Identify Namespace Data > -// > -typedef struct { > - // > - // NVM Command Set Specific > - // > - UINT64 Nsze; /* Namespace Size (total number of blocks = in > formatted namespace) */ > - UINT64 Ncap; /* Namespace Capacity (max number of logic= al blocks) > */ > - UINT64 Nuse; /* Namespace Utilization */ > - UINT8 Nsfeat; /* Namespace Features */ > - UINT8 Nlbaf; /* Number of LBA Formats */ > - UINT8 Flbas; /* Formatted LBA Size */ > - UINT8 Mc; /* Metadata Capabilities */ > - UINT8 Dpc; /* End-to-end Data Protection capabilities= */ > - UINT8 Dps; /* End-to-end Data Protection Type Setting= s */ > - UINT8 Nmic; /* Namespace Multi-path I/O and Namespace = Sharing > Capabilities */ > - UINT8 Rescap; /* Reservation Capabilities */ > - UINT8 Rsvd1[88]; /* Reserved as of Nvm Express 1.1 Spec */ > - UINT64 Eui64; /* IEEE Extended Unique Identifier */ > - // > - // LBA Format > - // > - NVME_LBAFORMAT LbaFormat[16]; > - > - UINT8 Rsvd2[192]; /* Reserved as of Nvm Express 1.1 Spec */ > - UINT8 VendorData[3712]; /* Vendor specific Data */ > -} NVME_ADMIN_NAMESPACE_DATA; > - > -// > -// NvmExpress Admin Identify Cmd > -// > -typedef struct { > - // > - // CDW 10 > - // > - UINT32 Cns:2; > - UINT32 Rsvd1:30; > -} NVME_ADMIN_IDENTIFY; > - > -// > -// NvmExpress Admin Create I/O Completion Queue > -// > -typedef struct { > - // > - // CDW 10 > - // > - UINT32 Qid:16; /* Queue Identifier */ > - UINT32 Qsize:16; /* Queue Size */ > - > - // > - // CDW 11 > - // > - UINT32 Pc:1; /* Physically Contiguous */ > - UINT32 Ien:1; /* Interrupts Enabled */ > - UINT32 Rsvd1:14; /* reserved as of Nvm Express 1.1 Spec */ > - UINT32 Iv:16; /* Interrupt Vector */ > -} NVME_ADMIN_CRIOCQ; > - > -// > -// NvmExpress Admin Create I/O Submission Queue > -// > -typedef struct { > - // > - // CDW 10 > - // > - UINT32 Qid:16; /* Queue Identifier */ > - UINT32 Qsize:16; /* Queue Size */ > - > - // > - // CDW 11 > - // > - UINT32 Pc:1; /* Physically Contiguous */ > - UINT32 Qprio:2; /* Queue Priority */ > - UINT32 Rsvd1:13; /* Reserved as of Nvm Express 1.1 Spec */ > - UINT32 Cqid:16; /* Completion Queue ID */ > -} NVME_ADMIN_CRIOSQ; > - > -// > -// NvmExpress Admin Delete I/O Completion Queue > -// > -typedef struct { > - // > - // CDW 10 > - // > - UINT16 Qid; > - UINT16 Rsvd1; > -} NVME_ADMIN_DEIOCQ; > - > -// > -// NvmExpress Admin Delete I/O Submission Queue > -// > -typedef struct { > - // > - // CDW 10 > - // > - UINT16 Qid; > - UINT16 Rsvd1; > -} NVME_ADMIN_DEIOSQ; > - > -// > -// NvmExpress Admin Security Send > -// > -typedef struct { > - // > - // CDW 10 > - // > - UINT32 Resv:8; /* Reserve */ > - UINT32 Spsp:16; /* SP Specific */ > - UINT32 Secp:8; /* Security Protocol */ > - > - // > - // CDW 11 > - // > - UINT32 Tl; /* Transfer Length */ > -} NVME_ADMIN_SECSEND; > - > -// > -// NvmExpress Admin Abort Command > -// > -typedef struct { > - // > - // CDW 10 > - // > - UINT32 Sqid:16; /* Submission Queue identifier */ > - UINT32 Cid:16; /* Command Identifier */ > -} NVME_ADMIN_ABORT; > - > -// > -// NvmExpress Admin Firmware Activate Command > -// > -typedef struct { > - // > - // CDW 10 > - // > - UINT32 Fs:3; /* Submission Queue identifier */ > - UINT32 Aa:2; /* Command Identifier */ > - UINT32 Rsvd1:27; > -} NVME_ADMIN_FIRMWARE_ACTIVATE; > - > -// > -// NvmExpress Admin Firmware Image Download Command > -// > -typedef struct { > - // > - // CDW 10 > - // > - UINT32 Numd; /* Number of Dwords */ > - // > - // CDW 11 > - // > - UINT32 Ofst; /* Offset */ > -} NVME_ADMIN_FIRMWARE_IMAGE_DOWNLOAD; > - > -// > -// NvmExpress Admin Get Features Command > -// > -typedef struct { > - // > - // CDW 10 > - // > - UINT32 Fid:8; /* Feature Identifier */ > - UINT32 Sel:3; /* Select */ > - UINT32 Rsvd1:21; > -} NVME_ADMIN_GET_FEATURES; > - > -// > -// NvmExpress Admin Get Log Page Command > -// > -typedef struct { > - // > - // CDW 10 > - // > - UINT32 Lid:8; /* Log Page Identifier */ > - #define LID_ERROR_INFO > - #define LID_SMART_INFO > - #define LID_FW_SLOT_INFO > - UINT32 Rsvd1:8; > - UINT32 Numd:12; /* Number of Dwords */ > - UINT32 Rsvd2:4; /* Reserved as of Nvm Express 1.1 Spec */ > -} NVME_ADMIN_GET_LOG_PAGE; > - > -// > -// NvmExpress Admin Set Features Command > -// > -typedef struct { > - // > - // CDW 10 > - // > - UINT32 Fid:8; /* Feature Identifier */ > - UINT32 Rsvd1:23; > - UINT32 Sv:1; /* Save */ > -} NVME_ADMIN_SET_FEATURES; > - > -// > -// NvmExpress Admin Format NVM Command > -// > -typedef struct { > - // > - // CDW 10 > - // > - UINT32 Lbaf:4; /* LBA Format */ > - UINT32 Ms:1; /* Metadata Settings */ > - UINT32 Pi:3; /* Protection Information */ > - UINT32 Pil:1; /* Protection Information Location */ > - UINT32 Ses:3; /* Secure Erase Settings */ > - UINT32 Rsvd1:20; > -} NVME_ADMIN_FORMAT_NVM; > - > -// > -// NvmExpress Admin Security Receive Command > -// > -typedef struct { > - // > - // CDW 10 > - // > - UINT32 Rsvd1:8; > - UINT32 Spsp:16; /* SP Specific */ > - UINT32 Secp:8; /* Security Protocol */ > - // > - // CDW 11 > - // > - UINT32 Al; /* Allocation Length */ > -} NVME_ADMIN_SECURITY_RECEIVE; > - > -// > -// NvmExpress Admin Security Send Command > -// > -typedef struct { > - // > - // CDW 10 > - // > - UINT32 Rsvd1:8; > - UINT32 Spsp:16; /* SP Specific */ > - UINT32 Secp:8; /* Security Protocol */ > - // > - // CDW 11 > - // > - UINT32 Tl; /* Transfer Length */ > -} NVME_ADMIN_SECURITY_SEND; > - > -typedef union { > - NVME_ADMIN_IDENTIFY Identify; > - NVME_ADMIN_CRIOCQ CrIoCq; > - NVME_ADMIN_CRIOSQ CrIoSq; > - NVME_ADMIN_DEIOCQ DeIoCq; > - NVME_ADMIN_DEIOSQ DeIoSq; > - NVME_ADMIN_ABORT Abort; > - NVME_ADMIN_FIRMWARE_ACTIVATE Activate; > - NVME_ADMIN_FIRMWARE_IMAGE_DOWNLOAD > FirmwareImageDownload; > - NVME_ADMIN_GET_FEATURES GetFeatures; > - NVME_ADMIN_GET_LOG_PAGE GetLogPage; > - NVME_ADMIN_SET_FEATURES SetFeatures; > - NVME_ADMIN_FORMAT_NVM FormatNvm; > - NVME_ADMIN_SECURITY_RECEIVE SecurityReceive; > - NVME_ADMIN_SECURITY_SEND SecuritySend; > -} NVME_ADMIN_CMD; > - > -typedef struct { > - UINT32 Cdw10; > - UINT32 Cdw11; > - UINT32 Cdw12; > - UINT32 Cdw13; > - UINT32 Cdw14; > - UINT32 Cdw15; > -} NVME_RAW; > - > -typedef union { > - NVME_ADMIN_CMD Admin; // Union of Admin commands > - NVME_CMD Nvm; // Union of Nvm commands > - NVME_RAW Raw; > -} NVME_PAYLOAD; > - > -// > -// Submission Queue > -// > -typedef struct { > - // > - // CDW 0, Common to all comnmands > - // > - UINT8 Opc; // Opcode > - UINT8 Fuse:2; // Fused Operation > - UINT8 Rsvd1:5; > - UINT8 Psdt:1; // PRP or SGL for Data Transfer > - UINT16 Cid; // Command Identifier > - > - // > - // CDW 1 > - // > - UINT32 Nsid; // Namespace Identifier > - > - // > - // CDW 2,3 > - // > - UINT64 Rsvd2; > - > - // > - // CDW 4,5 > - // > - UINT64 Mptr; // Metadata Pointer > - > - // > - // CDW 6-9 > - // > - UINT64 Prp[2]; // First and second PRP entries > - > - NVME_PAYLOAD Payload; > - > -} NVME_SQ; > - > -// > -// Completion Queue > -// > -typedef struct { > - // > - // CDW 0 > - // > - UINT32 Dword0; > - // > - // CDW 1 > - // > - UINT32 Rsvd1; > - // > - // CDW 2 > - // > - UINT16 Sqhd; // Submission Queue Head Pointer > - UINT16 Sqid; // Submission Queue Identifier > - // > - // CDW 3 > - // > - UINT16 Cid; // Command Identifier > - UINT16 Pt:1; // Phase Tag > - UINT16 Sc:8; // Status Code > - UINT16 Sct:3; // Status Code Type > - UINT16 Rsvd2:2; > - UINT16 Mo:1; // More > - UINT16 Dnr:1; // Retry > -} NVME_CQ; > - > -// > -// Nvm Express Admin cmd opcodes > -// > -#define NVME_ADMIN_DELIOSQ_OPC 0 > -#define NVME_ADMIN_CRIOSQ_OPC 1 > -#define NVME_ADMIN_DELIOCQ_OPC 4 > -#define NVME_ADMIN_CRIOCQ_OPC 5 > -#define NVME_ADMIN_IDENTIFY_OPC 6 > -#define NVME_ADMIN_SECURITY_SEND_OPC 0x81 > -#define NVME_ADMIN_SECURITY_RECV_OPC 0x82 > - > -#define NVME_IO_FLUSH_OPC 0 > -#define NVME_IO_WRITE_OPC 1 > -#define NVME_IO_READ_OPC 2 > - > -// > -// Offset from the beginning of private Data queue Buffer > -// > -#define NVME_ASQ_BUF_OFFSET EFI_PAGE_SIZE > - > -#pragma pack() > - > -#endif > - > diff --git a/SecurityPkg/Tcg/Opal/OpalPassword/OpalPasswordCommon.h > b/SecurityPkg/Tcg/Opal/OpalPassword/OpalPasswordCommon.h > index e10146e466..f9fdb64137 100644 > --- a/SecurityPkg/Tcg/Opal/OpalPassword/OpalPasswordCommon.h > +++ b/SecurityPkg/Tcg/Opal/OpalPassword/OpalPasswordCommon.h > @@ -1,7 +1,7 @@ > /** @file > Opal Password common header file. >=20 > -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 BS= D > License > which accompanies this distribution. The full text of the license may b= e > found at > @@ -30,38 +30,15 @@ typedef struct { > } OPAL_PCI_DEVICE; >=20 > 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 } } >=20 > #endif // _OPAL_PASSWORD_COMMON_H_ > diff --git a/SecurityPkg/Tcg/Opal/OpalPassword/OpalPasswordPei.h > b/SecurityPkg/Tcg/Opal/OpalPassword/OpalPasswordPei.h > index 31aab37f5d..c86598f21c 100644 > --- a/SecurityPkg/Tcg/Opal/OpalPassword/OpalPasswordPei.h > +++ b/SecurityPkg/Tcg/Opal/OpalPassword/OpalPasswordPei.h > @@ -1,7 +1,7 @@ > /** @file > Opal Password PEI driver which is used to unlock Opal Password for S3. >=20 > -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 BS= D > License > which accompanies this distribution. The full text of the license may b= e > found at > @@ -16,8 +16,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY > KIND, EITHER EXPRESS OR IMPLIED. > #define _OPAL_PASSWORD_PEI_H_ >=20 > #include > -#include > -#include >=20 > #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 >=20 > #include >=20 > #include > +#include >=20 > #include "OpalPasswordCommon.h" > -#include "OpalAhciMode.h" > -#include "OpalNvmeMode.h" >=20 > // > -// 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 >=20 > // > -// 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 >=20 > #pragma pack(1) >=20 > -/** > -* 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'= ) >=20 > 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; >=20 > -#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) >=20 > #pragma pack() >=20 > -/** > - 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 memor= y > address of the > - allocated range. > - @param DeviceAddress The resulting map address for the bus ma= ster > 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 allocate= d. > - @retval EFI_UNSUPPORTED Attributes is unsupported. The only lega= l > 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'= ) >=20 > -/** > - Frees memory that was allocated with AllocateBuffer(). > +typedef struct { > + UINTN Signature; > + EFI_PEI_NOTIFY_DESCRIPTOR SscPpiNotifyList; >=20 > - @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; >=20 > -**/ > -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) >=20 > #endif // _OPAL_PASSWORD_PEI_H_ >=20 > 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 BS= D > License > -which accompanies this distribution. The full text of the license may b= e > 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 Valu= e. > - > - @param Address The system memory address to test. > - @param MaskValue The mask Value of memory. > - @param TestValue The test Value of memory. > - @param Timeout The time out Value for wait memory set, uses= 100ns > as a unit. > - > - @retval EFI_TIMEOUT The system memory setting is time out. > - @retval EFI_SUCCESS The system memory is correct set. > - > -**/ > -EFI_STATUS > -EFIAPI > -AhciWaitMemSet ( > - IN EFI_PHYSICAL_ADDRESS Address, > - IN UINT32 MaskValue, > - IN UINT32 TestValue, > - IN UINT64 Timeout > - ) > -{ > - UINT32 Value; > - UINT32 Delay; > - > - Delay =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 waitting = memory > set. If 0, then just try once. > - > - @retval EFI_NOTREADY The memory is not set. > - @retval EFI_TIMEOUT The memory setting retry times out. > - @retval EFI_SUCCESS The memory is correct set. > - > -**/ > -EFI_STATUS > -EFIAPI > -AhciCheckMemSet ( > - IN UINTN Address, > - IN UINT32 MaskValue, > - IN UINT32 TestValue, > - IN OUT UINTN *RetryTimes OPTIONAL > - ) > -{ > - UINT32 Value; > - > - if (RetryTimes !=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 NOT= 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 t= ransfer. > - @param CommandList The command list will be used for the = transfer. > - @param AtapiCommand The atapi command will be used for the > transfer. > - @param AtapiCommandLength The Length of the atapi command. > - @param CommandSlotNumber The command slot will be used for the > transfer. > - @param DataPhysicalAddr The pointer to the Data Buffer pci bus > master address. > - @param DataLength The Data count to be transferred. > - > -**/ > -VOID > -EFIAPI > -AhciBuildCommand ( > - IN AHCI_CONTEXT *AhciContext, > - IN UINT8 Port, > - IN UINT8 PortMultiplier, > - IN EFI_AHCI_COMMAND_FIS *CommandFis, > - IN EFI_AHCI_COMMAND_LIST *CommandList, > - IN EFI_AHCI_ATAPI_COMMAND *AtapiCommand OPTIONAL, > - IN UINT8 AtapiCommandLength, > - IN UINT8 CommandSlotNumber, > - IN OUT VOID *DataPhysicalAddr, > - IN UINT64 DataLength > - ) > -{ > - EFI_AHCI_REGISTERS *AhciRegisters; > - UINT32 AhciBar; > - UINT64 BaseAddr; > - UINT64 PrdtNumber; > - UINTN RemainedData; > - UINTN MemAddr; > - DATA_64 Data64; > - UINT32 Offset; > - > - AhciRegisters =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 4MB > 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 occ= urs. > - @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 successfull= y. > - > -**/ > -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->AhciRFis)= ; > - 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 port > - // > - 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_WIDTH = + > EFI_AHCI_PORT_TFD; > - PortTfd =3D AhciReadReg (AhciBar, (UINT32) Offset); > - // > - // PxTFD will be updated if there is a D2H or SetupFIS received. > - // For PIO IN transfer, D2H means a device error. Therefore we o= nly > 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 hardw= are > 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 Mode > 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 mode= . > - > - @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 Mode > 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->AhciRFis)= ; > - > - // > - // Single task envrionment, we only use one command table for all port > - // > - 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 soft= ware. > - // > - 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.B= SY > 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" >=20 > -EFI_GUID mOpalDeviceAtaGuid =3D OPAL_DEVICE_ATA_GUID; > -EFI_GUID mOpalDeviceNvmeGuid =3D OPAL_DEVICE_NVME_GUID; > +EFI_GUID mOpalDeviceLockBoxGuid =3D OPAL_DEVICE_LOCKBOX_GUID; >=20 > BOOLEAN mOpalEndOfDxe =3D FALSE; > OPAL_REQUEST_VARIABLE *mOpalRequestVariable =3D NULL; > UINTN mOpalRequestVariableSize =3D 0; > CHAR16 mPopUpString[100]; >=20 > -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 follow= ing > 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; >=20 > // > @@ -233,14 +206,12 @@ OpalSupportUpdatePassword ( > @param[out] DevInfoLength Device information length needed. > @param[out] DevInfo Device information extracted. >=20 > - @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; >=20 > 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 + *DevInfoL= ength); > - 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->Devi= ce, > PciDevPath->Function, PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET)); > } > @@ -333,251 +277,159 @@ ExtractDeviceInfoFromDevicePath ( > } >=20 > 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; > } >=20 > /** > - 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. >=20 > **/ > 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; >=20 > // > - // 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; > } >=20 > - if (DevInfoLengthAta =3D=3D 0) { > + if (TotalDevInfoLength =3D=3D 0) { > return; > } >=20 > - 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; > } >=20 > - TmpDev =3D TmpDev->Next; > - } > - > - if (DevInfoLengthNvme =3D=3D 0) { > + Status =3D RestoreLockBox ( > + &gS3StorageDeviceInitListGuid, > + S3InitDevices, > + &S3InitDevicesLength > + ); > + ASSERT_EFI_ERROR (Status); > + S3InitDevicesExist =3D TRUE; > + } else { > return; > } >=20 > - 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; > } >=20 > - 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; > } >=20 > + TempDevInfo =3D (OPAL_DEVICE_LOCKBOX_DATA *) ((UINTN) > TempDevInfo + DevInfoLength); > TmpDev =3D TmpDev->Next; > } >=20 > Status =3D SaveLockBox ( > - &mOpalDeviceNvmeGuid, > - DevInfoNvme, > - DevInfoLengthNvme > + &mOpalDeviceLockBoxGuid, > + DevInfo, > + TotalDevInfoLength > ); > ASSERT_EFI_ERROR (Status); >=20 > Status =3D SetLockBoxAttributes ( > - &mOpalDeviceNvmeGuid, > + &mOpalDeviceLockBoxGuid, > LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY > ); > ASSERT_EFI_ERROR (Status); >=20 > - 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); > } >=20 > /** > @@ -596,9 +448,6 @@ OpalEndOfDxeEventNotify ( > VOID *Context > ) > { > - EFI_STATUS Status; > - EFI_PHYSICAL_ADDRESS Address; > - UINT64 Length; > OPAL_DRIVER_DEVICE *TmpDev; >=20 > DEBUG ((DEBUG_INFO, "%a() - enter\n", __FUNCTION__)); > @@ -623,24 +472,7 @@ OpalEndOfDxeEventNotify ( > return; > } >=20 > - // > - // Assume 64K size and alignment are enough. > - // > - Length =3D 0x10000; > - Address =3D 0xFFFFFFFF; > - Status =3D gDS->AllocateMemorySpace ( > - EfiGcdAllocateMaxAddressSearchBottomUp, > - EfiGcdMemoryTypeMemoryMappedIo, > - 16, // 2^16: 64K Alignment > - Length, > - &Address, > - gImageHandle, > - NULL > - ); > - ASSERT_EFI_ERROR (Status); > - > - BuildOpalDeviceInfoAta ((UINT32) Address); > - BuildOpalDeviceInfoNvme ((UINT32) Address); > + BuildOpalDeviceInfo (); >=20 > // > // 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 BS= D > License > -which accompanies this distribution. The full text of the license may b= e > 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_P= AGE_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 Da= ta > structure. > - @param[in] WaitReady - Flag for waitting status ready or = not > - > - @return EFI_SUCCESS - Successfully to wait specific stat= us. > - @return others - Fail to wait for specific controll= er 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 t= o 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 Da= ta > structure. > - > - @return EFI_SUCCESS - Successfully disable the controlle= r. > - @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 Da= ta > structure. > - > - @return EFI_SUCCESS - Successfully enable the controller= . > - @return EFI_DEVICE_ERROR - Fail to enable the controller. > - @return EFI_TIMEOUT - Fail to enable the controller in g= iven 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 Da= ta > structure. > - > - @return EFI_SUCCESS - Successfully shutdown the controll= er. > - @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 Conventiona= l > Reset\n")); > - break; > - case 0xC: > - DEBUG ((DEBUG_INFO, "Invalid Queue Deletion\n")); > - break; > - case 0xD: > - DEBUG ((DEBUG_INFO, "Feature Identifier Not Saveable\n")); > - break; > - case 0xE: > - DEBUG ((DEBUG_INFO, "Feature Not Changeable\n")); > - break; > - case 0xF: > - DEBUG ((DEBUG_INFO, "Feature Not Namespace Specific\n")); > - break; > - case 0x10: > - DEBUG ((DEBUG_INFO, "Firmware Application Requires NVM > Subsystem Reset\n")); > - break; > - case 0x80: > - DEBUG ((DEBUG_INFO, "Conflicting Attributes\n")); > - break; > - case 0x81: > - DEBUG ((DEBUG_INFO, "Invalid Protection Information\n")); > - break; > - case 0x82: > - DEBUG ((DEBUG_INFO, "Attempted Write to Read Only Range\n")); > - break; > - } > - break; > - > - case 0x2: > - switch (Cq->Sc) { > - case 0x80: > - DEBUG ((DEBUG_INFO, "Write Fault\n")); > - break; > - case 0x81: > - DEBUG ((DEBUG_INFO, "Unrecovered Read Error\n")); > - break; > - case 0x82: > - DEBUG ((DEBUG_INFO, "End-to-end Guard Check Error\n")); > - break; > - case 0x83: > - DEBUG ((DEBUG_INFO, "End-to-end Application Tag Check Error\n"= )); > - break; > - case 0x84: > - DEBUG ((DEBUG_INFO, "End-to-end Reference Tag Check Error\n"))= ; > - break; > - case 0x85: > - DEBUG ((DEBUG_INFO, "Compare Failure\n")); > - break; > - case 0x86: > - DEBUG ((DEBUG_INFO, "Access Denied\n")); > - break; > - } > - break; > - > - default: > - DEBUG ((DEBUG_INFO, "Unknown error\n")); > - break; > - } > - > - return EFI_DEVICE_ERROR; > -} > - > -/** > - Create PRP lists for Data transfer which is larger than 2 memory pages= . > - Note here we calcuate the number of required PRP lists and allocate th= em > at one time. > - > - @param[in] Nvme - The pointer to the NVME_CONTEXT Da= ta > structure. > - @param[in] SqId - The SQ index for this PRP > - @param[in] PhysicalAddr - The physical base address of Data = Buffer. > - @param[in] Pages - The number of pages to be transfer= ed. > - @param[out] PrpListHost - The host base address of PRP lists= . > - @param[in,out] PrpListNo - The number of PRP List. > - > - @retval The pointer Value to the first PRP List of the PRP lists. > - > -**/ > -STATIC > -UINT64 > -NvmeCreatePrpList ( > - IN NVME_CONTEXT *Nvme, > - IN UINT16 SqId, > - IN EFI_PHYSICAL_ADDRESS PhysicalAddr, > - IN UINTN Pages, > - OUT VOID **PrpListHost, > - IN OUT UINTN *PrpListNo > - ) > -{ > - UINTN PrpEntryNo; > - UINT64 PrpListBase; > - UINTN PrpListIndex; > - UINTN PrpEntryIndex; > - UINT64 Remainder; > - EFI_PHYSICAL_ADDRESS PrpListPhyAddr; > - UINTN Bytes; > - UINT8 *PrpEntry; > - EFI_PHYSICAL_ADDRESS NewPhyAddr; > - > - /// > - /// The number of Prp Entry in a memory page. > - /// > - PrpEntryNo =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; ++PrpListIndex= ) { > - PrpListBase =3D *(UINT64*)PrpListHost + PrpListIndex * EFI_PAGE_SIZE= ; > - > - for (PrpEntryIndex =3D 0; PrpEntryIndex < PrpEntryNo; ++PrpEntryInde= x) { > - 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_S= IZE); > - 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) ? Remain= der : > 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 Da= ta > 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 complet= ed > - @retval others - Error occurred on device side. > -**/ > -EFI_STATUS > -NvmeWaitAllComplete ( > - IN NVME_CONTEXT *Nvme, > - IN UINT8 Qid > - ) > -{ > - return EFI_SUCCESS; > -} > - > -/** > - Sends an NVM Express Command Packet to an NVM Express controller or > namespace. This function supports > - both blocking I/O and nonblocking I/O. The blocking I/O functionality = is > required, and the nonblocking > - I/O functionality is optional. > - > - @param[in] Nvme - The pointer to the NVME_CONTEXT Da= ta > structure. > - @param[in] NamespaceId - Is a 32 bit Namespace ID to which = the > Express HCI command packet will be sent. > - A Value of 0 denotes the NVM Expre= ss controller, a Value > of all 0FFh in the namespace > - ID specifies that the command pack= et should be sent to > all valid namespaces. > - @param[in] NamespaceUuid - Is a 64 bit Namespace UUID to whic= h > the Express HCI command packet will be sent. > - A Value of 0 denotes the NVM Expre= ss controller, a Value > of all 0FFh in the namespace > - UUID specifies that the command pa= cket should be sent > to all valid namespaces. > - @param[in,out] Packet - A pointer to the NVM Express HCI > Command Packet to send to the NVMe namespace specified > - by NamespaceId. > - > - @retval EFI_SUCCESS - The NVM Express Command Packet was= sent > by the host. TransferLength bytes were transferred > - to, or from DataBuffer. > - @retval EFI_NOT_READY - The NVM Express Command Packet cou= ld > not be sent because the controller is not ready. The caller > - may retry again later. > - @retval EFI_DEVICE_ERROR - A device error occurred while atte= mpting > 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 sen= t, so no additional > status information is available. > - @retval EFI_UNSUPPORTED - The command described by the NVM > Express Command Packet is not supported by the host adapter. > - The NVM Express Command Packet was= not sent, so no > additional status information is available. > - @retval EFI_TIMEOUT - A timeout occurred while waiting f= or 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 NULL= )) { > - DEBUG ((DEBUG_ERROR, "NvmePassThru, invalid parameter: > NvmeCmd(%x)/NvmeResponse(%x)\n", > - (UINTN)Packet->NvmeCmd, (UINTN)Packet->NvmeResponse)); > - return EFI_INVALID_PARAMETER; > - } > - > - if (Packet->QueueId !=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 suppor= ted. > - /// > - 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 as > 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", Statu= s)); > - 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 ti= meout > 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 Da= ta > structure. > - @param[in] Buffer - The Buffer used to store the ident= ify controller > Data. > - > - @return EFI_SUCCESS - Successfully get the identify cont= roller Data. > - @return others - Fail to get the identify controlle= r 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 fie= ld > shall be cleared to 0h. > - // For the Identify command, the Namespace Identifier is only used for= 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 Da= ta > structure. > - @param[in] NamespaceId - The specified namespace identifier= . > - @param[in] Buffer - The Buffer used to store the ident= ify > namespace Data. > - > - @return EFI_SUCCESS - Successfully get the identify name= space > Data. > - @return others - Fail to get the identify namespace= Data. > - > -**/ > -STATIC > -EFI_STATUS > -NvmeIdentifyNamespace ( > - IN NVME_CONTEXT *Nvme, > - IN UINT32 NamespaceId, > - IN VOID *Buffer > - ) > -{ > - NVM_EXPRESS_PASS_THRU_COMMAND_PACKET CommandPacket; > - NVM_EXPRESS_COMMAND Command; > - NVM_EXPRESS_RESPONSE Response; > - EFI_STATUS Status; > - > - ZeroMem (&CommandPacket, > sizeof(NVM_EXPRESS_PASS_THRU_COMMAND_PACKET)); > - ZeroMem (&Command, sizeof(NVM_EXPRESS_COMMAND)); > - ZeroMem (&Response, sizeof(NVM_EXPRESS_RESPONSE)); > - > - CommandPacket.NvmeCmd =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 Da= ta > 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 Da= ta > 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 Da= ta > structure. > - > - @return EFI_SUCCESS - Successfully create io completion = queue. > - @return others - Fail to create io completion queue= . > - > -**/ > -STATIC > -EFI_STATUS > -NvmeCreateIoCompletionQueue ( > - IN NVME_CONTEXT *Nvme > - ) > -{ > - NVM_EXPRESS_PASS_THRU_COMMAND_PACKET CommandPacket; > - NVM_EXPRESS_COMMAND Command; > - NVM_EXPRESS_RESPONSE Response; > - EFI_STATUS Status; > - NVME_ADMIN_CRIOCQ CrIoCq; > - > - ZeroMem (&CommandPacket, > sizeof(NVM_EXPRESS_PASS_THRU_COMMAND_PACKET)); > - ZeroMem (&Command, sizeof(NVM_EXPRESS_COMMAND)); > - ZeroMem (&Response, sizeof(NVM_EXPRESS_RESPONSE)); > - ZeroMem (&CrIoCq, sizeof(NVME_ADMIN_CRIOCQ)); > - > - CommandPacket.NvmeCmd =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 Da= ta > structure. > - > - @return EFI_SUCCESS - Successfully create io submission = queue. > - @return others - Fail to create io submission queue= . > - > -**/ > -STATIC > -EFI_STATUS > -NvmeCreateIoSubmissionQueue ( > - IN NVME_CONTEXT *Nvme > - ) > -{ > - NVM_EXPRESS_PASS_THRU_COMMAND_PACKET CommandPacket; > - NVM_EXPRESS_COMMAND Command; > - NVM_EXPRESS_RESPONSE Response; > - EFI_STATUS Status; > - NVME_ADMIN_CRIOSQ CrIoSq; > - > - ZeroMem (&CommandPacket, > sizeof(NVM_EXPRESS_PASS_THRU_COMMAND_PACKET)); > - ZeroMem (&Command, sizeof(NVM_EXPRESS_COMMAND)); > - ZeroMem (&Response, sizeof(NVM_EXPRESS_RESPONSE)); > - ZeroMem (&CrIoSq, sizeof(NVME_ADMIN_CRIOSQ)); > - > - CommandPacket.NvmeCmd =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_CONTEX= T Data > structure. > - @param[in] SendCommand - The flag to indicate the comma= nd > type, TRUE for Send command and FALSE for receive command > - @param[in] SecurityProtocol - Security Protocol > - @param[in] SpSpecific - Security Protocol Specific > - @param[in] TransferLength - Transfer Length of Buffer (in = bytes) - > always a multiple of 512 > - @param[in,out] TransferBuffer - Address of Data to transfer > - > - @return EFI_SUCCESS - Successfully create io submission = queue. > - @return others - Fail to send/receive commands. > - > -**/ > -EFI_STATUS > -NvmeSecuritySendReceive ( > - IN NVME_CONTEXT *Nvme, > - IN BOOLEAN SendCommand, > - IN UINT8 SecurityProtocol, > - IN UINT16 SpSpecific, > - IN UINTN TransferLength, > - IN OUT VOID *TransferBuffer > - ) > -{ > - NVM_EXPRESS_PASS_THRU_COMMAND_PACKET CommandPacket; > - NVM_EXPRESS_COMMAND Command; > - NVM_EXPRESS_RESPONSE Response; > - EFI_STATUS Status; > - NVME_ADMIN_SECSEND SecSend; > - OACS *Oacs; > - UINT8 Opcode; > - VOID* *SecBuff; > - > - Oacs =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 Da= ta > structure. > - > - @return EFI_SUCCESS - Successfully destroy io completion= queue. > - @return others - Fail to destroy io completion queu= e. > - > -**/ > -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 Da= ta > structure. > - > - @return EFI_SUCCESS - Successfully destroy io submission= queue. > - @return others - Fail to destroy io submission queu= e. > - > -**/ > -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 Da= ta > structure. > - > - @retval EFI_SUCCESS - The NVM Express Controller is init= ialized > successfully. > - @retval Others - A device error occurred while init= ializing 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 NVM > 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 doesn'= 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 page > 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 Da= ta > structure. > - > - @retval EFI_SUCCESS - The NVM Express Controller is un-i= nitialized > successfully. > - @retval Others - A device error occurred while un-i= nitializing 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 NvmeStatus= Max) { > - /// > - /// 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 S3. >=20 > -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 BS= D > License > which accompanies this distribution. The full text of the license may b= e > found at > @@ -14,249 +14,34 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF > ANY KIND, EITHER EXPRESS OR IMPLIED. >=20 > #include "OpalPasswordPei.h" >=20 > -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; >=20 > /** > - Get IOMMU PPI. > + Tell whether the input EDKII_PEI_STORAGE_SECURITY_CMD_PPI instance > has already > + been handled by the Opal PEI driver. >=20 > - @return Pointer to IOMMU PPI. > + @param[in] Private Pointer to the Opal PEI driver private data. > + @param[in] SscInstance Pointer to the > EDKII_PEI_STORAGE_SECURITY_CMD_PPI. >=20 > -**/ > -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 memor= y > address of the > - allocated range. > - @param DeviceAddress The resulting map address for the bus ma= ster > 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 allocate= d. > - @retval EFI_UNSUPPORTED Attributes is unsupported. The only lega= l > 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. >=20 > **/ > -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 trus= ted IO. > - @param[in] IoType OPAL_IO_TYPE indicating whether to p= erform a > Trusted Send or Trusted Receive. > - @param[in] SecurityProtocol Security Protocol > - @param[in] SpSpecific Security Protocol Specific > - @param[in] TransferLength Transfer Length of Buffer (in bytes)= - > always a multiple of 512 > - @param[in] Buffer Address of Data to transfer > - > - @retval EFI_SUCCESS Perform the IO action success. > - @retval Others Perform the IO action failed. > - > -**/ > -EFI_STATUS > -PerformTrustedIo ( > - OPAL_PEI_DEVICE *PeiDev, > - OPAL_IO_TYPE IoType, > - UINT8 SecurityProtocol, > - UINT16 SpSpecific, > - UINTN TransferLength, > - VOID *Buffer > +BOOLEAN > +IsSscInstanceHandled ( > + IN OPAL_PEI_DRIVER_PRIVATE_DATA *Private, > + IN EDKII_PEI_STORAGE_SECURITY_CMD_PPI *SscInstance > ) > { > - EFI_STATUS Status; > - UINTN BufferSizeBlocks; > - EFI_ATA_COMMAND_BLOCK AtaCommandBlock; > - OPAL_DEVICE_ATA *DevInfoAta; > - AHCI_CONTEXT *AhciContext; > - NVME_CONTEXT *NvmeContext; > - > - Status =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; >=20 > - Status =3D AhciPioTransfer( > - AhciContext, > - (UINT8) DevInfoAta->Port, > - (UINT8) DevInfoAta->PortMultiplierPort, > - NULL, > - 0, > - ( IoType =3D=3D OpalSend ) ? FALSE : TRUE, // i/o dire= ction > - &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)); > } >=20 > - return Status; > + return FALSE; > } >=20 > /** > @@ -351,14 +136,16 @@ SecurityReceiveData ( > return EFI_DEVICE_ERROR; > } >=20 > - 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 > + ); > } >=20 > /** > @@ -441,111 +228,15 @@ SecuritySendData ( > return EFI_DEVICE_ERROR; > } >=20 > - 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 f= or > 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 th= is > 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 > + ); > } >=20 > /** > @@ -651,272 +342,178 @@ UnlockOpalPassword ( > } >=20 > /** > - 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. >=20 > **/ > 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; >=20 > // > - // 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, DevInfoBuffer, > &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; > } >=20 > - for (DevInfoAta =3D (OPAL_DEVICE_ATA *) DevInfo; > - (UINTN) DevInfoAta < ((UINTN) DevInfo + DevInfoLengthAta); > - DevInfoAta =3D (OPAL_DEVICE_ATA *) ((UINTN) DevInfoAta + DevInfoA= ta- > >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, 0x2= 4)); > - PciWrite32 (PCI_LIB_ADDRESS (Bus, Device, Function, 0x24), DevInfo= Ata- > >BarAddr); > - > - ZeroMem (&AhciContext, sizeof (AHCI_CONTEXT)); > - AhciContext.AhciBar =3D DevInfoAta->BarAddr; > - AhciAllocateResource (&AhciContext); > - Status =3D AhciModeInitialize (&AhciContext, (UINT8)DevInfoAta->Po= rt); > - 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), AhciBar= ); > - } > - 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; > - } >=20 > - 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, 0x= 0); > - 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)Ss= cPpi; > + Private->SscPpiInstanceNum++; > } >=20 > - 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; > + } >=20 > - 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; > + } > + } > + } > } >=20 > - DEBUG ((DEBUG_INFO, "%a() - exit\n", __FUNCTION__)); > -} > - > -/** > - Unlock OPAL password for S3. > + ZeroMem (DevInfoBuffer, DevInfoLength); > + FreePages (DevInfoBuffer, EFI_SIZE_TO_PAGES (DevInfoLength)); >=20 > -**/ > -VOID > -OpalPasswordS3 ( > - VOID > - ) > -{ > - UnlockOpalPasswordAta (); > - UnlockOpalPasswordNvme (); > } >=20 > /** > - Entry point of the notification callback function itself within the PE= IM. > + One notified function at the installation of > EDKII_PEI_STORAGE_SECURITY_CMD_PPI. > It is to unlock OPAL password for S3. >=20 > - @param PeiServices Indirect reference to the PEI Services Table. > - @param NotifyDescriptor Address of the notification descriptor data > structure. > - @param Ppi Address of the PPI that was installed. > + @param[in] PeiServices Indirect reference to the PEI Services = Table. > + @param[in] NotifyDescriptor Address of the notification descriptor = data > structure. > + @param[in] Ppi Address of the PPI that was installed. >=20 > @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; >=20 > - 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__)); >=20 > - DEBUG ((DEBUG_INFO, "%a() - enter at S3 resume\n", __FUNCTION__)); > + Private =3D OPAL_PEI_PRIVATE_DATA_FROM_THIS_NOTIFY (NotifyDesc); > + UnlockOpalPasswordDevices (Private); >=20 > - OpalPasswordS3 (); > - > - DEBUG ((DEBUG_INFO, "%a() - exit at S3 resume\n", __FUNCTION__)); > + DEBUG ((DEBUG_INFO, "%a exit at S3 resume!\n", __FUNCTION__)); >=20 > return EFI_SUCCESS; > } >=20 > -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 > }; >=20 > /** > @@ -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; >=20 > - 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