blob: e2e4ba43e7c4c8d40aeecdd7891f6c39d50664be [file] [log] [blame]
/** @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>
#include <Library/DevicePathLib.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 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
//
/**
Callback for EDKII_ATA_AHCI_HOST_CONTROLLER_PPI installation.
@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
@retval Others Cannot initialize AHCI controller from given EDKII_ATA_AHCI_HOST_CONTROLLER_PPI
**/
EFI_STATUS
EFIAPI
AtaAhciHostControllerPpiInstallationCallback (
IN EFI_PEI_SERVICES **PeiServices,
IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
IN VOID *Ppi
);
/**
Callback for EDKII_PCI_DEVICE_PPI installation.
@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
@retval Others Cannot initialize AHCI controller from given PCI_DEVICE_PPI
**/
EFI_STATUS
EFIAPI
AtaAhciPciDevicePpiInstallationCallback (
IN EFI_PEI_SERVICES **PeiServices,
IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
IN VOID *Ppi
);
/**
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
);
/**
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