12fcbc377Syt /*
22fcbc377Syt  * CDDL HEADER START
32fcbc377Syt  *
42fcbc377Syt  * The contents of this file are subject to the terms of the
52fcbc377Syt  * Common Development and Distribution License (the "License").
62fcbc377Syt  * You may not use this file except in compliance with the License.
72fcbc377Syt  *
82fcbc377Syt  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
92fcbc377Syt  * or http://www.opensolaris.org/os/licensing.
102fcbc377Syt  * See the License for the specific language governing permissions
112fcbc377Syt  * and limitations under the License.
122fcbc377Syt  *
132fcbc377Syt  * When distributing Covered Code, include this CDDL HEADER in each
142fcbc377Syt  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
152fcbc377Syt  * If applicable, add the following below this CDDL HEADER, with the
162fcbc377Syt  * fields enclosed by brackets "[]" replaced with your own identifying
172fcbc377Syt  * information: Portions Copyright [yyyy] [name of copyright owner]
182fcbc377Syt  *
192fcbc377Syt  * CDDL HEADER END
202fcbc377Syt  */
212fcbc377Syt 
222fcbc377Syt /*
230a4c4cecSXiao-Yu Zhang  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
242fcbc377Syt  * Use is subject to license terms.
252fcbc377Syt  */
262ac30289SMarcel Telka /*
272ac30289SMarcel Telka  * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
28*33b27906SGarrett D'Amore  * Copyright 2021 RackTop Systems, Inc.
292ac30289SMarcel Telka  */
302fcbc377Syt 
312fcbc377Syt #ifndef _AHCIREG_H
322fcbc377Syt #define	_AHCIREG_H
332fcbc377Syt 
342fcbc377Syt #ifdef	__cplusplus
352fcbc377Syt extern "C" {
362fcbc377Syt #endif
372fcbc377Syt 
382fcbc377Syt #define	AHCI_MAX_PORTS		32
392fcbc377Syt #define	AHCI_PORT_MAX_CMD_SLOTS	32
402fcbc377Syt 
412fcbc377Syt #define	VIA_VENID		0x1106
422fcbc377Syt 
432fcbc377Syt /*
442fcbc377Syt  * In AHCI spec, command table contains a list of 0 (no data transfer)
452fcbc377Syt  * to up to 65,535 scatter/gather entries for the data transfer.
462fcbc377Syt  */
472fcbc377Syt #define	AHCI_MAX_PRDT_NUMBER	65535
482fcbc377Syt #define	AHCI_MIN_PRDT_NUMBER	1
492fcbc377Syt 
502fcbc377Syt /*
512fcbc377Syt  * The default value of s/g entrie is 257, at least 1MB (4KB/pg * 256) + 1
522fcbc377Syt  * if misaligned, and it's tuable by setting ahci_dma_prdt_number in
532fcbc377Syt  * /etc/system file.
542fcbc377Syt  */
552fcbc377Syt #define	AHCI_PRDT_NUMBER	257
562fcbc377Syt 
5795c11c1fSyt /* PCI header offset for AHCI Base Address */
5895c11c1fSyt #define	AHCI_PCI_RNUM		0x24
592fcbc377Syt 
602fcbc377Syt /* various global HBA capability bits */
612fcbc377Syt #define	AHCI_HBA_CAP_NP		(0x1f << 0) /* number of ports */
622fcbc377Syt #define	AHCI_HBA_CAP_SXS	(0x1 << 5) /* external SATA */
632fcbc377Syt #define	AHCI_HBA_CAP_EMS	(0x1 << 6) /* enclosure management */
642fcbc377Syt #define	AHCI_HBA_CAP_CCCS	(0x1 << 7) /* command completed coalescing */
652fcbc377Syt #define	AHCI_HBA_CAP_NCS	(0x1f << 8) /* number of command slots */
662fcbc377Syt #define	AHCI_HBA_CAP_PSC	(0x1 << 13) /* partial state capable */
672fcbc377Syt #define	AHCI_HBA_CAP_SSC	(0x1 << 14) /* slumber state capable */
682fcbc377Syt #define	AHCI_HBA_CAP_PMD	(0x1 << 15) /* PIO multiple DRQ block */
692fcbc377Syt #define	AHCI_HBA_CAP_FBSS	(0x1 << 16) /* FIS-based switching */
702fcbc377Syt #define	AHCI_HBA_CAP_SPM	(0x1 << 17) /* port multiplier */
712fcbc377Syt #define	AHCI_HBA_CAP_SAM	(0x1 << 18) /* AHCI mode only */
722fcbc377Syt #define	AHCI_HBA_CAP_ISS	(0xf << 20) /* interface speed support */
732fcbc377Syt #define	AHCI_HBA_CAP_SCLO	(0x1 << 24) /* command list override */
742fcbc377Syt #define	AHCI_HBA_CAP_SAL	(0x1 << 25) /* activity LED */
752fcbc377Syt #define	AHCI_HBA_CAP_SALP	(0x1 << 26) /* aggressive link power mgmt */
762fcbc377Syt #define	AHCI_HBA_CAP_SSS	(0x1 << 27) /* staggered  spin-up */
772fcbc377Syt #define	AHCI_HBA_CAP_SMPS	(0x1 << 28) /* mechanical presence switch */
782fcbc377Syt #define	AHCI_HBA_CAP_SSNTF	(0x1 << 29) /* Snotification register */
792fcbc377Syt #define	AHCI_HBA_CAP_SNCQ	(0x1 << 30) /* Native Command Queuing */
802fcbc377Syt #define	AHCI_HBA_CAP_S64A	((uint32_t)0x1 << 31) /* 64-bit addressing */
812fcbc377Syt #define	AHCI_HBA_CAP_NCS_SHIFT	8  /* Number of command slots */
822fcbc377Syt #define	AHCI_HBA_CAP_ISS_SHIFT	20 /* Interface speed support */
832fcbc377Syt 
842fcbc377Syt /* various global HBA control bits */
852fcbc377Syt #define	AHCI_HBA_GHC_HR		(0x1 << 0) /* HBA Reset */
862fcbc377Syt #define	AHCI_HBA_GHC_IE		(0x1 << 1) /* Interrupt Enable */
872fcbc377Syt #define	AHCI_HBA_GHC_MRSM	(0x1 << 2) /* MSI Revert to Single Message */
882fcbc377Syt #define	AHCI_HBA_GHC_AE		((uint32_t)0x1 << 31) /* AHCI Enable */
892fcbc377Syt 
902fcbc377Syt /* various global HBA Command Completion Coalescing (CCC) control bits */
912fcbc377Syt #define	AHCI_HBA_CCC_CTL_EN		0x00000001  /* Enable */
922fcbc377Syt #define	AHCI_HBA_CCC_CTL_INT_MASK	(0x1f << 3) /* Interrupt */
932fcbc377Syt #define	AHCI_HBA_CCC_CTL_CC_MASK	0x0000ff00  /* Command Completions */
942fcbc377Syt #define	AHCI_HBA_CCC_CTL_TV_MASK	0xffff0000  /* Timeout Value */
952fcbc377Syt #define	AHCI_HBA_CCC_CTL_INT_SHIFT	3
962fcbc377Syt #define	AHCI_HBA_CCC_CTL_CC_SHIFT	8
972fcbc377Syt #define	AHCI_HBA_CCC_CTL_TV_SHIFT	16
982fcbc377Syt 
992fcbc377Syt /* global HBA Enclosure Management Location (EM_LOC) */
1002fcbc377Syt #define	AHCI_HBA_EM_LOC_SZ_MASK		0x0000ffff /* Buffer Size */
1012fcbc377Syt #define	AHCI_HBA_EM_LOC_OFST_MASK	0xffff0000 /* Offset */
1022fcbc377Syt #define	AHCI_HBA_EM_LOC_OFST_SHIFT	16
1032fcbc377Syt 
1042fcbc377Syt /* global HBA Enclosure Management Control (EM_CTL) bits */
1052fcbc377Syt #define	AHCI_HBA_EM_CTL_STS_MR		(0x1 << 0) /* Message Received */
1062fcbc377Syt #define	AHCI_HBA_EM_CTL_CTL_TM		(0x1 << 8) /* Transmit Message */
1072fcbc377Syt #define	AHCI_HBA_EM_CTL_CTL_RST		(0x1 << 9) /* Reset */
1082fcbc377Syt #define	AHCI_HBA_EM_CTL_SUPP_LED	(0x1 << 16) /* LED Message Types */
1092fcbc377Syt #define	AHCI_HBA_EM_CTL_SUPP_SAFTE	(0x1 << 17) /* SAF-TE EM Messages */
1102fcbc377Syt #define	AHCI_HBA_EM_CTL_SUPP_SES2	(0x1 << 18) /* SES-2 EM Messages */
1112fcbc377Syt #define	AHCI_HBA_EM_CTL_SUPP_SGPIO	(0x1 << 19) /* SGPIO EM Messages */
1122fcbc377Syt #define	AHCI_HBA_EM_CTL_ATTR_SMB	(0x1 << 24) /* Single Message Buffer */
1132fcbc377Syt #define	AHCI_HBA_EM_CTL_ATTR_XMT	(0x1 << 25) /* Transmit Only */
1142fcbc377Syt #define	AHCI_HBA_EM_CTL_ATTR_ALHD	(0x1 << 26) /* Activity LED HW Driven */
1152fcbc377Syt #define	AHCI_HBA_EM_CTL_ATTR_PM		(0x1 << 27) /* PM Support */
1162fcbc377Syt 
117*33b27906SGarrett D'Amore #define	AHCI_HBA_CAP2_BOH	(0x1 << 0) /* BIOS/OS Handoff */
118*33b27906SGarrett D'Amore #define	AHCI_HBA_CAP2_NVMP	(0x1 << 1) /* NVMHCI present */
119*33b27906SGarrett D'Amore #define	AHCI_HBA_CAP2_APST	(0x1 << 2) /* Auto Partial to Slumber */
120*33b27906SGarrett D'Amore #define	AHCI_HBA_CAP2_SDS	(0x1 << 3) /* Device Sleep */
121*33b27906SGarrett D'Amore #define	AHCI_HBA_CAP2_SADM	(0x1 << 4) /* Aggressive Dev Sleep Mgmt */
122*33b27906SGarrett D'Amore #define	AHCI_HBA_CAP2_DESO	(0x1 << 5) /* DevSleep from Slumber Only */
1232fcbc377Syt 
1242fcbc377Syt /* global HBA registers definitions */
1252fcbc377Syt #define	AHCI_GLOBAL_OFFSET(ahci_ctlp)	(ahci_ctlp->ahcictl_ahci_addr)
1262fcbc377Syt 	/* HBA Capabilities */
1272fcbc377Syt #define	AHCI_GLOBAL_CAP(ahci_ctlp)	(AHCI_GLOBAL_OFFSET(ahci_ctlp) + 0x00)
1282fcbc377Syt 	/* Global HBA Control */
1292fcbc377Syt #define	AHCI_GLOBAL_GHC(ahci_ctlp)	(AHCI_GLOBAL_OFFSET(ahci_ctlp) + 0x04)
1302fcbc377Syt 	/* Interrupt Status Register */
1312fcbc377Syt #define	AHCI_GLOBAL_IS(ahci_ctlp)	(AHCI_GLOBAL_OFFSET(ahci_ctlp) + 0x08)
1322fcbc377Syt 	/* Ports Implemented */
1332fcbc377Syt #define	AHCI_GLOBAL_PI(ahci_ctlp)	(AHCI_GLOBAL_OFFSET(ahci_ctlp) + 0x0c)
1342fcbc377Syt 	/* AHCI Version */
1352fcbc377Syt #define	AHCI_GLOBAL_VS(ahci_ctlp)	(AHCI_GLOBAL_OFFSET(ahci_ctlp) + 0x10)
1362fcbc377Syt 	/* Command Completion Coalescing Control */
1372fcbc377Syt #define	AHCI_GLOBAL_CCC_CTL(ahci_ctlp)	(AHCI_GLOBAL_OFFSET(ahci_ctlp) + 0x14)
1382fcbc377Syt 	/* Command Completion Coalescing Ports */
1392fcbc377Syt #define	AHCI_GLOBAL_CCC_PORTS(ahci_ctlp)	\
1402fcbc377Syt 					(AHCI_GLOBAL_OFFSET(ahci_ctlp) + 0x18)
1412fcbc377Syt 	/* Enclosure Management Location */
1422fcbc377Syt #define	AHCI_GLOBAL_EM_LOC(ahci_ctlp)	(AHCI_GLOBAL_OFFSET(ahci_ctlp) + 0x1c)
1432fcbc377Syt 	/* Enclosure Management Control */
1442fcbc377Syt #define	AHCI_GLOBAL_EM_CTL(ahci_ctlp)	(AHCI_GLOBAL_OFFSET(ahci_ctlp) + 0x20)
1452ac30289SMarcel Telka 	/* HBA Capabilities Extended (AHCI spec 1.2) */
1462ac30289SMarcel Telka #define	AHCI_GLOBAL_CAP2(ahci_ctlp)	(AHCI_GLOBAL_OFFSET(ahci_ctlp) + 0x24)
1472ac30289SMarcel Telka 	/* BIOS/OS Handoff Control and Status (AHCI spec 1.2) */
1482ac30289SMarcel Telka #define	AHCI_GLOBAL_BOHC(ahci_ctlp)	(AHCI_GLOBAL_OFFSET(ahci_ctlp) + 0x28)
1492fcbc377Syt 
1502fcbc377Syt #define	AHCI_PORT_IMPLEMENTED(ahci_ctlp, port)	\
1512fcbc377Syt 	((0x1 << port) & ahci_ctlp->ahcictl_ports_implemented)
1522fcbc377Syt 
1532fcbc377Syt /* various port interrupt bits */
1542fcbc377Syt 	/* Device to Host Register FIS Interrupt */
1552fcbc377Syt #define	AHCI_INTR_STATUS_DHRS (0x1 << 0)
1562fcbc377Syt 	/* PIO Setup FIS Interrupt */
1572fcbc377Syt #define	AHCI_INTR_STATUS_PSS			(0x1 << 1)
1582fcbc377Syt 	/* DMA Setup FIS Interrupt */
1592fcbc377Syt #define	AHCI_INTR_STATUS_DSS			(0x1 << 2)
1602fcbc377Syt 	/* Set Device Bits Interrupt */
1612fcbc377Syt #define	AHCI_INTR_STATUS_SDBS			(0x1 << 3)
1622fcbc377Syt 	/* Unknown FIS Interrupt */
1632fcbc377Syt #define	AHCI_INTR_STATUS_UFS			(0x1 << 4)
1642fcbc377Syt 	/* Descriptor Processed */
1652fcbc377Syt #define	AHCI_INTR_STATUS_DPS			(0x1 << 5)
1662fcbc377Syt 	/* Port Connect Change Status */
1672fcbc377Syt #define	AHCI_INTR_STATUS_PCS			(0x1 << 6)
1682fcbc377Syt 	/* Device Mechanical Presence Status */
1692fcbc377Syt #define	AHCI_INTR_STATUS_DMPS			(0x1 << 7)
1702fcbc377Syt 	/* PhyRdy Change Status */
1712fcbc377Syt #define	AHCI_INTR_STATUS_PRCS			(0x1 << 22)
1722fcbc377Syt 	/* Incorrect Port Multiplier Status */
1732fcbc377Syt #define	AHCI_INTR_STATUS_IPMS			(0x1 << 23)
1742fcbc377Syt 	/* Overflow Status */
1752fcbc377Syt #define	AHCI_INTR_STATUS_OFS			(0x1 << 24)
1762fcbc377Syt 	/* Interface Non-fatal Error Status */
1772fcbc377Syt #define	AHCI_INTR_STATUS_INFS			(0x1 << 26)
1782fcbc377Syt 	/* Interface Fatal Error Status */
1792fcbc377Syt #define	AHCI_INTR_STATUS_IFS			(0x1 << 27)
1802fcbc377Syt 	/* Host Bus Data Error Status */
1812fcbc377Syt #define	AHCI_INTR_STATUS_HBDS			(0x1 << 28)
1822fcbc377Syt 	/* Host Bus Fatal Error Status */
1832fcbc377Syt #define	AHCI_INTR_STATUS_HBFS			(0x1 << 29)
1842fcbc377Syt 	/* Task File Error Status */
1852fcbc377Syt #define	AHCI_INTR_STATUS_TFES			(0x1 << 30)
1862fcbc377Syt 	/* Cold Port Detect Status */
1872fcbc377Syt #define	AHCI_INTR_STATUS_CPDS			((uint32_t)0x1 << 31)
1882fcbc377Syt #define	AHCI_PORT_INTR_MASK			0xfec000ff
1892fcbc377Syt 
1902fcbc377Syt /* port command and status bits */
1912fcbc377Syt #define	AHCI_CMD_STATUS_ST	(0x1 << 0) /* Start */
1922fcbc377Syt #define	AHCI_CMD_STATUS_SUD	(0x1 << 1) /* Spin-up device */
1932fcbc377Syt #define	AHCI_CMD_STATUS_POD	(0x1 << 2) /* Power on device */
1942fcbc377Syt #define	AHCI_CMD_STATUS_CLO	(0x1 << 3) /* Command list override */
1952fcbc377Syt #define	AHCI_CMD_STATUS_FRE	(0x1 << 4) /* FIS receive enable */
1962fcbc377Syt #define	AHCI_CMD_STATUS_CCS	(0x1f << 8) /* Current command slot */
1972fcbc377Syt 			/* Mechanical presence switch state */
1982fcbc377Syt #define	AHCI_CMD_STATUS_MPSS	(0x1 << 13)
1992fcbc377Syt #define	AHCI_CMD_STATUS_FR	(0x1 << 14) /* FIS receiving running */
2002fcbc377Syt #define	AHCI_CMD_STATUS_CR	(0x1 << 15) /* Command list running */
2012fcbc377Syt #define	AHCI_CMD_STATUS_CPS	(0x1 << 16) /* Cold presence state */
2022fcbc377Syt #define	AHCI_CMD_STATUS_PMA	(0x1 << 17) /* Port multiplier attached */
2032fcbc377Syt #define	AHCI_CMD_STATUS_HPCP	(0x1 << 18) /* Hot plug capable port */
2042fcbc377Syt 			/* Mechanical presence switch attached to port */
2052fcbc377Syt #define	AHCI_CMD_STATUS_MPSP	(0x1 << 19)
2062fcbc377Syt #define	AHCI_CMD_STATUS_CPD	(0x1 << 20) /* Cold presence detection */
2072fcbc377Syt #define	AHCI_CMD_STATUS_ESP	(0x1 << 21) /* External SATA port */
2082fcbc377Syt #define	AHCI_CMD_STATUS_ATAPI	(0x1 << 24) /* Device is ATAPI */
2092fcbc377Syt #define	AHCI_CMD_STATUS_DLAE	(0x1 << 25) /* Drive LED on ATAPI enable */
2102fcbc377Syt 			/* Aggressive link power magament enable */
2112fcbc377Syt #define	AHCI_CMD_STATUS_ALPE	(0x1 << 26)
2122fcbc377Syt #define	AHCI_CMD_STATUS_ASP	(0x1 << 27) /* Aggressive slumber/partial */
2132fcbc377Syt 			/* Interface communication control */
2142fcbc377Syt #define	AHCI_CMD_STATUS_ICC	(0xf << 28)
2152fcbc377Syt #define	AHCI_CMD_STATUS_CCS_SHIFT	8
2162fcbc377Syt #define	AHCI_CMD_STATUS_ICC_SHIFT	28
2172fcbc377Syt 
2182fcbc377Syt /* port task file data bits */
2192fcbc377Syt #define	AHCI_TFD_STS_MASK	0x000000ff
2202fcbc377Syt #define	AHCI_TFD_ERR_MASK	0x0000ff00
2212fcbc377Syt #define	AHCI_TFD_STS_BSY	(0x1 << 7)
2222fcbc377Syt #define	AHCI_TFD_STS_DRQ	(0x1 << 3)
2232fcbc377Syt #define	AHCI_TFD_STS_ERR	(0x1 << 0)
2242fcbc377Syt #define	AHCI_TFD_ERR_SHIFT	8
2250a4c4cecSXiao-Yu Zhang #define	AHCI_TFD_ERR_SGS	(0x1 << 0) /* DDR1: Send_good_status */
2262fcbc377Syt 
2278aa6aadbSXiao-Yu Zhang /* FIS-Based Switching Control Register */
2288aa6aadbSXiao-Yu Zhang #define	AHCI_FBS_SWE_MASK	(0xf << 16)	/* Device With Error */
2298aa6aadbSXiao-Yu Zhang #define	AHCI_FBS_ADO_MASK	(0xf << 12)	/* Active Device Optimization */
2308aa6aadbSXiao-Yu Zhang #define	AHCI_FBS_DEV_MASK	(0xf << 8)	/* Device To Issue */
2318aa6aadbSXiao-Yu Zhang #define	AHCI_FBS_SDE		(0x1 << 2)	/* Single Device Error */
2328aa6aadbSXiao-Yu Zhang #define	AHCI_FBS_DEC		(0x1 << 1)	/* Device Error Clear */
2338aa6aadbSXiao-Yu Zhang #define	AHCI_FBS_EN		(0x1 << 0)	/* Enable */
2348aa6aadbSXiao-Yu Zhang 
2358aa6aadbSXiao-Yu Zhang /* Sxxx Registers */
2362fcbc377Syt #define	AHCI_SERROR_CLEAR_ALL			0xffffffff
2378aa6aadbSXiao-Yu Zhang #define	AHCI_SNOTIF_CLEAR_ALL			0xffffffff
2382fcbc377Syt 
2392fcbc377Syt /* per port registers offset */
2402fcbc377Syt #define	AHCI_PORT_OFFSET(ahci_ctlp, port)			\
2412fcbc377Syt 		(ahci_ctlp->ahcictl_ahci_addr + (0x100 + (port * 0x80)))
2422fcbc377Syt 	/* Command List Base Address */
2432fcbc377Syt #define	AHCI_PORT_PxCLB(ahci_ctlp, port)			\
2442fcbc377Syt 			(AHCI_PORT_OFFSET(ahci_ctlp, port) + 0x00)
2452fcbc377Syt 	/* Command List Base Address Upper 32-Bits */
2462fcbc377Syt #define	AHCI_PORT_PxCLBU(ahci_ctlp, port)			\
2472fcbc377Syt 			(AHCI_PORT_OFFSET(ahci_ctlp, port) + 0x04)
2482fcbc377Syt 	/* FIS Base Address */
2492fcbc377Syt #define	AHCI_PORT_PxFB(ahci_ctlp, port)				\
2502fcbc377Syt 			(AHCI_PORT_OFFSET(ahci_ctlp, port) + 0x08)
2512fcbc377Syt 	/* FIS Base Address Upper 32-Bits */
2522fcbc377Syt #define	AHCI_PORT_PxFBU(ahci_ctlp, port)			\
2532fcbc377Syt 			(AHCI_PORT_OFFSET(ahci_ctlp, port) + 0x0c)
2542fcbc377Syt 	/* Interrupt Status */
2552fcbc377Syt #define	AHCI_PORT_PxIS(ahci_ctlp, port)				\
2562fcbc377Syt 			(AHCI_PORT_OFFSET(ahci_ctlp, port) + 0x10)
2572fcbc377Syt 	/* Interrupt Enable */
2582fcbc377Syt #define	AHCI_PORT_PxIE(ahci_ctlp, port)				\
2592fcbc377Syt 			(AHCI_PORT_OFFSET(ahci_ctlp, port) + 0x14)
2602fcbc377Syt 	/* Command and Status */
2612fcbc377Syt #define	AHCI_PORT_PxCMD(ahci_ctlp, port)			\
2622fcbc377Syt 			(AHCI_PORT_OFFSET(ahci_ctlp, port) + 0x18)
2632fcbc377Syt 	/* Task File Data */
2642fcbc377Syt #define	AHCI_PORT_PxTFD(ahci_ctlp, port)			\
2652fcbc377Syt 			(AHCI_PORT_OFFSET(ahci_ctlp, port) + 0x20)
2662fcbc377Syt 	/* Signature */
2672fcbc377Syt #define	AHCI_PORT_PxSIG(ahci_ctlp, port)			\
2682fcbc377Syt 			(AHCI_PORT_OFFSET(ahci_ctlp, port) + 0x24)
2692fcbc377Syt 	/* Serial ATA Status (SCR0:SStatus) */
2702fcbc377Syt #define	AHCI_PORT_PxSSTS(ahci_ctlp, port)			\
2712fcbc377Syt 			(AHCI_PORT_OFFSET(ahci_ctlp, port) + 0x28)
2722fcbc377Syt 	/* Serial ATA Control (SCR2:SControl) */
2732fcbc377Syt #define	AHCI_PORT_PxSCTL(ahci_ctlp, port)			\
2742fcbc377Syt 			(AHCI_PORT_OFFSET(ahci_ctlp, port) + 0x2c)
2752fcbc377Syt 	/* Serial ATA Error (SCR1:SError) */
2762fcbc377Syt #define	AHCI_PORT_PxSERR(ahci_ctlp, port)			\
2772fcbc377Syt 			(AHCI_PORT_OFFSET(ahci_ctlp, port) + 0x30)
2782fcbc377Syt 	/* Serial ATA Active (SCR3:SActive) */
2792fcbc377Syt #define	AHCI_PORT_PxSACT(ahci_ctlp, port)			\
2802fcbc377Syt 			(AHCI_PORT_OFFSET(ahci_ctlp, port) + 0x34)
2812fcbc377Syt 	/* Command Issue */
2822fcbc377Syt #define	AHCI_PORT_PxCI(ahci_ctlp, port)				\
2832fcbc377Syt 			(AHCI_PORT_OFFSET(ahci_ctlp, port) + 0x38)
2842fcbc377Syt 	/* SNotification */
2852fcbc377Syt #define	AHCI_PORT_PxSNTF(ahci_ctlp, port)			\
2862fcbc377Syt 			(AHCI_PORT_OFFSET(ahci_ctlp, port) + 0x3c)
2878aa6aadbSXiao-Yu Zhang 	/* FIS-Based Switching Control */
2888aa6aadbSXiao-Yu Zhang #define	AHCI_PORT_PxFBS(ahci_ctlp, port)			\
2898aa6aadbSXiao-Yu Zhang 			(AHCI_PORT_OFFSET(ahci_ctlp, port) + 0x40)
2902fcbc377Syt 
2912fcbc377Syt #define	AHCI_SLOT_MASK(ahci_ctlp)				\
2922fcbc377Syt 	((ahci_ctlp->ahcictl_num_cmd_slots == AHCI_PORT_MAX_CMD_SLOTS) ? \
2932fcbc377Syt 	0xffffffff : ((0x1 << ahci_ctlp->ahcictl_num_cmd_slots) - 1))
29482263d52Syt #define	AHCI_NCQ_SLOT_MASK(ahci_portp)				\
29582263d52Syt 	((ahci_portp->ahciport_max_ncq_tags == AHCI_PORT_MAX_CMD_SLOTS) ? \
29682263d52Syt 	0xffffffff : ((0x1 << ahci_portp->ahciport_max_ncq_tags) - 1))
2978aa6aadbSXiao-Yu Zhang #define	AHCI_PMPORT_MASK(ahci_portp)				\
2988aa6aadbSXiao-Yu Zhang 	((0x1 << ahci_portp->ahciport_pmult_info->ahcipmi_num_dev_ports) - 1)
2992fcbc377Syt 
3002fcbc377Syt /* Device signatures */
3012fcbc377Syt #define	AHCI_SIGNATURE_PORT_MULTIPLIER	0x96690101
3022fcbc377Syt #define	AHCI_SIGNATURE_ATAPI		0xeb140101
3032fcbc377Syt #define	AHCI_SIGNATURE_DISK		0x00000101
3042fcbc377Syt 
3052fcbc377Syt #define	AHCI_H2D_REGISTER_FIS_TYPE	0x27
3062fcbc377Syt #define	AHCI_H2D_REGISTER_FIS_LENGTH	5
3072fcbc377Syt 
30868d33a25Syt #define	AHCI_CMDHEAD_ATAPI	0x1 /* set to 1 for ATAPI command */
3092fcbc377Syt #define	AHCI_CMDHEAD_DATA_WRITE	0x1 /* From system memory to device */
3102fcbc377Syt #define	AHCI_CMDHEAD_DATA_READ	0x0 /* From device to system memory */
3112fcbc377Syt #define	AHCI_CMDHEAD_PREFETCHABLE	0x1 /* if set, HBA prefetch PRDs */
3122fcbc377Syt 
3132fcbc377Syt /* Register - Host to Device FIS (from SATA spec) */
3142fcbc377Syt typedef struct ahci_fis_h2d_register {
3152fcbc377Syt 	/* offset 0x00 */
3162fcbc377Syt 	uint32_t	ahcifhr_type_pmp_rsvd_cmddevctl_cmd_features;
3172fcbc377Syt 
3182fcbc377Syt #define	SET_FIS_TYPE(fis, type)					\
3192fcbc377Syt 	(fis->ahcifhr_type_pmp_rsvd_cmddevctl_cmd_features |= (type & 0xff))
3202fcbc377Syt 
3212fcbc377Syt #define	SET_FIS_PMP(fis, pmp)					\
322*33b27906SGarrett D'Amore 	(fis->ahcifhr_type_pmp_rsvd_cmddevctl_cmd_features |=	\
3232fcbc377Syt 		((pmp & 0xf) << 8))
3242fcbc377Syt 
3252fcbc377Syt #define	SET_FIS_CDMDEVCTL(fis, cmddevctl)			\
3262fcbc377Syt 	(fis->ahcifhr_type_pmp_rsvd_cmddevctl_cmd_features |=	\
3272fcbc377Syt 		((cmddevctl & 0x1) << 15))
3282fcbc377Syt 
3292fcbc377Syt #define	GET_FIS_COMMAND(fis)					\
3302fcbc377Syt 	((fis->ahcifhr_type_pmp_rsvd_cmddevctl_cmd_features >> 16) & 0xff)
3312fcbc377Syt 
3322fcbc377Syt #define	SET_FIS_COMMAND(fis, command)				\
3332fcbc377Syt 	(fis->ahcifhr_type_pmp_rsvd_cmddevctl_cmd_features |=	\
3342fcbc377Syt 		((command & 0xff) << 16))
3352fcbc377Syt 
3362fcbc377Syt #define	GET_FIS_FEATURES(fis)					\
3372fcbc377Syt 	((fis->ahcifhr_type_pmp_rsvd_cmddevctl_cmd_features >> 24) & 0xff)
3382fcbc377Syt 
3392fcbc377Syt #define	SET_FIS_FEATURES(fis, features)				\
3402fcbc377Syt 	(fis->ahcifhr_type_pmp_rsvd_cmddevctl_cmd_features |=	\
3412fcbc377Syt 		((features & 0xff) << 24))
3422fcbc377Syt 
3432fcbc377Syt 	/* offset 0x04 */
3442fcbc377Syt 	uint32_t	ahcifhr_sector_cyllow_cylhi_devhead;
3452fcbc377Syt 
3462fcbc377Syt #define	GET_FIS_SECTOR(fis)					\
3472fcbc377Syt 	(fis->ahcifhr_sector_cyllow_cylhi_devhead & 0xff)
3482fcbc377Syt 
3492fcbc377Syt #define	SET_FIS_SECTOR(fis, sector)				\
3502fcbc377Syt 	(fis->ahcifhr_sector_cyllow_cylhi_devhead |= ((sector & 0xff)))
3512fcbc377Syt 
3522fcbc377Syt #define	GET_FIS_CYL_LOW(fis)					\
3532fcbc377Syt 	((fis->ahcifhr_sector_cyllow_cylhi_devhead >> 8) & 0xff)
3542fcbc377Syt 
3552fcbc377Syt #define	SET_FIS_CYL_LOW(fis, cyl_low)				\
3562fcbc377Syt 	(fis->ahcifhr_sector_cyllow_cylhi_devhead |= ((cyl_low & 0xff) << 8))
3572fcbc377Syt 
3582fcbc377Syt #define	GET_FIS_CYL_HI(fis)					\
3592fcbc377Syt 	((fis->ahcifhr_sector_cyllow_cylhi_devhead >> 16) & 0xff)
3602fcbc377Syt 
3612fcbc377Syt #define	SET_FIS_CYL_HI(fis, cyl_hi)				\
3622fcbc377Syt 	(fis->ahcifhr_sector_cyllow_cylhi_devhead |= ((cyl_hi & 0xff) << 16))
3632fcbc377Syt 
3642fcbc377Syt #define	GET_FIS_DEV_HEAD(fis)					\
3652fcbc377Syt 	((fis->ahcifhr_sector_cyllow_cylhi_devhead >> 24) & 0xff)
3662fcbc377Syt 
3672fcbc377Syt #define	SET_FIS_DEV_HEAD(fis, dev_head)				\
3682fcbc377Syt 	(fis->ahcifhr_sector_cyllow_cylhi_devhead |= ((dev_head & 0xff) << 24))
3692fcbc377Syt 
3702fcbc377Syt 	/* offset 0x08 */
3712fcbc377Syt 	uint32_t	ahcifhr_sectexp_cyllowexp_cylhiexp_featuresexp;
3722fcbc377Syt 
3732fcbc377Syt #define	GET_FIS_SECTOR_EXP(fis)					\
3742fcbc377Syt 	(fis->ahcifhr_sectexp_cyllowexp_cylhiexp_featuresexp  & 0xff)
3752fcbc377Syt 
3762fcbc377Syt #define	SET_FIS_SECTOR_EXP(fis, sectorexp)			\
3772fcbc377Syt 	(fis->ahcifhr_sectexp_cyllowexp_cylhiexp_featuresexp |=	\
3782fcbc377Syt 		((sectorexp & 0xff)))
3792fcbc377Syt 
3802fcbc377Syt #define	GET_FIS_CYL_LOW_EXP(fis)				\
3812fcbc377Syt 	((fis->ahcifhr_sectexp_cyllowexp_cylhiexp_featuresexp >> 8) & 0xff)
3822fcbc377Syt 
3832fcbc377Syt #define	SET_FIS_CYL_LOW_EXP(fis, cyllowexp)			\
3842fcbc377Syt 	(fis->ahcifhr_sectexp_cyllowexp_cylhiexp_featuresexp |=	\
3852fcbc377Syt 		((cyllowexp & 0xff) << 8))
3862fcbc377Syt 
3872fcbc377Syt #define	GET_FIS_CYL_HI_EXP(fis)					\
3882fcbc377Syt 	((fis->ahcifhr_sectexp_cyllowexp_cylhiexp_featuresexp >> 16) & 0xff)
3892fcbc377Syt 
3902fcbc377Syt #define	SET_FIS_CYL_HI_EXP(fis, cylhiexp)			\
3912fcbc377Syt 	(fis->ahcifhr_sectexp_cyllowexp_cylhiexp_featuresexp |=	\
3922fcbc377Syt 		((cylhiexp & 0xff) << 16))
3932fcbc377Syt 
3942fcbc377Syt #define	SET_FIS_FEATURES_EXP(fis, features_exp)			\
3952fcbc377Syt 	(fis->ahcifhr_sectexp_cyllowexp_cylhiexp_featuresexp |=	\
3962fcbc377Syt 		((features_exp & 0xff) << 24))
3972fcbc377Syt 
3982fcbc377Syt 	/* offset 0x0c */
3992fcbc377Syt 	uint32_t	ahcifhr_sectcount_sectcountexp_rsvd_devctl;
4002fcbc377Syt 
4012fcbc377Syt #define	GET_FIS_SECTOR_COUNT(fis)				\
4022fcbc377Syt 	(fis->ahcifhr_sectcount_sectcountexp_rsvd_devctl & 0xff)
4032fcbc377Syt 
4042fcbc377Syt #define	SET_FIS_SECTOR_COUNT(fis, sector_count)			\
405*33b27906SGarrett D'Amore 	(fis->ahcifhr_sectcount_sectcountexp_rsvd_devctl |=	\
4062fcbc377Syt 		((sector_count & 0xff)))
4072fcbc377Syt 
4082fcbc377Syt #define	GET_FIS_SECTOR_COUNT_EXP(fis)				\
4092fcbc377Syt 	((fis->ahcifhr_sectcount_sectcountexp_rsvd_devctl >> 8) & 0xff)
4102fcbc377Syt 
4112fcbc377Syt #define	SET_FIS_SECTOR_COUNT_EXP(fis, sector_count_exp)		\
4122fcbc377Syt 	(fis->ahcifhr_sectcount_sectcountexp_rsvd_devctl |=	\
4132fcbc377Syt 		((sector_count_exp & 0xff) << 8))
4142fcbc377Syt 
4152fcbc377Syt #define	SET_FIS_DEVCTL(fis, devctl)				\
416*33b27906SGarrett D'Amore 	(fis->ahcifhr_sectcount_sectcountexp_rsvd_devctl |=	\
4172fcbc377Syt 		((devctl & 0xff) << 24))
4182fcbc377Syt 
4192fcbc377Syt 	/* offset 0x10 */
4202fcbc377Syt 	uint32_t	ahcifhr_rsvd3[1]; /* should be zero */
4212fcbc377Syt } ahci_fis_h2d_register_t;
4222fcbc377Syt 
4232fcbc377Syt /* Register - Device to Host FIS (from SATA spec) */
4242fcbc377Syt typedef struct ahci_fis_d2h_register {
4252fcbc377Syt 	/* offset 0x00 */
4262fcbc377Syt 	uint32_t	ahcifdr_type_intr_rsvd_status_error;
4272fcbc377Syt 
4282fcbc377Syt #define	GET_RFIS_STATUS(fis)					\
4292fcbc377Syt 	((fis->ahcifdr_type_intr_rsvd_status_error >> 16) & 0xff)
4302fcbc377Syt 
4312fcbc377Syt #define	GET_RFIS_ERROR(fis)					\
4322fcbc377Syt 	((fis->ahcifdr_type_intr_rsvd_status_error >> 24) & 0xff)
4332fcbc377Syt 
4342fcbc377Syt 	/* offset 0x04 */
4352fcbc377Syt 	uint32_t	ahcifdr_sector_cyllow_cylhi_devhead;
4362fcbc377Syt 
4372fcbc377Syt #define	GET_RFIS_CYL_LOW(fis)					\
4382fcbc377Syt 	(fis->ahcifdr_sector_cyllow_cylhi_devhead & 0xff)
4392fcbc377Syt 
4402fcbc377Syt #define	GET_RFIS_CYL_MID(fis)					\
4412fcbc377Syt 	((fis->ahcifdr_sector_cyllow_cylhi_devhead >> 8) & 0xff)
4422fcbc377Syt 
4432fcbc377Syt #define	GET_RFIS_CYL_HI(fis)					\
4442fcbc377Syt 	((fis->ahcifdr_sector_cyllow_cylhi_devhead >> 16) & 0xff)
4452fcbc377Syt 
4462fcbc377Syt #define	GET_RFIS_DEV_HEAD(fis)					\
4472fcbc377Syt 	((fis->ahcifdr_sector_cyllow_cylhi_devhead >> 24) & 0xff)
4482fcbc377Syt 
4492fcbc377Syt 	/* offset 0x08 */
4502fcbc377Syt 	uint32_t	ahcifdr_sectexp_cyllowexp_cylhiexp_rsvd;
4512fcbc377Syt 
4522fcbc377Syt #define	GET_RFIS_CYL_LOW_EXP(fis)					\
4532fcbc377Syt 	(fis->ahcifdr_sectexp_cyllowexp_cylhiexp_rsvd  & 0xff)
4542fcbc377Syt 
4552fcbc377Syt #define	GET_RFIS_CYL_MID_EXP(fis)				\
4562fcbc377Syt 	((fis->ahcifdr_sectexp_cyllowexp_cylhiexp_rsvd >> 8) & 0xff)
4572fcbc377Syt 
4582fcbc377Syt #define	GET_RFIS_CYL_HI_EXP(fis)					\
4592fcbc377Syt 	((fis->ahcifdr_sectexp_cyllowexp_cylhiexp_rsvd >> 16) & 0xff)
4602fcbc377Syt 
4612fcbc377Syt 	/* offset 0x0c */
4622fcbc377Syt 	uint32_t	ahcifdr_sectcount_sectcountexp_rsvd;
4632fcbc377Syt 
4642fcbc377Syt #define	GET_RFIS_SECTOR_COUNT(fis)				\
4652fcbc377Syt 	(fis->ahcifdr_sectcount_sectcountexp_rsvd & 0xff)
4662fcbc377Syt 
4672fcbc377Syt #define	GET_RFIS_SECTOR_COUNT_EXP(fis)				\
4682fcbc377Syt 	((fis->ahcifdr_sectcount_sectcountexp_rsvd >> 8) & 0xff)
4692fcbc377Syt 
4702fcbc377Syt 	/* offset 0x10 */
4712fcbc377Syt 	uint32_t	ahcifdr_rsvd;
4722fcbc377Syt } ahci_fis_d2h_register_t;
4732fcbc377Syt 
4742fcbc377Syt /* Set Device Bits - Device to Host FIS (from SATA spec) */
4752fcbc377Syt typedef struct ahci_fis_set_device_bits {
4762fcbc377Syt 	/* offset 0x00 */
4772fcbc377Syt 	uint32_t	ahcifsdb_type_rsvd_intr_status_error;
4782fcbc377Syt 
47968d33a25Syt #define	GET_N_BIT_OF_SET_DEV_BITS(fis)				\
48068d33a25Syt 	((fis->ahcifsdb_type_rsvd_intr_status_error >> 15) & 0x1)
48168d33a25Syt 
4822fcbc377Syt 	/* offset 0x04 */
4832fcbc377Syt 	uint32_t	ahcifsdb_rsvd;
4842fcbc377Syt } ahci_fis_set_device_bits_t;
4852fcbc377Syt 
4862fcbc377Syt /* DMA Setup - Device to Host or Host to Device (from SATA spec) */
4872fcbc377Syt typedef struct ahci_fis_dma_setup {
4882fcbc377Syt 	/* offset 0x00 */
4892fcbc377Syt 	uint32_t	ahcifds_type_rsvd_direction_intr_rsvd;
4902fcbc377Syt 
4912fcbc377Syt 	/* offset 0x04 */
4922fcbc377Syt 	uint32_t	ahcifds_dma_buffer_identifier_low;
4932fcbc377Syt 
4942fcbc377Syt 	/* offset 0x08 */
4952fcbc377Syt 	uint32_t	ahcifds_dma_buffer_identifier_high;
4962fcbc377Syt 
4972fcbc377Syt 	/* offset 0x0c */
4982fcbc377Syt 	uint32_t	ahcifds_rsvd1;
4992fcbc377Syt 
5002fcbc377Syt 	/* offset 0x10 */
5012fcbc377Syt 	uint32_t	ahcifds_dma_buffer_offset;
5022fcbc377Syt 
5032fcbc377Syt 	/* offset 0x14 */
5042fcbc377Syt 	uint32_t	ahcifds_dma_transfer_count;
5052fcbc377Syt 
5062fcbc377Syt 	/* offset 0x18 */
5072fcbc377Syt 	uint32_t	ahcifds_rsvd2;
5082fcbc377Syt } ahci_fis_dma_setup_t;
5092fcbc377Syt 
5102fcbc377Syt /* PIO Setup - Device to Host FIS (from SATA spec) */
5112fcbc377Syt typedef struct ahci_fis_pio_setup {
5122fcbc377Syt 	/* offset 0x00 */
5132fcbc377Syt 	uint32_t	ahcifps_type_rsvd_direction_intr_status_error;
5142fcbc377Syt 
5152fcbc377Syt 	/* offset 0x04 */
5162fcbc377Syt 	uint32_t	ahcifps_sector_cyllow_cylhi_devhead;
5172fcbc377Syt 
5182fcbc377Syt 	/* offset 0x08 */
5192fcbc377Syt 	uint32_t	ahcifps_sectexp_cyllowexp_cylhiexp_rsvd;
5202fcbc377Syt 
5212fcbc377Syt 	/* offset 0x0c */
5222fcbc377Syt 	uint32_t	ahcifps_sectcount_sectcountexp_rsvd_e_status;
5232fcbc377Syt 
5242fcbc377Syt 	/* offset 0x10 */
5252fcbc377Syt 	uint32_t	ahcifps_transfer_count_rsvd;
5262fcbc377Syt } ahci_fis_pio_setup_t;
5272fcbc377Syt 
5282fcbc377Syt /* BIST Active - Host to Device or Device to Host (from SATA spec) */
5292fcbc377Syt typedef struct ahci_fis_bist_active {
5302fcbc377Syt 	/* offset 0x00 */
5312fcbc377Syt 	uint32_t	ahcifba_type_rsvd_pattern_rsvd;
5322fcbc377Syt 
5332fcbc377Syt 	/* offset 0x04 */
5342fcbc377Syt 	uint32_t	ahcifba_data1;
5352fcbc377Syt 
5362fcbc377Syt 	/* offset 0x08 */
5372fcbc377Syt 	uint32_t	ahcifba_data2;
5382fcbc377Syt } ahci_fis_bist_active_t;
5392fcbc377Syt 
5402fcbc377Syt /* Up to 64 bytes */
5412fcbc377Syt typedef struct ahci_fis_unknown {
5422fcbc377Syt 	uint32_t	ahcifu_first_dword;
5432fcbc377Syt 	uint32_t	ahcifu_dword[15];
5442fcbc377Syt } ahci_fis_unknown_t;
5452fcbc377Syt 
5462fcbc377Syt /*
5472fcbc377Syt  * This is a software constructed FIS. For data transfer,
5482fcbc377Syt  * this is the H2D Register FIS format as specified in
5492fcbc377Syt  * the Serial ATA 1.0a specification. Valid Command FIS
5502fcbc377Syt  * length are 2 to 16 Dwords.
5512fcbc377Syt  */
5522fcbc377Syt typedef struct ahci_fis_command {
5532fcbc377Syt 	union {
5542fcbc377Syt 		ahci_fis_h2d_register_t	ahcifc_h2d_register;
5552fcbc377Syt 		ahci_fis_bist_active_t	ahcifc_bist_active;
5562fcbc377Syt 	} ahcifc_fis;
5572fcbc377Syt 	uint32_t	ahcifc_rsvd3[11]; /* should be zero */
5582fcbc377Syt } ahci_fis_command_t;
5592fcbc377Syt 
5602fcbc377Syt /* Received FISes structure - size 100h */
5612fcbc377Syt typedef struct ahci_rcvd_fis {
5622fcbc377Syt 	/* offset 0x00 - DMA Setup FIS */
5632fcbc377Syt 	ahci_fis_dma_setup_t		ahcirf_dma_setup_fis;
5642fcbc377Syt 	uint32_t			ahcirf_fis_rsvd1;
5652fcbc377Syt 
5662fcbc377Syt 	/* offset 0x20 - PIO Setup FIS */
5672fcbc377Syt 	ahci_fis_pio_setup_t		ahcirf_pio_setup_fis;
5682fcbc377Syt 	uint32_t			ahcirf_fis_rsvd2[3];
5692fcbc377Syt 
5702fcbc377Syt 	/* offset 0x40 - D2H Register FIS */
5712fcbc377Syt 	ahci_fis_d2h_register_t		ahcirf_d2h_register_fis;
5722fcbc377Syt 	uint32_t			ahcirf_fis_rsvd3;
5732fcbc377Syt 
5742fcbc377Syt 	/* offset 0x58 - Set Device Bits FIS */
5752fcbc377Syt 	ahci_fis_set_device_bits_t	ahcirf_set_device_bits_fis;
5762fcbc377Syt 
5772fcbc377Syt 	/* offset 0x60 - Unknown FIS */
5782fcbc377Syt 	ahci_fis_unknown_t		ahcirf_unknown_fis;
5792fcbc377Syt 
5802fcbc377Syt 	/* offset 0xa0h - Reserved */
581259105bcSying tian - Beijing China 	uint32_t			ahcirf_fis_rsvd4[24];
5822fcbc377Syt } ahci_rcvd_fis_t;
5832fcbc377Syt 
5842fcbc377Syt /* physical region description table (PRDT) item structure */
5852fcbc377Syt typedef struct ahci_prdt_item {
5862fcbc377Syt 	/* DW 0 - Data Base Address */
5872fcbc377Syt 	uint32_t	ahcipi_data_base_addr;
5882fcbc377Syt 
5892fcbc377Syt 	/* DW 1 - Data Base Address Upper */
5902fcbc377Syt 	uint32_t	ahcipi_data_base_addr_upper;
5912fcbc377Syt 
5922fcbc377Syt 	/* DW 2 - Reserved */
5932fcbc377Syt 	uint32_t	ahcipi_rsvd;
5942fcbc377Syt 
5952fcbc377Syt 	/* DW 3 - Description Information */
5962fcbc377Syt 	uint32_t	ahcipi_descr_info;
5972fcbc377Syt 
5982fcbc377Syt #define	GET_PRDT_ITEM_INTR_ON_COMPLETION(prdt_item)	\
5992fcbc377Syt 		((prdt_item.ahcipi_descr_info >> 31) & 0x01)
6002fcbc377Syt 
6012fcbc377Syt #define	GET_PRDT_ITEM_DATA_BYTE_COUNT(prdt_item)	\
6022fcbc377Syt 		(prdt_item.ahcipi_descr_info & 0x3fffff)
6032fcbc377Syt 
6042fcbc377Syt } ahci_prdt_item_t;
6052fcbc377Syt 
6062fcbc377Syt /* command table structure */
6072fcbc377Syt typedef struct ahci_cmd_table {
6082fcbc377Syt 	/* offset 0x00 - Command FIS */
6092fcbc377Syt 	ahci_fis_command_t	ahcict_command_fis;
6102fcbc377Syt 
6112fcbc377Syt 	/* offset 0x40 - ATAPI Command */
61268d33a25Syt 	uint8_t			ahcict_atapi_cmd[SATA_ATAPI_MAX_CDB_LEN];
6132fcbc377Syt 
6142fcbc377Syt 	/* offset 0x50 - Reserved */
6152fcbc377Syt 	uint32_t		ahcict_rsvd[12];
6162fcbc377Syt 
6172fcbc377Syt 	/* offset 0x80 - Physical Region Description Table */
6182fcbc377Syt 	ahci_prdt_item_t	ahcict_prdt[AHCI_PRDT_NUMBER];
6192fcbc377Syt } ahci_cmd_table_t;
6202fcbc377Syt 
6212fcbc377Syt /* command head structure - size 20h */
6222fcbc377Syt typedef struct ahci_cmd_header {
6232fcbc377Syt 	/* DW 0 - Description Information */
6242fcbc377Syt 	uint32_t	ahcich_descr_info;
6252fcbc377Syt 
6262fcbc377Syt #define	BZERO_DESCR_INFO(cmd_header)				\
6272fcbc377Syt 	(cmd_header->ahcich_descr_info = 0)
6282fcbc377Syt 
6292fcbc377Syt #define	GET_PRD_TABLE_LENGTH(cmd_header)			\
6302fcbc377Syt 		((cmd_header->ahcich_descr_info >> 16) & 0xffff)
6312fcbc377Syt 
6322fcbc377Syt #define	SET_PRD_TABLE_LENGTH(cmd_header, length)		\
6332fcbc377Syt 	(cmd_header->ahcich_descr_info |= ((length & 0xffff) << 16))
6342fcbc377Syt 
6352fcbc377Syt #define	GET_PORT_MULTI_PORT(cmd_header)				\
6362fcbc377Syt 		((cmd_header->ahcich_descr_info >> 12) & 0x0f)
6372fcbc377Syt 
6382fcbc377Syt #define	SET_PORT_MULTI_PORT(cmd_header, flags)			\
6392fcbc377Syt 	(cmd_header->ahcich_descr_info |= ((flags & 0x0f) << 12))
6402fcbc377Syt 
6412fcbc377Syt #define	GET_CLEAR_BUSY_UPON_R_OK(cmd_header)			\
6422fcbc377Syt 		((cmd_header->ahcich_descr_info >> 10) & 0x01)
6432fcbc377Syt 
6442fcbc377Syt #define	SET_CLEAR_BUSY_UPON_R_OK(cmd_header, flags)		\
6452fcbc377Syt 	(cmd_header->ahcich_descr_info |= ((flags & 0x01) << 10))
6462fcbc377Syt 
6472fcbc377Syt #define	GET_BIST(cmd_header)					\
6482fcbc377Syt 		((cmd_header->ahcich_descr_info >> 9) & 0x01)
6492fcbc377Syt 
6502fcbc377Syt #define	GET_RESET(cmd_header)					\
6512fcbc377Syt 		((cmd_header->ahcich_descr_info >> 8) & 0x01)
6522fcbc377Syt 
6532fcbc377Syt #define	SET_RESET(cmd_header, features_exp)			\
6542fcbc377Syt 	(cmd_header->ahcich_descr_info |= ((features_exp & 0x01) << 8))
6552fcbc377Syt 
6562fcbc377Syt #define	GET_PREFETCHABLE(cmd_header)				\
6572fcbc377Syt 		((cmd_header->ahcich_descr_info >> 7) & 0x01)
6582fcbc377Syt 
6592fcbc377Syt #define	SET_PREFETCHABLE(cmd_header, flags)			\
6602fcbc377Syt 	(cmd_header->ahcich_descr_info |= ((flags & 0x01) << 7))
6612fcbc377Syt 
6622fcbc377Syt #define	GET_WRITE(cmd_header)					\
6632fcbc377Syt 		((cmd_header->ahcich_descr_info >> 6) & 0x01)
6642fcbc377Syt 
6652fcbc377Syt #define	SET_WRITE(cmd_header, flags)				\
6662fcbc377Syt 	(cmd_header->ahcich_descr_info |= ((flags & 0x01) << 6))
6672fcbc377Syt 
6682fcbc377Syt #define	GET_ATAPI(cmd_header)					\
6692fcbc377Syt 		((cmd_header->ahcich_descr_info >> 5) & 0x01)
6702fcbc377Syt 
6712fcbc377Syt #define	SET_ATAPI(cmd_header, flags)				\
6722fcbc377Syt 	(cmd_header->ahcich_descr_info |= ((flags & 0x01) << 5))
6732fcbc377Syt 
6742fcbc377Syt #define	GET_COMMAND_FIS_LENGTH(cmd_header)			\
6752fcbc377Syt 		(cmd_header->ahcich_descr_info && 0x1f)
6762fcbc377Syt 
6772fcbc377Syt #define	SET_COMMAND_FIS_LENGTH(cmd_header, length)		\
6782fcbc377Syt 	(cmd_header->ahcich_descr_info |= (length & 0x1f))
6792fcbc377Syt 
6802fcbc377Syt 	/* DW 1 - Physical Region Descriptor Byte Count */
6812fcbc377Syt 	uint32_t	ahcich_prd_byte_count;
6822fcbc377Syt 
6832fcbc377Syt #define	BZERO_PRD_BYTE_COUNT(cmd_header)			\
6842fcbc377Syt 	(cmd_header->ahcich_prd_byte_count = 0)
6852fcbc377Syt 
6862fcbc377Syt 	/* DW 2 - Command Table Base Address */
6872fcbc377Syt 	uint32_t	ahcich_cmd_tab_base_addr;
6882fcbc377Syt 
6892fcbc377Syt #define	SET_COMMAND_TABLE_BASE_ADDR(cmd_header, base_address)	\
6902fcbc377Syt 	(cmd_header->ahcich_cmd_tab_base_addr = base_address)
6912fcbc377Syt 
6922fcbc377Syt 	/* DW 3 - Command Table Base Address Upper */
6932fcbc377Syt 	uint32_t	ahcich_cmd_tab_base_addr_upper;
6942fcbc377Syt 
6952fcbc377Syt #define	SET_COMMAND_TABLE_BASE_ADDR_UPPER(cmd_header, base_address) \
6962fcbc377Syt 	(cmd_header->ahcich_cmd_tab_base_addr_upper = base_address)
6972fcbc377Syt 
6982fcbc377Syt 	/* DW 4-7 - Reserved */
6992fcbc377Syt 	uint32_t	ahcich_rsvd[4];
7002fcbc377Syt } ahci_cmd_header_t;
7012fcbc377Syt 
7022fcbc377Syt 
7032fcbc377Syt #ifdef	__cplusplus
7042fcbc377Syt }
7052fcbc377Syt #endif
7062fcbc377Syt 
7072fcbc377Syt #endif /* _AHCIREG_H */
708