1 /*
2 * Copyright 2007, Marcus Overhagen. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 */
5 #ifndef _AHCI_DEFS_H
6 #define _AHCI_DEFS_H
7
8 #include <ata_types.h>
9 #include <bus/PCI.h>
10 #include <bus/SCSI.h>
11
12 #ifdef __cplusplus
13 extern "C" {
14 #endif
15
16 #define AHCI_DEVICE_MODULE_NAME "busses/scsi/ahci/driver_v1"
17 #define AHCI_SIM_MODULE_NAME "busses/scsi/ahci/sim/driver_v1"
18
19 // RW1 = Write 1 to set bit (writing 0 is ignored)
20 // RWC = Write 1 to clear bit (writing 0 is ignored)
21
22
23 enum {
24 CAP_S64A = (1U << 31), // Supports 64-bit Addressing
25 CAP_SNCQ = (1 << 30), // Supports Native Command Queuing
26 CAP_SSNTF = (1 << 29), // Supports SNotification Register
27 CAP_SMPS = (1 << 28), // Supports Mechanical Presence Switch
28 CAP_SSS = (1 << 27), // Supports Staggered Spin-up
29 CAP_SALP = (1 << 26), // Supports Aggressive Link Power Management
30 CAP_SAL = (1 << 25), // Supports Activity LED
31 CAP_SCLO = (1 << 24), // Supports Command List Override
32 CAP_ISS_MASK = 0xf, // Interface Speed Support
33 CAP_ISS_SHIFT = 20,
34 CAP_SNZO = (1 << 19), // Supports Non-Zero DMA Offsets
35 CAP_SAM = (1 << 18), // Supports AHCI mode only
36 CAP_SPM = (1 << 17), // Supports Port Multiplier
37 CAP_FBSS = (1 << 16), // FIS-based Switching Supported
38 CAP_PMD = (1 << 15), // PIO Multiple DRQ Block
39 CAP_SSC = (1 << 14), // Slumber State Capable
40 CAP_PSC = (1 << 13), // Partial State Capable
41 CAP_NCS_MASK = 0x1f, // Number of Command Slots
42 // (zero-based number)
43 CAP_NCS_SHIFT = 8,
44 CAP_CCCS = (1 << 7), // Command Completion Coalescing Supported
45 CAP_EMS = (1 << 6), // Enclosure Management Supported
46 CAP_SXS = (1 << 5), // Supports External SATA
47 CAP_NP_MASK = 0x1f, // Number of Ports (zero-based number)
48 CAP_NP_SHIFT = 0,
49 };
50
51
52 enum {
53 GHC_AE = (1U << 31), // AHCI Enable
54 GHC_MRSM = (1 << 2), // MSI Revert to Single Message
55 GHC_IE = (1 << 1), // Interrupt Enable
56 GHC_HR = (1 << 0), // HBA Reset **RW1**
57 };
58
59
60 enum {
61 INT_CPD = (1 << 31), // Cold Port Detect Status/Enable
62 INT_TFE = (1 << 30), // Task File Error Status/Enable
63 INT_HBF = (1 << 29), // Host Bus Fatal Error Status/Enable
64 INT_HBD = (1 << 28), // Host Bus Data Error Status/Enable
65 INT_IF = (1 << 27), // Interface Fatal Error Status/Enable
66 INT_INF = (1 << 26), // Interface Non-fatal Error Status/Enable
67 INT_OF = (1 << 24), // Overflow Status/Enable
68 INT_IPM = (1 << 23), // Incorrect Port Multiplier Status/Enable
69 INT_PRC = (1 << 22), // PhyRdy Change Status/Enable
70 INT_DMP = (1 << 7), // Device Mechanical Presence Status/Enable
71 INT_PC = (1 << 6), // Port Change Interrupt Status/Enable
72 INT_DP = (1 << 5), // Descriptor Processed Interrupt/Enable
73 INT_UF = (1 << 4), // Unknown FIS Interrupt/Enable
74 INT_SDB = (1 << 3), // Set Device Bits Interrupt/Enable
75 INT_DS = (1 << 2), // DMA Setup FIS Interrupt/Enable
76 INT_PS = (1 << 1), // PIO Setup FIS Interrupt/Enable
77 INT_DHR = (1 << 0), // Device to Host Register FIS
78 // Interrupt/Enable
79 };
80
81
82 // Serial ATA Status and control
83 #define HBA_PORT_IPM_MASK 0x00000f00 // Interface Power Management
84 #define SSTS_PORT_IPM_ACTIVE 0x00000100 // active state
85 #define SSTS_PORT_IPM_PARTIAL 0x00000200 // partial state
86 #define SSTS_PORT_IPM_SLUMBER 0x00000600 // slumber power management state
87 #define SSTS_PORT_IPM_DEVSLEEP 0x00000800 // devsleep power management state
88 #define SCTL_PORT_IPM_NORES 0x00000000 // no power restrictions
89 #define SCTL_PORT_IPM_NOPART 0x00000100 // no transitions to partial
90 #define SCTL_PORT_IPM_NOSLUM 0x00000200 // no transitions to slumber
91
92 #define HBA_PORT_SPD_MASK 0x000000f0 // Interface speed
93
94 #define HBA_PORT_DET_MASK 0x0000000f // Device Detection
95 #define SSTS_PORT_DET_NODEV 0x00000000 // no device detected
96 #define SSTS_PORT_DET_NOPHY 0x00000001 // device present but PHY not est.
97 #define SSTS_PORT_DET_PRESENT 0x00000003 // device present and PHY est.
98 #define SSTS_PORT_DET_OFFLINE 0x00000004 // device offline due to disabled
99 #define SCTL_PORT_DET_NOINIT 0x00000000 // no initalization request
100 #define SCTL_PORT_DET_INIT 0x00000001 // perform interface initalization
101 #define SCTL_PORT_DET_DISABLE 0x00000004 // disable phy
102
103 // Device signatures
104 #define SATA_SIG_ATA 0x00000101 // SATA drive
105 #define SATA_SIG_ATAPI 0xEB140101 // ATAPI drive
106 #define SATA_SIG_SEMB 0xC33C0101 // Enclosure management bridge
107 #define SATA_SIG_PM 0x96690101 // Port multiplier
108
109 typedef struct {
110 uint32 clb; // Command List Base Address
111 // (alignment 1024 byte)
112 uint32 clbu; // Command List Base Address Upper 32-Bits
113 uint32 fb; // FIS Base Address (alignment 256 byte)
114 uint32 fbu; // FIS Base Address Upper 32-Bits
115 uint32 is; // Interrupt Status **RWC**
116 uint32 ie; // Interrupt Enable
117 uint32 cmd; // Command and Status
118 uint32 res1; // Reserved
119 uint32 tfd; // Task File Data
120 uint32 sig; // Signature
121 uint32 ssts; // Serial ATA Status (SCR0: SStatus)
122 uint32 sctl; // Serial ATA Control (SCR2: SControl)
123 uint32 serr; // Serial ATA Error (SCR1: SError) **RWC**
124 uint32 sact; // Serial ATA Active (SCR3: SActive) **RW1**
125 uint32 ci; // Command Issue **RW1**
126 uint32 sntf; // SNotification
127 uint32 fbs; // FIS-based Switching Control
128 uint32 devslp; // Device Sleep
129 uint32 res[10]; // Reserved
130 uint32 vendor[4]; // Vendor Specific
131 } ahci_port;
132
133
134 enum {
135 PORT_CMD_ICC_ACTIVE = (1 << 28), // Interface Communication control
136 PORT_CMD_ICC_SLUMBER = (6 << 28), // Interface Communication control
137 PORT_CMD_ICC_MASK = (0xf<<28), // Interface Communication control
138 PORT_CMD_ATAPI = (1 << 24), // Device is ATAPI
139 PORT_CMD_CR = (1 << 15), // Command List Running (DMA active)
140 PORT_CMD_FR = (1 << 14), // FIS Receive Running
141 PORT_CMD_FRE = (1 << 4), // FIS Receive Enable
142 PORT_CMD_CLO = (1 << 3), // Command List Override
143 PORT_CMD_POD = (1 << 2), // Power On Device
144 PORT_CMD_SUD = (1 << 1), // Spin-up Device
145 PORT_CMD_ST = (1 << 0), // Start DMA
146 };
147
148
149 enum {
150 PORT_INT_CPD = (1 << 31), // Cold Presence Detect Status/Enable
151 PORT_INT_TFE = (1 << 30), // Task File Error Status/Enable
152 PORT_INT_HBF = (1 << 29), // Host Bus Fatal Error Status/Enable
153 PORT_INT_HBD = (1 << 28), // Host Bus Data Error Status/Enable
154 PORT_INT_IF = (1 << 27), // Interface Fatal Error Status/Enable
155 PORT_INT_INF = (1 << 26), // Interface Non-fatal Error Status/Enable
156 PORT_INT_OF = (1 << 24), // Overflow Status/Enable
157 PORT_INT_IPM = (1 << 23), // Incorrect Port Multiplier Status/Enable
158 PORT_INT_PRC = (1 << 22), // PhyRdy Change Status/Enable
159 PORT_INT_DI = (1 << 7), // Device Interlock Status/Enable
160 PORT_INT_PC = (1 << 6), // Port Change Status/Enable
161 PORT_INT_DP = (1 << 5), // Descriptor Processed Interrupt
162 PORT_INT_UF = (1 << 4), // Unknown FIS Interrupt
163 PORT_INT_SDB = (1 << 3), // Set Device Bits FIS Interrupt
164 PORT_INT_DS = (1 << 2), // DMA Setup FIS Interrupt
165 PORT_INT_PS = (1 << 1), // PIO Setup FIS Interrupt
166 PORT_INT_DHR = (1 << 0), // Device to Host Register FIS Interrupt
167 };
168
169 #define PORT_INT_ERROR (PORT_INT_TFE | PORT_INT_HBF | PORT_INT_HBD \
170 | PORT_INT_IF | PORT_INT_INF | PORT_INT_OF \
171 | PORT_INT_IPM | PORT_INT_PRC | PORT_INT_PC \
172 | PORT_INT_UF)
173
174 #define PORT_INT_MASK (PORT_INT_ERROR | PORT_INT_DP | PORT_INT_SDB \
175 | PORT_INT_DS | PORT_INT_PS | PORT_INT_DHR)
176
177 enum {
178 PORT_FBS_DWE_SHIFT = 16, // Device With Error
179 PORT_FBS_DWE_MASK = 0xf,
180 PORT_FBS_ADO_SHIFT = 12, // Active Device Optimization
181 PORT_FBS_ADO_MASK = 0xf,
182 PORT_FBS_DEV_SHIFT = 8, // Device To Issue
183 PORT_FBS_DEV_MASK = 0xf,
184 PORT_FBS_SDE = 0x04, // Single Device Error
185 PORT_FBS_DEC = 0x02, // Device Error Clear
186 PORT_FBS_EN = 0x01, // Enable
187 };
188
189
190 enum {
191 PORT_DEVSLP_DM_SHIFT = 25, // DITO Multiplier
192 PORT_DEVSLP_DM_MASK = 0xf,
193 PORT_DEVSLP_DITO_SHIFT = 15, // Device Sleep Idle Timeout
194 PORT_DEVSLP_DITO_MASK = 0x3ff,
195 PORT_DEVSLP_MDAT_SHIFT = 10, // Minimum Device Sleep Assertion Time
196 PORT_DEVSLP_MDAT_MASK = 0x1f,
197 PORT_DEVSLP_DETO_SHIFT = 2, // Device Sleep Exit Timeout
198 PORT_DEVSLP_DETO_MASK = 0xff,
199 PORT_DEVSLP_DSP = 0x02, // Device Sleep Present
200 PORT_DEVSLP_ADSE = 0x01, // Aggressive Device Sleep Enable
201 };
202
203
204 enum {
205 CAP2_DESO = (1 << 5), // DevSleep Entrance from Slumber Only
206 CAP2_SADM = (1 << 4), // Supports Aggressive Device Sleep
207 // Management
208 CAP2_SDS = (1 << 3), // Supports Device Sleep
209 CAP2_APST = (1 << 2), // Automatic Partial to Slumber Transitions
210 CAP2_NVMP = (1 << 1), // NVMHCI Present
211 CAP2_BOH = (1 << 0), // BIOS/OS Handoff
212 };
213
214
215 typedef struct {
216 uint32 cap; // Host Capabilities
217 uint32 ghc; // Global Host Control
218 uint32 is; // Interrupt Status
219 uint32 pi; // Ports Implemented
220 uint32 vs; // Version
221 uint32 ccc_ctl; // Command Completion Coalescing Control
222 uint32 ccc_ports; // Command Completion Coalsecing Ports
223 uint32 em_loc; // Enclosure Management Location
224 uint32 em_ctl; // Enclosure Management Control
225 uint32 cap2; // Host Capabilities Extended
226 uint32 bohc; // BIOS/OS Handoff Control and Status
227 uint32 res[29]; // Reserved
228 uint32 vendor[24]; // Vendor Specific registers
229 ahci_port port[32];
230 } _PACKED ahci_hba;
231
232
233 typedef struct {
234 uint8 dsfis[0x1c]; // DMA Setup FIS
235 uint8 res1[0x04];
236 uint8 psfis[0x14]; // PIO Setup FIS
237 uint8 res2[0x0c];
238 uint8 rfis[0x14]; // D2H Register FIS
239 uint8 res3[0x04];
240 uint8 sdbfis[0x08]; // Set Device Bits FIS
241 uint8 ufis[0x40]; // Unknown FIS
242 uint8 res4[0x60];
243 } _PACKED fis;
244
245
246 typedef struct {
247 union {
248 struct {
249 uint16 cfl : 5; // command FIS length
250 uint16 a : 1; // ATAPI
251 uint16 w : 1; // Write
252 uint16 p : 1; // Prefetchable
253 uint16 r : 1; // Reset
254 uint16 b : 1; // Build In Self Test
255 uint16 c : 1; // Clear Busy upon R_OK
256 uint16 : 1;
257 uint16 pmp : 4; // Port Multiplier Port
258 uint16 prdtl; // physical region description table
259 // length;
260 } _PACKED;
261 uint32 prdtl_flags_cfl;
262 } _PACKED;
263 uint32 prdbc; // PRD Byte Count
264 uint32 ctba; // command table desciptor base address
265 // (alignment 128 byte)
266 uint32 ctbau; // command table desciptor base address upper
267 uint8 res1[0x10];
268 } _PACKED command_list_entry;
269
270 #define COMMAND_LIST_ENTRY_COUNT 32
271
272
273 // Command FIS layout - Host to Device (H2D)
274 // 0 - FIS Type (0x27)
275 // 1 - C bit (0x80)
276 // 2 - Command
277 // 3 - Features
278 // 4 - Sector Number (LBA Low, bits 0-7)
279 // 5 - Cylinder Low (LBA Mid, bits 8-15)
280 // 6 - Cylinder High (LBA High, bits 16-23)
281 // 7 - Device / Head (for 28-bit LBA commands, bits 24-27)
282 // 8 - Sector Number expanded (LBA Low-previous, bits 24-31)
283 // 9 - Cylinder Low expanded (LBA Mid-previous, bits 32-39)
284 // 10 - Cylinder High expanded (LBA High-previous, bits 40-47)
285 // 11 - Features expanded
286 // 12 - Sector Count (Sector count, bits 0-7)
287 // 13 - Sector Count expanded (Sector count, bits 8-15)
288 // 14 - Reserved (0)
289 // 15 - Control
290 // 16 - Reserved (0)
291 // 17 - Reserved (0)
292 // 18 - Reserved (0)
293 // 19 - Reserved (0)
294 typedef struct {
295 uint8 cfis[0x40]; // command FIS
296 uint8 acmd[0x20]; // ATAPI command
297 uint8 res[0x20]; // reserved
298 } _PACKED command_table;
299
300
301 typedef struct {
302 uint32 dba; // Data Base Address (2-byte aligned)
303 uint32 dbau; // Data Base Address Upper
304 uint32 res;
305 uint32 dbc; // Bytecount (0-based, even, max 4MB)
306 #define DBC_I 0x80000000 /* Interrupt on completition */
307 } _PACKED prd;
308
309 #define PRD_TABLE_ENTRY_COUNT 168
310 #define PRD_MAX_DATA_LENGTH 0x400000 /* 4 MB */
311
312
313 typedef struct {
314 uint16 vendor;
315 uint16 device;
316 const char *name;
317 uint32 flags;
318 } device_info;
319
320 status_t get_device_info(uint16 vendorID, uint16 deviceID, const char **name,
321 uint32 *flags);
322
323
324 extern scsi_sim_interface gAHCISimInterface;
325 extern device_manager_info *gDeviceManager;
326 extern scsi_for_sim_interface *gSCSI;
327
328
329 #define MAX_SECTOR_LBA_28 ((1ull << 28) - 1)
330 #define MAX_SECTOR_LBA_48 ((1ull << 48) - 1)
331
332
333 #define LO32(val) ((uint32)(val))
334 #define HI32(val) ((uint32)(((uint64)(val)) >> 32))
335
336 #define PCI_VENDOR_INTEL 0x8086
337 #define PCI_VENDOR_JMICRON 0x197b
338 #define PCI_JMICRON_CONTROLLER_CONTROL_1 0x40
339
340 #ifdef __cplusplus
341 }
342 #endif
343
344 #ifdef __cplusplus
345
346 inline
347 status_t
wait_until_set(volatile uint32 * reg,uint32 bits,bigtime_t timeout)348 wait_until_set(volatile uint32 *reg, uint32 bits, bigtime_t timeout)
349 {
350 int trys = (timeout + 9999) / 10000;
351 while (trys--) {
352 if (((*reg) & bits) == bits)
353 return B_OK;
354 snooze(10000);
355 }
356 return B_TIMED_OUT;
357 }
358
359 inline
360 status_t
wait_until_clear(volatile uint32 * reg,uint32 bits,bigtime_t timeout)361 wait_until_clear(volatile uint32 *reg, uint32 bits, bigtime_t timeout)
362 {
363 int trys = (timeout + 9999) / 10000;
364 while (trys--) {
365 if (((*reg) & bits) == 0)
366 return B_OK;
367 snooze(10000);
368 }
369 return B_TIMED_OUT;
370 }
371
372 #endif /* __cplusplus */
373
374 #endif /* _AHCI_DEFS_H */
375