AHCI
include/drivers/ahci.h View source View on GitHubStructs
Section titled “Structs”ahci_fis_reg_h2d
Section titled “ahci_fis_reg_h2d”struct ahci_fis_reg_h2d {
uint8_t fis_type;
uint8_t pmport : 4;
uint8_t reserved1 : 3;
uint8_t c : 1;
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];
}; ahci_fis_reg_d2h
Section titled “ahci_fis_reg_d2h”struct ahci_fis_reg_d2h {
uint8_t fis_type;
uint8_t pmport : 4;
uint8_t rsv0 : 2;
uint8_t i : 1;
uint8_t rsv1 : 1;
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];
}; ahci_prdt_entry
Section titled “ahci_prdt_entry”struct ahci_prdt_entry {
uint32_t dba;
uint32_t dbau;
uint32_t reserved;
uint32_t dbc : 22;
uint32_t reserved2 : 9;
uint32_t i : 1;
}; ahci_cmd_table
Section titled “ahci_cmd_table”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[];
}; ahci_full_port
Section titled “ahci_full_port”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;
volatile _Atomic uint32_t slot_bitmap;
}; ahci_port
Section titled “ahci_port”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];
}; ahci_device
Section titled “ahci_device”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];
irq_t irq_num;
struct spinlock lock;
struct ahci_full_port regs[32];
}; ahci_disk
Section titled “ahci_disk”struct ahci_disk {
struct ahci_device *device;
uint32_t port;
uint16_t sector_size;
}; ahci_controller
Section titled “ahci_controller”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];
}; ahci_cmd_header
Section titled “ahci_cmd_header”struct ahci_cmd_header {
uint8_t cfl : 5;
uint8_t a : 1;
uint8_t w : 1;
uint8_t p : 1;
uint8_t r : 1;
uint8_t b : 1;
uint8_t c : 1;
uint8_t rsv0 : 1;
uint8_t pmp : 4;
uint16_t prdtl;
uint32_t prdbc;
uint32_t ctba;
uint32_t ctbau;
uint32_t rsv1[4];
}; ahci_request
Section titled “ahci_request”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;
volatile bool done;
int status;
void (*on_complete)(struct ahci_request *);
void *user_data;
}; Functions
Section titled “Functions”ahci_discover
Section titled “ahci_discover”void ahci_discover(struct ahci_controller *ctrl); ahci_find_slot
Section titled “ahci_find_slot”uint32_t ahci_find_slot(struct ahci_full_port *port); ahci_setup_controller
Section titled “ahci_setup_controller”struct ahci_disk * ahci_setup_controller(struct ahci_controller *ctrl, uint32_t *d_cnt); ahci_identify
Section titled “ahci_identify”void ahci_identify(struct ahci_disk *disk); ahci_prepare_command
Section titled “ahci_prepare_command”void ahci_prepare_command(struct ahci_full_port *port, uint32_t slot, bool write, uint8_t *buf, uint64_t size); ahci_setup_fis
Section titled “ahci_setup_fis”void ahci_setup_fis(struct ahci_cmd_table *cmd_tbl, uint8_t command, bool is_atapi); ahci_send_command
Section titled “ahci_send_command”void ahci_send_command(struct ahci_disk *disk, struct ahci_full_port *port, struct ahci_request *req); ahci_discover_device
Section titled “ahci_discover_device”struct ahci_disk * ahci_discover_device(uint8_t bus, uint8_t device, uint8_t function, uint32_t *out_disk_count); ahci_write_sector
Section titled “ahci_write_sector”bool ahci_write_sector(struct block_device *disk, uint64_t lba, const uint8_t *in_buf, uint16_t cnt); ahci_write_sector_async
Section titled “ahci_write_sector_async”bool ahci_write_sector_async(struct block_device *disk, uint64_t lba, uint8_t *in_buf, uint16_t count, struct ahci_request *req); ahci_read_sector
Section titled “ahci_read_sector”bool ahci_read_sector(struct block_device *disk, uint64_t lba, uint8_t *out_buf, uint16_t cnt); ahci_read_sector_async
Section titled “ahci_read_sector_async”bool ahci_read_sector_async(struct block_device *disk, uint64_t lba, uint8_t *buf, uint16_t count, struct ahci_request *req); ahci_read_sector_wrapper
Section titled “ahci_read_sector_wrapper”bool ahci_read_sector_wrapper(struct block_device *disk, uint64_t lba, uint8_t *buf, uint64_t cnt); ahci_read_sector_async_wrapper
Section titled “ahci_read_sector_async_wrapper”bool ahci_read_sector_async_wrapper(struct block_device *disk, uint64_t lba, uint8_t *buf, uint64_t cnt, struct ahci_request *req); ahci_write_sector_wrapper
Section titled “ahci_write_sector_wrapper”bool ahci_write_sector_wrapper(struct block_device *disk, uint64_t lba, const uint8_t *buf, uint64_t cnt); ahci_write_sector_async_wrapper
Section titled “ahci_write_sector_async_wrapper”bool ahci_write_sector_async_wrapper(struct block_device *disk, uint64_t lba, const uint8_t *buf, uint64_t cnt, struct ahci_request *req); ahci_submit_bio_request
Section titled “ahci_submit_bio_request”bool ahci_submit_bio_request(struct block_device *disk, struct bio_request *bio); ahci_do_coalesce
Section titled “ahci_do_coalesce”void ahci_do_coalesce(struct block_device *disk, struct bio_request *into, struct bio_request *from); ahci_should_coalesce
Section titled “ahci_should_coalesce”bool ahci_should_coalesce(struct block_device *disk, const struct bio_request *a, const struct bio_request *b); ahci_reorder
Section titled “ahci_reorder”void ahci_reorder(struct block_device *disk); ahci_create_generic
Section titled “ahci_create_generic”struct block_device * ahci_create_generic(struct ahci_disk *disk); ahci_isr_handler
Section titled “ahci_isr_handler”enum irq_result ahci_isr_handler(void *ctx, uint8_t vector, struct irq_context * *); ahci_get_port
Section titled “ahci_get_port”struct ahci_port ahci_get_port(struct ahci_device *dev, int n); Macros
Section titled “Macros”AHCI_CMD_TIMEOUT_MS
Section titled “AHCI_CMD_TIMEOUT_MS”#define AHCI_CMD_TIMEOUT_MS 5000 // Data commands (read/write) AHCI_IDENT_TIMEOUT_MS
Section titled “AHCI_IDENT_TIMEOUT_MS”#define AHCI_IDENT_TIMEOUT_MS 10000 // Identify, flush cache, etc. AHCI_RESET_TIMEOUT_MS
Section titled “AHCI_RESET_TIMEOUT_MS”#define AHCI_RESET_TIMEOUT_MS 30000 // Full controller reset or COMRESET AHCI_CAP
Section titled “AHCI_CAP”#define AHCI_CAP 0x00 // Host Capabilities AHCI_GHC
Section titled “AHCI_GHC”#define AHCI_GHC 0x04 // Global Host Control AHCI_IS
Section titled “AHCI_IS”#define AHCI_IS 0x08 // Interrupt Status AHCI_PI
Section titled “AHCI_PI”#define AHCI_PI 0x0C // Ports Implemented AHCI_VS
Section titled “AHCI_VS”#define AHCI_VS 0x10 // AHCI Version AHCI_CCC_CTL
Section titled “AHCI_CCC_CTL”#define AHCI_CCC_CTL 0x14 // Command Completion Coalescing Control AHCI_CCC_PORTS
Section titled “AHCI_CCC_PORTS”#define AHCI_CCC_PORTS 0x18 // CCC Ports AHCI_EM_LOC
Section titled “AHCI_EM_LOC”#define AHCI_EM_LOC 0x1C // Enclosure Management Location AHCI_EM_CTL
Section titled “AHCI_EM_CTL”#define AHCI_EM_CTL 0x20 // Enclosure Management Control AHCI_CAP2
Section titled “AHCI_CAP2”#define AHCI_CAP2 0x24 // Host Capabilities Extended AHCI_BOHC
Section titled “AHCI_BOHC”#define AHCI_BOHC 0x28 // BIOS/OS Handoff Control and Status AHCI_PORT_BASE
Section titled “AHCI_PORT_BASE”#define AHCI_PORT_BASE 0x100 // Base offset for port registers AHCI_PORT_SIZE
Section titled “AHCI_PORT_SIZE”#define AHCI_PORT_SIZE 0x80 // Size of each port register set AHCI_MAX_PORTS
Section titled “AHCI_MAX_PORTS”#define AHCI_MAX_PORTS 32 AHCI_MAX_SLOTS
Section titled “AHCI_MAX_SLOTS”#define AHCI_MAX_SLOTS 32 AHCI_PORT_CLB
Section titled “AHCI_PORT_CLB”#define AHCI_PORT_CLB 0x00 // Command List Base Address AHCI_PORT_CLBU
Section titled “AHCI_PORT_CLBU”#define AHCI_PORT_CLBU 0x04 // Command List Base Address Upper AHCI_PORT_FB
Section titled “AHCI_PORT_FB”#define AHCI_PORT_FB 0x08 // FIS Base Address AHCI_PORT_FBU
Section titled “AHCI_PORT_FBU”#define AHCI_PORT_FBU 0x0C // FIS Base Address Upper AHCI_PORT_IS
Section titled “AHCI_PORT_IS”#define AHCI_PORT_IS 0x10 // Interrupt Status AHCI_PORT_IE
Section titled “AHCI_PORT_IE”#define AHCI_PORT_IE 0x14 // Interrupt Enable AHCI_PORT_CMD
Section titled “AHCI_PORT_CMD”#define AHCI_PORT_CMD 0x18 // Command and Status AHCI_PORT_TFD
Section titled “AHCI_PORT_TFD”#define AHCI_PORT_TFD 0x20 // Task File Data AHCI_PORT_SIG
Section titled “AHCI_PORT_SIG”#define AHCI_PORT_SIG 0x24 // Signature AHCI_PORT_SSTS
Section titled “AHCI_PORT_SSTS”#define AHCI_PORT_SSTS 0x28 // SATA Status AHCI_PORT_SCTL
Section titled “AHCI_PORT_SCTL”#define AHCI_PORT_SCTL 0x2C // SATA Control AHCI_PORT_SERR
Section titled “AHCI_PORT_SERR”#define AHCI_PORT_SERR 0x30 // SATA Error AHCI_PORT_SACT
Section titled “AHCI_PORT_SACT”#define AHCI_PORT_SACT 0x34 // SATA Active AHCI_PORT_CI
Section titled “AHCI_PORT_CI”#define AHCI_PORT_CI 0x38 // Command Issue AHCI_PORT_SNTF
Section titled “AHCI_PORT_SNTF”#define AHCI_PORT_SNTF 0x3C // SATA Notification AHCI_DEV_NULL
Section titled “AHCI_DEV_NULL”#define AHCI_DEV_NULL 0 AHCI_DEV_SATA
Section titled “AHCI_DEV_SATA”#define AHCI_DEV_SATA 1 AHCI_DEV_BUSY
Section titled “AHCI_DEV_BUSY”#define AHCI_DEV_BUSY (1 << 30) AHCI_DEV_DRDY
Section titled “AHCI_DEV_DRDY”#define AHCI_DEV_DRDY 0x40 AHCI_DEV_SATAPI
Section titled “AHCI_DEV_SATAPI”#define AHCI_DEV_SATAPI 2 AHCI_DEV_SEMB
Section titled “AHCI_DEV_SEMB”#define AHCI_DEV_SEMB 3 AHCI_DEV_PM
Section titled “AHCI_DEV_PM”#define AHCI_DEV_PM 4 AHCI_CMD_TABLE_FIS_SIZE
Section titled “AHCI_CMD_TABLE_FIS_SIZE”#define AHCI_CMD_TABLE_FIS_SIZE 64 AHCI_CMD_TABLE_ATAPI_SIZE
Section titled “AHCI_CMD_TABLE_ATAPI_SIZE”#define AHCI_CMD_TABLE_ATAPI_SIZE 16 AHCI_MAX_PRDT_ENTRIES
Section titled “AHCI_MAX_PRDT_ENTRIES”#define AHCI_MAX_PRDT_ENTRIES 65535 AHCI_GHC_HR
Section titled “AHCI_GHC_HR”#define AHCI_GHC_HR (1U << 0) AHCI_GHC_AE
Section titled “AHCI_GHC_AE”#define AHCI_GHC_AE (1U << 31) AHCI_DET_NO_DEVICE
Section titled “AHCI_DET_NO_DEVICE”#define AHCI_DET_NO_DEVICE 0x0 AHCI_DET_PRESENT
Section titled “AHCI_DET_PRESENT”#define AHCI_DET_PRESENT 0x3 AHCI_IPM_NO_INTERFACE
Section titled “AHCI_IPM_NO_INTERFACE”#define AHCI_IPM_NO_INTERFACE 0x0 AHCI_IPM_ACTIVE
Section titled “AHCI_IPM_ACTIVE”#define AHCI_IPM_ACTIVE 0x1 AHCI_CMD_READ_DMA_EXT
Section titled “AHCI_CMD_READ_DMA_EXT”#define AHCI_CMD_READ_DMA_EXT 0x25 AHCI_CMD_WRITE_DMA_EXT
Section titled “AHCI_CMD_WRITE_DMA_EXT”#define AHCI_CMD_WRITE_DMA_EXT 0x35 AHCI_CMD_IDENTIFY
Section titled “AHCI_CMD_IDENTIFY”#define AHCI_CMD_IDENTIFY 0xEC AHCI_CMD_ST
Section titled “AHCI_CMD_ST”#define AHCI_CMD_ST (1U << 0) // Start AHCI_CMD_SUD
Section titled “AHCI_CMD_SUD”#define AHCI_CMD_SUD (1U << 1) // Spin-Up Device AHCI_CMD_FRE
Section titled “AHCI_CMD_FRE”#define AHCI_CMD_FRE (1U << 4) // FIS Receive Enable AHCI_CMD_FR
Section titled “AHCI_CMD_FR”#define AHCI_CMD_FR (1U << 14) // FIS Receive Running AHCI_CMD_CR
Section titled “AHCI_CMD_CR”#define AHCI_CMD_CR (1U << 15) // Command List Running AHCI_CMD_CLO
Section titled “AHCI_CMD_CLO”#define AHCI_CMD_CLO (1U << 3) // Command List Override AHCI_PORT_IPM_ACTIVE
Section titled “AHCI_PORT_IPM_ACTIVE”#define AHCI_PORT_IPM_ACTIVE 1 AHCI_PORT_DET_PRESENT
Section titled “AHCI_PORT_DET_PRESENT”#define AHCI_PORT_DET_PRESENT 3 AHCI_CMD_FLAGS_WRITE
Section titled “AHCI_CMD_FLAGS_WRITE”#define AHCI_CMD_FLAGS_WRITE (1 << 6) AHCI_CMD_FLAGS_PRDTL
Section titled “AHCI_CMD_FLAGS_PRDTL”#define AHCI_CMD_FLAGS_PRDTL 1 FIS_TYPE_REG_H2D
Section titled “FIS_TYPE_REG_H2D”#define FIS_TYPE_REG_H2D 0x27 FIS_REG_CMD
Section titled “FIS_REG_CMD”#define FIS_REG_CMD 0x80 LBA_MODE
Section titled “LBA_MODE”#define LBA_MODE 0x40 CONTROL_BIT
Section titled “CONTROL_BIT”#define CONTROL_BIT 0x80 AHCI_CMD_FLAGS_CFL_MASK
Section titled “AHCI_CMD_FLAGS_CFL_MASK”#define AHCI_CMD_FLAGS_CFL_MASK 0x1F AHCI_CMD_FLAGS_W_BIT
Section titled “AHCI_CMD_FLAGS_W_BIT”#define AHCI_CMD_FLAGS_W_BIT 0x40 ahci_log
Section titled “ahci_log”#define ahci_log(log_level, fmt, ...) \
log(LOG_SITE(ahci), LOG_HANDLE(ahci), log_level, fmt, ##__VA_ARGS__) AHCI_PORT_OFFSET
Section titled “AHCI_PORT_OFFSET”#define AHCI_PORT_OFFSET(n) (0x100 + (n) * 0x80)