xref: /haiku/src/add-ons/kernel/busses/scsi/ahci/ahci_defs.h (revision 2b76973fa2401f7a5edf68e6470f3d3210cbcff3)
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 <bus/PCI.h>
9 #include <bus/SCSI.h>
10 #include <PCI_x86.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		= (1 << 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 (zero-based number)
42 	CAP_NCS_SHIFT	= 8,
43 	CAP_CCCS 		= (1 << 7),		// Command Completion Coalescing Supported
44 	CAP_EMS 		= (1 << 6),		// Enclosure Management Supported
45 	CAP_SXS 		= (1 << 5), 	// Supports External SATA
46 	CAP_NP_MASK		= 0x1f,			// Number of Ports (zero-based number)
47 	CAP_NP_SHIFT	= 0,
48 };
49 
50 
51 enum {
52 	GHC_AE			= (1 << 31),	// AHCI Enable
53 	GHC_MRSM		= (1 << 2),		// MSI Revert to Single Message
54 	GHC_IE			= (1 << 1),		// Interrupt Enable
55 	GHC_HR			= (1 << 0),		// HBA Reset **RW1**
56 };
57 
58 
59 enum {
60 	INT_CPD			= (1 << 31),	// Cold Port Detect Status/Enable
61 	INT_TFE			= (1 << 30),	// Task File Error Status/Enable
62 	INT_HBF			= (1 << 29),	// Host Bus Fatal Error Status/Enable
63 	INT_HBD			= (1 << 28),	// Host Bus Data Error Status/Enable
64 	INT_IF			= (1 << 27),	// Interface Fatal Error Status/Enable
65 	INT_INF			= (1 << 26),	// Interface Non-fatal Error Status/Enable
66 	INT_OF			= (1 << 24),	// Overflow Status/Enable
67 	INT_IPM			= (1 << 23),	// Incorrect Port Multiplier Status/Enable
68 	INT_PRC			= (1 << 22),	// PhyRdy Change Status/Enable
69 	INT_DMP			= (1 << 7),		// Device Mechanical Presence Status/Enable
70 	INT_PC			= (1 << 6),		// Port Change Interrupt Status/Enable
71 	INT_DP			= (1 << 5),		// Descriptor Processed Interrupt/Enable
72 	INT_UF			= (1 << 4),		// Unknown FIS Interrupt/Enable
73 	INT_SDB			= (1 << 3),		// Set Device Bits Interrupt/Enable
74 	INT_DS			= (1 << 2),		// DMA Setup FIS Interrupt/Enable
75 	INT_PS			= (1 << 1),		// PIO Setup FIS Interrupt/Enable
76 	INT_DHR			= (1 << 0),		// Device to Host Register FIS Interrupt/Enable
77 };
78 
79 
80 typedef struct {
81 	uint32		clb;			// Command List Base Address (alignment 1024 byte)
82 	uint32		clbu;			// Command List Base Address Upper 32-Bits
83 	uint32		fb;				// FIS Base Address (alignment 256 byte)
84 	uint32		fbu;			// FIS Base Address Upper 32-Bits
85 	uint32		is;				// Interrupt Status **RWC**
86 	uint32		ie;				// Interrupt Enable
87 	uint32		cmd;			// Command and Status
88 	uint32 		res1;			// Reserved
89 	uint32		tfd;			// Task File Data
90 	uint32		sig;			// Signature
91 	uint32		ssts;			// Serial ATA Status (SCR0: SStatus)
92 	uint32		sctl;			// Serial ATA Control (SCR2: SControl)
93 	uint32		serr;			// Serial ATA Error (SCR1: SError) **RWC**
94 	uint32		sact;			// Serial ATA Active (SCR3: SActive) **RW1**
95 	uint32		ci;				// Command Issue **RW1**
96 	uint32		sntf;			// SNotification
97 	uint32		res2;			// Reserved for FIS-based Switching Definition
98 	uint32		res[11];		// Reserved
99 	uint32		vendor[4];		// Vendor Specific
100 } _PACKED ahci_port;
101 
102 
103 enum {
104 	PORT_CMD_ICC_ACTIVE	 = (1 << 28),	// Interface Communication control
105 	PORT_CMD_ICC_SLUMBER = (6 << 28),	// Interface Communication control
106 	PORT_CMD_ICC_MASK    = (0xf<<28),	// Interface Communication control
107 	PORT_CMD_ATAPI	= (1 << 24),	// Device is ATAPI
108 	PORT_CMD_CR		= (1 << 15),	// Command List Running (DMA active)
109 	PORT_CMD_FR		= (1 << 14),	// FIS Receive Running
110 	PORT_CMD_FER	= (1 << 4),		// FIS Receive Enable
111 	PORT_CMD_CLO	= (1 << 3),		// Command List Override
112 	PORT_CMD_POD	= (1 << 2),		// Power On Device
113 	PORT_CMD_SUD	= (1 << 1),		// Spin-up Device
114 	PORT_CMD_ST		= (1 << 0),		// Start DMA
115 };
116 
117 
118 enum {
119 	PORT_INT_CPD	= (1 << 31),	// Cold Presence Detect Status/Enable
120 	PORT_INT_TFE	= (1 << 30),	// Task File Error Status/Enable
121 	PORT_INT_HBF	= (1 << 29),	// Host Bus Fatal Error Status/Enable
122 	PORT_INT_HBD	= (1 << 28),	// Host Bus Data Error Status/Enable
123 	PORT_INT_IF		= (1 << 27),	// Interface Fatal Error Status/Enable
124 	PORT_INT_INF	= (1 << 26),	// Interface Non-fatal Error Status/Enable
125 	PORT_INT_OF		= (1 << 24),	// Overflow Status/Enable
126 	PORT_INT_IPM	= (1 << 23),	// Incorrect Port Multiplier Status/Enable
127 	PORT_INT_PRC	= (1 << 22),	// PhyRdy Change Status/Enable
128 	PORT_INT_DI		= (1 << 7),		// Device Interlock Status/Enable
129 	PORT_INT_PC		= (1 << 6),		// Port Change Status/Enable
130 	PORT_INT_DP		= (1 << 5),		// Descriptor Processed Interrupt
131 	PORT_INT_UF		= (1 << 4),		// Unknown FIS Interrupt
132 	PORT_INT_SDB	= (1 << 3),		// Set Device Bits FIS Interrupt
133 	PORT_INT_DS		= (1 << 2),		// DMA Setup FIS Interrupt
134 	PORT_INT_PS		= (1 << 1),		// PIO Setup FIS Interrupt
135 	PORT_INT_DHR	= (1 << 0),		// Device to Host Register FIS Interrupt
136 };
137 
138 #define PORT_INT_ERROR 	(PORT_INT_TFE | PORT_INT_HBF | PORT_INT_HBD \
139 						 | PORT_INT_IF | PORT_INT_INF | PORT_INT_OF \
140 						 | PORT_INT_IPM | PORT_INT_PRC | PORT_INT_PC \
141 						 | PORT_INT_UF)
142 
143 #define PORT_INT_MASK	(PORT_INT_ERROR | PORT_INT_DP | PORT_INT_SDB \
144 						 | PORT_INT_DS | PORT_INT_PS | PORT_INT_DHR)
145 
146 enum {
147 	ATA_BSY 		= 0x80,
148 	ATA_DF 			= 0x20,
149 	ATA_DRQ			= 0x08,
150 	ATA_ERR			= 0x01,
151 };
152 
153 
154 typedef struct {
155 	uint32		cap;			// Host Capabilities
156 	uint32		ghc;			// Global Host Control
157 	uint32		is;				// Interrupt Status
158 	uint32		pi;				// Ports Implemented
159 	uint32		vs;				// Version
160 	uint32		ccc_ctl;		// Command Completion Coalescing Control
161 	uint32		ccc_ports;		// Command Completion Coalsecing Ports
162 	uint32		em_loc;			// Enclosure Management Location
163 	uint32		em_ctl;			// Enclosure Management Control
164 	uint32		res[31];		// Reserved
165 	uint32		vendor[24];		// Vendor Specific registers
166 	ahci_port	port[32];
167 } _PACKED ahci_hba;
168 
169 
170 typedef struct {
171 	uint8		dsfis[0x1c];	// DMA Setup FIS
172 	uint8		res1[0x04];
173 	uint8		psfis[0x14];	// PIO Setup FIS
174 	uint8		res2[0x0c];
175 	uint8		rfis[0x14];		// D2H Register FIS
176 	uint8		res3[0x04];
177 	uint8		sdbfis[0x08];	// Set Device Bits FIS
178 	uint8		ufis[0x40];		// Unknown FIS
179 	uint8		res4[0x60];
180 } _PACKED fis;
181 
182 
183 typedef struct {
184   union {
185    struct {
186 	uint16		cfl : 5;		// command FIS length
187 	uint16		a : 1;			// ATAPI
188 	uint16		w : 1;			// Write
189 	uint16		p : 1;			// Prefetchable
190 	uint16		r : 1;			// Reset
191 	uint16		b : 1;			// Build In Self Test
192 	uint16		c : 1;			// Clear Busy upon R_OK
193 	uint16		: 1;
194 	uint16		pmp : 4;		// Port Multiplier Port
195 	uint16		prdtl;			// physical region description table length;
196    } _PACKED;
197     uint32		prdtl_flags_cfl;
198   } _PACKED;
199 	uint32		prdbc;			// PRD Byte Count
200 	uint32		ctba;			// command table desciptor base address
201 								// (alignment 128 byte)
202 	uint32		ctbau;			// command table desciptor base address upper
203 	uint8		res1[0x10];
204 } _PACKED command_list_entry;
205 
206 #define COMMAND_LIST_ENTRY_COUNT 32
207 
208 
209 // Command FIS layout - Host to Device (H2D)
210 //  0 - FIS Type (0x27)
211 //  1 - C bit (0x80)
212 //  2 - Command
213 //  3 - Features
214 //  4 - Sector Number           (LBA Low, bits 0-7)
215 //  5 - Cylinder Low            (LBA Mid, bits 8-15)
216 //  6 - Cylinder High           (LBA High, bits 16-23)
217 //  7 - Device / Head           (for 28-bit LBA commands, bits 24-27)
218 //  8 - Sector Number expanded  (LBA Low-previous, bits 24-31)
219 //  9 - Cylinder Low expanded   (LBA Mid-previous, bits 32-39)
220 // 10 - Cylinder High expanded  (LBA High-previous, bits 40-47)
221 // 11 - Features expanded
222 // 12 - Sector Count            (Sector count, bits 0-7)
223 // 13 - Sector Count expanded   (Sector count, bits 8-15)
224 // 14 - Reserved (0)
225 // 15 - Control
226 // 16 - Reserved (0)
227 // 17 - Reserved (0)
228 // 18 - Reserved (0)
229 // 19 - Reserved (0)
230 typedef struct {
231 	uint8		cfis[0x40];		// command FIS
232 	uint8		acmd[0x20];		// ATAPI command
233 	uint8		res[0x20];		// reserved
234 } _PACKED command_table;
235 
236 
237 typedef struct {
238 	uint32		dba;			// Data Base Address (2-byte aligned)
239 	uint32		dbau;			// Data Base Address Upper
240 	uint32		res;
241 	uint32		dbc;			// Bytecount (0-based, even, max 4MB)
242 	#define DBC_I	0x80000000	/* Interrupt on completition */
243 } _PACKED prd;
244 
245 #define PRD_TABLE_ENTRY_COUNT 168
246 #define PRD_MAX_DATA_LENGTH 0x400000 /* 4 MB */
247 
248 
249 typedef struct {
250 	uint16 vendor;
251 	uint16 device;
252 	const char *name;
253 	uint32 flags;
254 } device_info;
255 
256 status_t get_device_info(uint16 vendorID, uint16 deviceID, const char **name,
257 	uint32 *flags);
258 
259 
260 extern scsi_sim_interface gAHCISimInterface;
261 extern device_manager_info *gDeviceManager;
262 extern scsi_for_sim_interface *gSCSI;
263 extern pci_x86_module_info* gPCIx86Module;
264 
265 
266 #define MAX_SECTOR_LBA_28 ((1ull << 28) - 1)
267 #define MAX_SECTOR_LBA_48 ((1ull << 48) - 1)
268 
269 
270 #define LO32(val) ((uint32)(addr_t)(val))
271 #define HI32(val) ((uint32)(((uint64)(addr_t)(val)) >> 32))
272 #define ASSERT(expr) if (expr) {} else panic(#expr)
273 
274 #define PCI_VENDOR_INTEL	0x8086
275 #define PCI_VENDOR_JMICRON	0x197b
276 #define PCI_JMICRON_CONTROLLER_CONTROL_1	0x40
277 
278 #ifdef __cplusplus
279 }
280 #endif
281 
282 #ifdef __cplusplus
283 
284 template <class T>
285 int count_bits_set(T value)
286 {
287 	int count = 0;
288 	for (T mask = 1; mask; mask <<= 1)
289 		if (value & mask)
290 			count++;
291 	return count;
292 }
293 
294 inline
295 status_t
296 wait_until_set(volatile uint32 *reg, uint32 bits, bigtime_t timeout)
297 {
298 	int trys = (timeout + 9999) / 10000;
299 	while (trys--) {
300 		if (((*reg) & bits) == bits)
301 			return B_OK;
302 		snooze(10000);
303 	}
304 	return B_TIMED_OUT;
305 }
306 
307 inline
308 status_t
309 wait_until_clear(volatile uint32 *reg, uint32 bits, bigtime_t timeout)
310 {
311 	int trys = (timeout + 9999) / 10000;
312 	while (trys--) {
313 		if (((*reg) & bits) == 0)
314 			return B_OK;
315 		snooze(10000);
316 	}
317 	return B_TIMED_OUT;
318 }
319 
320 #endif	/* __cplusplus */
321 
322 #endif	/* _AHCI_DEFS_H */
323