/** @file
Ahci.h - AHCI Driver private data structures and definitions.
Derived from Ahci.efi (AMI AmiModulePkg/AHCI).
Source path: e:\hs\AmiModulePkg\AHCI\AhciBus.c
Build: DEBUG_VS2015 X64
Module GUID (EFI_ATA_PASS_THRU_PROTOCOL): 18A031AB-B443-4D1A-A5C0-0C09261E9F71
**/
#ifndef __AHCI_H__
#define __AHCI_H__
#include <Uefi.h>
#include <Protocol/BlockIo.h>
#include <Protocol/BlockIo2.h>
#include <Protocol/AtaPassThru.h>
#include <Protocol/PciIo.h>
#include <Protocol/IdeControllerInit.h>
#include <Protocol/DevicePath.h>
#include <Protocol/ComponentName2.h>
//
// Protocol GUIDs consumed by this driver
//
#define AHCI_DRIVER_BINDING_PROTOCOL_GUID \
{ 0xC88B0B6D, 0x0DFC, 0x49A7, { 0x9C, 0xB4, 0x49, 0x07, 0x4B, 0x4C, 0x3A, 0x78 } }
//
// AHCI Register offsets (per port, stride 0x80)
//
#define AHCI_PORT_REG_CLB 0x00 // Command List Base Address (lower 32 bits)
#define AHCI_PORT_REG_CLBU 0x04 // Command List Base Address (upper 32 bits)
#define AHCI_PORT_REG_FB 0x08 // FIS Base Address (lower 32 bits)
#define AHCI_PORT_REG_FBU 0x0C // FIS Base Address (upper 32 bits)
#define AHCI_PORT_REG_IS 0x10 // Interrupt Status
#define AHCI_PORT_REG_IE 0x14 // Interrupt Enable
#define AHCI_PORT_REG_CMD 0x18 // Command and Status
#define AHCI_PORT_REG_TFD 0x1C // Task File Data
#define AHCI_PORT_REG_SIG 0x20 // Signature
#define AHCI_PORT_REG_SSTS 0x24 // Serial ATA Status (SCR0)
#define AHCI_PORT_REG_SCTL 0x28 // Serial ATA Control (SCR2)
#define AHCI_PORT_REG_SERR 0x2C // Serial ATA Error (SCR1)
#define AHCI_PORT_REG_SACT 0x30 // Serial ATA Active (SCR3)
#define AHCI_PORT_REG_CI 0x34 // Command Issue
#define AHCI_PORT_REG_SNTF 0x38 // Serial ATA Notification (SCR4)
#define AHCI_PORT_REG_FBS 0x3C // FIS-Based Switching
//
// AHCI Generic Host Controller registers
//
#define AHCI_GHC_CAP 0x00 // Host Capabilities
#define AHCI_GHC_GHC 0x04 // Global Host Control
#define AHCI_GHC_IS 0x08 // Interrupt Status
#define AHCI_GHC_PI 0x0C // Ports Implemented
#define AHCI_GHC_VS 0x10 // Version
#define AHCI_GHC_CCC_CTL 0x14 // Command Completion Coalescing Control
#define AHCI_GHC_CCC_PORTS 0x18 // Command Completion Coalescing Ports
#define AHCI_GHC_EM_LOC 0x1C // Enclosure Management Location
#define AHCI_GHC_EM_CTL 0x20 // Enclosure Management Control
#define AHCI_GHC_CAP2 0x24 // Host Capabilities Extended
#define AHCI_GHC_BOHC 0x28 // BIOS/OS Handoff Control and Status
//
// Port command register (PxCMD) bits
//
#define AHCI_PXCMD_ST 0x0001 // Start
#define AHCI_PXCMD_SUD 0x0002 // Spin-Up Device
#define AHCI_PXCMD_POD 0x0004 // Power On Device
#define AHCI_PXCMD_CLO 0x0008 // Command List Override
#define AHCI_PXCMD_FRE 0x0010 // FIS Receive Enable
#define AHCI_PXCMD_CCS_MASK 0x1F00 // Current Command Slot
#define AHCI_PXCMD_CCS_SHIFT 8
#define AHCI_PXCMD_MPSS 0x2000 // Mechanical Presence Switch
#define AHCI_PXCMD_FR 0x4000 // FIS Receive Running
#define AHCI_PXCMD_CR 0x8000 // Command List Running
#define AHCI_PXCMD_CPD 0x010000 // Cold Presence Detection
#define AHCI_PXCMD_ESP 0x020000 // External SATA Port
#define AHCI_PXCMD_FBSCP 0x040000 // FIS-Based Switching Capable Port
#define AHCI_PXCMD_APSTE 0x080000 // Automatic Partial to Slumber
#define AHCI_PXCMD_ATAPI 0x100000 // Device is ATAPI
#define AHCI_PXCMD_DLAE 0x400000 // Drive LED on ATAPI Enable
#define AHCI_PXCMD_ALPE 0x800000 // Aggressive Link PM Enable
#define AHCI_PXCMD_ASP 0x1000000 // Aggressive Slumber/Partial
#define AHCI_PXCMD_ICC_MASK 0xF0000000 // Interface Communication Control
#define AHCI_PXCMD_ICC_SHIFT 28
//
// Port interrupt status bits
//
#define AHCI_PXIS_DHRS 0x00000001 // Device to Host Register FIS
#define AHCI_PXIS_PSS 0x00000002 // PIO Setup FIS
#define AHCI_PXIS_DSS 0x00000004 // DMA Setup FIS
#define AHCI_PXIS_SDBS 0x00000008 // Set Device Bits
#define AHCI_PXIS_UFS 0x00000010 // Unknown FIS
#define AHCI_PXIS_DPS 0x00000020 // Descriptor Processed
#define AHCI_PXIS_PCS 0x00000040 // Port Connect Change
#define AHCI_PXIS_DMP 0x00000080 // Device Mechanical Presence
#define AHCI_PXIS_PRCS 0x00000100 // PhyRdy Change Status
#define AHCI_PXIS_IPMS 0x00000400 // Incorrect Port Multiplier
#define AHCI_PXIS_OFS 0x00001000 // Overflow Status
#define AHCI_PXIS_INFS 0x00020000 // Interface Non-Fatal Error
#define AHCI_PXIS_IFS 0x00040000 // Interface Fatal Error
#define AHCI_PXIS_HBDS 0x00100000 // Host Bus Data Error
#define AHCI_PXIS_HBFS 0x00200000 // Host Bus Fatal Error
#define AHCI_PXIS_TFES 0x00400000 // Task File Error Status
#define AHCI_PXIS_CPDS 0x00800000 // Cold Port Detect
#define AHCI_PXIS_MASK 0xFFFFFC00 // Reserved bits
//
// ATA Command Block register offsets within task file
//
#define ATA_REG_DATA 0x00
#define ATA_REG_FEATURES 0x01
#define ATA_REG_SECTOR_COUNT 0x02
#define ATA_REG_LBA_LOW 0x03
#define ATA_REG_LBA_MID 0x04
#define ATA_REG_LBA_HIGH 0x05
#define ATA_REG_DEVICE 0x06
#define ATA_REG_COMMAND 0x07
#define ATA_REG_CONTROL 0x0C
#define ATA_REG_ERROR 0x11
#define ATA_REG_SECTOR_COUNT2 0x12
#define ATA_REG_LBA_LOW2 0x13
#define ATA_REG_LBA_MID2 0x14
#define ATA_REG_LBA_HIGH2 0x15
//
// DMA / Packet transfer directions
//
#define AHCI_DIR_READ 0
#define AHCI_DIR_WRITE 1
#define AHCI_DIR_NO_DATA 2
//
// AHCI Command Header structure (32 bytes)
//
typedef struct {
UINT32 Prdtl : 16; // Physical Region Descriptor Table Length
UINT32 P : 1; // Prefetchable
UINT32 W : 1; // Write (0=read from device, 1=write to device)
UINT32 A : 1; // ATAPI
UINT32 Reserved0: 4; // Reserved
UINT32 Cfl : 5; // Command FIS Length (in DWORDS)
UINT32 Reserved1: 4; // Reserved
UINT32 Prdbc; // Physical Region Descriptor Byte Count
UINT32 Ctba; // Command Table Base Address (lower 32 bits)
UINT32 Ctbau; // Command Table Base Address (upper 32 bits)
UINT32 Reserved2[4]; // Reserved
} AHCI_CMD_HEADER;
//
// AHCI Command Table (144 bytes header + PRD entries)
//
typedef struct {
UINT8 Cfis[64]; // Command FIS
UINT8 Acmd[16]; // ATAPI Command
UINT8 Reserved[48]; // Reserved
// PRD entries follow at offset 128
} AHCI_CMD_TABLE;
//
// Physical Region Descriptor (PRD) entry (16 bytes)
//
typedef struct {
UINT32 Dba; // Data Base Address (lower 32 bits)
UINT32 Dbau; // Data Base Address (upper 32 bits)
UINT32 Reserved0;
UINT32 Dbc : 22; // Data Byte Count (max 4MB)
UINT32 Reserved1 : 9;
UINT32 I : 1; // Interrupt on Completion
} AHCI_PRD_ENTRY;
//
// FIS - Register Host to Device (FIS type 0x27)
//
typedef struct {
UINT8 FisType; // 0x27
UINT8 PmPort : 4; // Port Multiplier Port
UINT8 Rsv0 : 1;
UINT8 C : 1; // Indicates register FIS is a command
UINT8 Rsv1 : 2;
UINT8 Command; // ATA command register
UINT8 Features; // ATA features register
UINT8 LbaLow; // LBA low
UINT8 LbaMid; // LBA mid
UINT8 LbaHigh; // LBA high
UINT8 Device; // Device register
UINT8 LbaLow2; // LBA low extended
UINT8 LbaMid2; // LBA mid extended
UINT8 LbaHigh2; // LBA high extended
UINT8 Features2; // Features extended
UINT8 Count; // Sector count
UINT8 Count2; // Sector count extended
UINT8 Reserved[8];
UINT8 Control; // Control register
UINT8 Reserved2[7];
} AHCI_REG_H2D_FIS;
//
// FIS - Register Device to Host (FIS type 0x34)
//
typedef struct {
UINT8 FisType; // 0x34
UINT8 PmPort : 4;
UINT8 Rsv0 : 2;
UINT8 I : 1;
UINT8 Rsv1 : 1;
UINT8 Status;
UINT8 Error;
UINT8 LbaLow;
UINT8 LbaMid;
UINT8 LbaHigh;
UINT8 Device;
UINT8 LbaLow2;
UINT8 LbaMid2;
UINT8 LbaHigh2;
UINT8 Count;
UINT8 Count2;
UINT8 Reserved[6];
} AHCI_REG_D2H_FIS;
//
// FIS - DMA Setup (FIS type 0x41)
//
typedef struct {
UINT8 FisType; // 0x41
UINT8 PmPort : 4;
UINT8 Rsv0 : 1;
UINT8 D : 1;
UINT8 Rsv1 : 2;
UINT8 Rsv2;
UINT8 DmaBufferIdLow;
UINT8 DmaBufferIdHigh;
UINT32 Rsv3;
UINT32 DmaBufOffset;
UINT32 TransferCount;
UINT32 Rsv4;
} AHCI_DMA_SETUP_FIS;
//
// FIS - PIO Setup (FIS type 0x5F)
//
typedef struct {
UINT8 FisType; // 0x5F
UINT8 PmPort : 4;
UINT8 Rsv0 : 1;
UINT8 D : 1;
UINT8 Rsv1 : 2;
UINT8 Status;
UINT8 Error;
UINT8 LbaLow;
UINT8 LbaMid;
UINT8 LbaHigh;
UINT8 Device;
UINT8 LbaLow2;
UINT8 LbaMid2;
UINT8 LbaHigh2;
UINT8 Count;
UINT8 Count2;
UINT8 Rsv2;
UINT8 E_Status;
UINT16 TransferCount;
UINT8 Rsv3[2];
} AHCI_PIO_SETUP_FIS;
//
// AHCI PORT state machine
//
#define AHCI_PORT_STATE_CREATED 1 // Port structure allocated
#define AHCI_PORT_STATE_ERROR 2 // Device detection failed
#define AHCI_PORT_STATE_CONFIGURED 3 // Device configured (identify done)
#define AHCI_PORT_STATE_READY 4 // Device ready for I/O
//
// AHCI Port media types (from ATA IDENTIFY word 0)
//
#define AHCI_MEDIA_TYPE_NONE 0
#define AHCI_MEDIA_TYPE_HDD 1
#define AHCI_MEDIA_TYPE_ATAPI 2
//
// AHCI Port signature types (from PxSIG)
//
#define AHCI_SIG_ATA 0x00000101 // ATA drive (SATA)
#define AHCI_SIG_ATAPI 0xEB140101 // ATAPI drive (SATA)
#define AHCI_SIG_PM_PORT 0x96690101 // Port Multiplier
#define AHCI_SIG_SEMB 0xC33C0101 // Enclosure Management Bridge
#define AHCI_SIG_PM 0xFFFFFFFF // Port Multiplier (inverted)
//
// Private AHCI PORT structure (allocated per detected SATA port)
// Total size: 0x3D0 (976) bytes
//
typedef struct _AHCI_PORT {
//
// +0x0000: Port identification and state
//
UINT8 Port; // +0x00: SATA port number
UINT8 PmPort; // +0x01: Port multiplier port (0xFF = direct)
UINT8 PmType; // +0x02: PM type from SATA Phy command
UINT8 State; // +0x03: Port state (AHCI_PORT_STATE_*)
//
// +0x0004: Padding / reserved
//
UINT8 Reserved04[4];
//
// +0x0008: Device information
//
UINT32 PortType; // +0x08: Port type from PxSIG register
UINT32 MediaType; // +0x0C: Media type (0/1/2)
//
// +0x0010: ATA IDENTIFY data buffer (512 bytes)
//
UINT16 IdentifyData[256]; // +0x10: ATA IDENTIFY DEVICE data
//
// +0x0210: Extended identify or scratch space (304 bytes)
//
UINT8 Reserved210[0x130]; // +0x0210 - 0x0340: reserved
//
// +0x0340: AHCI MMIO register info
//
UINT64 AhciBarBase; // +0x340: Mapped AHCI BAR base address for this port
UINT64 AhciBarSize; // +0x348: Mapped AHCI BAR size for this port
//
// +0x0350: Back-pointer to controller
//
struct _AHCI_CONTROLLER *Controller; // +0x350: Owning AHCI_CONTROLLER
//
// +0x0358: Protocol interfaces
//
EFI_BLOCK_IO_MEDIA *BlockIoMedia; // +0x358: EFI_BLOCK_IO_MEDIA pointer
VOID *BlockIo; // +0x360: EFI_BLOCK_IO_PROTOCOL
VOID *BlockIo2; // +0x368: EFI_BLOCK_IO2_PROTOCOL
//
// +0x0370: Reserved for additional protocol pointers
//
UINT8 Reserved370[0x28]; // +0x370 - 0x398: reserved
//
// +0x0398: Linked list entry (embedded LIST_ENTRY)
//
LIST_ENTRY Link; // +0x398: Port list link structure (16 bytes)
} AHCI_PORT;
#define AHCI_PORT_FROM_LIST_ENTRY(Entry) \
CR (Entry, AHCI_PORT, Link, AHCI_PORT_SIGNATURE)
#define AHCI_PORT_SIGNATURE SIGNATURE_32 ('A','H','C','I')
//
// AHCI CONTROLLER private structure
// Stores per-controller state for AHCI HBAs
//
typedef struct _AHCI_CONTROLLER {
//
// +0x0000: Controller identification
//
UINT64 Signature; // +0x00: Signature
//
// +0x0008: AHCI register base (MMIO remapped)
//
UINT64 AhciRegBase; // +0x08: AHCI MMIO register base
//
// +0x0010 - 0x0050: AHCI HBA register space
//
UINT32 Capability; // +0x10: CAP register value
UINT32 PortsImplemented; // +0x14: PI register value
UINT32 AhciVersion; // +0x18: VS register value
UINT32 Capability2; // +0x1C: CAP2 register value
UINT8 Reserved20[0x30]; // +0x20 - 0x50: reserved
//
// +0x0050: Port management
//
UINT64 PortBarInfo; // +0x50: Port BAR pointer
UINT64 PortCount; // +0x58: Number of ports
//
// +0x0060: Port linked list
//
LIST_ENTRY PortListHead; // +0x60: Head of AHCI_PORT linked list
//
// +0x0070: Additional controller state
//
VOID *ControllerRegs; // +0x70: Controller register block
VOID *PortListTail; // +0x78: Tail pointer for port list
} AHCI_CONTROLLER;
//
// Port register offset calculation
// AHCI maps each port at: AhciRegBase + (Port + 2) * 0x80
//
#define AHCI_PORT_REG_BASE(Controller, Port) \
((Controller)->AhciRegBase + ((UINT64)(Port) + 2) * 0x80)
#define AHCI_PORT_READ_DWORD(Controller, Port, RegOffset) \
MmioRead32 (AHCI_PORT_REG_BASE (Controller, Port) + (RegOffset))
#define AHCI_PORT_WRITE_DWORD(Controller, Port, RegOffset, Value) \
MmioWrite32 (AHCI_PORT_REG_BASE (Controller, Port) + (RegOffset), (Value))
//
// AHCI command timeout values (in microseconds)
//
#define AHCI_MMIO_POLL_TIMEOUT 50000 // 50ms
#define AHCI_COMMAND_TIMEOUT 30000 // 30ms
#define AHCI_SPINUP_TIMEOUT 1000000 // 1s
#define AHCI_PORT_RESET_TIMEOUT 10000 // 10ms
//
// ATA commands used by this driver
//
#define ATA_CMD_IDENTIFY_DEVICE 0xEC
#define ATA_CMD_READ_DMA 0xC8
#define ATA_CMD_READ_DMA_EXT 0x25
#define ATA_CMD_WRITE_DMA 0xCA
#define ATA_CMD_WRITE_DMA_EXT 0x35
#define ATA_CMD_READ_SECTORS 0x20
#define ATA_CMD_WRITE_SECTORS 0x30
#define ATA_CMD_READ_FPDMA_QUEUED 0x60
#define ATA_CMD_WRITE_FPDMA_QUEUED 0x61
#define ATA_CMD_PACKET 0xA0
#define ATA_CMD_IDENTIFY_PACKET_DEVICE 0xA1
#define ATA_CMD_READ_BUFFER 0xE4
#define ATA_CMD_WRITE_BUFFER 0xE8
#define ATA_CMD_SET_FEATURES 0xEF
#define ATA_CMD_SET_MAX 0xF9
#define ATA_CMD_FLUSH_CACHE 0xE7
#define ATA_CMD_FLUSH_CACHE_EXT 0xEA
#define ATA_CMD_STANDBY_IMMEDIATE 0xE0
#define ATA_CMD_IDLE_IMMEDIATE 0xE1
#define ATA_CMD_CHECK_POWER_MODE 0xE5
#define ATA_CMD_READ_VERIFY 0x40
#define ATA_CMD_READ_LOG_EXT 0x2F
#define ATA_CMD_WRITE_LOG_EXT 0x3F
//
// ATA SET FEATURES subcommands
//
#define ATA_SET_FEATURES_TRANSFER_MODE 0x03
#define ATA_SET_FEATURES_SET_TRANSFER_MODE 0x03
#define ATA_SET_FEATURES_ENABLE_RW_DMA_SETUP 0x07
#define ATA_SET_FEATURES_DISABLE_RW_DMA_SETUP 0x47
#define ATA_SET_FEATURES_ENABLE_APM 0x05
#define ATA_SET_FEATURES_DISABLE_APM 0x85
#define ATA_SET_FEATURES_PUI_SET 0x06
#define ATA_SET_FEATURES_PUI_CLEAR 0x86
//
// Transfer modes
//
#define ATA_TRANSFER_MODE_PIO_DEFAULT 0x00
#define ATA_TRANSFER_MODE_MULTI_DMA 0x20
#define ATA_TRANSFER_MODE_UDMA 0x40
//
// ATA Set Features - RW DMA Setup subcommands
//
#define ATA_RW_DMA_SETUP_ENABLE 0x07
#define ATA_RW_DMA_SETUP_DISABLE 0x47
//
// ATA Status register bits
//
#define ATA_STS_BUSY 0x80
#define ATA_STS_DRDY 0x40
#define ATA_STS_DWF 0x20
#define ATA_STS_DSC 0x10
#define ATA_STS_DRQ 0x08
#define ATA_STS_CORR 0x04
#define ATA_STS_ERROR 0x01
//
// ATA Device register bits
//
#define ATA_DEVICE_LBA 0x40
#define ATA_DEVICE_SLAVE 0x10
//
// ATA Control register bits
//
#define ATA_CTL_SRST 0x04 // Software Reset
#define ATA_CTL_RESET 0x02 // nIEN
//
// CRC-16 constants for ATA identify data verification
//
#define ATA_IDENTIFY_CRC16_POLY 0x1021
#define ATA_IDENTIFY_CRC16_INIT 0x0000
//
// Max ATA transfer length in blocks (for 48-bit LBA)
//
#define AHCI_MAX_BLOCKS_PER_CMD 0x10000 // 65536 blocks
//
// AHCI Debug Level definitions
//
#define AHCI_DEBUG_ERROR 0x80000000
#define AHCI_DEBUG_WARN 0x40000000
#define AHCI_DEBUG_INFO 0x20000000
#define AHCI_DEBUG_VERBOSE 0x10000000
//
// AHCI Debug Trace masks
//
#define AHCI_TRACE_ENTRY 0x00000001
#define AHCI_TRACE_EXIT 0x00000002
#define AHCI_TRACE_IO 0x00000100
//
// Function prototypes
//
//
// Driver entry point and binding
//
EFI_STATUS
EFIAPI
AhciDriverEntryPoint (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
);
EFI_STATUS
EFIAPI
AhciDriverBindingSupported (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
);
EFI_STATUS
EFIAPI
AhciDriverBindingStart (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
);
EFI_STATUS
EFIAPI
AhciDriverBindingStop (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN UINTN NumberOfChildren,
IN EFI_HANDLE *ChildHandleBuffer OPTIONAL
);
//
// Component name protocol
//
EFI_STATUS
EFIAPI
AhciGetDriverName (
IN EFI_COMPONENT_NAME2_PROTOCOL *This,
IN CHAR8 *Language,
OUT CHAR16 **DriverName
);
EFI_STATUS
EFIAPI
AhciGetComponentName (
IN EFI_COMPONENT_NAME2_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_HANDLE ChildHandle OPTIONAL,
IN CHAR8 *Language,
OUT CHAR16 **ComponentName
);
//
// Controller initialization
//
EFI_STATUS
AhciInitController (
IN AHCI_CONTROLLER *Controller,
IN EFI_PCI_IO_PROTOCOL *PciIo,
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
IN EFI_HANDLE ControllerHandle
);
VOID
AhciStopController (
IN AHCI_CONTROLLER *Controller
);
//
// Port management
//
EFI_STATUS
AhciInitializePortRegisters (
IN AHCI_CONTROLLER *Controller,
IN UINT8 Port
);
EFI_STATUS
AhciCreatePort (
IN OUT AHCI_CONTROLLER *Controller,
IN EFI_PCI_IO_PROTOCOL *PciIo,
IN UINT8 Port,
IN UINT8 PmPort
);
EFI_STATUS
AhciEnumerateDevice (
IN EFI_HANDLE ImageHandle,
IN EFI_HANDLE ControllerHandle,
IN AHCI_CONTROLLER *Controller,
IN VOID *AhciBarInfo,
IN EFI_PCI_IO_PROTOCOL *PciIo,
IN UINT8 Port,
IN UINT8 PmPort
);
EFI_STATUS
AhciConfigureDevice (
IN AHCI_PORT *Port,
OUT UINT64 *Capacity
);
EFI_STATUS
AhciIdentifySataPort (
IN AHCI_PORT *Port,
IN EFI_PCI_IO_PROTOCOL *PciIo,
IN UINT8 PortNumber,
IN UINT8 PmPortNumber
);
EFI_STATUS
AhciIdentifyPmPort (
IN AHCI_PORT *Port,
IN EFI_PCI_IO_PROTOCOL *PciIo,
IN UINT8 Port,
IN UINT8 PmPort
);
EFI_STATUS
AhciSetPortInterfacePower (
IN AHCI_PORT *Port
);
EFI_STATUS
AhciSetDeviceFeature (
IN AHCI_PORT *Port,
IN UINT64 Capacity
);
//
// Block I/O interface functions
//
EFI_STATUS
EFIAPI
AhciBlockIoGetMediaInfo (
IN EFI_BLOCK_IO_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
OUT UINT32 *MediaId
);
EFI_STATUS
EFIAPI
AhciBlockIoGetDevicePath (
IN EFI_BLOCK_IO_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath
);
EFI_STATUS
EFIAPI
AhciBlockIoFlush (
IN EFI_BLOCK_IO_PROTOCOL *This
);
EFI_STATUS
EFIAPI
AhciBlockIoReadBlocks (
IN EFI_BLOCK_IO_PROTOCOL *This,
IN UINT32 MediaId,
IN EFI_LBA Lba,
IN UINTN BufferSize,
OUT VOID *Buffer
);
EFI_STATUS
EFIAPI
AhciBlockIoRead (
IN EFI_BLOCK_IO_PROTOCOL *This,
IN UINT32 MediaId,
IN EFI_LBA Lba,
IN UINTN BufferSize,
OUT VOID *Buffer
);
EFI_STATUS
EFIAPI
AhciBlockIoWrite (
IN EFI_BLOCK_IO_PROTOCOL *This,
IN UINT32 MediaId,
IN EFI_LBA Lba,
IN UINTN BufferSize,
OUT VOID *Buffer
);
EFI_STATUS
EFIAPI
AhciNonBlockingRead (
IN EFI_BLOCK_IO2_PROTOCOL *This,
IN UINT32 MediaId,
IN EFI_LBA Lba,
IN EFI_BLOCK_IO2_TOKEN *Token,
IN UINTN BufferSize,
OUT VOID *Buffer
);
EFI_STATUS
EFIAPI
AhciNonBlockingWrite (
IN EFI_BLOCK_IO2_PROTOCOL *This,
IN UINT32 MediaId,
IN EFI_LBA Lba,
IN EFI_BLOCK_IO2_TOKEN *Token,
IN UINTN BufferSize,
OUT VOID *Buffer
);
EFI_STATUS
EFIAPI
AhciBlockIo2Read (
IN EFI_BLOCK_IO2_PROTOCOL *This,
IN UINT32 MediaId,
IN EFI_LBA Lba,
IN EFI_BLOCK_IO2_TOKEN *Token,
IN UINTN BufferSize,
OUT VOID *Buffer
);
EFI_STATUS
EFIAPI
AhciBlockIo2Write (
IN EFI_BLOCK_IO2_PROTOCOL *This,
IN UINT32 MediaId,
IN EFI_LBA Lba,
IN EFI_BLOCK_IO2_TOKEN *Token,
IN UINTN BufferSize,
OUT VOID *Buffer
);
EFI_STATUS
EFIAPI
AhciBlockIoRwDispatch (
IN EFI_BLOCK_IO_PROTOCOL *This,
IN UINT32 MediaId,
IN EFI_LBA Lba,
IN UINTN BufferSize,
OUT VOID *Buffer,
IN BOOLEAN IsWrite
);
EFI_STATUS
EFIAPI
AhciBlockIoRwExDispatch (
IN EFI_BLOCK_IO2_PROTOCOL *This,
IN UINT32 MediaId,
IN EFI_LBA Lba,
IN EFI_BLOCK_IO2_TOKEN *Token,
IN UINTN BufferSize,
OUT VOID *Buffer,
IN BOOLEAN IsWrite
);
//
// Media detection and setup
//
EFI_STATUS
AhciSetupBlockIoMedia (
IN AHCI_PORT *Port
);
EFI_STATUS
AhciGetMediaInfo (
IN AHCI_PORT *Port
);
EFI_STATUS
AhciDetectPartitionType (
IN AHCI_PORT *Port
);
EFI_STATUS
AhciParsePartitionEntry (
IN UINT32 *Mbr,
IN UINTN PartitionIndex,
OUT UINT16 *PartitionType
);
//
// Command path: ATA command building and execution
//
EFI_STATUS
AhciInitTaskFile (
IN AHCI_PORT *Port,
IN EFI_PCI_IO_PROTOCOL *PciIo,
IN UINT8 *TaskFile,
IN UINTN TaskFileSize,
...
);
UINT16
AhciCalcCrc16 (
OUT UINT16 *CrcOut,
IN UINT8 *Data,
IN UINTN Length
);
VOID
AhciCopyMem (
OUT VOID *Destination,
IN VOID *Source,
IN UINTN Length
);
EFI_STATUS
AhciSetupCmdHeader (
IN AHCI_PORT *Port,
IN AHCI_CMD_HEADER *CmdHeader,
IN UINT64 CommandTableBase
);
EFI_STATUS
AhciSetupCmdTable (
IN AHCI_PORT *Port,
IN UINT8 *TaskFile,
IN UINT32 *CmdSlot,
IN AHCI_CMD_TABLE *CmdTable
);
EFI_STATUS
AhciSetupPrdTable (
IN AHCI_PORT *Port,
IN UINT64 *DataBuffer,
IN UINT64 DataBufferSize,
IN VOID *PrdTableBase
);
EFI_STATUS
AhciStartCommand (
IN AHCI_CONTROLLER *Controller,
IN AHCI_PORT *Port
);
EFI_STATUS
AhciWaitCommandComplete (
IN AHCI_PORT *Port,
IN UINT32 TimeoutMs,
IN BOOLEAN IsBlocking
);
//
// Port reset and control
//
EFI_STATUS
AhciPortReset (
IN AHCI_CONTROLLER *Controller,
IN EFI_PCI_IO_PROTOCOL *PciIo,
IN UINT8 Port,
IN UINT8 PmPort,
IN UINT8 ResetType,
IN UINT8 ResetFlags
);
EFI_STATUS
AhciSoftReset (
IN AHCI_PORT *Port,
IN UINT8 ResetType
);
EFI_STATUS
AhciResetPort (
IN AHCI_PORT *Port
);
EFI_STATUS
AhciResetPmPorts (
IN AHCI_PORT *Port
);
EFI_STATUS
AhciPollPortReady (
IN AHCI_PORT *Port,
IN OUT UINT64 *PortStatus,
IN UINT8 Timeout,
IN UINT8 Flags
);
EFI_STATUS
AhciReadPortStatus (
IN AHCI_PORT *Port,
IN OUT UINT64 *PortStatus,
IN UINT8 Timeout,
IN UINT8 Flags,
IN UINT8 ReadType
);
EFI_STATUS
AhciClearPortError (
IN AHCI_PORT *Port,
IN OUT UINT64 *PortStatus,
IN UINT8 Flags,
IN UINT8 ClearType
);
EFI_STATUS
AhciSetAhciMode (
IN AHCI_CONTROLLER *Controller,
IN UINT8 Port,
IN UINT64 AhciBarBase
);
//
// ATA command execution
//
EFI_STATUS
AhciAtaSoftReset (
IN AHCI_PORT *Port,
IN UINT8 *TaskFile
);
EFI_STATUS
AhciNonDataCommand (
IN AHCI_PORT *Port,
IN UINT8 *TaskFile,
IN UINT64 Timeout
);
EFI_STATUS
AhciDmaCommand (
IN AHCI_PORT *Port,
IN UINT8 *TaskFile,
IN UINT64 Timeout
);
EFI_STATUS
AhciPacketCommand (
IN AHCI_PORT *Port,
IN UINT64 *TaskFile,
IN UINT64 Timeout
);
EFI_STATUS
AhciSataPhyCommand (
IN AHCI_PORT *Port,
IN UINT8 PhyCmd,
IN UINT8 PhyArg,
OUT UINT16 *Result,
IN UINT8 Flags
);
EFI_STATUS
AhciCheckMediaType (
IN AHCI_PORT *Port
);
EFI_STATUS
AhciDetectMedia (
IN AHCI_PORT *Port
);
//
// Read/Write LBA operations
//
EFI_STATUS
AhciReadLba (
IN AHCI_PORT *Port,
IN UINT64 Lba,
IN UINTN BlockCount,
OUT VOID *Buffer,
IN UINT8 ReadType,
IN BOOLEAN IsVerified
);
EFI_STATUS
AhciWriteLba (
IN AHCI_PORT *Port,
IN UINT64 Lba,
IN UINTN BlockCount,
OUT VOID *Buffer,
IN UINT8 WriteType,
IN BOOLEAN Fua
);
EFI_STATUS
AhciReadVerify (
IN AHCI_PORT *Port,
IN UINT64 Lba,
IN UINTN BlockCount
);
//
// Feature configuration
//
EFI_STATUS
AhciSetTransferMode (
IN AHCI_PORT *Port
);
EFI_STATUS
AhciSetFeatureRwDmaSetup (
IN AHCI_PORT *Port
);
EFI_STATUS
AhciReadCapacity (
IN AHCI_PORT *Port
);
//
// Memory and debug support
//
VOID *
AhciAllocateMemory (
IN UINTN Size
);
VOID *
AhciAllocateZeroPool (
IN UINTN Size
);
VOID
AhciZeroMem (
OUT VOID *Buffer,
IN UINTN Length
);
VOID
AhciDebugPrint (
IN UINTN ErrorLevel,
IN CONST CHAR8 *Format,
...
);
VOID
AhciDebugPrint2 (
IN UINTN ErrorLevel
);
VOID
AhciDebugTrace (
IN UINT32 EntryType,
IN UINT32 TraceId
);
VOID
AhciAssert (
IN CONST CHAR8 *FileName,
IN UINTN LineNumber,
IN CONST CHAR8 *Description
);
BOOLEAN
AhciDebugLevelEnabled (
VOID
);
//
// Protocol helpers
//
BOOLEAN
AhciIsDevicePathNode (
IN CHAR8 *DevicePath
);
BOOLEAN
AhciCompareDevicePath (
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath1,
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath2
);
UINT32
AhciReadUint32Le (
IN VOID *Buffer
);
//
// HOB / boot services helpers
//
EFI_PHYSICAL_ADDRESS
AhciGetHobList (
IN EFI_HANDLE ImageHandle
);
EFI_STATUS
AhciTestProtocol (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
);
EFI_STATUS
AhciAcquirePortAccess (
IN AHCI_PORT *Port,
IN UINT8 *TaskFile,
IN BOOLEAN IsWrite
);
EFI_STATUS
AhciPreparePortAccess (
IN AHCI_PORT *Port
);
//
// Debug protocol cache
//
VOID
AhciCacheDebugProtocol (
VOID
);
EFI_STATUS
AhciGetDebugInterface (
VOID
);
//
// MMIO polling
//
EFI_STATUS
AhciMmioPollReady (
IN AHCI_CONTROLLER *Controller,
IN UINT8 Port,
IN UINT8 RegOffset,
IN UINT32 Mask,
IN UINT32 Timeout
);
EFI_STATUS
AhciMmioPollRead (
IN AHCI_CONTROLLER *Controller,
IN UINT8 Port,
IN UINT32 RegOffset,
IN UINT32 ExpectedMask,
IN UINT32 ExpectedValue
);
//
// Global variables
//
extern EFI_HANDLE gImageHandle;
extern EFI_SYSTEM_TABLE *gST;
extern EFI_BOOT_SERVICES *gBS;
extern EFI_RUNTIME_SERVICES *gRT;
extern AHCI_CONTROLLER *gAhciController;
#endif // __AHCI_H__