]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Bus/Ata/AhciPei/AhciPei.h
MdeModulePkg/AhciPei: Add AHCI mode ATA device support in PEI
[mirror_edk2.git] / MdeModulePkg / Bus / Ata / AhciPei / AhciPei.h
diff --git a/MdeModulePkg/Bus/Ata/AhciPei/AhciPei.h b/MdeModulePkg/Bus/Ata/AhciPei/AhciPei.h
new file mode 100644 (file)
index 0000000..b2c586d
--- /dev/null
@@ -0,0 +1,708 @@
+/** @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