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