X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=MdeModulePkg%2FBus%2FAta%2FAhciPei%2FAhciPei.h;fp=MdeModulePkg%2FBus%2FAta%2FAhciPei%2FAhciPei.h;h=b2c586de5452f0448a5d5025b94438a195e988be;hb=87bc3f192e17cd8f7caf0f3b7a87e039ceab323f;hp=0000000000000000000000000000000000000000;hpb=05fd2a9268332d770dd082be4af076ba0217cf54;p=mirror_edk2.git diff --git a/MdeModulePkg/Bus/Ata/AhciPei/AhciPei.h b/MdeModulePkg/Bus/Ata/AhciPei/AhciPei.h new file mode 100644 index 0000000000..b2c586de54 --- /dev/null +++ b/MdeModulePkg/Bus/Ata/AhciPei/AhciPei.h @@ -0,0 +1,708 @@ +/** @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.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions + of the BSD License which accompanies this distribution. The + full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef _AHCI_PEI_H_ +#define _AHCI_PEI_H_ + +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +// +// Structure forward declarations +// +typedef struct _PEI_AHCI_CONTROLLER_PRIVATE_DATA PEI_AHCI_CONTROLLER_PRIVATE_DATA; + +#include "AhciPeiPassThru.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]; // Unkonwn 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 strucute which is pointed to by the entry in the command list +// +typedef struct { + EFI_AHCI_COMMAND_FIS CommandFis; // A software constructed FIS. + EFI_AHCI_ATAPI_COMMAND AtapiCmd; // 12 or 16 bytes ATAPI 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; + 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 + ); + +/** + 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