My Project
Loading...
Searching...
No Matches
ahci.h
Go to the documentation of this file.
1/*
2 * PROJECT: MatanelOS Kernel
3 * LICENSE: GPLv3
4 * PURPOSE: AHCI Driver types and functions.
5 */
6
7#ifndef X86_DRIVER_AHCI_H
8#define X86_DRIVER_AHCI_H
9
10#include <stdint.h>
11#include <stdbool.h>
12#include <stddef.h>
13#include "../blk/block.h"
14#include "../../mtstatus.h"
15
16// Maximum number of AHCI Ports supported
17#define AHCI_MAX_PORTS 32
18
19typedef enum _FIS_TYPE {
20 FIS_TYPE_REG_H2D = 0x27, // Register FIS - host to device
21 FIS_TYPE_REG_D2H = 0x34, // Register FIS - device to host
22 FIS_TYPE_DMA_ACT = 0x39, // DMA activate FIS - device to host
23 FIS_TYPE_DMA_SETUP = 0x41, // DMA setup FIS - bidirectional
24 FIS_TYPE_DATA = 0x46, // Data FIS - bidirectional
25 FIS_TYPE_BIST = 0x58, // BIST activate FIS - bidirectional
26 FIS_TYPE_PIO_SETUP = 0x5F, // PIO setup FIS - device to host
27 FIS_TYPE_DEV_BITS = 0xA1, // Set device bits FIS - device to host
29
31typedef volatile struct _HBA_MEM {
32 uint32_t cap; // 0x00: Host Capabilities.
33 uint32_t ghc; // 0x04: Global host control
34 uint32_t is; // 0x08: Interrupt Status
35 uint32_t pi; // 0x0C: Ports implemented.
36 uint32_t vs; // 0x10: Version
37 uint32_t ccc_ctl; // 0x14: Command completion coalescing control
38 uint32_t ccc_pts; // 0x18: Command completion coalescing ports.
39 uint32_t em_loc; // 0x1C: Enclosure management location
40 uint32_t em_ctl; // 0x20: Enclosure management control
41 uint32_t cap2; // 0x24: Host capabilities EXTENDED.
42 uint32_t bohc; // 0x28: BIOS/OS handoff control and status.
43 uint8_t rsv[0xA0 - 0x2C];
44 uint8_t venor[0x100 - 0xA0];
47
49typedef volatile struct _HBA_PORT {
50 uint32_t clb; // 0x00: Command list base address lower 32 bits.
51 uint32_t clbu; // 0x04: Command list base address higher 32 bits.
52 uint32_t fb; // 0x08: FIS Base address lower 32 bits.
53 uint32_t fbu; // 0x0C: FIS Base address higher 32 bits.
54 uint32_t is; // 0x10: Interrupt Status.
55 uint32_t ie; // 0x14: Interrupt Enable.
56 uint32_t cmd; // 0x18: Command And Status.
57 uint32_t rsv0; // 0x1C: RESERVED.
58 uint32_t tfd; // 0x20: Task File Data.
59 uint32_t sig; // 0x24: Signature.
60 uint32_t ssts; // 0x28: Serial ATA Status.
61 uint32_t sctl; // 0x2C: Serial ATA Control.
62 uint32_t serr; // 0x30: Serial ATA Error.
63 uint32_t sact; // 0x34: Serial ATA Active.
64 uint32_t ci; // 0x38: Command Issue.
65 uint32_t sntf; // 0x3C: Serial ATA notification.
66 uint32_t fbs; // 0x40: FIS-Based switch control.
67 uint32_t rsv1[11]; // 0x44 - 0x6F: RESERVED.
68 uint32_t vendor[4]; // 0x70: Vendor Specific.
70
71// Data structures for FIS and Command Tables
72
74#pragma pack(push, 1)
75typedef struct _FIS_REG_H2D {
76 uint8_t fis_type;
77 uint8_t pmport : 4;
78 uint8_t rsv0 : 3;
79 uint8_t c : 1; // 1: command, 0: control
80 uint8_t command; // ATA command
81 uint8_t featurel; // feature low
82 uint8_t lba0; // LBA low byte
83 uint8_t lba1; // LBA mid byte
84 uint8_t lba2; // LBA high byte
85 uint8_t device;
86 uint8_t lba3; // LBA byte 3
87 uint8_t lba4; // LBA byte 4
88 uint8_t lba5; // LBA byte 5
89 uint8_t featureh; // feature high
90 uint8_t countl; // sector count low
91 uint8_t counth; // sector count high
92 uint8_t icc; // ISO command completion
93 uint8_t control;
94 uint8_t rsv1[4];
96
98typedef struct _HBA_PRDT_ENTRY {
99 uint32_t dba; // Data base address
100 uint32_t dbau; // Data base address upper 32 bits
101 uint32_t rsv0; // Reserved
102
103 // DW3
104 uint32_t dbc : 22; // Byte count, 4M max
105 uint32_t rsv1 : 9; // Reserved
106 uint32_t i : 1; // Interrupt on completionn
108
110typedef struct _HBA_CMD_TBL {
111 // 0x00
112 uint8_t cfis[64]; // Command FIS
113
114 // 0x40
115 uint8_t acmd[16]; // ATAPI command, 12 or 16 bytes
116
117 // 0x50
118 uint8_t rsv[48]; // Reserved
119
120 // 0x80
121 HBA_PRDT_ENTRY prdt_entry[1]; // Physical region descriptor table entries, 0 ~ 65535
123#pragma pack(pop)
124
128typedef struct _HBA_CMD_HEADER {
129 volatile uint32_t dw0; // control flags + PRDTL
130 volatile uint32_t prdbc; // physical region descriptor byte count transferred
131 uint32_t ctba; // command table base address (lower)
132 uint32_t ctbau; // command table base address upper
133 uint32_t rsv1[4]; // reserved
135#ifndef _MSC_VER
136_Static_assert(sizeof(HBA_CMD_HEADER) == 32, "SIZEOF HBA_CMD_HEADER ISNT 32 BYTES! -- Misalignment check.");
137_Static_assert(sizeof(HBA_PRDT_ENTRY) == 16, "PRDT must be 16 bytes");
138_Static_assert(offsetof(HBA_CMD_TBL, prdt_entry) == 0x80, "PRDT must start at offset 0x80 in CMD_TBL");
139_Static_assert(sizeof(((HBA_CMD_TBL*)0)->cfis) == 64, "cfis must be 64 bytes");
140#endif
141
142// AHCI Driver API
143
144// Bit masks / helpers for dw0
145// Bit masks / helpers for dw0
146#define HBA_CMD_HDR_CFL_MASK 0x0000001Fu
147#define HBA_CMD_HDR_A_BIT (1u << 5)
148#define HBA_CMD_HDR_W_BIT (1u << 6)
149#define HBA_CMD_HDR_P_BIT (1u << 7)
150#define HBA_CMD_HDR_PRDTL_MASK 0xFFFF0000u
151#define ATA_DEV_BSY 0x80 // Busy
152#define ATA_DEV_DRQ 0x08 // Data Request
153#define ATA_DEV_ERR 0x01 // Error
154
155#define ATA_CMD_READ_DMA_EX 0x25
156#define ATA_CMD_WRITE_DMA_EX 0x35
157
158#define AHCI_DEV_NULL 0
159#define AHCI_DEV_SATA 1
160#define AHCI_DEV_SEMB 2
161#define AHCI_DEV_PM 3
162#define AHCI_DEV_SATAPI 4
163
164#define HBA_PORT_IPM_ACTIVE 1
165#define HBA_PORT_DET_PRESENT 3
166
167#define HBA_PxCMD_ST 0x0001
168#define HBA_PxCMD_FRE 0x0010
169#define HBA_PxCMD_FR 0x4000
170#define HBA_PxCMD_CR 0x8000
171#define HBA_PxIS_TFES (1 << 30) /* TFES - Task File Error Status */
172
173static inline void hba_cmd_hdr_set_cfl(HBA_CMD_HEADER* h, uint32_t cfl) {
174 h->dw0 = (h->dw0 & ~HBA_CMD_HDR_CFL_MASK) | ((cfl)&HBA_CMD_HDR_CFL_MASK);
175}
176static inline uint32_t hba_cmd_hdr_get_cfl(HBA_CMD_HEADER* h) {
177 return h->dw0 & HBA_CMD_HDR_CFL_MASK;
178}
179
180static inline void hba_cmd_hdr_set_w(HBA_CMD_HEADER* h, int w) {
181 if (w) h->dw0 |= HBA_CMD_HDR_W_BIT;
182 else h->dw0 &= ~HBA_CMD_HDR_W_BIT;
183}
184static inline int hba_cmd_hdr_get_w(HBA_CMD_HEADER* h) {
185 return (h->dw0 & HBA_CMD_HDR_W_BIT) ? 1 : 0;
186}
187
188static inline void hba_cmd_hdr_set_prdtl(HBA_CMD_HEADER* h, uint32_t prdtl) {
189 h->dw0 = (h->dw0 & ~HBA_CMD_HDR_PRDTL_MASK) | (((prdtl) & 0xFFFFu) << 16);
190}
191static inline uint32_t hba_cmd_hdr_get_prdtl(HBA_CMD_HEADER* h) {
192 return (h->dw0 >> 16) & 0xFFFFu;
193}
194
195/* Uncomment to see AHCI Debug Prints */
197
198
203MTSTATUS ahci_init(void);
204
212MTSTATUS ahci_read_sector(BLOCK_DEVICE* dev, uint32_t lba, void* buf, size_t bytes);
213
221MTSTATUS ahci_write_sector(BLOCK_DEVICE* dev, uint32_t lba, const void* buf, size_t bytes);
222
229
230#endif
struct _FIS_REG_H2D FIS_REG_H2D
Register - Host to Device FIS (FIS_TYPE_REG_H2D)
BLOCK_DEVICE * ahci_get_block_device(int index)
Retrieve a pointer to the AHCI driver's BLOCK_DEVICE instance.
Definition ahci.c:562
MTSTATUS ahci_init(void)
define AHCI_DEBUG_PRINT
Definition ahci.c:292
struct _HBA_CMD_TBL HBA_CMD_TBL
Command Table: one per slot.
MTSTATUS ahci_write_sector(BLOCK_DEVICE *dev, uint32_t lba, const void *buf, size_t bytes)
Write a single bytes-byte sector to given LBA on a specific BLOCK_DEVICE.
Definition ahci.c:450
_FIS_TYPE
Definition ahci.h:19
@ FIS_TYPE_DMA_ACT
Definition ahci.h:22
@ FIS_TYPE_PIO_SETUP
Definition ahci.h:26
@ FIS_TYPE_REG_H2D
Definition ahci.h:20
@ FIS_TYPE_BIST
Definition ahci.h:25
@ FIS_TYPE_DEV_BITS
Definition ahci.h:27
@ FIS_TYPE_DATA
Definition ahci.h:24
@ FIS_TYPE_DMA_SETUP
Definition ahci.h:23
@ FIS_TYPE_REG_D2H
Definition ahci.h:21
struct _HBA_PRDT_ENTRY HBA_PRDT_ENTRY
Physical Region Descriptor Table Entry.
#define HBA_CMD_HDR_W_BIT
Definition ahci.h:148
struct _HBA_CMD_HEADER HBA_CMD_HEADER
HBA Command Header (defines an AHCI Command)
enum _FIS_TYPE FIS_TYPE
volatile struct _HBA_PORT HBA_PORT
Per port registers at HBA_MEM + 0x100 + (port * 0x80)
MTSTATUS ahci_read_sector(BLOCK_DEVICE *dev, uint32_t lba, void *buf, size_t bytes)
Read a single bytes-byte sector from the given LBA on a specific BLOCK_DEVICE.
Definition ahci.c:330
volatile struct _HBA_MEM HBA_MEM
AHCI Register layout (Global HBA Registers)
#define HBA_CMD_HDR_PRDTL_MASK
Definition ahci.h:150
#define HBA_CMD_HDR_CFL_MASK
Definition ahci.h:146
struct _BLOCK_DEVICE BLOCK_DEVICE
struct _ACPI_SDT_HEADER h
Definition mh.h:0
int32_t MTSTATUS
Definition mtstatus.h:12
Register - Host to Device FIS (FIS_TYPE_REG_H2D)
Definition ahci.h:75
uint8_t command
Definition ahci.h:80
uint8_t device
Definition ahci.h:85
uint8_t lba2
Definition ahci.h:84
uint8_t c
Definition ahci.h:79
uint8_t lba4
Definition ahci.h:87
uint8_t lba0
Definition ahci.h:82
uint8_t counth
Definition ahci.h:91
uint8_t featureh
Definition ahci.h:89
uint8_t lba5
Definition ahci.h:88
uint8_t icc
Definition ahci.h:92
uint8_t lba3
Definition ahci.h:86
uint8_t rsv0
Definition ahci.h:78
uint8_t pmport
Definition ahci.h:77
uint8_t rsv1[4]
Definition ahci.h:94
uint8_t fis_type
Definition ahci.h:76
uint8_t countl
Definition ahci.h:90
uint8_t lba1
Definition ahci.h:83
uint8_t featurel
Definition ahci.h:81
uint8_t control
Definition ahci.h:93
HBA Command Header (defines an AHCI Command)
Definition ahci.h:128
uint32_t ctbau
Definition ahci.h:132
uint32_t ctba
Definition ahci.h:131
volatile uint32_t prdbc
Definition ahci.h:130
uint32_t rsv1[4]
Definition ahci.h:133
volatile uint32_t dw0
Definition ahci.h:129
Command Table: one per slot.
Definition ahci.h:110
uint8_t cfis[64]
Definition ahci.h:112
uint8_t acmd[16]
Definition ahci.h:115
uint8_t rsv[48]
Definition ahci.h:118
HBA_PRDT_ENTRY prdt_entry[1]
Definition ahci.h:121
AHCI Register layout (Global HBA Registers)
Definition ahci.h:31
uint32_t bohc
Definition ahci.h:42
uint32_t em_ctl
Definition ahci.h:40
uint32_t cap2
Definition ahci.h:41
uint32_t ccc_ctl
Definition ahci.h:37
uint8_t rsv[0xA0 - 0x2C]
Definition ahci.h:43
uint32_t pi
Definition ahci.h:35
uint32_t ccc_pts
Definition ahci.h:38
uint32_t em_loc
Definition ahci.h:39
uint8_t venor[0x100 - 0xA0]
Definition ahci.h:44
uint32_t cap
Definition ahci.h:32
uint32_t ghc
Definition ahci.h:33
uint32_t vs
Definition ahci.h:36
uint32_t is
Definition ahci.h:34
Per port registers at HBA_MEM + 0x100 + (port * 0x80)
Definition ahci.h:49
uint32_t ssts
Definition ahci.h:60
uint32_t clb
Definition ahci.h:50
uint32_t rsv1[11]
Definition ahci.h:67
uint32_t tfd
Definition ahci.h:58
uint32_t fb
Definition ahci.h:52
uint32_t fbu
Definition ahci.h:53
uint32_t ci
Definition ahci.h:64
uint32_t sntf
Definition ahci.h:65
uint32_t cmd
Definition ahci.h:56
uint32_t clbu
Definition ahci.h:51
uint32_t ie
Definition ahci.h:55
uint32_t serr
Definition ahci.h:62
uint32_t is
Definition ahci.h:54
uint32_t sact
Definition ahci.h:63
uint32_t vendor[4]
Definition ahci.h:68
uint32_t rsv0
Definition ahci.h:57
uint32_t sctl
Definition ahci.h:61
uint32_t sig
Definition ahci.h:59
uint32_t fbs
Definition ahci.h:66
Physical Region Descriptor Table Entry.
Definition ahci.h:98
uint32_t dbc
Definition ahci.h:104
uint32_t dbau
Definition ahci.h:100
uint32_t dba
Definition ahci.h:99
uint32_t i
Definition ahci.h:106
uint32_t rsv1
Definition ahci.h:105
uint32_t rsv0
Definition ahci.h:101