]>
Commit | Line | Data |
---|---|---|
1 | #ifndef __libqos_ahci_h | |
2 | #define __libqos_ahci_h | |
3 | ||
4 | /* | |
5 | * AHCI qtest library functions and definitions | |
6 | * | |
7 | * Copyright (c) 2014 John Snow <[email protected]> | |
8 | * | |
9 | * Permission is hereby granted, free of charge, to any person obtaining a copy | |
10 | * of this software and associated documentation files (the "Software"), to deal | |
11 | * in the Software without restriction, including without limitation the rights | |
12 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
13 | * copies of the Software, and to permit persons to whom the Software is | |
14 | * furnished to do so, subject to the following conditions: | |
15 | * | |
16 | * The above copyright notice and this permission notice shall be included in | |
17 | * all copies or substantial portions of the Software. | |
18 | * | |
19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
22 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
23 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
24 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
25 | * THE SOFTWARE. | |
26 | */ | |
27 | ||
28 | #include <stdint.h> | |
29 | #include <stdlib.h> | |
30 | #include <stdbool.h> | |
31 | ||
32 | #include "libqos/pci.h" | |
33 | #include "libqos/malloc-pc.h" | |
34 | ||
35 | /*** Supplementary PCI Config Space IDs & Masks ***/ | |
36 | #define PCI_DEVICE_ID_INTEL_Q35_AHCI (0x2922) | |
37 | #define PCI_MSI_FLAGS_RESERVED (0xFF00) | |
38 | #define PCI_PM_CTRL_RESERVED (0xFC) | |
39 | #define PCI_BCC(REG32) ((REG32) >> 24) | |
40 | #define PCI_PI(REG32) (((REG32) >> 8) & 0xFF) | |
41 | #define PCI_SCC(REG32) (((REG32) >> 16) & 0xFF) | |
42 | ||
43 | /*** Recognized AHCI Device Types ***/ | |
44 | #define AHCI_INTEL_ICH9 (PCI_DEVICE_ID_INTEL_Q35_AHCI << 16 | \ | |
45 | PCI_VENDOR_ID_INTEL) | |
46 | ||
47 | /*** AHCI/HBA Register Offsets and Bitmasks ***/ | |
48 | #define AHCI_CAP (0) | |
49 | #define AHCI_CAP_NP (0x1F) | |
50 | #define AHCI_CAP_SXS (0x20) | |
51 | #define AHCI_CAP_EMS (0x40) | |
52 | #define AHCI_CAP_CCCS (0x80) | |
53 | #define AHCI_CAP_NCS (0x1F00) | |
54 | #define AHCI_CAP_PSC (0x2000) | |
55 | #define AHCI_CAP_SSC (0x4000) | |
56 | #define AHCI_CAP_PMD (0x8000) | |
57 | #define AHCI_CAP_FBSS (0x10000) | |
58 | #define AHCI_CAP_SPM (0x20000) | |
59 | #define AHCI_CAP_SAM (0x40000) | |
60 | #define AHCI_CAP_RESERVED (0x80000) | |
61 | #define AHCI_CAP_ISS (0xF00000) | |
62 | #define AHCI_CAP_SCLO (0x1000000) | |
63 | #define AHCI_CAP_SAL (0x2000000) | |
64 | #define AHCI_CAP_SALP (0x4000000) | |
65 | #define AHCI_CAP_SSS (0x8000000) | |
66 | #define AHCI_CAP_SMPS (0x10000000) | |
67 | #define AHCI_CAP_SSNTF (0x20000000) | |
68 | #define AHCI_CAP_SNCQ (0x40000000) | |
69 | #define AHCI_CAP_S64A (0x80000000) | |
70 | ||
71 | #define AHCI_GHC (1) | |
72 | #define AHCI_GHC_HR (0x01) | |
73 | #define AHCI_GHC_IE (0x02) | |
74 | #define AHCI_GHC_MRSM (0x04) | |
75 | #define AHCI_GHC_RESERVED (0x7FFFFFF8) | |
76 | #define AHCI_GHC_AE (0x80000000) | |
77 | ||
78 | #define AHCI_IS (2) | |
79 | #define AHCI_PI (3) | |
80 | #define AHCI_VS (4) | |
81 | ||
82 | #define AHCI_CCCCTL (5) | |
83 | #define AHCI_CCCCTL_EN (0x01) | |
84 | #define AHCI_CCCCTL_RESERVED (0x06) | |
85 | #define AHCI_CCCCTL_CC (0xFF00) | |
86 | #define AHCI_CCCCTL_TV (0xFFFF0000) | |
87 | ||
88 | #define AHCI_CCCPORTS (6) | |
89 | #define AHCI_EMLOC (7) | |
90 | ||
91 | #define AHCI_EMCTL (8) | |
92 | #define AHCI_EMCTL_STSMR (0x01) | |
93 | #define AHCI_EMCTL_CTLTM (0x100) | |
94 | #define AHCI_EMCTL_CTLRST (0x200) | |
95 | #define AHCI_EMCTL_RESERVED (0xF0F0FCFE) | |
96 | ||
97 | #define AHCI_CAP2 (9) | |
98 | #define AHCI_CAP2_BOH (0x01) | |
99 | #define AHCI_CAP2_NVMP (0x02) | |
100 | #define AHCI_CAP2_APST (0x04) | |
101 | #define AHCI_CAP2_RESERVED (0xFFFFFFF8) | |
102 | ||
103 | #define AHCI_BOHC (10) | |
104 | #define AHCI_RESERVED (11) | |
105 | #define AHCI_NVMHCI (24) | |
106 | #define AHCI_VENDOR (40) | |
107 | #define AHCI_PORTS (64) | |
108 | ||
109 | /*** Port Memory Offsets & Bitmasks ***/ | |
110 | #define AHCI_PX_CLB (0) | |
111 | #define AHCI_PX_CLB_RESERVED (0x1FF) | |
112 | ||
113 | #define AHCI_PX_CLBU (1) | |
114 | ||
115 | #define AHCI_PX_FB (2) | |
116 | #define AHCI_PX_FB_RESERVED (0xFF) | |
117 | ||
118 | #define AHCI_PX_FBU (3) | |
119 | ||
120 | #define AHCI_PX_IS (4) | |
121 | #define AHCI_PX_IS_DHRS (0x1) | |
122 | #define AHCI_PX_IS_PSS (0x2) | |
123 | #define AHCI_PX_IS_DSS (0x4) | |
124 | #define AHCI_PX_IS_SDBS (0x8) | |
125 | #define AHCI_PX_IS_UFS (0x10) | |
126 | #define AHCI_PX_IS_DPS (0x20) | |
127 | #define AHCI_PX_IS_PCS (0x40) | |
128 | #define AHCI_PX_IS_DMPS (0x80) | |
129 | #define AHCI_PX_IS_RESERVED (0x23FFF00) | |
130 | #define AHCI_PX_IS_PRCS (0x400000) | |
131 | #define AHCI_PX_IS_IPMS (0x800000) | |
132 | #define AHCI_PX_IS_OFS (0x1000000) | |
133 | #define AHCI_PX_IS_INFS (0x4000000) | |
134 | #define AHCI_PX_IS_IFS (0x8000000) | |
135 | #define AHCI_PX_IS_HBDS (0x10000000) | |
136 | #define AHCI_PX_IS_HBFS (0x20000000) | |
137 | #define AHCI_PX_IS_TFES (0x40000000) | |
138 | #define AHCI_PX_IS_CPDS (0x80000000) | |
139 | ||
140 | #define AHCI_PX_IE (5) | |
141 | #define AHCI_PX_IE_DHRE (0x1) | |
142 | #define AHCI_PX_IE_PSE (0x2) | |
143 | #define AHCI_PX_IE_DSE (0x4) | |
144 | #define AHCI_PX_IE_SDBE (0x8) | |
145 | #define AHCI_PX_IE_UFE (0x10) | |
146 | #define AHCI_PX_IE_DPE (0x20) | |
147 | #define AHCI_PX_IE_PCE (0x40) | |
148 | #define AHCI_PX_IE_DMPE (0x80) | |
149 | #define AHCI_PX_IE_RESERVED (0x23FFF00) | |
150 | #define AHCI_PX_IE_PRCE (0x400000) | |
151 | #define AHCI_PX_IE_IPME (0x800000) | |
152 | #define AHCI_PX_IE_OFE (0x1000000) | |
153 | #define AHCI_PX_IE_INFE (0x4000000) | |
154 | #define AHCI_PX_IE_IFE (0x8000000) | |
155 | #define AHCI_PX_IE_HBDE (0x10000000) | |
156 | #define AHCI_PX_IE_HBFE (0x20000000) | |
157 | #define AHCI_PX_IE_TFEE (0x40000000) | |
158 | #define AHCI_PX_IE_CPDE (0x80000000) | |
159 | ||
160 | #define AHCI_PX_CMD (6) | |
161 | #define AHCI_PX_CMD_ST (0x1) | |
162 | #define AHCI_PX_CMD_SUD (0x2) | |
163 | #define AHCI_PX_CMD_POD (0x4) | |
164 | #define AHCI_PX_CMD_CLO (0x8) | |
165 | #define AHCI_PX_CMD_FRE (0x10) | |
166 | #define AHCI_PX_CMD_RESERVED (0xE0) | |
167 | #define AHCI_PX_CMD_CCS (0x1F00) | |
168 | #define AHCI_PX_CMD_MPSS (0x2000) | |
169 | #define AHCI_PX_CMD_FR (0x4000) | |
170 | #define AHCI_PX_CMD_CR (0x8000) | |
171 | #define AHCI_PX_CMD_CPS (0x10000) | |
172 | #define AHCI_PX_CMD_PMA (0x20000) | |
173 | #define AHCI_PX_CMD_HPCP (0x40000) | |
174 | #define AHCI_PX_CMD_MPSP (0x80000) | |
175 | #define AHCI_PX_CMD_CPD (0x100000) | |
176 | #define AHCI_PX_CMD_ESP (0x200000) | |
177 | #define AHCI_PX_CMD_FBSCP (0x400000) | |
178 | #define AHCI_PX_CMD_APSTE (0x800000) | |
179 | #define AHCI_PX_CMD_ATAPI (0x1000000) | |
180 | #define AHCI_PX_CMD_DLAE (0x2000000) | |
181 | #define AHCI_PX_CMD_ALPE (0x4000000) | |
182 | #define AHCI_PX_CMD_ASP (0x8000000) | |
183 | #define AHCI_PX_CMD_ICC (0xF0000000) | |
184 | ||
185 | #define AHCI_PX_RES1 (7) | |
186 | ||
187 | #define AHCI_PX_TFD (8) | |
188 | #define AHCI_PX_TFD_STS (0xFF) | |
189 | #define AHCI_PX_TFD_STS_ERR (0x01) | |
190 | #define AHCI_PX_TFD_STS_CS1 (0x06) | |
191 | #define AHCI_PX_TFD_STS_DRQ (0x08) | |
192 | #define AHCI_PX_TFD_STS_CS2 (0x70) | |
193 | #define AHCI_PX_TFD_STS_BSY (0x80) | |
194 | #define AHCI_PX_TFD_ERR (0xFF00) | |
195 | #define AHCI_PX_TFD_RESERVED (0xFFFF0000) | |
196 | ||
197 | #define AHCI_PX_SIG (9) | |
198 | #define AHCI_PX_SIG_SECTOR_COUNT (0xFF) | |
199 | #define AHCI_PX_SIG_LBA_LOW (0xFF00) | |
200 | #define AHCI_PX_SIG_LBA_MID (0xFF0000) | |
201 | #define AHCI_PX_SIG_LBA_HIGH (0xFF000000) | |
202 | ||
203 | #define AHCI_PX_SSTS (10) | |
204 | #define AHCI_PX_SSTS_DET (0x0F) | |
205 | #define AHCI_PX_SSTS_SPD (0xF0) | |
206 | #define AHCI_PX_SSTS_IPM (0xF00) | |
207 | #define AHCI_PX_SSTS_RESERVED (0xFFFFF000) | |
208 | #define SSTS_DET_NO_DEVICE (0x00) | |
209 | #define SSTS_DET_PRESENT (0x01) | |
210 | #define SSTS_DET_ESTABLISHED (0x03) | |
211 | #define SSTS_DET_OFFLINE (0x04) | |
212 | ||
213 | #define AHCI_PX_SCTL (11) | |
214 | ||
215 | #define AHCI_PX_SERR (12) | |
216 | #define AHCI_PX_SERR_ERR (0xFFFF) | |
217 | #define AHCI_PX_SERR_DIAG (0xFFFF0000) | |
218 | #define AHCI_PX_SERR_DIAG_X (0x04000000) | |
219 | ||
220 | #define AHCI_PX_SACT (13) | |
221 | #define AHCI_PX_CI (14) | |
222 | #define AHCI_PX_SNTF (15) | |
223 | ||
224 | #define AHCI_PX_FBS (16) | |
225 | #define AHCI_PX_FBS_EN (0x1) | |
226 | #define AHCI_PX_FBS_DEC (0x2) | |
227 | #define AHCI_PX_FBS_SDE (0x4) | |
228 | #define AHCI_PX_FBS_DEV (0xF00) | |
229 | #define AHCI_PX_FBS_ADO (0xF000) | |
230 | #define AHCI_PX_FBS_DWE (0xF0000) | |
231 | #define AHCI_PX_FBS_RESERVED (0xFFF000F8) | |
232 | ||
233 | #define AHCI_PX_RES2 (17) | |
234 | #define AHCI_PX_VS (28) | |
235 | ||
236 | #define HBA_DATA_REGION_SIZE (256) | |
237 | #define HBA_PORT_DATA_SIZE (128) | |
238 | #define HBA_PORT_NUM_REG (HBA_PORT_DATA_SIZE/4) | |
239 | ||
240 | #define AHCI_VERSION_0_95 (0x00000905) | |
241 | #define AHCI_VERSION_1_0 (0x00010000) | |
242 | #define AHCI_VERSION_1_1 (0x00010100) | |
243 | #define AHCI_VERSION_1_2 (0x00010200) | |
244 | #define AHCI_VERSION_1_3 (0x00010300) | |
245 | ||
246 | /*** Structures ***/ | |
247 | ||
248 | /** | |
249 | * Generic FIS structure. | |
250 | */ | |
251 | typedef struct FIS { | |
252 | uint8_t fis_type; | |
253 | uint8_t flags; | |
254 | char data[0]; | |
255 | } __attribute__((__packed__)) FIS; | |
256 | ||
257 | /** | |
258 | * Register device-to-host FIS structure. | |
259 | */ | |
260 | typedef struct RegD2HFIS { | |
261 | /* DW0 */ | |
262 | uint8_t fis_type; | |
263 | uint8_t flags; | |
264 | uint8_t status; | |
265 | uint8_t error; | |
266 | /* DW1 */ | |
267 | uint8_t lba_low; | |
268 | uint8_t lba_mid; | |
269 | uint8_t lba_high; | |
270 | uint8_t device; | |
271 | /* DW2 */ | |
272 | uint8_t lba3; | |
273 | uint8_t lba4; | |
274 | uint8_t lba5; | |
275 | uint8_t res1; | |
276 | /* DW3 */ | |
277 | uint16_t count; | |
278 | uint8_t res2; | |
279 | uint8_t res3; | |
280 | /* DW4 */ | |
281 | uint16_t res4; | |
282 | uint16_t res5; | |
283 | } __attribute__((__packed__)) RegD2HFIS; | |
284 | ||
285 | /** | |
286 | * Register host-to-device FIS structure. | |
287 | */ | |
288 | typedef struct RegH2DFIS { | |
289 | /* DW0 */ | |
290 | uint8_t fis_type; | |
291 | uint8_t flags; | |
292 | uint8_t command; | |
293 | uint8_t feature_low; | |
294 | /* DW1 */ | |
295 | uint8_t lba_low; | |
296 | uint8_t lba_mid; | |
297 | uint8_t lba_high; | |
298 | uint8_t device; | |
299 | /* DW2 */ | |
300 | uint8_t lba3; | |
301 | uint8_t lba4; | |
302 | uint8_t lba5; | |
303 | uint8_t feature_high; | |
304 | /* DW3 */ | |
305 | uint16_t count; | |
306 | uint8_t icc; | |
307 | uint8_t control; | |
308 | /* DW4 */ | |
309 | uint32_t aux; | |
310 | } __attribute__((__packed__)) RegH2DFIS; | |
311 | ||
312 | /** | |
313 | * Command List entry structure. | |
314 | * The command list contains between 1-32 of these structures. | |
315 | */ | |
316 | typedef struct AHCICommand { | |
317 | uint8_t b1; | |
318 | uint8_t b2; | |
319 | uint16_t prdtl; /* Phys Region Desc. Table Length */ | |
320 | uint32_t prdbc; /* Phys Region Desc. Byte Count */ | |
321 | uint32_t ctba; /* Command Table Descriptor Base Address */ | |
322 | uint32_t ctbau; /* '' Upper */ | |
323 | uint32_t res[4]; | |
324 | } __attribute__((__packed__)) AHCICommand; | |
325 | ||
326 | /** | |
327 | * Physical Region Descriptor; pointed to by the Command List Header, | |
328 | * struct ahci_command. | |
329 | */ | |
330 | typedef struct PRD { | |
331 | uint32_t dba; /* Data Base Address */ | |
332 | uint32_t dbau; /* Data Base Address Upper */ | |
333 | uint32_t res; /* Reserved */ | |
334 | uint32_t dbc; /* Data Byte Count (0-indexed) & Interrupt Flag (bit 2^31) */ | |
335 | } PRD; | |
336 | ||
337 | typedef struct HBACap { | |
338 | uint32_t cap; | |
339 | uint32_t cap2; | |
340 | } HBACap; | |
341 | ||
342 | /*** Macro Utilities ***/ | |
343 | #define BITANY(data, mask) (((data) & (mask)) != 0) | |
344 | #define BITSET(data, mask) (((data) & (mask)) == (mask)) | |
345 | #define BITCLR(data, mask) (((data) & (mask)) == 0) | |
346 | #define ASSERT_BIT_SET(data, mask) g_assert_cmphex((data) & (mask), ==, (mask)) | |
347 | #define ASSERT_BIT_CLEAR(data, mask) g_assert_cmphex((data) & (mask), ==, 0) | |
348 | ||
349 | /* For calculating how big the PRD table needs to be: */ | |
350 | #define CMD_TBL_SIZ(n) ((0x80 + ((n) * sizeof(PRD)) + 0x7F) & ~0x7F) | |
351 | ||
352 | #endif |