From nobody Wed May 1 18:02:26 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of groups.io designates 66.175.222.12 as permitted sender) client-ip=66.175.222.12; envelope-from=bounce+27952+39409+1787277+3901457@groups.io; helo=web01.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zoho.com: domain of groups.io designates 66.175.222.12 as permitted sender) smtp.mailfrom=bounce+27952+39409+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1556006799; cv=none; d=zoho.com; s=zohoarc; b=M1iwiSBaO8lBkT74BiUg0PdhU7UvLmUbh1TVNs/zizBXTBRlVnt+MBvlkvd1cXpg9bBU5Z1uePubVCYHnSpF8yqzxx+KbxWkC4rrAVILjGImYmgoP/khTgQS/jlCwYshkziLG6dvQ/yUMq0RX3QoK45+UEQfrEsokb+cAGVy9jI= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1556006799; h=Cc:Date:From:In-Reply-To:List-Id:List-Unsubscribe:Message-ID:Reply-To:References:Sender:Subject:To:ARC-Authentication-Results; bh=Lqn3wvzQgWsJS67DDFEenULsG4ZICCEjAWl/YGWFlmU=; b=SPRCDDULwxtQ/Xhm4P1iNLFB9O3vH2Z5kjQoEcKxXU+tgIx/2sNG1d6zqVcMlOtDWTIXphLsABgVR/OSPu0EVrH6io0fH7y3HzfURIEt2U/iOkjCT7obTWzP+uGBU8mL4loUlaw3AZlmyQ4BefVwASoFp78TWF3DdrTj4fidnkQ= ARC-Authentication-Results: i=1; mx.zoho.com; dkim=pass; spf=pass (zoho.com: domain of groups.io designates 66.175.222.12 as permitted sender) smtp.mailfrom=bounce+27952+39409+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) header.from= Received: from web01.groups.io (web01.groups.io [66.175.222.12]) by mx.zohomail.com with SMTPS id 1556006799929437.9015744160332; Tue, 23 Apr 2019 01:06:39 -0700 (PDT) Return-Path: X-Received: from mga05.intel.com (mga05.intel.com []) by groups.io with SMTP; Tue, 23 Apr 2019 01:06:38 -0700 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False X-Received: from fmsmga006.fm.intel.com ([10.253.24.20]) by fmsmga105.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 23 Apr 2019 01:06:37 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.60,385,1549958400"; d="scan'208";a="339945777" X-Received: from shwdeopenpsi014.ccr.corp.intel.com ([10.239.9.8]) by fmsmga006.fm.intel.com with ESMTP; 23 Apr 2019 01:06:33 -0700 From: "Wu, Hao A" To: devel@edk2.groups.io Cc: Hao Wu , Ray Ni , Eric Dong , Jian J Wang Subject: [edk2-devel] [PATCH v3 1/2] MdeModulePkg/AhciPei: Limit max transfer blocknum for 48-bit address Date: Tue, 23 Apr 2019 16:06:29 +0800 Message-Id: <20190423080630.14992-2-hao.a.wu@intel.com> In-Reply-To: <20190423080630.14992-1-hao.a.wu@intel.com> References: <20190423080630.14992-1-hao.a.wu@intel.com> Precedence: Bulk List-Unsubscribe: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,hao.a.wu@intel.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1556006799; bh=YgolYO7PJ6RC2TFZzKEmgcJmeoF2hZuoDdEyxp1FnxE=; h=Cc:Date:From:Reply-To:Subject:To; b=IqqJkixlqhKrS3fZhUohkDYYJFnRqpH2XXpqcHm3fpQtYIogHjmqYsyBsNdb+pRmdAl yvQ0oeXlRWXUM3Yf1+2moe2sCRs/dbhFNwC4sZ1LVJNuEBbK0k7oTtWZbc1i8Vwc6ozQe H4hjSN3KdupY2q661uX2ms7g7HOqnG5LLCg= X-ZohoMail-DKIM: pass (identity @groups.io) Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" REF:https://bugzilla.tianocore.org/show_bug.cgi?id=3D1483 Due to the limited resource on the VTd DMA buffer size in the PEI phase, the driver will limit the maximum transfer block number for 48-bit addressing. According to PCDs: gIntelSiliconPkgTokenSpaceGuid.PcdVTdPeiDmaBufferSize|0x00400000 gIntelSiliconPkgTokenSpaceGuid.PcdVTdPeiDmaBufferSizeS3|0x00200000 The default buffer size allocated for IOMMU mapping is: * 4M bytes for non-S3 cases; * 2M bytes for S3 For ATA devices in 48-bit address mode, the maximum block number is currently set to 0xFFFF. For a device with block size equal to 512 bytes, the maximum buffer allowed for mapping within AhciPei driver will be close to 32M bytes. Thus, this commit will limit the 48-bit mode maximum block number to 0x800, which means 1M-byte maximum buffer for mapping when the block size of a device is 512 bytes. By doing so, potential failure on calls to the IOMMU 'Map' service can be avoided. Cc: Ray Ni Cc: Eric Dong Cc: Jian J Wang Signed-off-by: Hao Wu Reviewed-by: Ray Ni --- MdeModulePkg/Bus/Ata/AhciPei/AhciMode.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/MdeModulePkg/Bus/Ata/AhciPei/AhciMode.c b/MdeModulePkg/Bus/Ata= /AhciPei/AhciMode.c index a83c213a47..11754b3057 100644 --- a/MdeModulePkg/Bus/Ata/AhciPei/AhciMode.c +++ b/MdeModulePkg/Bus/Ata/AhciPei/AhciMode.c @@ -48,7 +48,13 @@ UINT8 mAtaTrustCommands[2] =3D { // Look up table (Lba48Bit) for maximum transfer block number // #define MAX_28BIT_TRANSFER_BLOCK_NUM 0x100 -#define MAX_48BIT_TRANSFER_BLOCK_NUM 0xFFFF +// +// Due to limited resource for VTd PEI DMA buffer on platforms, the driver +// limits the maximum transfer block number for 48-bit addressing. +// Here, setting to 0x800 means that for device with 512-byte block size, = the +// maximum buffer for DMA mapping will be 1M bytes in size. +// +#define MAX_48BIT_TRANSFER_BLOCK_NUM 0x800 =20 UINT32 mMaxTransferBlockNumber[2] =3D { MAX_28BIT_TRANSFER_BLOCK_NUM, --=20 2.12.0.windows.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#39409): https://edk2.groups.io/g/devel/message/39409 Mute This Topic: https://groups.io/mt/31306791/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Wed May 1 18:02:26 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of groups.io designates 66.175.222.12 as permitted sender) client-ip=66.175.222.12; envelope-from=bounce+27952+39408+1787277+3901457@groups.io; helo=web01.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zoho.com: domain of groups.io designates 66.175.222.12 as permitted sender) smtp.mailfrom=bounce+27952+39408+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1556006800; cv=none; d=zoho.com; s=zohoarc; b=MNq4dTCmcSU8aJzxb/JP1gw3xp/c1tqyOf6Kj3ygN3UkDDRDGXmyuU3d+RQ6Z/sgT5DgGoae1ZJ3Gm8oPGS6mEZI1W/EzYAKt3t5U2gJefoMattRzk6BJ6qzM3yY3ePWu2QmUxb1aC+e+i8jlBm5Q0+8BGXAoiqqV0M37zB7uyU= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1556006800; h=Cc:Date:From:In-Reply-To:List-Id:List-Unsubscribe:Message-ID:Reply-To:References:Sender:Subject:To:ARC-Authentication-Results; bh=pHRve512+BrA0GJnjtTd9MGGjP1wPacZ47b3MYryXVU=; b=CcWGLgytvZSon67+nznDRRLpDhMXo5v04noMz6cthkjIetFK0sQn8AXMY5M3ay/SnJiAvmdKlDu2BWFadh9i4IWIttnCcE+aRH58YBZFrLwAzdfflY3ryRZfcmm/XJAdbeUj5QcfMK1b89w3+ImyGszgDhWjCiEAYHM99CfXmXQ= ARC-Authentication-Results: i=1; mx.zoho.com; dkim=pass; spf=pass (zoho.com: domain of groups.io designates 66.175.222.12 as permitted sender) smtp.mailfrom=bounce+27952+39408+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) header.from= Received: from web01.groups.io (web01.groups.io [66.175.222.12]) by mx.zohomail.com with SMTPS id 1556006800045668.2027065716659; Tue, 23 Apr 2019 01:06:40 -0700 (PDT) Return-Path: X-Received: from mga05.intel.com (mga05.intel.com [192.55.52.43]) by groups.io with SMTP; Tue, 23 Apr 2019 01:06:38 -0700 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False X-Received: from fmsmga006.fm.intel.com ([10.253.24.20]) by fmsmga105.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 23 Apr 2019 01:06:38 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.60,385,1549958400"; d="scan'208";a="339945796" X-Received: from shwdeopenpsi014.ccr.corp.intel.com ([10.239.9.8]) by fmsmga006.fm.intel.com with ESMTP; 23 Apr 2019 01:06:35 -0700 From: "Wu, Hao A" To: devel@edk2.groups.io Cc: Hao Wu , Ray Ni , Eric Dong , Jian J Wang Subject: [edk2-devel] [PATCH v3 2/2] MdeModulePkg/AhciPei: Add PEI BlockIO support Date: Tue, 23 Apr 2019 16:06:30 +0800 Message-Id: <20190423080630.14992-3-hao.a.wu@intel.com> In-Reply-To: <20190423080630.14992-1-hao.a.wu@intel.com> References: <20190423080630.14992-1-hao.a.wu@intel.com> Precedence: Bulk List-Unsubscribe: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,hao.a.wu@intel.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1556006798; bh=DNPj4r3zIhQlhMbVwrRS5nMqilvZCpkkN2F7U7utwas=; h=Cc:Date:From:Reply-To:Subject:To; b=rjTWlHuJDsWCyzb6Fwmg+bp3P5mY+vmB67DtQvJN9qqQxZRej9bdPtCw4PdKQfFspT/ ED28vweDWI4pNKu+j6fK45ZskH9AKmMXh+25TD7RKlDQO6uFDn+lfY1T98osixcCnwac4 m2sz1Ntmoomwa8yJSCEFE4cX3Fy3PMy1iNk= X-ZohoMail-DKIM: pass (identity @groups.io) Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" REF:https://bugzilla.tianocore.org/show_bug.cgi?id=3D1483 This commit will add the PEI BlockIO (2) PPIs support for AHCI mode ATA devices. More specifically, the driver will consume the ATA AHCI host controller PPI for ATA controllers working under AHCI code within the system. And then produces the below additional PPIs for each controller: EFI PEI Recovery Block IO PPI EFI PEI Recovery Block IO2 PPI Cc: Ray Ni Cc: Eric Dong Cc: Jian J Wang Signed-off-by: Hao Wu Reviewed-by: Ray Ni --- MdeModulePkg/Bus/Ata/AhciPei/AhciPei.inf | 4 + MdeModulePkg/Bus/Ata/AhciPei/AhciPei.h | 30 ++ MdeModulePkg/Bus/Ata/AhciPei/AhciPeiBlockIo.h | 257 ++++++++++ MdeModulePkg/Bus/Ata/AhciPei/AhciMode.c | 118 +++++ MdeModulePkg/Bus/Ata/AhciPei/AhciPei.c | 35 ++ MdeModulePkg/Bus/Ata/AhciPei/AhciPeiBlockIo.c | 516 ++++++++++++++++++++ 6 files changed, 960 insertions(+) diff --git a/MdeModulePkg/Bus/Ata/AhciPei/AhciPei.inf b/MdeModulePkg/Bus/At= a/AhciPei/AhciPei.inf index bf686a198f..912ff7a8ba 100644 --- a/MdeModulePkg/Bus/Ata/AhciPei/AhciPei.inf +++ b/MdeModulePkg/Bus/Ata/AhciPei/AhciPei.inf @@ -26,6 +26,8 @@ [Defines] [Sources] AhciPei.c AhciPei.h + AhciPeiBlockIo.c + AhciPeiBlockIo.h AhciPeiPassThru.c AhciPeiPassThru.h AhciPeiS3.c @@ -54,6 +56,8 @@ [Ppis] gEdkiiIoMmuPpiGuid ## CONSUMES gEfiEndOfPeiSignalPpiGuid ## CONSUMES gEdkiiPeiAtaPassThruPpiGuid ## SOMETIMES_PRODUCES + gEfiPeiVirtualBlockIoPpiGuid ## SOMETIMES_PRODUCES + gEfiPeiVirtualBlockIo2PpiGuid ## SOMETIMES_PRODUCES gEdkiiPeiStorageSecurityCommandPpiGuid ## SOMETIMES_PRODUCES =20 [Guids] diff --git a/MdeModulePkg/Bus/Ata/AhciPei/AhciPei.h b/MdeModulePkg/Bus/Ata/= AhciPei/AhciPei.h index e6a9c0a333..9a34dc6e4f 100644 --- a/MdeModulePkg/Bus/Ata/AhciPei/AhciPei.h +++ b/MdeModulePkg/Bus/Ata/AhciPei/AhciPei.h @@ -19,6 +19,7 @@ #include #include #include +#include #include #include =20 @@ -35,6 +36,7 @@ typedef struct _PEI_AHCI_CONTROLLER_PRIVATE_DATA PEI_AHCI_CONTROLLER_PRIV= ATE_DATA; =20 #include "AhciPeiPassThru.h" +#include "AhciPeiBlockIo.h" #include "AhciPeiStorageSecurity.h" =20 // @@ -312,6 +314,8 @@ struct _PEI_AHCI_CONTROLLER_PRIVATE_DATA { =20 EFI_ATA_PASS_THRU_MODE AtaPassThruMode; EDKII_PEI_ATA_PASS_THRU_PPI AtaPassThruPpi; + EFI_PEI_RECOVERY_BLOCK_IO_PPI BlkIoPpi; + EFI_PEI_RECOVERY_BLOCK_IO2_PPI BlkIo2Ppi; EDKII_PEI_STORAGE_SECURITY_CMD_PPI StorageSecurityPpi; EFI_PEI_PPI_DESCRIPTOR AtaPassThruPpiList; EFI_PEI_PPI_DESCRIPTOR BlkIoPpiList; @@ -554,6 +558,32 @@ AhciModeInitialization ( ); =20 /** + Transfer data from ATA device. + + This function performs one ATA pass through transaction to transfer data= from/to + ATA device. It chooses the appropriate ATA command and protocol to invok= e PassThru + interface of ATA pass through. + + @param[in] DeviceData A pointer to PEI_AHCI_ATA_DEVICE_DATA s= tructure. + @param[in,out] Buffer The pointer to the current transaction = buffer. + @param[in] StartLba The starting logical block address to b= e accessed. + @param[in] TransferLength The block number or sector count of the= transfer. + @param[in] IsWrite Indicates whether it is a write operati= on. + + @retval EFI_SUCCESS The data transfer is complete successfully. + @return others Some error occurs when transferring data. + +**/ +EFI_STATUS +TransferAtaDevice ( + IN PEI_AHCI_ATA_DEVICE_DATA *DeviceData, + IN OUT VOID *Buffer, + IN EFI_LBA StartLba, + IN UINT32 TransferLength, + IN BOOLEAN IsWrite + ); + +/** Trust transfer data from/to ATA device. =20 This function performs one ATA pass through transaction to do a trust tr= ansfer diff --git a/MdeModulePkg/Bus/Ata/AhciPei/AhciPeiBlockIo.h b/MdeModulePkg/B= us/Ata/AhciPei/AhciPeiBlockIo.h new file mode 100644 index 0000000000..5896ae5acf --- /dev/null +++ b/MdeModulePkg/Bus/Ata/AhciPei/AhciPeiBlockIo.h @@ -0,0 +1,257 @@ +/** @file + The AhciPei driver is used to manage ATA hard disk device working under = AHCI + mode at PEI phase. + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _AHCI_PEI_BLOCKIO_H_ +#define _AHCI_PEI_BLOCKIO_H_ + +// +// ATA hard disk device for EFI_PEI_BLOCK_DEVICE_TYPE +// +#define EDKII_PEI_BLOCK_DEVICE_TYPE_ATA_HARD_DISK 8 + +/** + Gets the count of block I/O devices that one specific block driver detec= ts. + + This function is used for getting the count of block I/O devices that one + specific block driver detects. If no device is detected, then the functi= on + will return zero. + + @param[in] PeiServices General-purpose services that are avail= able + to every PEIM. + @param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO= _PPI + instance. + @param[out] NumberBlockDevices The number of block I/O devices discove= red. + + @retval EFI_SUCCESS The operation performed successfully. + +**/ +EFI_STATUS +EFIAPI +AhciBlockIoGetDeviceNo ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This, + OUT UINTN *NumberBlockDevices + ); + +/** + Gets a block device's media information. + + This function will provide the caller with the specified block device's = media + information. If the media changes, calling this function will update the= media + information accordingly. + + @param[in] PeiServices General-purpose services that are available to= every + PEIM + @param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO_PPI in= stance. + @param[in] DeviceIndex Specifies the block device to which the functi= on wants + to talk. Because the driver that implements Bl= ock I/O + PPIs will manage multiple block devices, the P= PIs that + want to talk to a single device must specify t= he + device index that was assigned during the enum= eration + process. This index is a number from one to + NumberBlockDevices. + @param[out] MediaInfo The media information of the specified block m= edia. + The caller is responsible for the ownership of= this + data structure. + + @par Note: + The MediaInfo structure describes an enumeration of possible block d= evice + types. This enumeration exists because no device paths are actually= passed + across interfaces that describe the type or class of hardware that i= s publishing + the block I/O interface. This enumeration will allow for policy deci= sions + in the Recovery PEIM, such as "Try to recover from legacy floppy fir= st, + LS-120 second, CD-ROM third." If there are multiple partitions abstr= acted + by a given device type, they should be reported in ascending order; = this + order also applies to nested partitions, such as legacy MBR, where t= he + outermost partitions would have precedence in the reporting order. T= he + same logic applies to systems such as IDE that have precedence relat= ionships + like "Master/Slave" or "Primary/Secondary". The master device should= be + reported first, the slave second. + + @retval EFI_SUCCESS Media information about the specified block d= evice + was obtained successfully. + @retval EFI_DEVICE_ERROR Cannot get the media information due to a har= dware + error. + +**/ +EFI_STATUS +EFIAPI +AhciBlockIoGetMediaInfo ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This, + IN UINTN DeviceIndex, + OUT EFI_PEI_BLOCK_IO_MEDIA *MediaInfo + ); + +/** + Reads the requested number of blocks from the specified block device. + + The function reads the requested number of blocks from the device. All t= he + blocks are read, or an error is returned. If there is no media in the de= vice, + the function returns EFI_NO_MEDIA. + + @param[in] PeiServices General-purpose services that are available to + every PEIM. + @param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO_PPI in= stance. + @param[in] DeviceIndex Specifies the block device to which the functi= on wants + to talk. Because the driver that implements Bl= ock I/O + PPIs will manage multiple block devices, PPIs = that + want to talk to a single device must specify t= he device + index that was assigned during the enumeration= process. + This index is a number from one to NumberBlock= Devices. + @param[in] StartLBA The starting logical block address (LBA) to re= ad from + on the device + @param[in] BufferSize The size of the Buffer in bytes. This number m= ust be + a multiple of the intrinsic block size of the = device. + @param[out] Buffer A pointer to the destination buffer for the da= ta. + The caller is responsible for the ownership of= the + buffer. + + @retval EFI_SUCCESS The data was read correctly from the dev= ice. + @retval EFI_DEVICE_ERROR The device reported an error while attem= pting + to perform the read operation. + @retval EFI_INVALID_PARAMETER The read request contains LBAs that are = not + valid, or the buffer is not properly ali= gned. + @retval EFI_NO_MEDIA There is no media in the device. + @retval EFI_BAD_BUFFER_SIZE The BufferSize parameter is not a multip= le of + the intrinsic block size of the device. + +**/ +EFI_STATUS +EFIAPI +AhciBlockIoReadBlocks ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This, + IN UINTN DeviceIndex, + IN EFI_PEI_LBA StartLBA, + IN UINTN BufferSize, + OUT VOID *Buffer + ); + +/** + Gets the count of block I/O devices that one specific block driver detec= ts. + + This function is used for getting the count of block I/O devices that one + specific block driver detects. If no device is detected, then the functi= on + will return zero. + + @param[in] PeiServices General-purpose services that are avail= able + to every PEIM. + @param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO= 2_PPI + instance. + @param[out] NumberBlockDevices The number of block I/O devices discove= red. + + @retval EFI_SUCCESS The operation performed successfully. + +**/ +EFI_STATUS +EFIAPI +AhciBlockIoGetDeviceNo2 ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_RECOVERY_BLOCK_IO2_PPI *This, + OUT UINTN *NumberBlockDevices + ); + +/** + Gets a block device's media information. + + This function will provide the caller with the specified block device's = media + information. If the media changes, calling this function will update the= media + information accordingly. + + @param[in] PeiServices General-purpose services that are available to= every + PEIM + @param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO2_PPI i= nstance. + @param[in] DeviceIndex Specifies the block device to which the functi= on wants + to talk. Because the driver that implements Bl= ock I/O + PPIs will manage multiple block devices, the P= PIs that + want to talk to a single device must specify t= he + device index that was assigned during the enum= eration + process. This index is a number from one to + NumberBlockDevices. + @param[out] MediaInfo The media information of the specified block m= edia. + The caller is responsible for the ownership of= this + data structure. + + @par Note: + The MediaInfo structure describes an enumeration of possible block d= evice + types. This enumeration exists because no device paths are actually= passed + across interfaces that describe the type or class of hardware that i= s publishing + the block I/O interface. This enumeration will allow for policy deci= sions + in the Recovery PEIM, such as "Try to recover from legacy floppy fir= st, + LS-120 second, CD-ROM third." If there are multiple partitions abstr= acted + by a given device type, they should be reported in ascending order; = this + order also applies to nested partitions, such as legacy MBR, where t= he + outermost partitions would have precedence in the reporting order. T= he + same logic applies to systems such as IDE that have precedence relat= ionships + like "Master/Slave" or "Primary/Secondary". The master device should= be + reported first, the slave second. + + @retval EFI_SUCCESS Media information about the specified block d= evice + was obtained successfully. + @retval EFI_DEVICE_ERROR Cannot get the media information due to a har= dware + error. + +**/ +EFI_STATUS +EFIAPI +AhciBlockIoGetMediaInfo2 ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_RECOVERY_BLOCK_IO2_PPI *This, + IN UINTN DeviceIndex, + OUT EFI_PEI_BLOCK_IO2_MEDIA *MediaInfo + ); + +/** + Reads the requested number of blocks from the specified block device. + + The function reads the requested number of blocks from the device. All t= he + blocks are read, or an error is returned. If there is no media in the de= vice, + the function returns EFI_NO_MEDIA. + + @param[in] PeiServices General-purpose services that are available to + every PEIM. + @param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO2_PPI i= nstance. + @param[in] DeviceIndex Specifies the block device to which the functi= on wants + to talk. Because the driver that implements Bl= ock I/O + PPIs will manage multiple block devices, PPIs = that + want to talk to a single device must specify t= he device + index that was assigned during the enumeration= process. + This index is a number from one to NumberBlock= Devices. + @param[in] StartLBA The starting logical block address (LBA) to re= ad from + on the device + @param[in] BufferSize The size of the Buffer in bytes. This number m= ust be + a multiple of the intrinsic block size of the = device. + @param[out] Buffer A pointer to the destination buffer for the da= ta. + The caller is responsible for the ownership of= the + buffer. + + @retval EFI_SUCCESS The data was read correctly from the dev= ice. + @retval EFI_DEVICE_ERROR The device reported an error while attem= pting + to perform the read operation. + @retval EFI_INVALID_PARAMETER The read request contains LBAs that are = not + valid, or the buffer is not properly ali= gned. + @retval EFI_NO_MEDIA There is no media in the device. + @retval EFI_BAD_BUFFER_SIZE The BufferSize parameter is not a multip= le of + the intrinsic block size of the device. + +**/ +EFI_STATUS +EFIAPI +AhciBlockIoReadBlocks2 ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_RECOVERY_BLOCK_IO2_PPI *This, + IN UINTN DeviceIndex, + IN EFI_PEI_LBA StartLBA, + IN UINTN BufferSize, + OUT VOID *Buffer + ); + +#endif diff --git a/MdeModulePkg/Bus/Ata/AhciPei/AhciMode.c b/MdeModulePkg/Bus/Ata= /AhciPei/AhciMode.c index 11754b3057..7287f8290e 100644 --- a/MdeModulePkg/Bus/Ata/AhciPei/AhciMode.c +++ b/MdeModulePkg/Bus/Ata/AhciPei/AhciMode.c @@ -1873,6 +1873,124 @@ AhciModeInitialization ( } =20 /** + Transfer data from ATA device. + + This function performs one ATA pass through transaction to transfer data= from/to + ATA device. It chooses the appropriate ATA command and protocol to invok= e PassThru + interface of ATA pass through. + + @param[in] DeviceData A pointer to PEI_AHCI_ATA_DEVICE_DATA s= tructure. + @param[in,out] Buffer The pointer to the current transaction = buffer. + @param[in] StartLba The starting logical block address to b= e accessed. + @param[in] TransferLength The block number or sector count of the= transfer. + @param[in] IsWrite Indicates whether it is a write operati= on. + + @retval EFI_SUCCESS The data transfer is complete successfully. + @return others Some error occurs when transferring data. + +**/ +EFI_STATUS +TransferAtaDevice ( + IN PEI_AHCI_ATA_DEVICE_DATA *DeviceData, + IN OUT VOID *Buffer, + IN EFI_LBA StartLba, + IN UINT32 TransferLength, + IN BOOLEAN IsWrite + ) +{ + PEI_AHCI_CONTROLLER_PRIVATE_DATA *Private; + EDKII_PEI_ATA_PASS_THRU_PPI *AtaPassThru; + EFI_ATA_COMMAND_BLOCK Acb; + EFI_ATA_PASS_THRU_COMMAND_PACKET Packet; + + Private =3D DeviceData->Private; + AtaPassThru =3D &Private->AtaPassThruPpi; + + // + // Ensure Lba48Bit and IsWrite are valid boolean values + // + ASSERT ((UINTN) DeviceData->Lba48Bit < 2); + ASSERT ((UINTN) IsWrite < 2); + if (((UINTN) DeviceData->Lba48Bit >=3D 2) || + ((UINTN) IsWrite >=3D 2)) { + return EFI_INVALID_PARAMETER; + } + + // + // Prepare for ATA command block. + // + ZeroMem (&Acb, sizeof (EFI_ATA_COMMAND_BLOCK)); + Acb.AtaCommand =3D mAtaCommands[DeviceData->Lba48Bit][IsWrite]; + Acb.AtaSectorNumber =3D (UINT8) StartLba; + Acb.AtaCylinderLow =3D (UINT8) RShiftU64 (StartLba, 8); + Acb.AtaCylinderHigh =3D (UINT8) RShiftU64 (StartLba, 16); + Acb.AtaDeviceHead =3D (UINT8) (BIT7 | BIT6 | BIT5 | + (DeviceData->PortMultiplier =3D=3D 0xFFFF= ? + 0 : (DeviceData->PortMultiplier << 4))); + Acb.AtaSectorCount =3D (UINT8) TransferLength; + if (DeviceData->Lba48Bit) { + Acb.AtaSectorNumberExp =3D (UINT8) RShiftU64 (StartLba, 24); + Acb.AtaCylinderLowExp =3D (UINT8) RShiftU64 (StartLba, 32); + Acb.AtaCylinderHighExp =3D (UINT8) RShiftU64 (StartLba, 40); + Acb.AtaSectorCountExp =3D (UINT8) (TransferLength >> 8); + } else { + Acb.AtaDeviceHead =3D (UINT8) (Acb.AtaDeviceHead | RShiftU64 (Sta= rtLba, 24)); + } + + // + // Prepare for ATA pass through packet. + // + ZeroMem (&Packet, sizeof (EFI_ATA_PASS_THRU_COMMAND_PACKET)); + if (IsWrite) { + Packet.OutDataBuffer =3D Buffer; + Packet.OutTransferLength =3D TransferLength; + } else { + Packet.InDataBuffer =3D Buffer; + Packet.InTransferLength =3D TransferLength; + } + Packet.Asb =3D NULL; + Packet.Acb =3D &Acb; + Packet.Protocol =3D mAtaPassThruCmdProtocols[IsWrite]; + Packet.Length =3D EFI_ATA_PASS_THRU_LENGTH_SECTOR_COUNT; + // + // |------------------------|-----------------| + // | ATA PIO Transfer Mode | Transfer Rate | + // |------------------------|-----------------| + // | PIO Mode 0 | 3.3Mbytes/sec | + // |------------------------|-----------------| + // | PIO Mode 1 | 5.2Mbytes/sec | + // |------------------------|-----------------| + // | PIO Mode 2 | 8.3Mbytes/sec | + // |------------------------|-----------------| + // | PIO Mode 3 | 11.1Mbytes/sec | + // |------------------------|-----------------| + // | PIO Mode 4 | 16.6Mbytes/sec | + // |------------------------|-----------------| + // + // As AtaBus is used to manage ATA devices, we have to use the lowest tr= ansfer + // rate to calculate the possible maximum timeout value for each read/wr= ite + // operation. The timout value is rounded up to nearest integar and here= an + // additional 30s is added to follow ATA spec in which it mentioned that= the + // device may take up to 30s to respond commands in the Standby/Idle mod= e. + // + // Calculate the maximum timeout value for PIO read/write operation. + // + Packet.Timeout =3D TIMER_PERIOD_SECONDS ( + DivU64x32 ( + MultU64x32 (TransferLength, DeviceData->Media.Block= Size), + 3300000 + ) + 31 + ); + + return AtaPassThru->PassThru ( + AtaPassThru, + DeviceData->Port, + DeviceData->PortMultiplier, + &Packet + ); +} + +/** Trust transfer data from/to ATA device. =20 This function performs one ATA pass through transaction to do a trust tr= ansfer diff --git a/MdeModulePkg/Bus/Ata/AhciPei/AhciPei.c b/MdeModulePkg/Bus/Ata/= AhciPei/AhciPei.c index 29e0aa7d65..31b072c118 100644 --- a/MdeModulePkg/Bus/Ata/AhciPei/AhciPei.c +++ b/MdeModulePkg/Bus/Ata/AhciPei/AhciPei.c @@ -16,6 +16,18 @@ EFI_PEI_PPI_DESCRIPTOR mAhciAtaPassThruPpiListTemplate = =3D { NULL }; =20 +EFI_PEI_PPI_DESCRIPTOR mAhciBlkIoPpiListTemplate =3D { + (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gEfiPeiVirtualBlockIoPpiGuid, + NULL +}; + +EFI_PEI_PPI_DESCRIPTOR mAhciBlkIo2PpiListTemplate =3D { + (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gEfiPeiVirtualBlockIo2PpiGuid, + NULL +}; + EFI_PEI_PPI_DESCRIPTOR mAhciStorageSecurityPpiListTemplate =3D { (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), &gEdkiiPeiStorageSecurityCommandPpiGuid, @@ -265,6 +277,29 @@ AtaAhciPeimEntry ( Private->AtaPassThruPpiList.Ppi =3D &Private->AtaPassThruPpi; PeiServicesInstallPpi (&Private->AtaPassThruPpiList); =20 + Private->BlkIoPpi.GetNumberOfBlockDevices =3D AhciBlockIoGetDeviceNo; + Private->BlkIoPpi.GetBlockDeviceMediaInfo =3D AhciBlockIoGetMediaInfo; + Private->BlkIoPpi.ReadBlocks =3D AhciBlockIoReadBlocks; + CopyMem ( + &Private->BlkIoPpiList, + &mAhciBlkIoPpiListTemplate, + sizeof (EFI_PEI_PPI_DESCRIPTOR) + ); + Private->BlkIoPpiList.Ppi =3D &Private->BlkIoPpi; + PeiServicesInstallPpi (&Private->BlkIoPpiList); + + Private->BlkIo2Ppi.Revision =3D EFI_PEI_RECOVERY_BLOCK_= IO2_PPI_REVISION; + Private->BlkIo2Ppi.GetNumberOfBlockDevices =3D AhciBlockIoGetDeviceNo2; + Private->BlkIo2Ppi.GetBlockDeviceMediaInfo =3D AhciBlockIoGetMediaInfo= 2; + Private->BlkIo2Ppi.ReadBlocks =3D AhciBlockIoReadBlocks2; + CopyMem ( + &Private->BlkIo2PpiList, + &mAhciBlkIo2PpiListTemplate, + sizeof (EFI_PEI_PPI_DESCRIPTOR) + ); + Private->BlkIo2PpiList.Ppi =3D &Private->BlkIo2Ppi; + PeiServicesInstallPpi (&Private->BlkIo2PpiList); + if (Private->TrustComputingDevices !=3D 0) { DEBUG (( DEBUG_INFO, diff --git a/MdeModulePkg/Bus/Ata/AhciPei/AhciPeiBlockIo.c b/MdeModulePkg/B= us/Ata/AhciPei/AhciPeiBlockIo.c new file mode 100644 index 0000000000..e7c7a39539 --- /dev/null +++ b/MdeModulePkg/Bus/Ata/AhciPei/AhciPeiBlockIo.c @@ -0,0 +1,516 @@ +/** @file + The AhciPei driver is used to manage ATA hard disk device working under = AHCI + mode at PEI phase. + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "AhciPei.h" + +/** + Traverse the attached ATA devices list to find out the device with given= index. + + @param[in] Private A pointer to the PEI_AHCI_CONTROLLER_PRIVATE_D= ATA + instance. + @param[in] DeviceIndex The device index. + + @retval The pointer to the PEI_AHCI_ATA_DEVICE_DATA structure of the = device + info to access. + +**/ +PEI_AHCI_ATA_DEVICE_DATA * +SearchDeviceByIndex ( + IN PEI_AHCI_CONTROLLER_PRIVATE_DATA *Private, + IN UINTN DeviceIndex + ) +{ + PEI_AHCI_ATA_DEVICE_DATA *DeviceData; + LIST_ENTRY *Node; + + if ((DeviceIndex =3D=3D 0) || (DeviceIndex > Private->ActiveDevices)) { + return NULL; + } + + Node =3D GetFirstNode (&Private->DeviceList); + while (!IsNull (&Private->DeviceList, Node)) { + DeviceData =3D AHCI_PEI_ATA_DEVICE_INFO_FROM_THIS (Node); + + if (DeviceData->DeviceIndex =3D=3D DeviceIndex) { + return DeviceData; + } + + Node =3D GetNextNode (&Private->DeviceList, Node); + } + + return NULL; +} + +/** + Read a number of blocks from ATA device. + + This function performs ATA pass through transactions to read data from A= TA device. + It may separate the read request into several ATA pass through transacti= ons. + + @param[in] DeviceData The pointer to the PEI_AHCI_ATA_DEVICE_= DATA + data structure. + @param[in,out] Buffer The pointer to the current transaction = buffer. + @param[in] StartLba The starting logical block address to b= e accessed. + @param[in] NumberOfBlocks The block number or sector count of the= transfer. + + @retval EFI_SUCCESS The data transfer is complete successfully. + @return Others Some error occurs when transferring data. + +**/ +EFI_STATUS +AccessAtaDevice ( + IN PEI_AHCI_ATA_DEVICE_DATA *DeviceData, + IN OUT UINT8 *Buffer, + IN EFI_LBA StartLba, + IN UINTN NumberOfBlocks + ) +{ + EFI_STATUS Status; + UINTN MaxTransferBlockNumber; + UINTN TransferBlockNumber; + UINTN BlockSize; + + // + // Ensure Lba48Bit is a valid boolean value + // + ASSERT ((UINTN) DeviceData->Lba48Bit < 2); + if ((UINTN) DeviceData->Lba48Bit >=3D 2) { + return EFI_INVALID_PARAMETER; + } + + Status =3D EFI_SUCCESS; + MaxTransferBlockNumber =3D mMaxTransferBlockNumber[DeviceData->Lba48Bit]; + BlockSize =3D DeviceData->Media.BlockSize; + + do { + if (NumberOfBlocks > MaxTransferBlockNumber) { + TransferBlockNumber =3D MaxTransferBlockNumber; + NumberOfBlocks -=3D MaxTransferBlockNumber; + } else { + TransferBlockNumber =3D NumberOfBlocks; + NumberOfBlocks =3D 0; + } + DEBUG (( + DEBUG_BLKIO, "%a: Blocking AccessAtaDevice, TransferBlockNumber =3D = %x; StartLba =3D %x\n", + __FUNCTION__, TransferBlockNumber, StartLba + )); + + Status =3D TransferAtaDevice ( + DeviceData, + Buffer, + StartLba, + (UINT32) TransferBlockNumber, + FALSE // Read + ); + if (EFI_ERROR (Status)) { + return Status; + } + + StartLba +=3D TransferBlockNumber; + Buffer +=3D TransferBlockNumber * BlockSize; + } while (NumberOfBlocks > 0); + + return Status; +} + +/** + Read specified bytes from Lba from the device. + + @param[in] DeviceData The pointer to the PEI_AHCI_ATA_DEVICE_DATA da= ta structure. + @param[out] Buffer The Buffer used to store the Data read from th= e device. + @param[in] StartLba The start block number. + @param[in] BufferSize Total bytes to be read. + + @retval EFI_SUCCESS Data are read from the device. + @retval Others Fail to read all the data. + +**/ +EFI_STATUS +AhciRead ( + IN PEI_AHCI_ATA_DEVICE_DATA *DeviceData, + OUT VOID *Buffer, + IN EFI_LBA StartLba, + IN UINTN BufferSize + ) +{ + EFI_STATUS Status; + UINTN BlockSize; + UINTN NumberOfBlocks; + + // + // Check parameters. + // + if (Buffer =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + if (BufferSize =3D=3D 0) { + return EFI_SUCCESS; + } + + BlockSize =3D DeviceData->Media.BlockSize; + if ((BufferSize % BlockSize) !=3D 0) { + return EFI_BAD_BUFFER_SIZE; + } + + if (StartLba > DeviceData->Media.LastBlock) { + return EFI_INVALID_PARAMETER; + } + NumberOfBlocks =3D BufferSize / BlockSize; + if (NumberOfBlocks - 1 > DeviceData->Media.LastBlock - StartLba) { + return EFI_INVALID_PARAMETER; + } + + // + // Invoke low level AtaDevice Access Routine. + // + Status =3D AccessAtaDevice (DeviceData, Buffer, StartLba, NumberOfBlocks= ); + + return Status; +} + + +/** + Gets the count of block I/O devices that one specific block driver detec= ts. + + This function is used for getting the count of block I/O devices that one + specific block driver detects. If no device is detected, then the functi= on + will return zero. + + @param[in] PeiServices General-purpose services that are avail= able + to every PEIM. + @param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO= _PPI + instance. + @param[out] NumberBlockDevices The number of block I/O devices discove= red. + + @retval EFI_SUCCESS The operation performed successfully. + +**/ +EFI_STATUS +EFIAPI +AhciBlockIoGetDeviceNo ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This, + OUT UINTN *NumberBlockDevices + ) +{ + PEI_AHCI_CONTROLLER_PRIVATE_DATA *Private; + + if (This =3D=3D NULL || NumberBlockDevices =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + Private =3D GET_AHCI_PEIM_HC_PRIVATE_DATA_FROM_THIS_BLKIO (This); + *NumberBlockDevices =3D Private->ActiveDevices; + + return EFI_SUCCESS; +} + +/** + Gets a block device's media information. + + This function will provide the caller with the specified block device's = media + information. If the media changes, calling this function will update the= media + information accordingly. + + @param[in] PeiServices General-purpose services that are available to= every + PEIM + @param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO_PPI in= stance. + @param[in] DeviceIndex Specifies the block device to which the functi= on wants + to talk. Because the driver that implements Bl= ock I/O + PPIs will manage multiple block devices, the P= PIs that + want to talk to a single device must specify t= he + device index that was assigned during the enum= eration + process. This index is a number from one to + NumberBlockDevices. + @param[out] MediaInfo The media information of the specified block m= edia. + The caller is responsible for the ownership of= this + data structure. + + @par Note: + The MediaInfo structure describes an enumeration of possible block d= evice + types. This enumeration exists because no device paths are actually= passed + across interfaces that describe the type or class of hardware that i= s publishing + the block I/O interface. This enumeration will allow for policy deci= sions + in the Recovery PEIM, such as "Try to recover from legacy floppy fir= st, + LS-120 second, CD-ROM third." If there are multiple partitions abstr= acted + by a given device type, they should be reported in ascending order; = this + order also applies to nested partitions, such as legacy MBR, where t= he + outermost partitions would have precedence in the reporting order. T= he + same logic applies to systems such as IDE that have precedence relat= ionships + like "Master/Slave" or "Primary/Secondary". The master device should= be + reported first, the slave second. + + @retval EFI_SUCCESS Media information about the specified block d= evice + was obtained successfully. + @retval EFI_DEVICE_ERROR Cannot get the media information due to a har= dware + error. + +**/ +EFI_STATUS +EFIAPI +AhciBlockIoGetMediaInfo ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This, + IN UINTN DeviceIndex, + OUT EFI_PEI_BLOCK_IO_MEDIA *MediaInfo + ) +{ + PEI_AHCI_CONTROLLER_PRIVATE_DATA *Private; + PEI_AHCI_ATA_DEVICE_DATA *DeviceData; + + if (This =3D=3D NULL || MediaInfo =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + Private =3D GET_AHCI_PEIM_HC_PRIVATE_DATA_FROM_THIS_BLKIO (This); + DeviceData =3D SearchDeviceByIndex (Private, DeviceIndex); + if (DeviceData =3D=3D NULL) { + return EFI_NOT_FOUND; + } + + MediaInfo->DeviceType =3D (EFI_PEI_BLOCK_DEVICE_TYPE) EDKII_PEI_BLOCK_= DEVICE_TYPE_ATA_HARD_DISK; + MediaInfo->MediaPresent =3D TRUE; + MediaInfo->LastBlock =3D (UINTN) DeviceData->Media.LastBlock; + MediaInfo->BlockSize =3D DeviceData->Media.BlockSize; + + return EFI_SUCCESS; +} + +/** + Reads the requested number of blocks from the specified block device. + + The function reads the requested number of blocks from the device. All t= he + blocks are read, or an error is returned. If there is no media in the de= vice, + the function returns EFI_NO_MEDIA. + + @param[in] PeiServices General-purpose services that are available to + every PEIM. + @param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO_PPI in= stance. + @param[in] DeviceIndex Specifies the block device to which the functi= on wants + to talk. Because the driver that implements Bl= ock I/O + PPIs will manage multiple block devices, PPIs = that + want to talk to a single device must specify t= he device + index that was assigned during the enumeration= process. + This index is a number from one to NumberBlock= Devices. + @param[in] StartLBA The starting logical block address (LBA) to re= ad from + on the device + @param[in] BufferSize The size of the Buffer in bytes. This number m= ust be + a multiple of the intrinsic block size of the = device. + @param[out] Buffer A pointer to the destination buffer for the da= ta. + The caller is responsible for the ownership of= the + buffer. + + @retval EFI_SUCCESS The data was read correctly from the dev= ice. + @retval EFI_DEVICE_ERROR The device reported an error while attem= pting + to perform the read operation. + @retval EFI_INVALID_PARAMETER The read request contains LBAs that are = not + valid, or the buffer is not properly ali= gned. + @retval EFI_NO_MEDIA There is no media in the device. + @retval EFI_BAD_BUFFER_SIZE The BufferSize parameter is not a multip= le of + the intrinsic block size of the device. + +**/ +EFI_STATUS +EFIAPI +AhciBlockIoReadBlocks ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This, + IN UINTN DeviceIndex, + IN EFI_PEI_LBA StartLBA, + IN UINTN BufferSize, + OUT VOID *Buffer + ) +{ + PEI_AHCI_CONTROLLER_PRIVATE_DATA *Private; + PEI_AHCI_ATA_DEVICE_DATA *DeviceData; + + if (This =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + Private =3D GET_AHCI_PEIM_HC_PRIVATE_DATA_FROM_THIS_BLKIO (This); + DeviceData =3D SearchDeviceByIndex (Private, DeviceIndex); + if (DeviceData =3D=3D NULL) { + return EFI_NOT_FOUND; + } + + return AhciRead (DeviceData, Buffer, StartLBA, BufferSize); +} + +/** + Gets the count of block I/O devices that one specific block driver detec= ts. + + This function is used for getting the count of block I/O devices that one + specific block driver detects. If no device is detected, then the functi= on + will return zero. + + @param[in] PeiServices General-purpose services that are avail= able + to every PEIM. + @param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO= 2_PPI + instance. + @param[out] NumberBlockDevices The number of block I/O devices discove= red. + + @retval EFI_SUCCESS The operation performed successfully. + +**/ +EFI_STATUS +EFIAPI +AhciBlockIoGetDeviceNo2 ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_RECOVERY_BLOCK_IO2_PPI *This, + OUT UINTN *NumberBlockDevices + ) +{ + PEI_AHCI_CONTROLLER_PRIVATE_DATA *Private; + + if (This =3D=3D NULL || NumberBlockDevices =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + Private =3D GET_AHCI_PEIM_HC_PRIVATE_DATA_FROM_THIS_BLKIO2 (This); + *NumberBlockDevices =3D Private->ActiveDevices; + + return EFI_SUCCESS; +} + +/** + Gets a block device's media information. + + This function will provide the caller with the specified block device's = media + information. If the media changes, calling this function will update the= media + information accordingly. + + @param[in] PeiServices General-purpose services that are available to= every + PEIM + @param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO2_PPI i= nstance. + @param[in] DeviceIndex Specifies the block device to which the functi= on wants + to talk. Because the driver that implements Bl= ock I/O + PPIs will manage multiple block devices, the P= PIs that + want to talk to a single device must specify t= he + device index that was assigned during the enum= eration + process. This index is a number from one to + NumberBlockDevices. + @param[out] MediaInfo The media information of the specified block m= edia. + The caller is responsible for the ownership of= this + data structure. + + @par Note: + The MediaInfo structure describes an enumeration of possible block d= evice + types. This enumeration exists because no device paths are actually= passed + across interfaces that describe the type or class of hardware that i= s publishing + the block I/O interface. This enumeration will allow for policy deci= sions + in the Recovery PEIM, such as "Try to recover from legacy floppy fir= st, + LS-120 second, CD-ROM third." If there are multiple partitions abstr= acted + by a given device type, they should be reported in ascending order; = this + order also applies to nested partitions, such as legacy MBR, where t= he + outermost partitions would have precedence in the reporting order. T= he + same logic applies to systems such as IDE that have precedence relat= ionships + like "Master/Slave" or "Primary/Secondary". The master device should= be + reported first, the slave second. + + @retval EFI_SUCCESS Media information about the specified block d= evice + was obtained successfully. + @retval EFI_DEVICE_ERROR Cannot get the media information due to a har= dware + error. + +**/ +EFI_STATUS +EFIAPI +AhciBlockIoGetMediaInfo2 ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_RECOVERY_BLOCK_IO2_PPI *This, + IN UINTN DeviceIndex, + OUT EFI_PEI_BLOCK_IO2_MEDIA *MediaInfo + ) +{ + PEI_AHCI_CONTROLLER_PRIVATE_DATA *Private; + PEI_AHCI_ATA_DEVICE_DATA *DeviceData; + + if (This =3D=3D NULL || MediaInfo =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + Private =3D GET_AHCI_PEIM_HC_PRIVATE_DATA_FROM_THIS_BLKIO2 (This); + DeviceData =3D SearchDeviceByIndex (Private, DeviceIndex); + if (DeviceData =3D=3D NULL) { + return EFI_NOT_FOUND; + } + + CopyMem ( + MediaInfo, + &DeviceData->Media, + sizeof (EFI_PEI_BLOCK_IO2_MEDIA) + ); + + return EFI_SUCCESS; +} + +/** + Reads the requested number of blocks from the specified block device. + + The function reads the requested number of blocks from the device. All t= he + blocks are read, or an error is returned. If there is no media in the de= vice, + the function returns EFI_NO_MEDIA. + + @param[in] PeiServices General-purpose services that are available to + every PEIM. + @param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO2_PPI i= nstance. + @param[in] DeviceIndex Specifies the block device to which the functi= on wants + to talk. Because the driver that implements Bl= ock I/O + PPIs will manage multiple block devices, PPIs = that + want to talk to a single device must specify t= he device + index that was assigned during the enumeration= process. + This index is a number from one to NumberBlock= Devices. + @param[in] StartLBA The starting logical block address (LBA) to re= ad from + on the device + @param[in] BufferSize The size of the Buffer in bytes. This number m= ust be + a multiple of the intrinsic block size of the = device. + @param[out] Buffer A pointer to the destination buffer for the da= ta. + The caller is responsible for the ownership of= the + buffer. + + @retval EFI_SUCCESS The data was read correctly from the dev= ice. + @retval EFI_DEVICE_ERROR The device reported an error while attem= pting + to perform the read operation. + @retval EFI_INVALID_PARAMETER The read request contains LBAs that are = not + valid, or the buffer is not properly ali= gned. + @retval EFI_NO_MEDIA There is no media in the device. + @retval EFI_BAD_BUFFER_SIZE The BufferSize parameter is not a multip= le of + the intrinsic block size of the device. + +**/ +EFI_STATUS +EFIAPI +AhciBlockIoReadBlocks2 ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_RECOVERY_BLOCK_IO2_PPI *This, + IN UINTN DeviceIndex, + IN EFI_PEI_LBA StartLBA, + IN UINTN BufferSize, + OUT VOID *Buffer + ) +{ + PEI_AHCI_CONTROLLER_PRIVATE_DATA *Private; + + if (This =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + Private =3D GET_AHCI_PEIM_HC_PRIVATE_DATA_FROM_THIS_BLKIO2 (This); + return AhciBlockIoReadBlocks ( + PeiServices, + &Private->BlkIoPpi, + DeviceIndex, + StartLBA, + BufferSize, + Buffer + ); +} --=20 2.12.0.windows.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#39408): https://edk2.groups.io/g/devel/message/39408 Mute This Topic: https://groups.io/mt/31306790/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-