Skip to content

AHCI

struct ahci_fis_reg_h2d {
uint8_t fis_type;
uint8_t pmport;
uint8_t reserved1;
uint8_t c;
uint8_t command;
uint8_t featurel;
uint8_t lba0;
uint8_t lba1;
uint8_t lba2;
uint8_t device;
uint8_t lba3;
uint8_t lba4;
uint8_t lba5;
uint8_t featureh;
uint8_t countl;
uint8_t counth;
uint8_t icc;
uint8_t control;
uint8_t reserved2[4];
};
struct ahci_fis_reg_d2h {
uint8_t fis_type;
uint8_t pmport;
uint8_t rsv0;
uint8_t i;
uint8_t rsv1;
uint8_t status;
uint8_t error;
uint8_t lba0;
uint8_t lba1;
uint8_t lba2;
uint8_t device;
uint8_t lba3;
uint8_t lba4;
uint8_t lba5;
uint8_t rsv2;
uint8_t countl;
uint8_t counth;
uint8_t rsv3[2];
uint8_t rsv4[4];
};
struct ahci_prdt_entry {
uint32_t dba;
uint32_t dbau;
uint32_t reserved;
uint32_t dbc;
uint32_t reserved2;
uint32_t i;
};
struct ahci_cmd_table {
uint8_t cfis[AHCI_CMD_TABLE_FIS_SIZE];
uint8_t acmd[AHCI_CMD_TABLE_ATAPI_SIZE];
uint8_t reserved[48];
struct ahci_prdt_entry prdt_entry[];
};

struct ahci_cmd_table referenced types:

struct ahci_full_port {
struct ahci_port *port;
void *cmd_list_base;
void *fis;
struct ahci_cmd_table **cmd_tables;
struct ahci_cmd_header **cmd_hdrs;
uint32_t slot_bitmap;
};

struct ahci_full_port referenced types:

struct ahci_port {
uint32_t clb;
uint32_t clbu;
uint32_t fb;
uint32_t fbu;
uint32_t is;
uint32_t ie;
uint32_t cmd;
uint32_t rsv0;
uint32_t tfd;
uint32_t sig;
uint32_t ssts;
uint32_t sctl;
uint32_t serr;
uint32_t sact;
uint32_t ci;
uint32_t sntf;
uint32_t fbs;
uint32_t rsv1[11];
uint32_t vendor[4];
};
struct ahci_device {
uint8_t type;
uint32_t signature;
uint32_t sectors;
uint16_t sector_size;
struct ahci_controller *ctrl;
uint64_t port_count;
struct thread *io_waiters[AHCI_MAX_PORTS][32];
uint16_t io_statuses[AHCI_MAX_PORTS][32];
struct ahci_request *io_requests[AHCI_MAX_PORTS][32];
uint8_t irq_num;
struct spinlock lock;
struct ahci_full_port regs[32];
};

struct ahci_device referenced types:

struct ahci_disk {
struct ahci_device *device;
uint32_t port;
uint16_t sector_size;
};

struct ahci_disk referenced types:

struct ahci_controller {
uint32_t cap;
uint32_t ghc;
uint32_t is;
uint32_t pi;
uint32_t vs;
uint32_t ccc_ctl;
uint32_t ccc_ports;
uint32_t em_loc;
uint32_t em_ctl;
uint32_t cap2;
uint32_t bohc;
uint8_t rsv[0xA0 - 0x2C];
uint8_t vendor[0x100 - 0xA0];
};
struct ahci_cmd_header {
uint8_t cfl;
uint8_t a;
uint8_t w;
uint8_t p;
uint8_t r;
uint8_t b;
uint8_t c;
uint8_t rsv0;
uint8_t pmp;
uint16_t prdtl;
uint32_t prdbc;
uint32_t ctba;
uint32_t ctbau;
uint32_t rsv1[4];
};
struct ahci_request {
uint32_t port;
uint32_t slot;
uint64_t lba;
void *buffer;
uint64_t size;
uint64_t sector_count;
bool write;
bool trigger_completion;
bool done;
int status;
void (*on_complete)(struct ahci_request *);
void *user_data;
};
struct ahci_port ahci_get_port(struct ahci_device *dev, int n);

ahci_get_port referenced types:

