ApertureOS
priv_ahci.h
Go to the documentation of this file.
1 #ifndef _PRIV_AHCI_H_
2 #define _PRIV_AHCI_H_
3 
4 #include "types.h"
5 #include "drivers.h"
6 
7 typedef enum
8 {
9  FIS_TYPE_REG_H2D = 0x27, // Register FIS - host to device
10  FIS_TYPE_REG_D2H = 0x34, // Register FIS - device to host
11  FIS_TYPE_DMA_ACT = 0x39, // DMA activate FIS - device to host
12  FIS_TYPE_DMA_SETUP = 0x41, // DMA setup FIS - bidirectional
13  FIS_TYPE_DATA = 0x46, // Data FIS - bidirectional
14  FIS_TYPE_BIST = 0x58, // BIST activate FIS - bidirectional
15  FIS_TYPE_PIO_SETUP = 0x5F, // PIO setup FIS - device to host
16  FIS_TYPE_DEV_BITS = 0xA1, // Set device bits FIS - device to host
17 } FIS_TYPE;
18 
19 typedef struct tagFIS_REG_H2D
20 {
21  // uint32_t 0
22  uint8_t fis_type; // FIS_TYPE_REG_H2D
23 
24  uint8_t pmport:4; // Port multiplier
25  uint8_t rsv0:3; // Reserved
26  uint8_t c:1; // 1: Command, 0: Control
27 
28  uint8_t command; // Command register
29  uint8_t featurel; // Feature register, 7:0
30 
31  // uint32_t 1
32  uint8_t lba0; // LBA low register, 7:0
33  uint8_t lba1; // LBA mid register, 15:8
34  uint8_t lba2; // LBA high register, 23:16
35  uint8_t device; // Device register
36 
37  // uint32_t 2
38  uint8_t lba3; // LBA register, 31:24
39  uint8_t lba4; // LBA register, 39:32
40  uint8_t lba5; // LBA register, 47:40
41  uint8_t featureh; // Feature register, 15:8
42 
43  // uint32_t 3
44  uint8_t countl; // Count register, 7:0
45  uint8_t counth; // Count register, 15:8
46  uint8_t icc; // Isochronous command completion
47  uint8_t control; // Control register
48 
49  // uint32_t 4
50  uint8_t rsv1[4]; // Reserved
51 } FIS_REG_H2D;
52 
53 typedef struct tagFIS_REG_D2H
54 {
55  // uint32_t 0
56  uint8_t fis_type; // FIS_TYPE_REG_D2H
57 
58  uint8_t pmport:4; // Port multiplier
59  uint8_t rsv0:2; // Reserved
60  uint8_t i:1; // Interrupt bit
61  uint8_t rsv1:1; // Reserved
62 
63  uint8_t status; // Status register
64  uint8_t error; // Error register
65 
66  // uint32_t 1
67  uint8_t lba0; // LBA low register, 7:0
68  uint8_t lba1; // LBA mid register, 15:8
69  uint8_t lba2; // LBA high register, 23:16
70  uint8_t device; // Device register
71 
72  // uint32_t 2
73  uint8_t lba3; // LBA register, 31:24
74  uint8_t lba4; // LBA register, 39:32
75  uint8_t lba5; // LBA register, 47:40
76  uint8_t rsv2; // Reserved
77 
78  // uint32_t 3
79  uint8_t countl; // Count register, 7:0
80  uint8_t counth; // Count register, 15:8
81  uint8_t rsv3[2]; // Reserved
82 
83  // uint32_t 4
84  uint8_t rsv4[4]; // Reserved
85 } FIS_REG_D2H;
86 
87 typedef struct tagFIS_DATA
88 {
89  // uint32_t 0
90  uint8_t fis_type; // FIS_TYPE_DATA
91 
92  uint8_t pmport:4; // Port multiplier
93  uint8_t rsv0:4; // Reserved
94 
95  uint8_t rsv1[2]; // Reserved
96 
97  // uint32_t 1 ~ N
98  uint32_t data[1]; // Payload
99 } FIS_DATA;
100 
101 typedef struct tagFIS_PIO_SETUP
102 {
103  // uint32_t 0
104  uint8_t fis_type; // FIS_TYPE_PIO_SETUP
105 
106  uint8_t pmport:4; // Port multiplier
107  uint8_t rsv0:1; // Reserved
108  uint8_t d:1; // Data transfer direction, 1 - device to host
109  uint8_t i:1; // Interrupt bit
110  uint8_t rsv1:1;
111 
112  uint8_t status; // Status register
113  uint8_t error; // Error register
114 
115  // uint32_t 1
116  uint8_t lba0; // LBA low register, 7:0
117  uint8_t lba1; // LBA mid register, 15:8
118  uint8_t lba2; // LBA high register, 23:16
119  uint8_t device; // Device register
120 
121  // uint32_t 2
122  uint8_t lba3; // LBA register, 31:24
123  uint8_t lba4; // LBA register, 39:32
124  uint8_t lba5; // LBA register, 47:40
125  uint8_t rsv2; // Reserved
126 
127  // uint32_t 3
128  uint8_t countl; // Count register, 7:0
129  uint8_t counth; // Count register, 15:8
130  uint8_t rsv3; // Reserved
131  uint8_t e_status; // New value of status register
132 
133  // uint32_t 4
134  uint16_t tc; // Transfer count
135  uint8_t rsv4[2]; // Reserved
136 } FIS_PIO_SETUP;
137 
138 typedef struct tagFIS_DMA_SETUP
139 {
140  // uint32_t 0
141  uint8_t fis_type; // FIS_TYPE_DMA_SETUP
142 
143  uint8_t pmport:4; // Port multiplier
144  uint8_t rsv0:1; // Reserved
145  uint8_t d:1; // Data transfer direction, 1 - device to host
146  uint8_t i:1; // Interrupt bit
147  uint8_t a:1; // Auto-activate. Specifies if DMA Activate FIS is needed
148 
149  uint8_t rsved[2]; // Reserved
150 
151  //uint32_t 1&2
152 
153  uint16_t DMAbufferID; // DMA Buffer Identifier. Used to Identify DMA buffer in host memory. SATA Spec says host specific and not in Spec. Trying AHCI spec might work.
154 
155  //uint32_t 3
156  uint32_t rsvd; //More reserved
157 
158  //uint32_t 4
159  uint32_t DMAbufOffset; //Byte offset into buffer. First 2 bits must be 0
160 
161  //uint32_t 5
162  uint32_t TransferCount; //Number of bytes to transfer. Bit 0 must be 0
163 
164  //uint32_t 6
165  uint32_t resvd; //Reserved
166 
167 } FIS_DMA_SETUP;
168 
169 typedef volatile struct tagHBA_PORT
170 {
171  uint32_t clb; // 0x00, command list base address, 1K-byte aligned
172  uint32_t clbu; // 0x04, command list base address upper 32 bits
173  uint32_t fb; // 0x08, FIS base address, 256-byte aligned
174  uint32_t fbu; // 0x0C, FIS base address upper 32 bits
175  uint32_t is; // 0x10, interrupt status
176  uint32_t ie; // 0x14, interrupt enable
177  uint32_t cmd; // 0x18, command and status
178  uint32_t rsv0; // 0x1C, Reserved
179  uint32_t tfd; // 0x20, task file data
180  uint32_t sig; // 0x24, signature
181  uint32_t ssts; // 0x28, SATA status (SCR0:SStatus)
182  uint32_t sctl; // 0x2C, SATA control (SCR2:SControl)
183  uint32_t serr; // 0x30, SATA error (SCR1:SError)
184  uint32_t sact; // 0x34, SATA active (SCR3:SActive)
185  uint32_t ci; // 0x38, command issue
186  uint32_t sntf; // 0x3C, SATA notification (SCR4:SNotification)
187  uint32_t fbs; // 0x40, FIS-based switch control
188  uint32_t rsv1[11]; // 0x44 ~ 0x6F, Reserved
189  uint32_t vendor[4]; // 0x70 ~ 0x7F, vendor specific
190 } HBA_PORT;
191 
192 typedef volatile struct tagHBA_MEM
193 {
194  // 0x00 - 0x2B, Generic Host Control
195  uint32_t cap; // 0x00, Host capability
196  uint32_t ghc; // 0x04, Global host control
197  uint32_t is; // 0x08, Interrupt status
198  uint32_t pi; // 0x0C, Port implemented
199  uint32_t vs; // 0x10, Version
200  uint32_t ccc_ctl; // 0x14, Command completion coalescing control
201  uint32_t ccc_pts; // 0x18, Command completion coalescing ports
202  uint32_t em_loc; // 0x1C, Enclosure management location
203  uint32_t em_ctl; // 0x20, Enclosure management control
204  uint32_t cap2; // 0x24, Host capabilities extended
205  uint32_t bohc; // 0x28, BIOS/OS handoff control and status
206 
207  // 0x2C - 0x9F, Reserved
208  uint8_t rsv[0xA0-0x2C];
209 
210  // 0xA0 - 0xFF, Vendor specific registers
211  uint8_t vendor[0x100-0xA0];
212 
213  // 0x100 - 0x10FF, Port control registers
214  HBA_PORT ports[1]; // 1 ~ 32
215 } HBA_MEM;
216 
217 typedef volatile struct tagHBA_FIS
218 {
219  // 0x00
220  FIS_DMA_SETUP dsfis; // DMA Setup FIS
221  uint8_t pad0[4];
222 
223  // 0x20
224  FIS_PIO_SETUP psfis; // PIO Setup FIS
225  uint8_t pad1[12];
226 
227  // 0x40
228  FIS_REG_D2H rfis; // Register – Device to Host FIS
229  uint8_t pad2[4];
230 
231  // 0x58
232  uint16_t sdbfis; // Set Device Bit FIS
233 
234  // 0x60
235  uint8_t ufis[64];
236 
237  // 0xA0
238  uint8_t rsv[0x100-0xA0];
239 } HBA_FIS;
240 
241 typedef struct tagHBA_CMD_HEADER
242 {
243  // DW0
244  uint8_t cfl:5; // Command FIS length in uint32_tS, 2 ~ 16
245  uint8_t a:1; // ATAPI
246  uint8_t w:1; // Write, 1: H2D, 0: D2H
247  uint8_t p:1; // Prefetchable
248 
249  uint8_t r:1; // Reset
250  uint8_t b:1; // BIST
251  uint8_t c:1; // Clear busy upon R_OK
252  uint8_t rsv0:1; // Reserved
253  uint8_t pmp:4; // Port multiplier port
254 
255  uint16_t prdtl; // Physical region descriptor table length in entries
256 
257  // DW1
258  volatile
259  uint32_t prdbc; // Physical region descriptor byte count transferred
260 
261  // DW2, 3
262  uint32_t ctba; // Command table descriptor base address
263  uint32_t ctbau; // Command table descriptor base address upper 32 bits
264 
265  // DW4 - 7
266  uint32_t rsv1[4]; // Reserved
268 
269 typedef struct tagHBA_PRDT_ENTRY
270 {
271  uint32_t dba; // Data base address
272  uint32_t dbau; // Data base address upper 32 bits
273  uint32_t rsv0; // Reserved
274 
275  // DW3
276  uint32_t dbc:22; // Byte count, 4M max
277  uint32_t rsv1:9; // Reserved
278  uint32_t i:1; // Interrupt on completion
280 
281 typedef struct tagHBA_CMD_TBL
282 {
283  // 0x00
284  uint8_t cfis[64]; // Command FIS
285 
286  // 0x40
287  uint8_t acmd[16]; // ATAPI command, 12 or 16 bytes
288 
289  // 0x50
290  uint8_t rsv[48]; // Reserved
291 
292  // 0x80
293  HBA_PRDT_ENTRY prdt_entry[1]; // Physical region descriptor table entries, 0 ~ 65535
294 } HBA_CMD_TBL;
295 
296 #define SATA_SIG_ATA 0x00000101 // SATA drive
297 #define SATA_SIG_ATAPI 0xEB140101 // SATAPI drive
298 #define SATA_SIG_SEMB 0xC33C0101 // Enclosure management bridge
299 #define SATA_SIG_PM 0x96690101 // Port multiplier
300 
301 #define HBA_PORT_IPM_ACTIVE 0x1
302 #define HBA_PORT_DET_PRESENT 0x3
303 
304 #define HBA_NO_DEVICE 0x00
305 
306 #define AHCI_DEV_SATAPI 0x01
307 #define AHCI_DEV_SATA 0x02
308 #define AHCI_DEV_PM 0x04
309 #define AHCI_DEV_SEMB 0x08
310 
311 #define ATA_DEV_BUSY 0x80
312 #define ATA_DEV_DRQ 0x08
313 
314 int
316 
317 void
319  uint32_t AHCI_BASE,
320  int portno);
321 
322 bool
324  uint64_t start,
325  uint32_t count,
326  uint16_t *buf,
327  bool write);
328 
329 void
330 AHCI_StartCMD(HBA_PORT *port);
331 
332 void
333 AHCI_StopCMD(HBA_PORT *port);
334 
335 #endif
uint8_t lba1
Definition: priv_ahci.h:33
volatile uint32_t prdbc
Definition: priv_ahci.h:259
uint8_t counth
Definition: priv_ahci.h:129
uint32_t sig
Definition: priv_ahci.h:180
uint32_t rsv0
Definition: priv_ahci.h:178
uint32_t sctl
Definition: priv_ahci.h:182
uint8_t error
Definition: priv_ahci.h:113
uint8_t rsv2
Definition: priv_ahci.h:76
int AHCI_FindCMDSlot(HBA_PORT *port)
Definition: ahci.c:299
uint32_t pi
Definition: priv_ahci.h:198
uint8_t lba0
Definition: priv_ahci.h:32
uint8_t rsv2
Definition: priv_ahci.h:125
uint16_t sdbfis
Definition: priv_ahci.h:232
FIS_REG_D2H rfis
Definition: priv_ahci.h:228
uint8_t lba2
Definition: priv_ahci.h:34
uint8_t e_status
Definition: priv_ahci.h:131
uint8_t lba3
Definition: priv_ahci.h:73
uint8_t icc
Definition: priv_ahci.h:46
uint8_t lba5
Definition: priv_ahci.h:40
uint8_t featureh
Definition: priv_ahci.h:41
void AHCI_StopCMD(HBA_PORT *port)
Definition: ahci.c:367
Definition: priv_ahci.h:15
uint8_t device
Definition: priv_ahci.h:119
uint32_t ctbau
Definition: priv_ahci.h:263
uint32_t is
Definition: priv_ahci.h:197
uint8_t command
Definition: priv_ahci.h:28
uint8_t lba5
Definition: priv_ahci.h:75
uint32_t em_loc
Definition: priv_ahci.h:202
uint8_t device
Definition: priv_ahci.h:35
uint32_t clbu
Definition: priv_ahci.h:172
uint16_t prdtl
Definition: priv_ahci.h:255
uint32_t em_ctl
Definition: priv_ahci.h:203
Definition: priv_ahci.h:269
uint32_t fb
Definition: priv_ahci.h:173
uint8_t lba1
Definition: priv_ahci.h:117
uint16_t DMAbufferID
Definition: priv_ahci.h:153
uint32_t ctba
Definition: priv_ahci.h:262
uint32_t sntf
Definition: priv_ahci.h:186
void AHCI_RebasePort(HBA_PORT *port, uint32_t AHCI_BASE, int portno)
Definition: ahci.c:314
uint8_t control
Definition: priv_ahci.h:47
uint8_t lba4
Definition: priv_ahci.h:74
Definition: priv_ahci.h:217
Definition: priv_ahci.h:169
uint8_t lba0
Definition: priv_ahci.h:67
uint32_t vs
Definition: priv_ahci.h:199
uint32_t resvd
Definition: priv_ahci.h:165
uint32_t dba
Definition: priv_ahci.h:271
Definition: priv_ahci.h:9
uint8_t lba4
Definition: priv_ahci.h:39
uint8_t device
Definition: priv_ahci.h:70
Definition: priv_ahci.h:19
uint32_t rsv0
Definition: priv_ahci.h:273
uint8_t lba1
Definition: priv_ahci.h:68
Definition: priv_ahci.h:87
uint32_t fbu
Definition: priv_ahci.h:174
uint8_t countl
Definition: priv_ahci.h:128
uint8_t fis_type
Definition: priv_ahci.h:104
uint32_t rsvd
Definition: priv_ahci.h:156
uint8_t countl
Definition: priv_ahci.h:44
uint32_t serr
Definition: priv_ahci.h:183
uint8_t lba3
Definition: priv_ahci.h:122
FIS_PIO_SETUP psfis
Definition: priv_ahci.h:224
Definition: priv_ahci.h:53
uint8_t lba4
Definition: priv_ahci.h:123
uint32_t sact
Definition: priv_ahci.h:184
uint32_t DMAbufOffset
Definition: priv_ahci.h:159
uint16_t tc
Definition: priv_ahci.h:134
FIS_TYPE
Definition: priv_ahci.h:7
uint8_t counth
Definition: priv_ahci.h:45
uint8_t lba5
Definition: priv_ahci.h:124
uint32_t ghc
Definition: priv_ahci.h:196
Definition: priv_ahci.h:192
uint8_t rsv3
Definition: priv_ahci.h:130
uint8_t fis_type
Definition: priv_ahci.h:22
uint32_t TransferCount
Definition: priv_ahci.h:162
uint32_t dbau
Definition: priv_ahci.h:272
uint32_t clb
Definition: priv_ahci.h:171
uint32_t cap
Definition: priv_ahci.h:195
Definition: priv_ahci.h:11
uint8_t lba2
Definition: priv_ahci.h:69
Definition: priv_ahci.h:101
Definition: priv_ahci.h:281
Definition: priv_ahci.h:13
uint8_t error
Definition: priv_ahci.h:64
Definition: priv_ahci.h:10
uint8_t counth
Definition: priv_ahci.h:80
uint8_t lba2
Definition: priv_ahci.h:118
uint32_t fbs
Definition: priv_ahci.h:187
void AHCI_StartCMD(HBA_PORT *port)
Definition: ahci.c:355
uint32_t ccc_ctl
Definition: priv_ahci.h:200
Definition: priv_ahci.h:14
uint32_t ssts
Definition: priv_ahci.h:181
uint32_t ie
Definition: priv_ahci.h:176
uint32_t ci
Definition: priv_ahci.h:185
FIS_DMA_SETUP dsfis
Definition: priv_ahci.h:220
uint8_t countl
Definition: priv_ahci.h:79
uint8_t fis_type
Definition: priv_ahci.h:56
uint8_t lba0
Definition: priv_ahci.h:116
uint32_t cap2
Definition: priv_ahci.h:204
Definition: priv_ahci.h:138
Definition: priv_ahci.h:16
Definition: priv_ahci.h:241
uint8_t fis_type
Definition: priv_ahci.h:90
uint8_t lba3
Definition: priv_ahci.h:38
uint8_t status
Definition: priv_ahci.h:112
uint32_t cmd
Definition: priv_ahci.h:177
uint32_t ccc_pts
Definition: priv_ahci.h:201
uint32_t is
Definition: priv_ahci.h:175
uint8_t status
Definition: priv_ahci.h:63
uint32_t tfd
Definition: priv_ahci.h:179
uint8_t featurel
Definition: priv_ahci.h:29
uint8_t fis_type
Definition: priv_ahci.h:141
bool AHCI_SendIOCommand(HBA_PORT *port, uint64_t start, uint32_t count, uint16_t *buf, bool write)
Definition: ahci.c:193
uint32_t bohc
Definition: priv_ahci.h:205
Definition: priv_ahci.h:12