xref: /illumos-gate/usr/src/uts/common/sys/sata/adapters/ahci/ahcireg.h (revision 437220cd296f6d8b6654d6d52508b40b1e2d1ac7)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 
28 #ifndef _AHCIREG_H
29 #define	_AHCIREG_H
30 
31 #pragma ident	"%Z%%M%	%I%	%E% SMI"
32 
33 #ifdef	__cplusplus
34 extern "C" {
35 #endif
36 
37 #define	AHCI_MAX_PORTS		32
38 #define	AHCI_PORT_MAX_CMD_SLOTS	32
39 
40 #define	VIA_VENID		0x1106
41 
42 /*
43  * In AHCI spec, command table contains a list of 0 (no data transfer)
44  * to up to 65,535 scatter/gather entries for the data transfer.
45  */
46 #define	AHCI_MAX_PRDT_NUMBER	65535
47 #define	AHCI_MIN_PRDT_NUMBER	1
48 
49 /*
50  * The default value of s/g entrie is 257, at least 1MB (4KB/pg * 256) + 1
51  * if misaligned, and it's tuable by setting ahci_dma_prdt_number in
52  * /etc/system file.
53  */
54 #define	AHCI_PRDT_NUMBER	257
55 
56 /* AHCI base address */
57 #define	AHCI_BASE_REG	6	/* BAR5 is the only useful register */
58 
59 /* various global HBA capability bits */
60 #define	AHCI_HBA_CAP_NP		(0x1f << 0) /* number of ports */
61 #define	AHCI_HBA_CAP_SXS	(0x1 << 5) /* external SATA */
62 #define	AHCI_HBA_CAP_EMS	(0x1 << 6) /* enclosure management */
63 #define	AHCI_HBA_CAP_CCCS	(0x1 << 7) /* command completed coalescing */
64 #define	AHCI_HBA_CAP_NCS	(0x1f << 8) /* number of command slots */
65 #define	AHCI_HBA_CAP_PSC	(0x1 << 13) /* partial state capable */
66 #define	AHCI_HBA_CAP_SSC	(0x1 << 14) /* slumber state capable */
67 #define	AHCI_HBA_CAP_PMD	(0x1 << 15) /* PIO multiple DRQ block */
68 #define	AHCI_HBA_CAP_FBSS	(0x1 << 16) /* FIS-based switching */
69 #define	AHCI_HBA_CAP_SPM	(0x1 << 17) /* port multiplier */
70 #define	AHCI_HBA_CAP_SAM	(0x1 << 18) /* AHCI mode only */
71 #define	AHCI_HBA_CAP_SNZO	(0x1 << 19) /* non-zero DMA offsets */
72 #define	AHCI_HBA_CAP_ISS	(0xf << 20) /* interface speed support */
73 #define	AHCI_HBA_CAP_SCLO	(0x1 << 24) /* command list override */
74 #define	AHCI_HBA_CAP_SAL	(0x1 << 25) /* activity LED */
75 #define	AHCI_HBA_CAP_SALP	(0x1 << 26) /* aggressive link power mgmt */
76 #define	AHCI_HBA_CAP_SSS	(0x1 << 27) /* staggered  spin-up */
77 #define	AHCI_HBA_CAP_SMPS	(0x1 << 28) /* mechanical presence switch */
78 #define	AHCI_HBA_CAP_SSNTF	(0x1 << 29) /* Snotification register */
79 #define	AHCI_HBA_CAP_SNCQ	(0x1 << 30) /* Native Command Queuing */
80 #define	AHCI_HBA_CAP_S64A	((uint32_t)0x1 << 31) /* 64-bit addressing */
81 #define	AHCI_HBA_CAP_NCS_SHIFT	8  /* Number of command slots */
82 #define	AHCI_HBA_CAP_ISS_SHIFT	20 /* Interface speed support */
83 
84 /* various global HBA control bits */
85 #define	AHCI_HBA_GHC_HR		(0x1 << 0) /* HBA Reset */
86 #define	AHCI_HBA_GHC_IE		(0x1 << 1) /* Interrupt Enable */
87 #define	AHCI_HBA_GHC_MRSM	(0x1 << 2) /* MSI Revert to Single Message */
88 #define	AHCI_HBA_GHC_AE		((uint32_t)0x1 << 31) /* AHCI Enable */
89 
90 /* various global HBA Command Completion Coalescing (CCC) control bits */
91 #define	AHCI_HBA_CCC_CTL_EN		0x00000001  /* Enable */
92 #define	AHCI_HBA_CCC_CTL_INT_MASK	(0x1f << 3) /* Interrupt */
93 #define	AHCI_HBA_CCC_CTL_CC_MASK	0x0000ff00  /* Command Completions */
94 #define	AHCI_HBA_CCC_CTL_TV_MASK	0xffff0000  /* Timeout Value */
95 #define	AHCI_HBA_CCC_CTL_INT_SHIFT	3
96 #define	AHCI_HBA_CCC_CTL_CC_SHIFT	8
97 #define	AHCI_HBA_CCC_CTL_TV_SHIFT	16
98 
99 /* global HBA Enclosure Management Location (EM_LOC) */
100 #define	AHCI_HBA_EM_LOC_SZ_MASK		0x0000ffff /* Buffer Size */
101 #define	AHCI_HBA_EM_LOC_OFST_MASK	0xffff0000 /* Offset */
102 #define	AHCI_HBA_EM_LOC_OFST_SHIFT	16
103 
104 /* global HBA Enclosure Management Control (EM_CTL) bits */
105 #define	AHCI_HBA_EM_CTL_STS_MR		(0x1 << 0) /* Message Received */
106 #define	AHCI_HBA_EM_CTL_CTL_TM		(0x1 << 8) /* Transmit Message */
107 #define	AHCI_HBA_EM_CTL_CTL_RST		(0x1 << 9) /* Reset */
108 #define	AHCI_HBA_EM_CTL_SUPP_LED	(0x1 << 16) /* LED Message Types */
109 #define	AHCI_HBA_EM_CTL_SUPP_SAFTE	(0x1 << 17) /* SAF-TE EM Messages */
110 #define	AHCI_HBA_EM_CTL_SUPP_SES2	(0x1 << 18) /* SES-2 EM Messages */
111 #define	AHCI_HBA_EM_CTL_SUPP_SGPIO	(0x1 << 19) /* SGPIO EM Messages */
112 #define	AHCI_HBA_EM_CTL_ATTR_SMB	(0x1 << 24) /* Single Message Buffer */
113 #define	AHCI_HBA_EM_CTL_ATTR_XMT	(0x1 << 25) /* Transmit Only */
114 #define	AHCI_HBA_EM_CTL_ATTR_ALHD	(0x1 << 26) /* Activity LED HW Driven */
115 #define	AHCI_HBA_EM_CTL_ATTR_PM		(0x1 << 27) /* PM Support */
116 
117 
118 /* global HBA registers definitions */
119 #define	AHCI_GLOBAL_OFFSET(ahci_ctlp)	(ahci_ctlp->ahcictl_ahci_addr)
120 	/* HBA Capabilities */
121 #define	AHCI_GLOBAL_CAP(ahci_ctlp)	(AHCI_GLOBAL_OFFSET(ahci_ctlp) + 0x00)
122 	/* Global HBA Control */
123 #define	AHCI_GLOBAL_GHC(ahci_ctlp)	(AHCI_GLOBAL_OFFSET(ahci_ctlp) + 0x04)
124 	/* Interrupt Status Register */
125 #define	AHCI_GLOBAL_IS(ahci_ctlp)	(AHCI_GLOBAL_OFFSET(ahci_ctlp) + 0x08)
126 	/* Ports Implemented */
127 #define	AHCI_GLOBAL_PI(ahci_ctlp)	(AHCI_GLOBAL_OFFSET(ahci_ctlp) + 0x0c)
128 	/* AHCI Version */
129 #define	AHCI_GLOBAL_VS(ahci_ctlp)	(AHCI_GLOBAL_OFFSET(ahci_ctlp) + 0x10)
130 	/* Command Completion Coalescing Control */
131 #define	AHCI_GLOBAL_CCC_CTL(ahci_ctlp)	(AHCI_GLOBAL_OFFSET(ahci_ctlp) + 0x14)
132 	/* Command Completion Coalescing Ports */
133 #define	AHCI_GLOBAL_CCC_PORTS(ahci_ctlp)	\
134 					(AHCI_GLOBAL_OFFSET(ahci_ctlp) + 0x18)
135 	/* Enclosure Management Location */
136 #define	AHCI_GLOBAL_EM_LOC(ahci_ctlp)	(AHCI_GLOBAL_OFFSET(ahci_ctlp) + 0x1c)
137 	/* Enclosure Management Control */
138 #define	AHCI_GLOBAL_EM_CTL(ahci_ctlp)	(AHCI_GLOBAL_OFFSET(ahci_ctlp) + 0x20)
139 
140 #define	AHCI_PORT_IMPLEMENTED(ahci_ctlp, port)	\
141 	((0x1 << port) & ahci_ctlp->ahcictl_ports_implemented)
142 
143 /* various port interrupt bits */
144 	/* Device to Host Register FIS Interrupt */
145 #define	AHCI_INTR_STATUS_DHRS (0x1 << 0)
146 	/* PIO Setup FIS Interrupt */
147 #define	AHCI_INTR_STATUS_PSS			(0x1 << 1)
148 	/* DMA Setup FIS Interrupt */
149 #define	AHCI_INTR_STATUS_DSS			(0x1 << 2)
150 	/* Set Device Bits Interrupt */
151 #define	AHCI_INTR_STATUS_SDBS			(0x1 << 3)
152 	/* Unknown FIS Interrupt */
153 #define	AHCI_INTR_STATUS_UFS			(0x1 << 4)
154 	/* Descriptor Processed */
155 #define	AHCI_INTR_STATUS_DPS			(0x1 << 5)
156 	/* Port Connect Change Status */
157 #define	AHCI_INTR_STATUS_PCS			(0x1 << 6)
158 	/* Device Mechanical Presence Status */
159 #define	AHCI_INTR_STATUS_DMPS			(0x1 << 7)
160 	/* PhyRdy Change Status */
161 #define	AHCI_INTR_STATUS_PRCS			(0x1 << 22)
162 	/* Incorrect Port Multiplier Status */
163 #define	AHCI_INTR_STATUS_IPMS			(0x1 << 23)
164 	/* Overflow Status */
165 #define	AHCI_INTR_STATUS_OFS			(0x1 << 24)
166 	/* Interface Non-fatal Error Status */
167 #define	AHCI_INTR_STATUS_INFS			(0x1 << 26)
168 	/* Interface Fatal Error Status */
169 #define	AHCI_INTR_STATUS_IFS			(0x1 << 27)
170 	/* Host Bus Data Error Status */
171 #define	AHCI_INTR_STATUS_HBDS			(0x1 << 28)
172 	/* Host Bus Fatal Error Status */
173 #define	AHCI_INTR_STATUS_HBFS			(0x1 << 29)
174 	/* Task File Error Status */
175 #define	AHCI_INTR_STATUS_TFES			(0x1 << 30)
176 	/* Cold Port Detect Status */
177 #define	AHCI_INTR_STATUS_CPDS			((uint32_t)0x1 << 31)
178 #define	AHCI_PORT_INTR_MASK			0xfec000ff
179 
180 /* port command and status bits */
181 #define	AHCI_CMD_STATUS_ST	(0x1 << 0) /* Start */
182 #define	AHCI_CMD_STATUS_SUD	(0x1 << 1) /* Spin-up device */
183 #define	AHCI_CMD_STATUS_POD	(0x1 << 2) /* Power on device */
184 #define	AHCI_CMD_STATUS_CLO	(0x1 << 3) /* Command list override */
185 #define	AHCI_CMD_STATUS_FRE	(0x1 << 4) /* FIS receive enable */
186 #define	AHCI_CMD_STATUS_CCS	(0x1f << 8) /* Current command slot */
187 			/* Mechanical presence switch state */
188 #define	AHCI_CMD_STATUS_MPSS	(0x1 << 13)
189 #define	AHCI_CMD_STATUS_FR	(0x1 << 14) /* FIS receiving running */
190 #define	AHCI_CMD_STATUS_CR	(0x1 << 15) /* Command list running */
191 #define	AHCI_CMD_STATUS_CPS	(0x1 << 16) /* Cold presence state */
192 #define	AHCI_CMD_STATUS_PMA	(0x1 << 17) /* Port multiplier attached */
193 #define	AHCI_CMD_STATUS_HPCP	(0x1 << 18) /* Hot plug capable port */
194 			/* Mechanical presence switch attached to port */
195 #define	AHCI_CMD_STATUS_MPSP	(0x1 << 19)
196 #define	AHCI_CMD_STATUS_CPD	(0x1 << 20) /* Cold presence detection */
197 #define	AHCI_CMD_STATUS_ESP	(0x1 << 21) /* External SATA port */
198 #define	AHCI_CMD_STATUS_ATAPI	(0x1 << 24) /* Device is ATAPI */
199 #define	AHCI_CMD_STATUS_DLAE	(0x1 << 25) /* Drive LED on ATAPI enable */
200 			/* Aggressive link power magament enable */
201 #define	AHCI_CMD_STATUS_ALPE	(0x1 << 26)
202 #define	AHCI_CMD_STATUS_ASP	(0x1 << 27) /* Aggressive slumber/partial */
203 			/* Interface communication control */
204 #define	AHCI_CMD_STATUS_ICC	(0xf << 28)
205 #define	AHCI_CMD_STATUS_CCS_SHIFT	8
206 #define	AHCI_CMD_STATUS_ICC_SHIFT	28
207 
208 /* port task file data bits */
209 #define	AHCI_TFD_STS_MASK	0x000000ff
210 #define	AHCI_TFD_ERR_MASK	0x0000ff00
211 #define	AHCI_TFD_STS_BSY	(0x1 << 7)
212 #define	AHCI_TFD_STS_DRQ	(0x1 << 3)
213 #define	AHCI_TFD_STS_ERR	(0x1 << 0)
214 #define	AHCI_TFD_ERR_SHIFT	8
215 
216 /* port SATA status bit fields */
217 #define	AHCI_SSTATUS_DET_MASK		0x0000000f
218 #define	AHCI_SSTATUS_SPD_MASK		0x000000f0
219 #define	AHCI_SSTATUS_IPM_MASK		0x00000f00
220 #define	AHCI_SSTATUS_SPD_SHIFT		4
221 #define	AHCI_SSTATUS_IPM_SHIFT		8
222 
223 #define	AHCI_SSTATUS_GET_DET(x)		(x & AHCI_SSTATUS_DET_MASK)
224 
225 #define	AHCI_SSTATUS_SET_DET(x, new_val)	\
226 	(x = (x & ~AHCI_SSTATUS_DET_MASK) | (new_val & AHCI_SSTATUS_DET_MASK))
227 
228 #define	AHCI_SSTATUS_DET_NODEV_NOPHY	0x0 /* no device, no PHY */
229 #define	AHCI_SSTATUS_DET_DEVPRESENT_NOPHY 0x1 /* dev present, no PHY */
230 #define	AHCI_SSTATUS_DET_DEVPRESENT_PHYONLINE 0x3 /* dev present, PHY online */
231 #define	AHCI_SSTATUS_DET_PHYOFFLINE	0x4 /* PHY offline */
232 
233 #define	AHCI_SSTATUS_GET_IPM(x) 		\
234 	((x & AHCI_SSTATUS_IPM_MASK) >> AHCI_SSTATUS_IPM_SHIFT)
235 
236 #define	AHCI_SSTATUS_IPM_NODEV_NOPHY	0x0 /* no device, no PHY */
237 #define	AHCI_SSTATUS_IPM_INTERFACE_ACTIVE 0x1 /* interface active */
238 #define	AHCI_SSTATUS_IPM_INTERFACE_POWERPARTIAL 0x2 /* partial power mgmt */
239 #define	AHCI_SSTATUS_IPM_INTERFACE_POWERSLUMBER 0x6 /* slumber power mgmt */
240 
241 /* port SATA control bit fields */
242 #define	AHCI_SCONTROL_DET_MASK		0x0000000f
243 
244 #define	AHCI_SCONTROL_GET_DET(x)	(x & AHCI_SCONTROL_DET_MASK)
245 #define	AHCI_SCONTROL_SET_DET(x, new_val)	\
246 	(x = (x & ~AHCI_SCONTROL_DET_MASK) | (new_val & AHCI_SCONTROL_DET_MASK))
247 
248 #define	AHCI_SCONTROL_DET_NOACTION	0x0 /* no action requested */
249 #define	AHCI_SCONTROL_DET_COMRESET	0x1 /* send COMRESET */
250 #define	AHCI_SCONTROL_DET_PHYOFFLINE	0x4 /* put Phy in offline mode */
251 
252 /* port SATA error bit fields */
253 	/* Recovered Data Integrity Error */
254 #define	AHCI_SERROR_ERR_I	(0x1 << 0)
255 	/* Recovered Communications Error */
256 #define	AHCI_SERROR_ERR_M	(0x1 << 1)
257 	/* Transient Data Integrity Error */
258 #define	AHCI_SERROR_ERR_T	(0x1 << 8)
259 	/* Persistent Communication or Data Integrity Error */
260 #define	AHCI_SERROR_ERR_C	(0x1 << 9)
261 	/* Protocol Error */
262 #define	AHCI_SERROR_ERR_P	(0x1 << 10)
263 	/* Internal Error */
264 #define	AHCI_SERROR_ERR_E	(0x1 << 11)
265 	/* PhyRdy Change */
266 #define	AHCI_SERROR_DIAG_N	(0x1 << 16)
267 	/* Phy Internal Error */
268 #define	AHCI_SERROR_DIAG_I	(0x1 << 17)
269 	/* Comm Wake */
270 #define	AHCI_SERROR_DIAG_W	(0x1 << 18)
271 	/* 10B to 8B Decode Error */
272 #define	AHCI_SERROR_DIAG_B	(0x1 << 19)
273 	/* Disparity Error */
274 #define	AHCI_SERROR_DIAG_D	(0x1 << 20)
275 	/* CRC Error */
276 #define	AHCI_SERROR_DIAG_C	(0x1 << 21)
277 	/* Handshake Error */
278 #define	AHCI_SERROR_DIAG_H	(0x1 << 22)
279 	/* Link Sequence Error */
280 #define	AHCI_SERROR_DIAG_S	(0x1 << 23)
281 	/* Transport State Transion Error */
282 #define	AHCI_SERROR_DIAG_T	(0x1 << 24)
283 	/* Unknown FIS Type */
284 #define	AHCI_SERROR_DIAG_F	(0x1 << 25)
285 	/* Exchanged */
286 #define	AHCI_SERROR_DIAG_X	(0x1 << 26)
287 
288 #define	AHCI_SERROR_CLEAR_ALL			0xffffffff
289 
290 /* per port registers offset */
291 #define	AHCI_PORT_OFFSET(ahci_ctlp, port)			\
292 		(ahci_ctlp->ahcictl_ahci_addr + (0x100 + (port * 0x80)))
293 	/* Command List Base Address */
294 #define	AHCI_PORT_PxCLB(ahci_ctlp, port)			\
295 			(AHCI_PORT_OFFSET(ahci_ctlp, port) + 0x00)
296 	/* Command List Base Address Upper 32-Bits */
297 #define	AHCI_PORT_PxCLBU(ahci_ctlp, port)			\
298 			(AHCI_PORT_OFFSET(ahci_ctlp, port) + 0x04)
299 	/* FIS Base Address */
300 #define	AHCI_PORT_PxFB(ahci_ctlp, port)				\
301 			(AHCI_PORT_OFFSET(ahci_ctlp, port) + 0x08)
302 	/* FIS Base Address Upper 32-Bits */
303 #define	AHCI_PORT_PxFBU(ahci_ctlp, port)			\
304 			(AHCI_PORT_OFFSET(ahci_ctlp, port) + 0x0c)
305 	/* Interrupt Status */
306 #define	AHCI_PORT_PxIS(ahci_ctlp, port)				\
307 			(AHCI_PORT_OFFSET(ahci_ctlp, port) + 0x10)
308 	/* Interrupt Enable */
309 #define	AHCI_PORT_PxIE(ahci_ctlp, port)				\
310 			(AHCI_PORT_OFFSET(ahci_ctlp, port) + 0x14)
311 	/* Command and Status */
312 #define	AHCI_PORT_PxCMD(ahci_ctlp, port)			\
313 			(AHCI_PORT_OFFSET(ahci_ctlp, port) + 0x18)
314 	/* Task File Data */
315 #define	AHCI_PORT_PxTFD(ahci_ctlp, port)			\
316 			(AHCI_PORT_OFFSET(ahci_ctlp, port) + 0x20)
317 	/* Signature */
318 #define	AHCI_PORT_PxSIG(ahci_ctlp, port)			\
319 			(AHCI_PORT_OFFSET(ahci_ctlp, port) + 0x24)
320 	/* Serial ATA Status (SCR0:SStatus) */
321 #define	AHCI_PORT_PxSSTS(ahci_ctlp, port)			\
322 			(AHCI_PORT_OFFSET(ahci_ctlp, port) + 0x28)
323 	/* Serial ATA Control (SCR2:SControl) */
324 #define	AHCI_PORT_PxSCTL(ahci_ctlp, port)			\
325 			(AHCI_PORT_OFFSET(ahci_ctlp, port) + 0x2c)
326 	/* Serial ATA Error (SCR1:SError) */
327 #define	AHCI_PORT_PxSERR(ahci_ctlp, port)			\
328 			(AHCI_PORT_OFFSET(ahci_ctlp, port) + 0x30)
329 	/* Serial ATA Active (SCR3:SActive) */
330 #define	AHCI_PORT_PxSACT(ahci_ctlp, port)			\
331 			(AHCI_PORT_OFFSET(ahci_ctlp, port) + 0x34)
332 	/* Command Issue */
333 #define	AHCI_PORT_PxCI(ahci_ctlp, port)				\
334 			(AHCI_PORT_OFFSET(ahci_ctlp, port) + 0x38)
335 	/* SNotification */
336 #define	AHCI_PORT_PxSNTF(ahci_ctlp, port)			\
337 			(AHCI_PORT_OFFSET(ahci_ctlp, port) + 0x3c)
338 
339 #define	AHCI_SLOT_MASK(ahci_ctlp)				\
340 	((ahci_ctlp->ahcictl_num_cmd_slots == AHCI_PORT_MAX_CMD_SLOTS) ? \
341 	0xffffffff : ((0x1 << ahci_ctlp->ahcictl_num_cmd_slots) - 1))
342 
343 /* Device signatures */
344 #define	AHCI_SIGNATURE_PORT_MULTIPLIER	0x96690101
345 #define	AHCI_SIGNATURE_ATAPI		0xeb140101
346 #define	AHCI_SIGNATURE_DISK		0x00000101
347 
348 /*
349  * The address of the control port for the port multiplier, which is
350  * used for control and status communication with the port multiplier
351  * itself.
352  */
353 #define	AHCI_PORTMULT_CONTROL_PORT	0x0f
354 
355 #define	AHCI_H2D_REGISTER_FIS_TYPE	0x27
356 #define	AHCI_H2D_REGISTER_FIS_LENGTH	5
357 
358 #define	AHCI_CMDHEAD_ATAPI	0x1 /* set to 1 for ATAPI command */
359 #define	AHCI_CMDHEAD_DATA_WRITE	0x1 /* From system memory to device */
360 #define	AHCI_CMDHEAD_DATA_READ	0x0 /* From device to system memory */
361 #define	AHCI_CMDHEAD_PREFETCHABLE	0x1 /* if set, HBA prefetch PRDs */
362 
363 /* Register - Host to Device FIS (from SATA spec) */
364 typedef struct ahci_fis_h2d_register {
365 	/* offset 0x00 */
366 	uint32_t	ahcifhr_type_pmp_rsvd_cmddevctl_cmd_features;
367 
368 #define	SET_FIS_TYPE(fis, type)					\
369 	(fis->ahcifhr_type_pmp_rsvd_cmddevctl_cmd_features |= (type & 0xff))
370 
371 #define	SET_FIS_PMP(fis, pmp)					\
372 	(fis->ahcifhr_type_pmp_rsvd_cmddevctl_cmd_features |= 	\
373 		((pmp & 0xf) << 8))
374 
375 #define	SET_FIS_CDMDEVCTL(fis, cmddevctl)			\
376 	(fis->ahcifhr_type_pmp_rsvd_cmddevctl_cmd_features |=	\
377 		((cmddevctl & 0x1) << 15))
378 
379 #define	GET_FIS_COMMAND(fis)					\
380 	((fis->ahcifhr_type_pmp_rsvd_cmddevctl_cmd_features >> 16) & 0xff)
381 
382 #define	SET_FIS_COMMAND(fis, command)				\
383 	(fis->ahcifhr_type_pmp_rsvd_cmddevctl_cmd_features |=	\
384 		((command & 0xff) << 16))
385 
386 #define	GET_FIS_FEATURES(fis)					\
387 	((fis->ahcifhr_type_pmp_rsvd_cmddevctl_cmd_features >> 24) & 0xff)
388 
389 #define	SET_FIS_FEATURES(fis, features)				\
390 	(fis->ahcifhr_type_pmp_rsvd_cmddevctl_cmd_features |=	\
391 		((features & 0xff) << 24))
392 
393 	/* offset 0x04 */
394 	uint32_t	ahcifhr_sector_cyllow_cylhi_devhead;
395 
396 #define	GET_FIS_SECTOR(fis)					\
397 	(fis->ahcifhr_sector_cyllow_cylhi_devhead & 0xff)
398 
399 #define	SET_FIS_SECTOR(fis, sector)				\
400 	(fis->ahcifhr_sector_cyllow_cylhi_devhead |= ((sector & 0xff)))
401 
402 #define	GET_FIS_CYL_LOW(fis)					\
403 	((fis->ahcifhr_sector_cyllow_cylhi_devhead >> 8) & 0xff)
404 
405 #define	SET_FIS_CYL_LOW(fis, cyl_low)				\
406 	(fis->ahcifhr_sector_cyllow_cylhi_devhead |= ((cyl_low & 0xff) << 8))
407 
408 #define	GET_FIS_CYL_HI(fis)					\
409 	((fis->ahcifhr_sector_cyllow_cylhi_devhead >> 16) & 0xff)
410 
411 #define	SET_FIS_CYL_HI(fis, cyl_hi)				\
412 	(fis->ahcifhr_sector_cyllow_cylhi_devhead |= ((cyl_hi & 0xff) << 16))
413 
414 #define	GET_FIS_DEV_HEAD(fis)					\
415 	((fis->ahcifhr_sector_cyllow_cylhi_devhead >> 24) & 0xff)
416 
417 #define	SET_FIS_DEV_HEAD(fis, dev_head)				\
418 	(fis->ahcifhr_sector_cyllow_cylhi_devhead |= ((dev_head & 0xff) << 24))
419 
420 	/* offset 0x08 */
421 	uint32_t	ahcifhr_sectexp_cyllowexp_cylhiexp_featuresexp;
422 
423 #define	GET_FIS_SECTOR_EXP(fis)					\
424 	(fis->ahcifhr_sectexp_cyllowexp_cylhiexp_featuresexp  & 0xff)
425 
426 #define	SET_FIS_SECTOR_EXP(fis, sectorexp)			\
427 	(fis->ahcifhr_sectexp_cyllowexp_cylhiexp_featuresexp |=	\
428 		((sectorexp & 0xff)))
429 
430 #define	GET_FIS_CYL_LOW_EXP(fis)				\
431 	((fis->ahcifhr_sectexp_cyllowexp_cylhiexp_featuresexp >> 8) & 0xff)
432 
433 #define	SET_FIS_CYL_LOW_EXP(fis, cyllowexp)			\
434 	(fis->ahcifhr_sectexp_cyllowexp_cylhiexp_featuresexp |=	\
435 		((cyllowexp & 0xff) << 8))
436 
437 #define	GET_FIS_CYL_HI_EXP(fis)					\
438 	((fis->ahcifhr_sectexp_cyllowexp_cylhiexp_featuresexp >> 16) & 0xff)
439 
440 #define	SET_FIS_CYL_HI_EXP(fis, cylhiexp)			\
441 	(fis->ahcifhr_sectexp_cyllowexp_cylhiexp_featuresexp |=	\
442 		((cylhiexp & 0xff) << 16))
443 
444 #define	SET_FIS_FEATURES_EXP(fis, features_exp)			\
445 	(fis->ahcifhr_sectexp_cyllowexp_cylhiexp_featuresexp |=	\
446 		((features_exp & 0xff) << 24))
447 
448 	/* offset 0x0c */
449 	uint32_t	ahcifhr_sectcount_sectcountexp_rsvd_devctl;
450 
451 #define	GET_FIS_SECTOR_COUNT(fis)				\
452 	(fis->ahcifhr_sectcount_sectcountexp_rsvd_devctl & 0xff)
453 
454 #define	SET_FIS_SECTOR_COUNT(fis, sector_count)			\
455 	(fis->ahcifhr_sectcount_sectcountexp_rsvd_devctl |= 	\
456 		((sector_count & 0xff)))
457 
458 #define	GET_FIS_SECTOR_COUNT_EXP(fis)				\
459 	((fis->ahcifhr_sectcount_sectcountexp_rsvd_devctl >> 8) & 0xff)
460 
461 #define	SET_FIS_SECTOR_COUNT_EXP(fis, sector_count_exp)		\
462 	(fis->ahcifhr_sectcount_sectcountexp_rsvd_devctl |=	\
463 		((sector_count_exp & 0xff) << 8))
464 
465 #define	SET_FIS_DEVCTL(fis, devctl)				\
466 	(fis->ahcifhr_sectcount_sectcountexp_rsvd_devctl |= 	\
467 		((devctl & 0xff) << 24))
468 
469 	/* offset 0x10 */
470 	uint32_t	ahcifhr_rsvd3[1]; /* should be zero */
471 } ahci_fis_h2d_register_t;
472 
473 /* Register - Device to Host FIS (from SATA spec) */
474 typedef struct ahci_fis_d2h_register {
475 	/* offset 0x00 */
476 	uint32_t	ahcifdr_type_intr_rsvd_status_error;
477 
478 #define	GET_RFIS_STATUS(fis)					\
479 	((fis->ahcifdr_type_intr_rsvd_status_error >> 16) & 0xff)
480 
481 #define	GET_RFIS_ERROR(fis)					\
482 	((fis->ahcifdr_type_intr_rsvd_status_error >> 24) & 0xff)
483 
484 	/* offset 0x04 */
485 	uint32_t	ahcifdr_sector_cyllow_cylhi_devhead;
486 
487 #define	GET_RFIS_CYL_LOW(fis)					\
488 	(fis->ahcifdr_sector_cyllow_cylhi_devhead & 0xff)
489 
490 #define	GET_RFIS_CYL_MID(fis)					\
491 	((fis->ahcifdr_sector_cyllow_cylhi_devhead >> 8) & 0xff)
492 
493 #define	GET_RFIS_CYL_HI(fis)					\
494 	((fis->ahcifdr_sector_cyllow_cylhi_devhead >> 16) & 0xff)
495 
496 #define	GET_RFIS_DEV_HEAD(fis)					\
497 	((fis->ahcifdr_sector_cyllow_cylhi_devhead >> 24) & 0xff)
498 
499 	/* offset 0x08 */
500 	uint32_t	ahcifdr_sectexp_cyllowexp_cylhiexp_rsvd;
501 
502 #define	GET_RFIS_CYL_LOW_EXP(fis)					\
503 	(fis->ahcifdr_sectexp_cyllowexp_cylhiexp_rsvd  & 0xff)
504 
505 #define	GET_RFIS_CYL_MID_EXP(fis)				\
506 	((fis->ahcifdr_sectexp_cyllowexp_cylhiexp_rsvd >> 8) & 0xff)
507 
508 #define	GET_RFIS_CYL_HI_EXP(fis)					\
509 	((fis->ahcifdr_sectexp_cyllowexp_cylhiexp_rsvd >> 16) & 0xff)
510 
511 	/* offset 0x0c */
512 	uint32_t	ahcifdr_sectcount_sectcountexp_rsvd;
513 
514 #define	GET_RFIS_SECTOR_COUNT(fis)				\
515 	(fis->ahcifdr_sectcount_sectcountexp_rsvd & 0xff)
516 
517 #define	GET_RFIS_SECTOR_COUNT_EXP(fis)				\
518 	((fis->ahcifdr_sectcount_sectcountexp_rsvd >> 8) & 0xff)
519 
520 	/* offset 0x10 */
521 	uint32_t	ahcifdr_rsvd;
522 } ahci_fis_d2h_register_t;
523 
524 /* Set Device Bits - Device to Host FIS (from SATA spec) */
525 typedef struct ahci_fis_set_device_bits {
526 	/* offset 0x00 */
527 	uint32_t	ahcifsdb_type_rsvd_intr_status_error;
528 
529 #define	GET_N_BIT_OF_SET_DEV_BITS(fis)				\
530 	((fis->ahcifsdb_type_rsvd_intr_status_error >> 15) & 0x1)
531 
532 	/* offset 0x04 */
533 	uint32_t	ahcifsdb_rsvd;
534 } ahci_fis_set_device_bits_t;
535 
536 /* DMA Setup - Device to Host or Host to Device (from SATA spec) */
537 typedef struct ahci_fis_dma_setup {
538 	/* offset 0x00 */
539 	uint32_t	ahcifds_type_rsvd_direction_intr_rsvd;
540 
541 	/* offset 0x04 */
542 	uint32_t	ahcifds_dma_buffer_identifier_low;
543 
544 	/* offset 0x08 */
545 	uint32_t	ahcifds_dma_buffer_identifier_high;
546 
547 	/* offset 0x0c */
548 	uint32_t	ahcifds_rsvd1;
549 
550 	/* offset 0x10 */
551 	uint32_t	ahcifds_dma_buffer_offset;
552 
553 	/* offset 0x14 */
554 	uint32_t	ahcifds_dma_transfer_count;
555 
556 	/* offset 0x18 */
557 	uint32_t	ahcifds_rsvd2;
558 } ahci_fis_dma_setup_t;
559 
560 /* PIO Setup - Device to Host FIS (from SATA spec) */
561 typedef struct ahci_fis_pio_setup {
562 	/* offset 0x00 */
563 	uint32_t	ahcifps_type_rsvd_direction_intr_status_error;
564 
565 	/* offset 0x04 */
566 	uint32_t	ahcifps_sector_cyllow_cylhi_devhead;
567 
568 	/* offset 0x08 */
569 	uint32_t	ahcifps_sectexp_cyllowexp_cylhiexp_rsvd;
570 
571 	/* offset 0x0c */
572 	uint32_t	ahcifps_sectcount_sectcountexp_rsvd_e_status;
573 
574 	/* offset 0x10 */
575 	uint32_t	ahcifps_transfer_count_rsvd;
576 } ahci_fis_pio_setup_t;
577 
578 /* BIST Active - Host to Device or Device to Host (from SATA spec) */
579 typedef struct ahci_fis_bist_active {
580 	/* offset 0x00 */
581 	uint32_t	ahcifba_type_rsvd_pattern_rsvd;
582 
583 	/* offset 0x04 */
584 	uint32_t	ahcifba_data1;
585 
586 	/* offset 0x08 */
587 	uint32_t	ahcifba_data2;
588 } ahci_fis_bist_active_t;
589 
590 /* Up to 64 bytes */
591 typedef struct ahci_fis_unknown {
592 	uint32_t	ahcifu_first_dword;
593 	uint32_t	ahcifu_dword[15];
594 } ahci_fis_unknown_t;
595 
596 /*
597  * This is a software constructed FIS. For data transfer,
598  * this is the H2D Register FIS format as specified in
599  * the Serial ATA 1.0a specification. Valid Command FIS
600  * length are 2 to 16 Dwords.
601  */
602 typedef struct ahci_fis_command {
603 	union {
604 		ahci_fis_h2d_register_t	ahcifc_h2d_register;
605 		ahci_fis_bist_active_t	ahcifc_bist_active;
606 	} ahcifc_fis;
607 	uint32_t	ahcifc_rsvd3[11]; /* should be zero */
608 } ahci_fis_command_t;
609 
610 /* Received FISes structure - size 100h */
611 typedef struct ahci_rcvd_fis {
612 	/* offset 0x00 - DMA Setup FIS */
613 	ahci_fis_dma_setup_t		ahcirf_dma_setup_fis;
614 	uint32_t			ahcirf_fis_rsvd1;
615 
616 	/* offset 0x20 - PIO Setup FIS */
617 	ahci_fis_pio_setup_t		ahcirf_pio_setup_fis;
618 	uint32_t			ahcirf_fis_rsvd2[3];
619 
620 	/* offset 0x40 - D2H Register FIS */
621 	ahci_fis_d2h_register_t		ahcirf_d2h_register_fis;
622 	uint32_t			ahcirf_fis_rsvd3;
623 
624 	/* offset 0x58 - Set Device Bits FIS */
625 	ahci_fis_set_device_bits_t	ahcirf_set_device_bits_fis;
626 
627 	/* offset 0x60 - Unknown FIS */
628 	ahci_fis_unknown_t		ahcirf_unknown_fis;
629 
630 	/* offset 0xa0h - Reserved */
631 	uint32_t			ahcirf_fis_rsvd4[15];
632 } ahci_rcvd_fis_t;
633 
634 /* physical region description table (PRDT) item structure */
635 typedef struct ahci_prdt_item {
636 	/* DW 0 - Data Base Address */
637 	uint32_t	ahcipi_data_base_addr;
638 
639 	/* DW 1 - Data Base Address Upper */
640 	uint32_t	ahcipi_data_base_addr_upper;
641 
642 	/* DW 2 - Reserved */
643 	uint32_t	ahcipi_rsvd;
644 
645 	/* DW 3 - Description Information */
646 	uint32_t	ahcipi_descr_info;
647 
648 #define	GET_PRDT_ITEM_INTR_ON_COMPLETION(prdt_item)	\
649 		((prdt_item.ahcipi_descr_info >> 31) & 0x01)
650 
651 #define	GET_PRDT_ITEM_DATA_BYTE_COUNT(prdt_item)	\
652 		(prdt_item.ahcipi_descr_info & 0x3fffff)
653 
654 } ahci_prdt_item_t;
655 
656 /* command table structure */
657 typedef struct ahci_cmd_table {
658 	/* offset 0x00 - Command FIS */
659 	ahci_fis_command_t	ahcict_command_fis;
660 
661 	/* offset 0x40 - ATAPI Command */
662 	uint8_t			ahcict_atapi_cmd[SATA_ATAPI_MAX_CDB_LEN];
663 
664 	/* offset 0x50 - Reserved */
665 	uint32_t		ahcict_rsvd[12];
666 
667 	/* offset 0x80 - Physical Region Description Table */
668 	ahci_prdt_item_t	ahcict_prdt[AHCI_PRDT_NUMBER];
669 } ahci_cmd_table_t;
670 
671 /* command head structure - size 20h */
672 typedef struct ahci_cmd_header {
673 	/* DW 0 - Description Information */
674 	uint32_t	ahcich_descr_info;
675 
676 #define	BZERO_DESCR_INFO(cmd_header)				\
677 	(cmd_header->ahcich_descr_info = 0)
678 
679 #define	GET_PRD_TABLE_LENGTH(cmd_header)			\
680 		((cmd_header->ahcich_descr_info >> 16) & 0xffff)
681 
682 #define	SET_PRD_TABLE_LENGTH(cmd_header, length)		\
683 	(cmd_header->ahcich_descr_info |= ((length & 0xffff) << 16))
684 
685 #define	GET_PORT_MULTI_PORT(cmd_header)				\
686 		((cmd_header->ahcich_descr_info >> 12) & 0x0f)
687 
688 #define	SET_PORT_MULTI_PORT(cmd_header, flags)			\
689 	(cmd_header->ahcich_descr_info |= ((flags & 0x0f) << 12))
690 
691 #define	GET_CLEAR_BUSY_UPON_R_OK(cmd_header)			\
692 		((cmd_header->ahcich_descr_info >> 10) & 0x01)
693 
694 #define	SET_CLEAR_BUSY_UPON_R_OK(cmd_header, flags)		\
695 	(cmd_header->ahcich_descr_info |= ((flags & 0x01) << 10))
696 
697 #define	GET_BIST(cmd_header)					\
698 		((cmd_header->ahcich_descr_info >> 9) & 0x01)
699 
700 #define	GET_RESET(cmd_header)					\
701 		((cmd_header->ahcich_descr_info >> 8) & 0x01)
702 
703 #define	SET_RESET(cmd_header, features_exp)			\
704 	(cmd_header->ahcich_descr_info |= ((features_exp & 0x01) << 8))
705 
706 #define	GET_PREFETCHABLE(cmd_header)				\
707 		((cmd_header->ahcich_descr_info >> 7) & 0x01)
708 
709 #define	SET_PREFETCHABLE(cmd_header, flags)			\
710 	(cmd_header->ahcich_descr_info |= ((flags & 0x01) << 7))
711 
712 #define	GET_WRITE(cmd_header)					\
713 		((cmd_header->ahcich_descr_info >> 6) & 0x01)
714 
715 #define	SET_WRITE(cmd_header, flags)				\
716 	(cmd_header->ahcich_descr_info |= ((flags & 0x01) << 6))
717 
718 #define	GET_ATAPI(cmd_header)					\
719 		((cmd_header->ahcich_descr_info >> 5) & 0x01)
720 
721 #define	SET_ATAPI(cmd_header, flags)				\
722 	(cmd_header->ahcich_descr_info |= ((flags & 0x01) << 5))
723 
724 #define	GET_COMMAND_FIS_LENGTH(cmd_header)			\
725 		(cmd_header->ahcich_descr_info && 0x1f)
726 
727 #define	SET_COMMAND_FIS_LENGTH(cmd_header, length)		\
728 	(cmd_header->ahcich_descr_info |= (length & 0x1f))
729 
730 	/* DW 1 - Physical Region Descriptor Byte Count */
731 	uint32_t	ahcich_prd_byte_count;
732 
733 #define	BZERO_PRD_BYTE_COUNT(cmd_header)			\
734 	(cmd_header->ahcich_prd_byte_count = 0)
735 
736 #define	SET_PRD_BYTE_COUNT(cmd_header, count)			\
737 	(cmd_header->ahcich_prd_byte_count = count)
738 
739 	/* DW 2 - Command Table Base Address */
740 	uint32_t	ahcich_cmd_tab_base_addr;
741 
742 #define	SET_COMMAND_TABLE_BASE_ADDR(cmd_header, base_address)	\
743 	(cmd_header->ahcich_cmd_tab_base_addr = base_address)
744 
745 	/* DW 3 - Command Table Base Address Upper */
746 	uint32_t	ahcich_cmd_tab_base_addr_upper;
747 
748 #define	SET_COMMAND_TABLE_BASE_ADDR_UPPER(cmd_header, base_address) \
749 	(cmd_header->ahcich_cmd_tab_base_addr_upper = base_address)
750 
751 	/* DW 4-7 - Reserved */
752 	uint32_t	ahcich_rsvd[4];
753 } ahci_cmd_header_t;
754 
755 
756 #ifdef	__cplusplus
757 }
758 #endif
759 
760 #endif /* _AHCIREG_H */
761