#define AHCI_CMD_TIMEOUT_MS 5000 // Data commands (read/write)
#define AHCI_IDENT_TIMEOUT_MS 10000 // Identify, flush cache, etc.
#define AHCI_RESET_TIMEOUT_MS 30000 // Full controller reset or COMRESET
#define AHCI_CAP 0x00 // Host Capabilities
#define AHCI_GHC 0x04 // Global Host Control
#define AHCI_IS 0x08 // Interrupt Status
#define AHCI_PI 0x0C // Ports Implemented
#define AHCI_VS 0x10 // AHCI Version
#define AHCI_CCC_CTL 0x14 // Command Completion Coalescing Control
#define AHCI_CCC_PORTS 0x18 // CCC Ports
#define AHCI_EM_LOC 0x1C // Enclosure Management Location
#define AHCI_EM_CTL 0x20 // Enclosure Management Control
#define AHCI_CAP2 0x24 // Host Capabilities Extended
#define AHCI_BOHC 0x28 // BIOS/OS Handoff Control and Status
#define AHCI_PORT_BASE 0x100 // Base offset for port registers
#define AHCI_PORT_SIZE 0x80 // Size of each port register set
#define AHCI_MAX_PORTS 32
#define AHCI_MAX_SLOTS 32
#define AHCI_PORT_CLB 0x00 // Command List Base Address
#define AHCI_PORT_CLBU 0x04 // Command List Base Address Upper
#define AHCI_PORT_FB 0x08 // FIS Base Address
#define AHCI_PORT_FBU 0x0C // FIS Base Address Upper
#define AHCI_PORT_IS 0x10 // Interrupt Status
#define AHCI_PORT_IE 0x14 // Interrupt Enable
#define AHCI_PORT_CMD 0x18 // Command and Status
#define AHCI_PORT_TFD 0x20 // Task File Data
#define AHCI_PORT_SIG 0x24 // Signature
#define AHCI_PORT_SSTS 0x28 // SATA Status
#define AHCI_PORT_SCTL 0x2C // SATA Control
#define AHCI_PORT_SERR 0x30 // SATA Error
#define AHCI_PORT_SACT 0x34 // SATA Active
#define AHCI_PORT_CI 0x38 // Command Issue
#define AHCI_PORT_SNTF 0x3C // SATA Notification
#define AHCI_DEV_NULL 0
#define AHCI_DEV_SATA 1
#define AHCI_DEV_BUSY (1 << 30)
#define AHCI_DEV_DRDY 0x40
#define AHCI_DEV_SATAPI 2
#define AHCI_DEV_SEMB 3
#define AHCI_DEV_PM 4
#define AHCI_CMD_TABLE_FIS_SIZE 64
#define AHCI_CMD_TABLE_ATAPI_SIZE 16
#define AHCI_MAX_PRDT_ENTRIES 65535
#define AHCI_GHC_HR (1U << 0)
#define AHCI_GHC_AE (1U << 31)
#define AHCI_DET_NO_DEVICE 0x0
#define AHCI_DET_PRESENT 0x3
#define AHCI_IPM_NO_INTERFACE 0x0
#define AHCI_IPM_ACTIVE 0x1
#define AHCI_CMD_READ_DMA_EXT 0x25
#define AHCI_CMD_WRITE_DMA_EXT 0x35
#define AHCI_CMD_IDENTIFY 0xEC
#define AHCI_CMD_ST (1U << 0) // Start
#define AHCI_CMD_SUD (1U << 1) // Spin-Up Device
#define AHCI_CMD_FRE (1U << 4) // FIS Receive Enable
#define AHCI_CMD_FR (1U << 14) // FIS Receive Running
#define AHCI_CMD_CR (1U << 15) // Command List Running
#define AHCI_CMD_CLO (1U << 3) // Command List Override
#define AHCI_PORT_IPM_ACTIVE 1
#define AHCI_PORT_DET_PRESENT 3
#define AHCI_CMD_FLAGS_WRITE (1 << 6)
#define AHCI_CMD_FLAGS_PRDTL 1
#define FIS_TYPE_REG_H2D 0x27
#define FIS_REG_CMD 0x80
#define LBA_MODE 0x40
#define CONTROL_BIT 0x80
#define AHCI_CMD_FLAGS_CFL_MASK 0x1F
#define AHCI_CMD_FLAGS_W_BIT 0x40
#define ahci_log(log_level, fmt, ...) \ log(LOG_SITE(ahci), LOG_HANDLE(ahci), log_level, fmt, ##__VA_ARGS__)
#define AHCI_PORT_OFFSET(n) (0x100 + (n) * 0x80)