ahcireg.h revision 3333:88329a0ff1be
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 2006 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
34extern "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#define	AHCI_SIGNATURE_NONE		0xffffffff
348
349
350/*
351 * The address of the control port for the port multiplier, which is
352 * used for control and status communication with the port multiplier
353 * itself.
354 */
355#define	AHCI_PORTMULT_CONTROL_PORT	0x0f
356
357#define	AHCI_H2D_REGISTER_FIS_TYPE	0x27
358#define	AHCI_H2D_REGISTER_FIS_LENGTH	5
359
360#define	AHCI_CMDHEAD_DATA_WRITE	0x1 /* From system memory to device */
361#define	AHCI_CMDHEAD_DATA_READ	0x0 /* From device to system memory */
362#define	AHCI_CMDHEAD_PREFETCHABLE	0x1 /* if set, HBA prefetch PRDs */
363
364/* Register - Host to Device FIS (from SATA spec) */
365typedef struct ahci_fis_h2d_register {
366	/* offset 0x00 */
367	uint32_t	ahcifhr_type_pmp_rsvd_cmddevctl_cmd_features;
368
369#define	SET_FIS_TYPE(fis, type)					\
370	(fis->ahcifhr_type_pmp_rsvd_cmddevctl_cmd_features |= (type & 0xff))
371
372#define	SET_FIS_PMP(fis, pmp)					\
373	(fis->ahcifhr_type_pmp_rsvd_cmddevctl_cmd_features |= 	\
374		((pmp & 0xf) << 8))
375
376#define	SET_FIS_CDMDEVCTL(fis, cmddevctl)			\
377	(fis->ahcifhr_type_pmp_rsvd_cmddevctl_cmd_features |=	\
378		((cmddevctl & 0x1) << 15))
379
380#define	GET_FIS_COMMAND(fis)					\
381	((fis->ahcifhr_type_pmp_rsvd_cmddevctl_cmd_features >> 16) & 0xff)
382
383#define	SET_FIS_COMMAND(fis, command)				\
384	(fis->ahcifhr_type_pmp_rsvd_cmddevctl_cmd_features |=	\
385		((command & 0xff) << 16))
386
387#define	GET_FIS_FEATURES(fis)					\
388	((fis->ahcifhr_type_pmp_rsvd_cmddevctl_cmd_features >> 24) & 0xff)
389
390#define	SET_FIS_FEATURES(fis, features)				\
391	(fis->ahcifhr_type_pmp_rsvd_cmddevctl_cmd_features |=	\
392		((features & 0xff) << 24))
393
394	/* offset 0x04 */
395	uint32_t	ahcifhr_sector_cyllow_cylhi_devhead;
396
397#define	GET_FIS_SECTOR(fis)					\
398	(fis->ahcifhr_sector_cyllow_cylhi_devhead & 0xff)
399
400#define	SET_FIS_SECTOR(fis, sector)				\
401	(fis->ahcifhr_sector_cyllow_cylhi_devhead |= ((sector & 0xff)))
402
403#define	GET_FIS_CYL_LOW(fis)					\
404	((fis->ahcifhr_sector_cyllow_cylhi_devhead >> 8) & 0xff)
405
406#define	SET_FIS_CYL_LOW(fis, cyl_low)				\
407	(fis->ahcifhr_sector_cyllow_cylhi_devhead |= ((cyl_low & 0xff) << 8))
408
409#define	GET_FIS_CYL_HI(fis)					\
410	((fis->ahcifhr_sector_cyllow_cylhi_devhead >> 16) & 0xff)
411
412#define	SET_FIS_CYL_HI(fis, cyl_hi)				\
413	(fis->ahcifhr_sector_cyllow_cylhi_devhead |= ((cyl_hi & 0xff) << 16))
414
415#define	GET_FIS_DEV_HEAD(fis)					\
416	((fis->ahcifhr_sector_cyllow_cylhi_devhead >> 24) & 0xff)
417
418#define	SET_FIS_DEV_HEAD(fis, dev_head)				\
419	(fis->ahcifhr_sector_cyllow_cylhi_devhead |= ((dev_head & 0xff) << 24))
420
421	/* offset 0x08 */
422	uint32_t	ahcifhr_sectexp_cyllowexp_cylhiexp_featuresexp;
423
424#define	GET_FIS_SECTOR_EXP(fis)					\
425	(fis->ahcifhr_sectexp_cyllowexp_cylhiexp_featuresexp  & 0xff)
426
427#define	SET_FIS_SECTOR_EXP(fis, sectorexp)			\
428	(fis->ahcifhr_sectexp_cyllowexp_cylhiexp_featuresexp |=	\
429		((sectorexp & 0xff)))
430
431#define	GET_FIS_CYL_LOW_EXP(fis)				\
432	((fis->ahcifhr_sectexp_cyllowexp_cylhiexp_featuresexp >> 8) & 0xff)
433
434#define	SET_FIS_CYL_LOW_EXP(fis, cyllowexp)			\
435	(fis->ahcifhr_sectexp_cyllowexp_cylhiexp_featuresexp |=	\
436		((cyllowexp & 0xff) << 8))
437
438#define	GET_FIS_CYL_HI_EXP(fis)					\
439	((fis->ahcifhr_sectexp_cyllowexp_cylhiexp_featuresexp >> 16) & 0xff)
440
441#define	SET_FIS_CYL_HI_EXP(fis, cylhiexp)			\
442	(fis->ahcifhr_sectexp_cyllowexp_cylhiexp_featuresexp |=	\
443		((cylhiexp & 0xff) << 16))
444
445#define	SET_FIS_FEATURES_EXP(fis, features_exp)			\
446	(fis->ahcifhr_sectexp_cyllowexp_cylhiexp_featuresexp |=	\
447		((features_exp & 0xff) << 24))
448
449	/* offset 0x0c */
450	uint32_t	ahcifhr_sectcount_sectcountexp_rsvd_devctl;
451
452#define	GET_FIS_SECTOR_COUNT(fis)				\
453	(fis->ahcifhr_sectcount_sectcountexp_rsvd_devctl & 0xff)
454
455#define	SET_FIS_SECTOR_COUNT(fis, sector_count)			\
456	(fis->ahcifhr_sectcount_sectcountexp_rsvd_devctl |= 	\
457		((sector_count & 0xff)))
458
459#define	GET_FIS_SECTOR_COUNT_EXP(fis)				\
460	((fis->ahcifhr_sectcount_sectcountexp_rsvd_devctl >> 8) & 0xff)
461
462#define	SET_FIS_SECTOR_COUNT_EXP(fis, sector_count_exp)		\
463	(fis->ahcifhr_sectcount_sectcountexp_rsvd_devctl |=	\
464		((sector_count_exp & 0xff) << 8))
465
466#define	SET_FIS_DEVCTL(fis, devctl)				\
467	(fis->ahcifhr_sectcount_sectcountexp_rsvd_devctl |= 	\
468		((devctl & 0xff) << 24))
469
470	/* offset 0x10 */
471	uint32_t	ahcifhr_rsvd3[1]; /* should be zero */
472} ahci_fis_h2d_register_t;
473
474/* Register - Device to Host FIS (from SATA spec) */
475typedef struct ahci_fis_d2h_register {
476	/* offset 0x00 */
477	uint32_t	ahcifdr_type_intr_rsvd_status_error;
478
479#define	GET_RFIS_STATUS(fis)					\
480	((fis->ahcifdr_type_intr_rsvd_status_error >> 16) & 0xff)
481
482#define	GET_RFIS_ERROR(fis)					\
483	((fis->ahcifdr_type_intr_rsvd_status_error >> 24) & 0xff)
484
485	/* offset 0x04 */
486	uint32_t	ahcifdr_sector_cyllow_cylhi_devhead;
487
488#define	GET_RFIS_CYL_LOW(fis)					\
489	(fis->ahcifdr_sector_cyllow_cylhi_devhead & 0xff)
490
491#define	GET_RFIS_CYL_MID(fis)					\
492	((fis->ahcifdr_sector_cyllow_cylhi_devhead >> 8) & 0xff)
493
494#define	GET_RFIS_CYL_HI(fis)					\
495	((fis->ahcifdr_sector_cyllow_cylhi_devhead >> 16) & 0xff)
496
497#define	GET_RFIS_DEV_HEAD(fis)					\
498	((fis->ahcifdr_sector_cyllow_cylhi_devhead >> 24) & 0xff)
499
500	/* offset 0x08 */
501	uint32_t	ahcifdr_sectexp_cyllowexp_cylhiexp_rsvd;
502
503#define	GET_RFIS_CYL_LOW_EXP(fis)					\
504	(fis->ahcifdr_sectexp_cyllowexp_cylhiexp_rsvd  & 0xff)
505
506#define	GET_RFIS_CYL_MID_EXP(fis)				\
507	((fis->ahcifdr_sectexp_cyllowexp_cylhiexp_rsvd >> 8) & 0xff)
508
509#define	GET_RFIS_CYL_HI_EXP(fis)					\
510	((fis->ahcifdr_sectexp_cyllowexp_cylhiexp_rsvd >> 16) & 0xff)
511
512	/* offset 0x0c */
513	uint32_t	ahcifdr_sectcount_sectcountexp_rsvd;
514
515#define	GET_RFIS_SECTOR_COUNT(fis)				\
516	(fis->ahcifdr_sectcount_sectcountexp_rsvd & 0xff)
517
518#define	GET_RFIS_SECTOR_COUNT_EXP(fis)				\
519	((fis->ahcifdr_sectcount_sectcountexp_rsvd >> 8) & 0xff)
520
521	/* offset 0x10 */
522	uint32_t	ahcifdr_rsvd;
523} ahci_fis_d2h_register_t;
524
525/* Set Device Bits - Device to Host FIS (from SATA spec) */
526typedef struct ahci_fis_set_device_bits {
527	/* offset 0x00 */
528	uint32_t	ahcifsdb_type_rsvd_intr_status_error;
529
530	/* offset 0x04 */
531	uint32_t	ahcifsdb_rsvd;
532} ahci_fis_set_device_bits_t;
533
534/* DMA Setup - Device to Host or Host to Device (from SATA spec) */
535typedef struct ahci_fis_dma_setup {
536	/* offset 0x00 */
537	uint32_t	ahcifds_type_rsvd_direction_intr_rsvd;
538
539	/* offset 0x04 */
540	uint32_t	ahcifds_dma_buffer_identifier_low;
541
542	/* offset 0x08 */
543	uint32_t	ahcifds_dma_buffer_identifier_high;
544
545	/* offset 0x0c */
546	uint32_t	ahcifds_rsvd1;
547
548	/* offset 0x10 */
549	uint32_t	ahcifds_dma_buffer_offset;
550
551	/* offset 0x14 */
552	uint32_t	ahcifds_dma_transfer_count;
553
554	/* offset 0x18 */
555	uint32_t	ahcifds_rsvd2;
556} ahci_fis_dma_setup_t;
557
558/* PIO Setup - Device to Host FIS (from SATA spec) */
559typedef struct ahci_fis_pio_setup {
560	/* offset 0x00 */
561	uint32_t	ahcifps_type_rsvd_direction_intr_status_error;
562
563	/* offset 0x04 */
564	uint32_t	ahcifps_sector_cyllow_cylhi_devhead;
565
566	/* offset 0x08 */
567	uint32_t	ahcifps_sectexp_cyllowexp_cylhiexp_rsvd;
568
569	/* offset 0x0c */
570	uint32_t	ahcifps_sectcount_sectcountexp_rsvd_e_status;
571
572	/* offset 0x10 */
573	uint32_t	ahcifps_transfer_count_rsvd;
574} ahci_fis_pio_setup_t;
575
576/* BIST Active - Host to Device or Device to Host (from SATA spec) */
577typedef struct ahci_fis_bist_active {
578	/* offset 0x00 */
579	uint32_t	ahcifba_type_rsvd_pattern_rsvd;
580
581	/* offset 0x04 */
582	uint32_t	ahcifba_data1;
583
584	/* offset 0x08 */
585	uint32_t	ahcifba_data2;
586} ahci_fis_bist_active_t;
587
588/* Up to 64 bytes */
589typedef struct ahci_fis_unknown {
590	uint32_t	ahcifu_first_dword;
591	uint32_t	ahcifu_dword[15];
592} ahci_fis_unknown_t;
593
594/*
595 * This is a software constructed FIS. For data transfer,
596 * this is the H2D Register FIS format as specified in
597 * the Serial ATA 1.0a specification. Valid Command FIS
598 * length are 2 to 16 Dwords.
599 */
600typedef struct ahci_fis_command {
601	union {
602		ahci_fis_h2d_register_t	ahcifc_h2d_register;
603		ahci_fis_bist_active_t	ahcifc_bist_active;
604	} ahcifc_fis;
605	uint32_t	ahcifc_rsvd3[11]; /* should be zero */
606} ahci_fis_command_t;
607
608/* Received FISes structure - size 100h */
609typedef struct ahci_rcvd_fis {
610	/* offset 0x00 - DMA Setup FIS */
611	ahci_fis_dma_setup_t		ahcirf_dma_setup_fis;
612	uint32_t			ahcirf_fis_rsvd1;
613
614	/* offset 0x20 - PIO Setup FIS */
615	ahci_fis_pio_setup_t		ahcirf_pio_setup_fis;
616	uint32_t			ahcirf_fis_rsvd2[3];
617
618	/* offset 0x40 - D2H Register FIS */
619	ahci_fis_d2h_register_t		ahcirf_d2h_register_fis;
620	uint32_t			ahcirf_fis_rsvd3;
621
622	/* offset 0x58 - Set Device Bits FIS */
623	ahci_fis_set_device_bits_t	ahcirf_set_device_bits_fis;
624
625	/* offset 0x60 - Unknown FIS */
626	ahci_fis_unknown_t		ahcirf_unknown_fis;
627
628	/* offset 0xa0h - Reserved */
629	uint32_t			ahcirf_fis_rsvd4[15];
630} ahci_rcvd_fis_t;
631
632/*
633 * XXX to be supported in second phase
634 *
635 * ATAPI command structure - 12 or 16 bytes
636 */
637typedef struct atapi_cmd {
638	uint32_t	atapi_cmd_head;
639	uint32_t	atapi_pad[3];
640} atapi_cmd_t;
641
642/* physical region description table (PRDT) item structure */
643typedef struct ahci_prdt_item {
644	/* DW 0 - Data Base Address */
645	uint32_t	ahcipi_data_base_addr;
646
647	/* DW 1 - Data Base Address Upper */
648	uint32_t	ahcipi_data_base_addr_upper;
649
650	/* DW 2 - Reserved */
651	uint32_t	ahcipi_rsvd;
652
653	/* DW 3 - Description Information */
654	uint32_t	ahcipi_descr_info;
655
656#define	GET_PRDT_ITEM_INTR_ON_COMPLETION(prdt_item)	\
657		((prdt_item.ahcipi_descr_info >> 31) & 0x01)
658
659#define	GET_PRDT_ITEM_DATA_BYTE_COUNT(prdt_item)	\
660		(prdt_item.ahcipi_descr_info & 0x3fffff)
661
662} ahci_prdt_item_t;
663
664/* command table structure */
665typedef struct ahci_cmd_table {
666	/* offset 0x00 - Command FIS */
667	ahci_fis_command_t	ahcict_command_fis;
668
669	/* offset 0x40 - ATAPI Command */
670	atapi_cmd_t		ahcict_atapi_cmd;
671
672	/* offset 0x50 - Reserved */
673	uint32_t		ahcict_rsvd[12];
674
675	/* offset 0x80 - Physical Region Description Table */
676	ahci_prdt_item_t	ahcict_prdt[AHCI_PRDT_NUMBER];
677} ahci_cmd_table_t;
678
679/* command head structure - size 20h */
680typedef struct ahci_cmd_header {
681	/* DW 0 - Description Information */
682	uint32_t	ahcich_descr_info;
683
684#define	BZERO_DESCR_INFO(cmd_header)				\
685	(cmd_header->ahcich_descr_info = 0)
686
687#define	GET_PRD_TABLE_LENGTH(cmd_header)			\
688		((cmd_header->ahcich_descr_info >> 16) & 0xffff)
689
690#define	SET_PRD_TABLE_LENGTH(cmd_header, length)		\
691	(cmd_header->ahcich_descr_info |= ((length & 0xffff) << 16))
692
693#define	GET_PORT_MULTI_PORT(cmd_header)				\
694		((cmd_header->ahcich_descr_info >> 12) & 0x0f)
695
696#define	SET_PORT_MULTI_PORT(cmd_header, flags)			\
697	(cmd_header->ahcich_descr_info |= ((flags & 0x0f) << 12))
698
699#define	GET_CLEAR_BUSY_UPON_R_OK(cmd_header)			\
700		((cmd_header->ahcich_descr_info >> 10) & 0x01)
701
702#define	SET_CLEAR_BUSY_UPON_R_OK(cmd_header, flags)		\
703	(cmd_header->ahcich_descr_info |= ((flags & 0x01) << 10))
704
705#define	GET_BIST(cmd_header)					\
706		((cmd_header->ahcich_descr_info >> 9) & 0x01)
707
708#define	GET_RESET(cmd_header)					\
709		((cmd_header->ahcich_descr_info >> 8) & 0x01)
710
711#define	SET_RESET(cmd_header, features_exp)			\
712	(cmd_header->ahcich_descr_info |= ((features_exp & 0x01) << 8))
713
714#define	GET_PREFETCHABLE(cmd_header)				\
715		((cmd_header->ahcich_descr_info >> 7) & 0x01)
716
717#define	SET_PREFETCHABLE(cmd_header, flags)			\
718	(cmd_header->ahcich_descr_info |= ((flags & 0x01) << 7))
719
720#define	GET_WRITE(cmd_header)					\
721		((cmd_header->ahcich_descr_info >> 6) & 0x01)
722
723#define	SET_WRITE(cmd_header, flags)				\
724	(cmd_header->ahcich_descr_info |= ((flags & 0x01) << 6))
725
726#define	GET_ATAPI(cmd_header)					\
727		((cmd_header->ahcich_descr_info >> 5) & 0x01)
728
729#define	SET_ATAPI(cmd_header, flags)				\
730	(cmd_header->ahcich_descr_info |= ((flags & 0x01) << 5))
731
732#define	GET_COMMAND_FIS_LENGTH(cmd_header)			\
733		(cmd_header->ahcich_descr_info && 0x1f)
734
735#define	SET_COMMAND_FIS_LENGTH(cmd_header, length)		\
736	(cmd_header->ahcich_descr_info |= (length & 0x1f))
737
738	/* DW 1 - Physical Region Descriptor Byte Count */
739	uint32_t	ahcich_prd_byte_count;
740
741#define	BZERO_PRD_BYTE_COUNT(cmd_header)			\
742	(cmd_header->ahcich_prd_byte_count = 0)
743
744#define	SET_PRD_BYTE_COUNT(cmd_header, count)			\
745	(cmd_header->ahcich_prd_byte_count = count)
746
747	/* DW 2 - Command Table Base Address */
748	uint32_t	ahcich_cmd_tab_base_addr;
749
750#define	SET_COMMAND_TABLE_BASE_ADDR(cmd_header, base_address)	\
751	(cmd_header->ahcich_cmd_tab_base_addr = base_address)
752
753	/* DW 3 - Command Table Base Address Upper */
754	uint32_t	ahcich_cmd_tab_base_addr_upper;
755
756#define	SET_COMMAND_TABLE_BASE_ADDR_UPPER(cmd_header, base_address) \
757	(cmd_header->ahcich_cmd_tab_base_addr_upper = base_address)
758
759	/* DW 4-7 - Reserved */
760	uint32_t	ahcich_rsvd[4];
761} ahci_cmd_header_t;
762
763
764#ifdef	__cplusplus
765}
766#endif
767
768#endif /* _AHCIREG_H */
769