--- /dev/null
+/** @file\r
+ The AhciPei driver is used to manage ATA hard disk device working under AHCI\r
+ mode at PEI phase.\r
+\r
+ Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>\r
+\r
+ This program and the accompanying materials\r
+ are licensed and made available under the terms and conditions\r
+ of the BSD License which accompanies this distribution. The\r
+ full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.php\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef _AHCI_PEI_H_\r
+#define _AHCI_PEI_H_\r
+\r
+#include <PiPei.h>\r
+\r
+#include <IndustryStandard/Atapi.h>\r
+\r
+#include <Ppi/AtaAhciController.h>\r
+#include <Ppi/IoMmu.h>\r
+#include <Ppi/EndOfPeiPhase.h>\r
+#include <Ppi/AtaPassThru.h>\r
+#include <Ppi/BlockIo2.h>\r
+#include <Ppi/StorageSecurityCommand.h>\r
+\r
+#include <Library/DebugLib.h>\r
+#include <Library/PeiServicesLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/IoLib.h>\r
+#include <Library/TimerLib.h>\r
+\r
+//\r
+// Structure forward declarations\r
+//\r
+typedef struct _PEI_AHCI_CONTROLLER_PRIVATE_DATA PEI_AHCI_CONTROLLER_PRIVATE_DATA;\r
+\r
+#include "AhciPeiPassThru.h"\r
+#include "AhciPeiStorageSecurity.h"\r
+\r
+//\r
+// ATA AHCI driver implementation related definitions\r
+//\r
+//\r
+// Refer SATA1.0a spec section 5.2, the Phy detection time should be less than 10ms.\r
+// The value is in millisecond units. Add a bit of margin for robustness.\r
+//\r
+#define AHCI_BUS_PHY_DETECT_TIMEOUT 15\r
+//\r
+// Refer SATA1.0a spec, the bus reset time should be less than 1s.\r
+// The value is in 100ns units.\r
+//\r
+#define AHCI_PEI_RESET_TIMEOUT 10000000\r
+//\r
+// Time out Value for ATA pass through protocol, in 100ns units.\r
+//\r
+#define ATA_TIMEOUT 30000000\r
+//\r
+// Maximal number of Physical Region Descriptor Table entries supported.\r
+//\r
+#define AHCI_MAX_PRDT_NUMBER 8\r
+\r
+#define AHCI_CAPABILITY_OFFSET 0x0000\r
+#define AHCI_CAP_SAM BIT18\r
+#define AHCI_CAP_SSS BIT27\r
+\r
+#define AHCI_GHC_OFFSET 0x0004\r
+#define AHCI_GHC_RESET BIT0\r
+#define AHCI_GHC_ENABLE BIT31\r
+\r
+#define AHCI_IS_OFFSET 0x0008\r
+#define AHCI_PI_OFFSET 0x000C\r
+\r
+#define AHCI_MAX_PORTS 32\r
+\r
+typedef struct {\r
+ UINT32 Lower32;\r
+ UINT32 Upper32;\r
+} DATA_32;\r
+\r
+typedef union {\r
+ DATA_32 Uint32;\r
+ UINT64 Uint64;\r
+} DATA_64;\r
+\r
+#define AHCI_ATAPI_SIG_MASK 0xFFFF0000\r
+#define AHCI_ATA_DEVICE_SIG 0x00000000\r
+\r
+//\r
+// Each PRDT entry can point to a memory block up to 4M byte\r
+//\r
+#define AHCI_MAX_DATA_PER_PRDT 0x400000\r
+\r
+#define AHCI_FIS_REGISTER_H2D 0x27 //Register FIS - Host to Device\r
+#define AHCI_FIS_REGISTER_H2D_LENGTH 20\r
+#define AHCI_FIS_REGISTER_D2H 0x34 //Register FIS - Device to Host\r
+#define AHCI_FIS_PIO_SETUP 0x5F //PIO Setup FIS - Device to Host\r
+\r
+#define AHCI_D2H_FIS_OFFSET 0x40\r
+#define AHCI_PIO_FIS_OFFSET 0x20\r
+#define AHCI_FIS_TYPE_MASK 0xFF\r
+\r
+//\r
+// Port register\r
+//\r
+#define AHCI_PORT_START 0x0100\r
+#define AHCI_PORT_REG_WIDTH 0x0080\r
+#define AHCI_PORT_CLB 0x0000\r
+#define AHCI_PORT_CLBU 0x0004\r
+#define AHCI_PORT_FB 0x0008\r
+#define AHCI_PORT_FBU 0x000C\r
+#define AHCI_PORT_IS 0x0010\r
+#define AHCI_PORT_IE 0x0014\r
+#define AHCI_PORT_CMD 0x0018\r
+#define AHCI_PORT_CMD_ST BIT0\r
+#define AHCI_PORT_CMD_SUD BIT1\r
+#define AHCI_PORT_CMD_POD BIT2\r
+#define AHCI_PORT_CMD_CLO BIT3\r
+#define AHCI_PORT_CMD_FRE BIT4\r
+#define AHCI_PORT_CMD_FR BIT14\r
+#define AHCI_PORT_CMD_CR BIT15\r
+#define AHCI_PORT_CMD_CPD BIT20\r
+#define AHCI_PORT_CMD_ATAPI BIT24\r
+#define AHCI_PORT_CMD_DLAE BIT25\r
+#define AHCI_PORT_CMD_ALPE BIT26\r
+#define AHCI_PORT_CMD_ACTIVE (1 << 28)\r
+#define AHCI_PORT_CMD_ICC_MASK (BIT28 | BIT29 | BIT30 | BIT31)\r
+\r
+#define AHCI_PORT_TFD 0x0020\r
+#define AHCI_PORT_TFD_ERR BIT0\r
+#define AHCI_PORT_TFD_DRQ BIT3\r
+#define AHCI_PORT_TFD_BSY BIT7\r
+#define AHCI_PORT_TFD_MASK (BIT7 | BIT3 | BIT0)\r
+\r
+#define AHCI_PORT_SIG 0x0024\r
+#define AHCI_PORT_SSTS 0x0028\r
+#define AHCI_PORT_SSTS_DET_MASK 0x000F\r
+#define AHCI_PORT_SSTS_DET 0x0001\r
+#define AHCI_PORT_SSTS_DET_PCE 0x0003\r
+\r
+#define AHCI_PORT_SCTL 0x002C\r
+#define AHCI_PORT_SCTL_IPM_INIT 0x0300\r
+\r
+#define AHCI_PORT_SERR 0x0030\r
+#define AHCI_PORT_CI 0x0038\r
+\r
+#define IS_ALIGNED(addr, size) (((UINTN) (addr) & (size - 1)) == 0)\r
+#define TIMER_PERIOD_SECONDS(Seconds) MultU64x32((UINT64)(Seconds), 10000000)\r
+\r
+#pragma pack(1)\r
+\r
+//\r
+// Received FIS structure\r
+//\r
+typedef struct {\r
+ UINT8 AhciDmaSetupFis[0x1C]; // Dma Setup Fis: offset 0x00\r
+ UINT8 AhciDmaSetupFisRsvd[0x04];\r
+ UINT8 AhciPioSetupFis[0x14]; // Pio Setup Fis: offset 0x20\r
+ UINT8 AhciPioSetupFisRsvd[0x0C];\r
+ UINT8 AhciD2HRegisterFis[0x14]; // D2H Register Fis: offset 0x40\r
+ UINT8 AhciD2HRegisterFisRsvd[0x04];\r
+ UINT64 AhciSetDeviceBitsFis; // Set Device Bits Fix: offset 0x58\r
+ UINT8 AhciUnknownFis[0x40]; // Unkonwn Fis: offset 0x60\r
+ UINT8 AhciUnknownFisRsvd[0x60];\r
+} EFI_AHCI_RECEIVED_FIS;\r
+\r
+//\r
+// Command List structure includes total 32 entries.\r
+// The entry Data structure is listed at the following.\r
+//\r
+typedef struct {\r
+ UINT32 AhciCmdCfl:5; //Command FIS Length\r
+ UINT32 AhciCmdA:1; //ATAPI\r
+ UINT32 AhciCmdW:1; //Write\r
+ UINT32 AhciCmdP:1; //Prefetchable\r
+ UINT32 AhciCmdR:1; //Reset\r
+ UINT32 AhciCmdB:1; //BIST\r
+ UINT32 AhciCmdC:1; //Clear Busy upon R_OK\r
+ UINT32 AhciCmdRsvd:1;\r
+ UINT32 AhciCmdPmp:4; //Port Multiplier Port\r
+ UINT32 AhciCmdPrdtl:16; //Physical Region Descriptor Table Length\r
+ UINT32 AhciCmdPrdbc; //Physical Region Descriptor Byte Count\r
+ UINT32 AhciCmdCtba; //Command Table Descriptor Base Address\r
+ UINT32 AhciCmdCtbau; //Command Table Descriptor Base Address Upper 32-BITs\r
+ UINT32 AhciCmdRsvd1[4];\r
+} EFI_AHCI_COMMAND_LIST;\r
+\r
+//\r
+// This is a software constructed FIS.\r
+// For Data transfer operations, this is the H2D Register FIS format as\r
+// specified in the Serial ATA Revision 2.6 specification.\r
+//\r
+typedef struct {\r
+ UINT8 AhciCFisType;\r
+ UINT8 AhciCFisPmNum:4;\r
+ UINT8 AhciCFisRsvd:1;\r
+ UINT8 AhciCFisRsvd1:1;\r
+ UINT8 AhciCFisRsvd2:1;\r
+ UINT8 AhciCFisCmdInd:1;\r
+ UINT8 AhciCFisCmd;\r
+ UINT8 AhciCFisFeature;\r
+ UINT8 AhciCFisSecNum;\r
+ UINT8 AhciCFisClyLow;\r
+ UINT8 AhciCFisClyHigh;\r
+ UINT8 AhciCFisDevHead;\r
+ UINT8 AhciCFisSecNumExp;\r
+ UINT8 AhciCFisClyLowExp;\r
+ UINT8 AhciCFisClyHighExp;\r
+ UINT8 AhciCFisFeatureExp;\r
+ UINT8 AhciCFisSecCount;\r
+ UINT8 AhciCFisSecCountExp;\r
+ UINT8 AhciCFisRsvd3;\r
+ UINT8 AhciCFisControl;\r
+ UINT8 AhciCFisRsvd4[4];\r
+ UINT8 AhciCFisRsvd5[44];\r
+} EFI_AHCI_COMMAND_FIS;\r
+\r
+//\r
+// ACMD: ATAPI command (12 or 16 bytes)\r
+//\r
+typedef struct {\r
+ UINT8 AtapiCmd[0x10];\r
+} EFI_AHCI_ATAPI_COMMAND;\r
+\r
+//\r
+// Physical Region Descriptor Table includes up to 65535 entries\r
+// The entry data structure is listed at the following.\r
+// the actual entry number comes from the PRDTL field in the command\r
+// list entry for this command slot.\r
+//\r
+typedef struct {\r
+ UINT32 AhciPrdtDba; //Data Base Address\r
+ UINT32 AhciPrdtDbau; //Data Base Address Upper 32-BITs\r
+ UINT32 AhciPrdtRsvd;\r
+ UINT32 AhciPrdtDbc:22; //Data Byte Count\r
+ UINT32 AhciPrdtRsvd1:9;\r
+ UINT32 AhciPrdtIoc:1; //Interrupt on Completion\r
+} EFI_AHCI_COMMAND_PRDT;\r
+\r
+//\r
+// Command table Data strucute which is pointed to by the entry in the command list\r
+//\r
+typedef struct {\r
+ EFI_AHCI_COMMAND_FIS CommandFis; // A software constructed FIS.\r
+ EFI_AHCI_ATAPI_COMMAND AtapiCmd; // 12 or 16 bytes ATAPI cmd.\r
+ UINT8 Reserved[0x30];\r
+ //\r
+ // The scatter/gather list for Data transfer.\r
+ //\r
+ EFI_AHCI_COMMAND_PRDT PrdtTable[AHCI_MAX_PRDT_NUMBER];\r
+} EFI_AHCI_COMMAND_TABLE;\r
+\r
+#pragma pack()\r
+\r
+typedef struct {\r
+ EFI_AHCI_RECEIVED_FIS *AhciRFis;\r
+ EFI_AHCI_COMMAND_LIST *AhciCmdList;\r
+ EFI_AHCI_COMMAND_TABLE *AhciCmdTable;\r
+ UINTN MaxRFisSize;\r
+ UINTN MaxCmdListSize;\r
+ UINTN MaxCmdTableSize;\r
+ VOID *AhciRFisMap;\r
+ VOID *AhciCmdListMap;\r
+ VOID *AhciCmdTableMap;\r
+} EFI_AHCI_REGISTERS;\r
+\r
+//\r
+// Unique signature for AHCI ATA device information structure.\r
+//\r
+#define AHCI_PEI_ATA_DEVICE_DATA_SIGNATURE SIGNATURE_32 ('A', 'P', 'A', 'D')\r
+\r
+//\r
+// AHCI mode device information structure.\r
+//\r
+typedef struct {\r
+ UINT32 Signature;\r
+ LIST_ENTRY Link;\r
+\r
+ UINT16 Port;\r
+ UINT16 PortMultiplier;\r
+ UINT8 FisIndex;\r
+ UINTN DeviceIndex;\r
+ ATA_IDENTIFY_DATA *IdentifyData;\r
+\r
+ BOOLEAN Lba48Bit;\r
+ BOOLEAN TrustComputing;\r
+ UINTN TrustComputingDeviceIndex;\r
+ EFI_PEI_BLOCK_IO2_MEDIA Media;\r
+\r
+ PEI_AHCI_CONTROLLER_PRIVATE_DATA *Private;\r
+} PEI_AHCI_ATA_DEVICE_DATA;\r
+\r
+#define AHCI_PEI_ATA_DEVICE_INFO_FROM_THIS(a) \\r
+ CR (a, \\r
+ PEI_AHCI_ATA_DEVICE_DATA, \\r
+ Link, \\r
+ AHCI_PEI_ATA_DEVICE_DATA_SIGNATURE \\r
+ );\r
+\r
+//\r
+// Unique signature for private data structure.\r
+//\r
+#define AHCI_PEI_CONTROLLER_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('A','P','C','P')\r
+\r
+//\r
+// ATA AHCI controller private data structure.\r
+//\r
+struct _PEI_AHCI_CONTROLLER_PRIVATE_DATA {\r
+ UINT32 Signature;\r
+ UINTN MmioBase;\r
+ UINTN DevicePathLength;\r
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
+\r
+ EFI_ATA_PASS_THRU_MODE AtaPassThruMode;\r
+ EDKII_PEI_ATA_PASS_THRU_PPI AtaPassThruPpi;\r
+ EDKII_PEI_STORAGE_SECURITY_CMD_PPI StorageSecurityPpi;\r
+ EFI_PEI_PPI_DESCRIPTOR AtaPassThruPpiList;\r
+ EFI_PEI_PPI_DESCRIPTOR BlkIoPpiList;\r
+ EFI_PEI_PPI_DESCRIPTOR BlkIo2PpiList;\r
+ EFI_PEI_PPI_DESCRIPTOR StorageSecurityPpiList;\r
+ EFI_PEI_NOTIFY_DESCRIPTOR EndOfPeiNotifyList;\r
+\r
+ EFI_AHCI_REGISTERS AhciRegisters;\r
+\r
+ UINT32 PortBitMap;\r
+ UINT32 ActiveDevices;\r
+ UINT32 TrustComputingDevices;\r
+ LIST_ENTRY DeviceList;\r
+\r
+ UINT16 PreviousPort;\r
+ UINT16 PreviousPortMultiplier;\r
+};\r
+\r
+#define GET_AHCI_PEIM_HC_PRIVATE_DATA_FROM_THIS_PASS_THRU(a) \\r
+ CR (a, PEI_AHCI_CONTROLLER_PRIVATE_DATA, AtaPassThruPpi, AHCI_PEI_CONTROLLER_PRIVATE_DATA_SIGNATURE)\r
+#define GET_AHCI_PEIM_HC_PRIVATE_DATA_FROM_THIS_BLKIO(a) \\r
+ CR (a, PEI_AHCI_CONTROLLER_PRIVATE_DATA, BlkIoPpi, AHCI_PEI_CONTROLLER_PRIVATE_DATA_SIGNATURE)\r
+#define GET_AHCI_PEIM_HC_PRIVATE_DATA_FROM_THIS_BLKIO2(a) \\r
+ CR (a, PEI_AHCI_CONTROLLER_PRIVATE_DATA, BlkIo2Ppi, AHCI_PEI_CONTROLLER_PRIVATE_DATA_SIGNATURE)\r
+#define GET_AHCI_PEIM_HC_PRIVATE_DATA_FROM_THIS_STROAGE_SECURITY(a) \\r
+ CR (a, PEI_AHCI_CONTROLLER_PRIVATE_DATA, StorageSecurityPpi, AHCI_PEI_CONTROLLER_PRIVATE_DATA_SIGNATURE)\r
+#define GET_AHCI_PEIM_HC_PRIVATE_DATA_FROM_THIS_NOTIFY(a) \\r
+ CR (a, PEI_AHCI_CONTROLLER_PRIVATE_DATA, EndOfPeiNotifyList, AHCI_PEI_CONTROLLER_PRIVATE_DATA_SIGNATURE)\r
+\r
+//\r
+// Global variables\r
+//\r
+extern UINT32 mMaxTransferBlockNumber[2];\r
+\r
+//\r
+// Internal functions\r
+//\r
+\r
+/**\r
+ Allocates pages that are suitable for an OperationBusMasterCommonBuffer or\r
+ OperationBusMasterCommonBuffer64 mapping.\r
+\r
+ @param Pages The number of pages to allocate.\r
+ @param HostAddress A pointer to store the base system memory address of the\r
+ allocated range.\r
+ @param DeviceAddress The resulting map address for the bus master PCI controller to use to\r
+ access the hosts HostAddress.\r
+ @param Mapping A resulting value to pass to Unmap().\r
+\r
+ @retval EFI_SUCCESS The requested memory pages were allocated.\r
+ @retval EFI_UNSUPPORTED Attributes is unsupported. The only legal attribute bits are\r
+ MEMORY_WRITE_COMBINE and MEMORY_CACHED.\r
+ @retval EFI_INVALID_PARAMETER One or more parameters are invalid.\r
+ @retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated.\r
+\r
+**/\r
+EFI_STATUS\r
+IoMmuAllocateBuffer (\r
+ IN UINTN Pages,\r
+ OUT VOID **HostAddress,\r
+ OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,\r
+ OUT VOID **Mapping\r
+ );\r
+\r
+/**\r
+ Frees memory that was allocated with AllocateBuffer().\r
+\r
+ @param Pages The number of pages to free.\r
+ @param HostAddress The base system memory address of the allocated range.\r
+ @param Mapping The mapping value returned from Map().\r
+\r
+ @retval EFI_SUCCESS The requested memory pages were freed.\r
+ @retval EFI_INVALID_PARAMETER The memory range specified by HostAddress and Pages\r
+ was not allocated with AllocateBuffer().\r
+\r
+**/\r
+EFI_STATUS\r
+IoMmuFreeBuffer (\r
+ IN UINTN Pages,\r
+ IN VOID *HostAddress,\r
+ IN VOID *Mapping\r
+ );\r
+\r
+/**\r
+ Provides the controller-specific addresses required to access system memory from a\r
+ DMA bus master.\r
+\r
+ @param Operation Indicates if the bus master is going to read or write to system memory.\r
+ @param HostAddress The system memory address to map to the PCI controller.\r
+ @param NumberOfBytes On input the number of bytes to map. On output the number of bytes\r
+ that were mapped.\r
+ @param DeviceAddress The resulting map address for the bus master PCI controller to use to\r
+ access the hosts HostAddress.\r
+ @param Mapping A resulting value to pass to Unmap().\r
+\r
+ @retval EFI_SUCCESS The range was mapped for the returned NumberOfBytes.\r
+ @retval EFI_UNSUPPORTED The HostAddress cannot be mapped as a common buffer.\r
+ @retval EFI_INVALID_PARAMETER One or more parameters are invalid.\r
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
+ @retval EFI_DEVICE_ERROR The system hardware could not map the requested address.\r
+\r
+**/\r
+EFI_STATUS\r
+IoMmuMap (\r
+ IN EDKII_IOMMU_OPERATION Operation,\r
+ IN VOID *HostAddress,\r
+ IN OUT UINTN *NumberOfBytes,\r
+ OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,\r
+ OUT VOID **Mapping\r
+ );\r
+\r
+/**\r
+ Completes the Map() operation and releases any corresponding resources.\r
+\r
+ @param Mapping The mapping value returned from Map().\r
+\r
+ @retval EFI_SUCCESS The range was unmapped.\r
+ @retval EFI_INVALID_PARAMETER Mapping is not a value that was returned by Map().\r
+ @retval EFI_DEVICE_ERROR The data was not committed to the target system memory.\r
+**/\r
+EFI_STATUS\r
+IoMmuUnmap (\r
+ IN VOID *Mapping\r
+ );\r
+\r
+/**\r
+ One notified function to cleanup the allocated DMA buffers at EndOfPei.\r
+\r
+ @param[in] PeiServices Pointer to PEI Services Table.\r
+ @param[in] NotifyDescriptor Pointer to the descriptor for the Notification\r
+ event that caused this function to execute.\r
+ @param[in] Ppi Pointer to the PPI data associated with this function.\r
+\r
+ @retval EFI_SUCCESS The function completes successfully\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+AhciPeimEndOfPei (\r
+ IN EFI_PEI_SERVICES **PeiServices,\r
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,\r
+ IN VOID *Ppi\r
+ );\r
+\r
+/**\r
+ Collect the number of bits set within a port bitmap.\r
+\r
+ @param[in] PortBitMap A 32-bit wide bit map of ATA AHCI ports.\r
+\r
+ @retval The number of bits set in the bitmap.\r
+\r
+**/\r
+UINT8\r
+AhciGetNumberOfPortsFromMap (\r
+ IN UINT32 PortBitMap\r
+ );\r
+\r
+/**\r
+ Start a PIO Data transfer on specific port.\r
+\r
+ @param[in] Private The pointer to the PEI_AHCI_CONTROLLER_PRIVATE_DATA.\r
+ @param[in] Port The number of port.\r
+ @param[in] PortMultiplier The number of port multiplier.\r
+ @param[in] FisIndex The offset index of the FIS base address.\r
+ @param[in] Read The transfer direction.\r
+ @param[in] AtaCommandBlock The EFI_ATA_COMMAND_BLOCK data.\r
+ @param[in,out] AtaStatusBlock The EFI_ATA_STATUS_BLOCK data.\r
+ @param[in,out] MemoryAddr The pointer to the data buffer.\r
+ @param[in] DataCount The data count to be transferred.\r
+ @param[in] Timeout The timeout value of PIO data transfer, uses\r
+ 100ns as a unit.\r
+\r
+ @retval EFI_DEVICE_ERROR The PIO data transfer abort with error occurs.\r
+ @retval EFI_TIMEOUT The operation is time out.\r
+ @retval EFI_UNSUPPORTED The device is not ready for transfer.\r
+ @retval EFI_OUT_OF_RESOURCES The operation fails due to lack of resources.\r
+ @retval EFI_SUCCESS The PIO data transfer executes successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+AhciPioTransfer (\r
+ IN PEI_AHCI_CONTROLLER_PRIVATE_DATA *Private,\r
+ IN UINT8 Port,\r
+ IN UINT8 PortMultiplier,\r
+ IN UINT8 FisIndex,\r
+ IN BOOLEAN Read,\r
+ IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock,\r
+ IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock,\r
+ IN OUT VOID *MemoryAddr,\r
+ IN UINT32 DataCount,\r
+ IN UINT64 Timeout\r
+ );\r
+\r
+/**\r
+ Start a non data transfer on specific port.\r
+\r
+ @param[in] Private The pointer to the PEI_AHCI_CONTROLLER_PRIVATE_DATA.\r
+ @param[in] Port The number of port.\r
+ @param[in] PortMultiplier The number of port multiplier.\r
+ @param[in] FisIndex The offset index of the FIS base address.\r
+ @param[in] AtaCommandBlock The EFI_ATA_COMMAND_BLOCK data.\r
+ @param[in,out] AtaStatusBlock The EFI_ATA_STATUS_BLOCK data.\r
+ @param[in] Timeout The timeout value of non data transfer, uses\r
+ 100ns as a unit.\r
+\r
+ @retval EFI_DEVICE_ERROR The non data transfer abort with error occurs.\r
+ @retval EFI_TIMEOUT The operation is time out.\r
+ @retval EFI_UNSUPPORTED The device is not ready for transfer.\r
+ @retval EFI_SUCCESS The non data transfer executes successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+AhciNonDataTransfer (\r
+ IN PEI_AHCI_CONTROLLER_PRIVATE_DATA *Private,\r
+ IN UINT8 Port,\r
+ IN UINT8 PortMultiplier,\r
+ IN UINT8 FisIndex,\r
+ IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock,\r
+ IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock,\r
+ IN UINT64 Timeout\r
+ );\r
+\r
+/**\r
+ Initialize ATA host controller at AHCI mode.\r
+\r
+ The function is designed to initialize ATA host controller.\r
+\r
+ @param[in,out] Private A pointer to the PEI_AHCI_CONTROLLER_PRIVATE_DATA instance.\r
+\r
+ @retval EFI_SUCCESS The ATA AHCI controller is initialized successfully.\r
+ @retval EFI_OUT_OF_RESOURCES Not enough resource to complete while initializing\r
+ the controller.\r
+ @retval Others A device error occurred while initializing the\r
+ controller.\r
+\r
+**/\r
+EFI_STATUS\r
+AhciModeInitialization (\r
+ IN OUT PEI_AHCI_CONTROLLER_PRIVATE_DATA *Private\r
+ );\r
+\r
+/**\r
+ Trust transfer data from/to ATA device.\r
+\r
+ This function performs one ATA pass through transaction to do a trust transfer\r
+ from/to ATA device. It chooses the appropriate ATA command and protocol to invoke\r
+ PassThru interface of ATA pass through.\r
+\r
+ @param[in] DeviceData Pointer to PEI_AHCI_ATA_DEVICE_DATA structure.\r
+ @param[in,out] Buffer The pointer to the current transaction buffer.\r
+ @param[in] SecurityProtocolId\r
+ The value of the "Security Protocol" parameter\r
+ of the security protocol command to be sent.\r
+ @param[in] SecurityProtocolSpecificData\r
+ The value of the "Security Protocol Specific"\r
+ parameter of the security protocol command to\r
+ be sent.\r
+ @param[in] TransferLength The block number or sector count of the transfer.\r
+ @param[in] IsTrustSend Indicates whether it is a trust send operation\r
+ or not.\r
+ @param[in] Timeout The timeout, in 100ns units, to use for the execution\r
+ of the security protocol command. A Timeout value\r
+ of 0 means that this function will wait indefinitely\r
+ for the security protocol command to execute. If\r
+ Timeout is greater than zero, then this function\r
+ will return EFI_TIMEOUT if the time required to\r
+ execute the receive data command is greater than\r
+ Timeout.\r
+ @param[out] TransferLengthOut\r
+ A pointer to a buffer to store the size in bytes\r
+ of the data written to the buffer. Ignore it when\r
+ IsTrustSend is TRUE.\r
+\r
+ @retval EFI_SUCCESS The data transfer is complete successfully.\r
+ @return others Some error occurs when transferring data.\r
+\r
+**/\r
+EFI_STATUS\r
+TrustTransferAtaDevice (\r
+ IN PEI_AHCI_ATA_DEVICE_DATA *DeviceData,\r
+ IN OUT VOID *Buffer,\r
+ IN UINT8 SecurityProtocolId,\r
+ IN UINT16 SecurityProtocolSpecificData,\r
+ IN UINTN TransferLength,\r
+ IN BOOLEAN IsTrustSend,\r
+ IN UINT64 Timeout,\r
+ OUT UINTN *TransferLengthOut\r
+ );\r
+\r
+/**\r
+ Returns a pointer to the next node in a device path.\r
+\r
+ If Node is NULL, then ASSERT().\r
+\r
+ @param Node A pointer to a device path node data structure.\r
+\r
+ @return a pointer to the device path node that follows the device path node\r
+ specified by Node.\r
+\r
+**/\r
+EFI_DEVICE_PATH_PROTOCOL *\r
+NextDevicePathNode (\r
+ IN CONST VOID *Node\r
+ );\r
+\r
+/**\r
+ Get the size of the current device path instance.\r
+\r
+ @param[in] DevicePath A pointer to the EFI_DEVICE_PATH_PROTOCOL\r
+ structure.\r
+ @param[out] InstanceSize The size of the current device path instance.\r
+ @param[out] EntireDevicePathEnd Indicate whether the instance is the last\r
+ one in the device path strucure.\r
+\r
+ @retval EFI_SUCCESS The size of the current device path instance is fetched.\r
+ @retval Others Fails to get the size of the current device path instance.\r
+\r
+**/\r
+EFI_STATUS\r
+GetDevicePathInstanceSize (\r
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,\r
+ OUT UINTN *InstanceSize,\r
+ OUT BOOLEAN *EntireDevicePathEnd\r
+ );\r
+\r
+/**\r
+ Check the validity of the device path of a ATA AHCI host controller.\r
+\r
+ @param[in] DevicePath A pointer to the EFI_DEVICE_PATH_PROTOCOL\r
+ structure.\r
+ @param[in] DevicePathLength The length of the device path.\r
+\r
+ @retval EFI_SUCCESS The device path is valid.\r
+ @retval EFI_INVALID_PARAMETER The device path is invalid.\r
+\r
+**/\r
+EFI_STATUS\r
+AhciIsHcDevicePathValid (\r
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,\r
+ IN UINTN DevicePathLength\r
+ );\r
+\r
+/**\r
+ Build the device path for an ATA device with given port and port multiplier number.\r
+\r
+ @param[in] Private A pointer to the PEI_AHCI_CONTROLLER_PRIVATE_DATA\r
+ data structure.\r
+ @param[in] Port The given port number.\r
+ @param[in] PortMultiplierPort The given port multiplier number.\r
+ @param[out] DevicePathLength The length of the device path in bytes specified\r
+ by DevicePath.\r
+ @param[out] DevicePath The device path of ATA device.\r
+\r
+ @retval EFI_SUCCESS The operation succeeds.\r
+ @retval EFI_INVALID_PARAMETER The parameters are invalid.\r
+ @retval EFI_OUT_OF_RESOURCES The operation fails due to lack of resources.\r
+\r
+**/\r
+EFI_STATUS\r
+AhciBuildDevicePath (\r
+ IN PEI_AHCI_CONTROLLER_PRIVATE_DATA *Private,\r
+ IN UINT16 Port,\r
+ IN UINT16 PortMultiplierPort,\r
+ OUT UINTN *DevicePathLength,\r
+ OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath\r
+ );\r
+\r
+/**\r
+ Collect the ports that need to be enumerated on a controller for S3 phase.\r
+\r
+ @param[in] HcDevicePath Device path of the controller.\r
+ @param[in] HcDevicePathLength Length of the device path specified by\r
+ HcDevicePath.\r
+ @param[out] PortBitMap Bitmap that indicates the ports that need\r
+ to be enumerated on the controller.\r
+\r
+ @retval The number of ports that need to be enumerated.\r
+\r
+**/\r
+UINT8\r
+AhciS3GetEumeratePorts (\r
+ IN EFI_DEVICE_PATH_PROTOCOL *HcDevicePath,\r
+ IN UINTN HcDevicePathLength,\r
+ OUT UINT32 *PortBitMap\r
+ );\r
+\r
+#endif\r