11cf4323eSThomas Huth #ifndef LIBQOS_AHCI_H
21cf4323eSThomas Huth #define LIBQOS_AHCI_H
31cf4323eSThomas Huth
41cf4323eSThomas Huth /*
51cf4323eSThomas Huth * AHCI qtest library functions and definitions
61cf4323eSThomas Huth *
71cf4323eSThomas Huth * Copyright (c) 2014 John Snow <jsnow@redhat.com>
81cf4323eSThomas Huth *
91cf4323eSThomas Huth * Permission is hereby granted, free of charge, to any person obtaining a copy
101cf4323eSThomas Huth * of this software and associated documentation files (the "Software"), to deal
111cf4323eSThomas Huth * in the Software without restriction, including without limitation the rights
121cf4323eSThomas Huth * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
131cf4323eSThomas Huth * copies of the Software, and to permit persons to whom the Software is
141cf4323eSThomas Huth * furnished to do so, subject to the following conditions:
151cf4323eSThomas Huth *
161cf4323eSThomas Huth * The above copyright notice and this permission notice shall be included in
171cf4323eSThomas Huth * all copies or substantial portions of the Software.
181cf4323eSThomas Huth *
191cf4323eSThomas Huth * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
201cf4323eSThomas Huth * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
211cf4323eSThomas Huth * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
221cf4323eSThomas Huth * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
231cf4323eSThomas Huth * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
241cf4323eSThomas Huth * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
251cf4323eSThomas Huth * THE SOFTWARE.
261cf4323eSThomas Huth */
271cf4323eSThomas Huth
28a2ce7dbdSPaolo Bonzini #include "libqos.h"
29a2ce7dbdSPaolo Bonzini #include "pci.h"
30a2ce7dbdSPaolo Bonzini #include "malloc-pc.h"
311cf4323eSThomas Huth
321cf4323eSThomas Huth /*** Supplementary PCI Config Space IDs & Masks ***/
331cf4323eSThomas Huth #define PCI_DEVICE_ID_INTEL_Q35_AHCI (0x2922)
341cf4323eSThomas Huth #define PCI_MSI_FLAGS_RESERVED (0xFF00)
351cf4323eSThomas Huth #define PCI_PM_CTRL_RESERVED (0xFC)
361cf4323eSThomas Huth #define PCI_BCC(REG32) ((REG32) >> 24)
371cf4323eSThomas Huth #define PCI_PI(REG32) (((REG32) >> 8) & 0xFF)
381cf4323eSThomas Huth #define PCI_SCC(REG32) (((REG32) >> 16) & 0xFF)
391cf4323eSThomas Huth
401cf4323eSThomas Huth /*** Recognized AHCI Device Types ***/
411cf4323eSThomas Huth #define AHCI_INTEL_ICH9 (PCI_DEVICE_ID_INTEL_Q35_AHCI << 16 | \
421cf4323eSThomas Huth PCI_VENDOR_ID_INTEL)
431cf4323eSThomas Huth
441cf4323eSThomas Huth /*** AHCI/HBA Register Offsets and Bitmasks ***/
451cf4323eSThomas Huth #define AHCI_CAP (0)
461cf4323eSThomas Huth #define AHCI_CAP_NP (0x1F)
471cf4323eSThomas Huth #define AHCI_CAP_SXS (0x20)
481cf4323eSThomas Huth #define AHCI_CAP_EMS (0x40)
491cf4323eSThomas Huth #define AHCI_CAP_CCCS (0x80)
501cf4323eSThomas Huth #define AHCI_CAP_NCS (0x1F00)
511cf4323eSThomas Huth #define AHCI_CAP_PSC (0x2000)
521cf4323eSThomas Huth #define AHCI_CAP_SSC (0x4000)
531cf4323eSThomas Huth #define AHCI_CAP_PMD (0x8000)
541cf4323eSThomas Huth #define AHCI_CAP_FBSS (0x10000)
551cf4323eSThomas Huth #define AHCI_CAP_SPM (0x20000)
561cf4323eSThomas Huth #define AHCI_CAP_SAM (0x40000)
571cf4323eSThomas Huth #define AHCI_CAP_RESERVED (0x80000)
581cf4323eSThomas Huth #define AHCI_CAP_ISS (0xF00000)
591cf4323eSThomas Huth #define AHCI_CAP_SCLO (0x1000000)
601cf4323eSThomas Huth #define AHCI_CAP_SAL (0x2000000)
611cf4323eSThomas Huth #define AHCI_CAP_SALP (0x4000000)
621cf4323eSThomas Huth #define AHCI_CAP_SSS (0x8000000)
631cf4323eSThomas Huth #define AHCI_CAP_SMPS (0x10000000)
641cf4323eSThomas Huth #define AHCI_CAP_SSNTF (0x20000000)
651cf4323eSThomas Huth #define AHCI_CAP_SNCQ (0x40000000)
661cf4323eSThomas Huth #define AHCI_CAP_S64A (0x80000000)
671cf4323eSThomas Huth
681cf4323eSThomas Huth #define AHCI_GHC (1)
691cf4323eSThomas Huth #define AHCI_GHC_HR (0x01)
701cf4323eSThomas Huth #define AHCI_GHC_IE (0x02)
711cf4323eSThomas Huth #define AHCI_GHC_MRSM (0x04)
721cf4323eSThomas Huth #define AHCI_GHC_RESERVED (0x7FFFFFF8)
731cf4323eSThomas Huth #define AHCI_GHC_AE (0x80000000)
741cf4323eSThomas Huth
751cf4323eSThomas Huth #define AHCI_IS (2)
761cf4323eSThomas Huth #define AHCI_PI (3)
771cf4323eSThomas Huth #define AHCI_VS (4)
781cf4323eSThomas Huth
791cf4323eSThomas Huth #define AHCI_CCCCTL (5)
801cf4323eSThomas Huth #define AHCI_CCCCTL_EN (0x01)
811cf4323eSThomas Huth #define AHCI_CCCCTL_RESERVED (0x06)
821cf4323eSThomas Huth #define AHCI_CCCCTL_CC (0xFF00)
831cf4323eSThomas Huth #define AHCI_CCCCTL_TV (0xFFFF0000)
841cf4323eSThomas Huth
851cf4323eSThomas Huth #define AHCI_CCCPORTS (6)
861cf4323eSThomas Huth #define AHCI_EMLOC (7)
871cf4323eSThomas Huth
881cf4323eSThomas Huth #define AHCI_EMCTL (8)
891cf4323eSThomas Huth #define AHCI_EMCTL_STSMR (0x01)
901cf4323eSThomas Huth #define AHCI_EMCTL_CTLTM (0x100)
911cf4323eSThomas Huth #define AHCI_EMCTL_CTLRST (0x200)
921cf4323eSThomas Huth #define AHCI_EMCTL_RESERVED (0xF0F0FCFE)
931cf4323eSThomas Huth
941cf4323eSThomas Huth #define AHCI_CAP2 (9)
951cf4323eSThomas Huth #define AHCI_CAP2_BOH (0x01)
961cf4323eSThomas Huth #define AHCI_CAP2_NVMP (0x02)
971cf4323eSThomas Huth #define AHCI_CAP2_APST (0x04)
981cf4323eSThomas Huth #define AHCI_CAP2_RESERVED (0xFFFFFFF8)
991cf4323eSThomas Huth
1001cf4323eSThomas Huth #define AHCI_BOHC (10)
1011cf4323eSThomas Huth #define AHCI_RESERVED (11)
1021cf4323eSThomas Huth #define AHCI_NVMHCI (24)
1031cf4323eSThomas Huth #define AHCI_VENDOR (40)
1041cf4323eSThomas Huth #define AHCI_PORTS (64)
1051cf4323eSThomas Huth
1061cf4323eSThomas Huth /*** Port Memory Offsets & Bitmasks ***/
1071cf4323eSThomas Huth #define AHCI_PX_CLB (0)
1081cf4323eSThomas Huth #define AHCI_PX_CLB_RESERVED (0x1FF)
1091cf4323eSThomas Huth
1101cf4323eSThomas Huth #define AHCI_PX_CLBU (1)
1111cf4323eSThomas Huth
1121cf4323eSThomas Huth #define AHCI_PX_FB (2)
1131cf4323eSThomas Huth #define AHCI_PX_FB_RESERVED (0xFF)
1141cf4323eSThomas Huth
1151cf4323eSThomas Huth #define AHCI_PX_FBU (3)
1161cf4323eSThomas Huth
1171cf4323eSThomas Huth #define AHCI_PX_IS (4)
1181cf4323eSThomas Huth #define AHCI_PX_IS_DHRS (0x1)
1191cf4323eSThomas Huth #define AHCI_PX_IS_PSS (0x2)
1201cf4323eSThomas Huth #define AHCI_PX_IS_DSS (0x4)
1211cf4323eSThomas Huth #define AHCI_PX_IS_SDBS (0x8)
1221cf4323eSThomas Huth #define AHCI_PX_IS_UFS (0x10)
1231cf4323eSThomas Huth #define AHCI_PX_IS_DPS (0x20)
1241cf4323eSThomas Huth #define AHCI_PX_IS_PCS (0x40)
1251cf4323eSThomas Huth #define AHCI_PX_IS_DMPS (0x80)
1261cf4323eSThomas Huth #define AHCI_PX_IS_RESERVED (0x23FFF00)
1271cf4323eSThomas Huth #define AHCI_PX_IS_PRCS (0x400000)
1281cf4323eSThomas Huth #define AHCI_PX_IS_IPMS (0x800000)
1291cf4323eSThomas Huth #define AHCI_PX_IS_OFS (0x1000000)
1301cf4323eSThomas Huth #define AHCI_PX_IS_INFS (0x4000000)
1311cf4323eSThomas Huth #define AHCI_PX_IS_IFS (0x8000000)
1321cf4323eSThomas Huth #define AHCI_PX_IS_HBDS (0x10000000)
1331cf4323eSThomas Huth #define AHCI_PX_IS_HBFS (0x20000000)
1341cf4323eSThomas Huth #define AHCI_PX_IS_TFES (0x40000000)
1351cf4323eSThomas Huth #define AHCI_PX_IS_CPDS (0x80000000)
1361cf4323eSThomas Huth
1371cf4323eSThomas Huth #define AHCI_PX_IE (5)
1381cf4323eSThomas Huth #define AHCI_PX_IE_DHRE (0x1)
1391cf4323eSThomas Huth #define AHCI_PX_IE_PSE (0x2)
1401cf4323eSThomas Huth #define AHCI_PX_IE_DSE (0x4)
1411cf4323eSThomas Huth #define AHCI_PX_IE_SDBE (0x8)
1421cf4323eSThomas Huth #define AHCI_PX_IE_UFE (0x10)
1431cf4323eSThomas Huth #define AHCI_PX_IE_DPE (0x20)
1441cf4323eSThomas Huth #define AHCI_PX_IE_PCE (0x40)
1451cf4323eSThomas Huth #define AHCI_PX_IE_DMPE (0x80)
1461cf4323eSThomas Huth #define AHCI_PX_IE_RESERVED (0x23FFF00)
1471cf4323eSThomas Huth #define AHCI_PX_IE_PRCE (0x400000)
1481cf4323eSThomas Huth #define AHCI_PX_IE_IPME (0x800000)
1491cf4323eSThomas Huth #define AHCI_PX_IE_OFE (0x1000000)
1501cf4323eSThomas Huth #define AHCI_PX_IE_INFE (0x4000000)
1511cf4323eSThomas Huth #define AHCI_PX_IE_IFE (0x8000000)
1521cf4323eSThomas Huth #define AHCI_PX_IE_HBDE (0x10000000)
1531cf4323eSThomas Huth #define AHCI_PX_IE_HBFE (0x20000000)
1541cf4323eSThomas Huth #define AHCI_PX_IE_TFEE (0x40000000)
1551cf4323eSThomas Huth #define AHCI_PX_IE_CPDE (0x80000000)
1561cf4323eSThomas Huth
1571cf4323eSThomas Huth #define AHCI_PX_CMD (6)
1581cf4323eSThomas Huth #define AHCI_PX_CMD_ST (0x1)
1591cf4323eSThomas Huth #define AHCI_PX_CMD_SUD (0x2)
1601cf4323eSThomas Huth #define AHCI_PX_CMD_POD (0x4)
1611cf4323eSThomas Huth #define AHCI_PX_CMD_CLO (0x8)
1621cf4323eSThomas Huth #define AHCI_PX_CMD_FRE (0x10)
1631cf4323eSThomas Huth #define AHCI_PX_CMD_RESERVED (0xE0)
1641cf4323eSThomas Huth #define AHCI_PX_CMD_CCS (0x1F00)
1651cf4323eSThomas Huth #define AHCI_PX_CMD_MPSS (0x2000)
1661cf4323eSThomas Huth #define AHCI_PX_CMD_FR (0x4000)
1671cf4323eSThomas Huth #define AHCI_PX_CMD_CR (0x8000)
1681cf4323eSThomas Huth #define AHCI_PX_CMD_CPS (0x10000)
1691cf4323eSThomas Huth #define AHCI_PX_CMD_PMA (0x20000)
1701cf4323eSThomas Huth #define AHCI_PX_CMD_HPCP (0x40000)
1711cf4323eSThomas Huth #define AHCI_PX_CMD_MPSP (0x80000)
1721cf4323eSThomas Huth #define AHCI_PX_CMD_CPD (0x100000)
1731cf4323eSThomas Huth #define AHCI_PX_CMD_ESP (0x200000)
1741cf4323eSThomas Huth #define AHCI_PX_CMD_FBSCP (0x400000)
1751cf4323eSThomas Huth #define AHCI_PX_CMD_APSTE (0x800000)
1761cf4323eSThomas Huth #define AHCI_PX_CMD_ATAPI (0x1000000)
1771cf4323eSThomas Huth #define AHCI_PX_CMD_DLAE (0x2000000)
1781cf4323eSThomas Huth #define AHCI_PX_CMD_ALPE (0x4000000)
1791cf4323eSThomas Huth #define AHCI_PX_CMD_ASP (0x8000000)
1801cf4323eSThomas Huth #define AHCI_PX_CMD_ICC (0xF0000000)
1811cf4323eSThomas Huth
1821cf4323eSThomas Huth #define AHCI_PX_RES1 (7)
1831cf4323eSThomas Huth
1841cf4323eSThomas Huth #define AHCI_PX_TFD (8)
1851cf4323eSThomas Huth #define AHCI_PX_TFD_STS (0xFF)
1861cf4323eSThomas Huth #define AHCI_PX_TFD_STS_ERR (0x01)
1871cf4323eSThomas Huth #define AHCI_PX_TFD_STS_CS1 (0x06)
1881cf4323eSThomas Huth #define AHCI_PX_TFD_STS_DRQ (0x08)
1891cf4323eSThomas Huth #define AHCI_PX_TFD_STS_CS2 (0x70)
1901cf4323eSThomas Huth #define AHCI_PX_TFD_STS_BSY (0x80)
1911cf4323eSThomas Huth #define AHCI_PX_TFD_ERR (0xFF00)
1921cf4323eSThomas Huth #define AHCI_PX_TFD_RESERVED (0xFFFF0000)
1931cf4323eSThomas Huth
1941cf4323eSThomas Huth #define AHCI_PX_SIG (9)
1951cf4323eSThomas Huth #define AHCI_PX_SIG_SECTOR_COUNT (0xFF)
1961cf4323eSThomas Huth #define AHCI_PX_SIG_LBA_LOW (0xFF00)
1971cf4323eSThomas Huth #define AHCI_PX_SIG_LBA_MID (0xFF0000)
1981cf4323eSThomas Huth #define AHCI_PX_SIG_LBA_HIGH (0xFF000000)
1991cf4323eSThomas Huth
2001cf4323eSThomas Huth #define AHCI_PX_SSTS (10)
2011cf4323eSThomas Huth #define AHCI_PX_SSTS_DET (0x0F)
2021cf4323eSThomas Huth #define AHCI_PX_SSTS_SPD (0xF0)
2031cf4323eSThomas Huth #define AHCI_PX_SSTS_IPM (0xF00)
2041cf4323eSThomas Huth #define AHCI_PX_SSTS_RESERVED (0xFFFFF000)
2051cf4323eSThomas Huth #define SSTS_DET_NO_DEVICE (0x00)
2061cf4323eSThomas Huth #define SSTS_DET_PRESENT (0x01)
2071cf4323eSThomas Huth #define SSTS_DET_ESTABLISHED (0x03)
2081cf4323eSThomas Huth #define SSTS_DET_OFFLINE (0x04)
2091cf4323eSThomas Huth
2101cf4323eSThomas Huth #define AHCI_PX_SCTL (11)
2111cf4323eSThomas Huth
2121cf4323eSThomas Huth #define AHCI_PX_SERR (12)
2131cf4323eSThomas Huth #define AHCI_PX_SERR_ERR (0xFFFF)
2141cf4323eSThomas Huth #define AHCI_PX_SERR_DIAG (0xFFFF0000)
2151cf4323eSThomas Huth #define AHCI_PX_SERR_DIAG_X (0x04000000)
2161cf4323eSThomas Huth
2171cf4323eSThomas Huth #define AHCI_PX_SACT (13)
2181cf4323eSThomas Huth #define AHCI_PX_CI (14)
2191cf4323eSThomas Huth #define AHCI_PX_SNTF (15)
2201cf4323eSThomas Huth
2211cf4323eSThomas Huth #define AHCI_PX_FBS (16)
2221cf4323eSThomas Huth #define AHCI_PX_FBS_EN (0x1)
2231cf4323eSThomas Huth #define AHCI_PX_FBS_DEC (0x2)
2241cf4323eSThomas Huth #define AHCI_PX_FBS_SDE (0x4)
2251cf4323eSThomas Huth #define AHCI_PX_FBS_DEV (0xF00)
2261cf4323eSThomas Huth #define AHCI_PX_FBS_ADO (0xF000)
2271cf4323eSThomas Huth #define AHCI_PX_FBS_DWE (0xF0000)
2281cf4323eSThomas Huth #define AHCI_PX_FBS_RESERVED (0xFFF000F8)
2291cf4323eSThomas Huth
2301cf4323eSThomas Huth #define AHCI_PX_RES2 (17)
2311cf4323eSThomas Huth #define AHCI_PX_VS (28)
2321cf4323eSThomas Huth
2331cf4323eSThomas Huth #define HBA_DATA_REGION_SIZE (256)
2341cf4323eSThomas Huth #define HBA_PORT_DATA_SIZE (128)
2351cf4323eSThomas Huth #define HBA_PORT_NUM_REG (HBA_PORT_DATA_SIZE/4)
2361cf4323eSThomas Huth
2371cf4323eSThomas Huth #define AHCI_VERSION_0_95 (0x00000905)
2381cf4323eSThomas Huth #define AHCI_VERSION_1_0 (0x00010000)
2391cf4323eSThomas Huth #define AHCI_VERSION_1_1 (0x00010100)
2401cf4323eSThomas Huth #define AHCI_VERSION_1_2 (0x00010200)
2411cf4323eSThomas Huth #define AHCI_VERSION_1_3 (0x00010300)
2421cf4323eSThomas Huth
2431cf4323eSThomas Huth #define AHCI_SECTOR_SIZE (512)
2441cf4323eSThomas Huth #define ATAPI_SECTOR_SIZE (2048)
2451cf4323eSThomas Huth
2461cf4323eSThomas Huth #define AHCI_SIGNATURE_CDROM (0xeb140101)
2471cf4323eSThomas Huth #define AHCI_SIGNATURE_DISK (0x00000101)
2481cf4323eSThomas Huth
2491cf4323eSThomas Huth /* FIS types */
2501cf4323eSThomas Huth enum {
2511cf4323eSThomas Huth REG_H2D_FIS = 0x27,
2521cf4323eSThomas Huth REG_D2H_FIS = 0x34,
2531cf4323eSThomas Huth DMA_ACTIVATE_FIS = 0x39,
2541cf4323eSThomas Huth DMA_SETUP_FIS = 0x41,
2551cf4323eSThomas Huth DATA_FIS = 0x46,
2561cf4323eSThomas Huth BIST_ACTIVATE_FIS = 0x58,
2571cf4323eSThomas Huth PIO_SETUP_FIS = 0x5F,
2581cf4323eSThomas Huth SDB_FIS = 0xA1
2591cf4323eSThomas Huth };
2601cf4323eSThomas Huth
2611cf4323eSThomas Huth /* FIS flags */
2621cf4323eSThomas Huth #define REG_H2D_FIS_CMD 0x80
2631cf4323eSThomas Huth
2641cf4323eSThomas Huth /* ATA Commands */
2651cf4323eSThomas Huth enum {
2661cf4323eSThomas Huth /* DMA */
2671cf4323eSThomas Huth CMD_READ_DMA = 0xC8,
2681cf4323eSThomas Huth CMD_READ_DMA_EXT = 0x25,
2691cf4323eSThomas Huth CMD_WRITE_DMA = 0xCA,
2701cf4323eSThomas Huth CMD_WRITE_DMA_EXT = 0x35,
2711cf4323eSThomas Huth /* PIO */
2721cf4323eSThomas Huth CMD_READ_PIO = 0x20,
2731cf4323eSThomas Huth CMD_READ_PIO_EXT = 0x24,
2741cf4323eSThomas Huth CMD_WRITE_PIO = 0x30,
2751cf4323eSThomas Huth CMD_WRITE_PIO_EXT = 0x34,
2761cf4323eSThomas Huth /* Misc */
2771cf4323eSThomas Huth CMD_READ_MAX = 0xF8,
2781cf4323eSThomas Huth CMD_READ_MAX_EXT = 0x27,
2791cf4323eSThomas Huth CMD_FLUSH_CACHE = 0xE7,
2801cf4323eSThomas Huth CMD_IDENTIFY = 0xEC,
2811cf4323eSThomas Huth CMD_PACKET = 0xA0,
2821cf4323eSThomas Huth CMD_PACKET_ID = 0xA1,
2831cf4323eSThomas Huth /* NCQ */
2841cf4323eSThomas Huth READ_FPDMA_QUEUED = 0x60,
2851cf4323eSThomas Huth WRITE_FPDMA_QUEUED = 0x61,
2861cf4323eSThomas Huth };
2871cf4323eSThomas Huth
2881cf4323eSThomas Huth /* ATAPI Commands */
2891cf4323eSThomas Huth enum {
2901cf4323eSThomas Huth CMD_ATAPI_TEST_UNIT_READY = 0x00,
2911cf4323eSThomas Huth CMD_ATAPI_REQUEST_SENSE = 0x03,
2921cf4323eSThomas Huth CMD_ATAPI_START_STOP_UNIT = 0x1b,
2931cf4323eSThomas Huth CMD_ATAPI_READ_10 = 0x28,
2941cf4323eSThomas Huth CMD_ATAPI_READ_CD = 0xbe,
2951cf4323eSThomas Huth };
2961cf4323eSThomas Huth
2971cf4323eSThomas Huth enum {
2981cf4323eSThomas Huth SENSE_NO_SENSE = 0x00,
2991cf4323eSThomas Huth SENSE_NOT_READY = 0x02,
3001cf4323eSThomas Huth SENSE_UNIT_ATTENTION = 0x06,
3011cf4323eSThomas Huth };
3021cf4323eSThomas Huth
3031cf4323eSThomas Huth enum {
3041cf4323eSThomas Huth ASC_MEDIUM_MAY_HAVE_CHANGED = 0x28,
3051cf4323eSThomas Huth ASC_MEDIUM_NOT_PRESENT = 0x3a,
3061cf4323eSThomas Huth };
3071cf4323eSThomas Huth
3081cf4323eSThomas Huth /* AHCI Command Header Flags & Masks*/
3091cf4323eSThomas Huth #define CMDH_CFL (0x1F)
3101cf4323eSThomas Huth #define CMDH_ATAPI (0x20)
3111cf4323eSThomas Huth #define CMDH_WRITE (0x40)
3121cf4323eSThomas Huth #define CMDH_PREFETCH (0x80)
3131cf4323eSThomas Huth #define CMDH_RESET (0x100)
3141cf4323eSThomas Huth #define CMDH_BIST (0x200)
3151cf4323eSThomas Huth #define CMDH_CLR_BSY (0x400)
3161cf4323eSThomas Huth #define CMDH_RES (0x800)
3171cf4323eSThomas Huth #define CMDH_PMP (0xF000)
3181cf4323eSThomas Huth
3191cf4323eSThomas Huth /* ATA device register masks */
3201cf4323eSThomas Huth #define ATA_DEVICE_MAGIC 0xA0 /* used in ata1-3 */
3211cf4323eSThomas Huth #define ATA_DEVICE_LBA 0x40
3221cf4323eSThomas Huth #define NCQ_DEVICE_MAGIC 0x40 /* for ncq device registers */
3231cf4323eSThomas Huth #define ATA_DEVICE_DRIVE 0x10
3241cf4323eSThomas Huth #define ATA_DEVICE_HEAD 0x0F
3251cf4323eSThomas Huth
3261cf4323eSThomas Huth /*** Structures ***/
3271cf4323eSThomas Huth
3281cf4323eSThomas Huth typedef struct AHCIPortQState {
3291cf4323eSThomas Huth uint64_t fb;
3301cf4323eSThomas Huth uint64_t clb;
3311cf4323eSThomas Huth uint64_t ctba[32];
3321cf4323eSThomas Huth uint16_t prdtl[32];
3331cf4323eSThomas Huth uint8_t next; /** Next Command Slot to Use **/
3341cf4323eSThomas Huth } AHCIPortQState;
3351cf4323eSThomas Huth
3361cf4323eSThomas Huth typedef struct AHCIQState {
3371cf4323eSThomas Huth QOSState *parent;
3381cf4323eSThomas Huth QPCIDevice *dev;
3391cf4323eSThomas Huth QPCIBar hba_bar;
3401cf4323eSThomas Huth uint64_t barsize;
3411cf4323eSThomas Huth uint32_t fingerprint;
3421cf4323eSThomas Huth uint32_t cap;
3431cf4323eSThomas Huth uint32_t cap2;
3441cf4323eSThomas Huth AHCIPortQState port[32];
3451cf4323eSThomas Huth bool enabled;
3461cf4323eSThomas Huth } AHCIQState;
3471cf4323eSThomas Huth
3481cf4323eSThomas Huth /**
3491cf4323eSThomas Huth * Generic FIS structure.
3501cf4323eSThomas Huth */
3511cf4323eSThomas Huth typedef struct FIS {
3521cf4323eSThomas Huth uint8_t fis_type;
3531cf4323eSThomas Huth uint8_t flags;
354f7795e40SPhilippe Mathieu-Daudé char data[];
3551cf4323eSThomas Huth } __attribute__((__packed__)) FIS;
3561cf4323eSThomas Huth
3571cf4323eSThomas Huth /**
3581cf4323eSThomas Huth * Register device-to-host FIS structure.
3591cf4323eSThomas Huth */
3601cf4323eSThomas Huth typedef struct RegD2HFIS {
3611cf4323eSThomas Huth /* DW0 */
3621cf4323eSThomas Huth uint8_t fis_type;
3631cf4323eSThomas Huth uint8_t flags;
3641cf4323eSThomas Huth uint8_t status;
3651cf4323eSThomas Huth uint8_t error;
3661cf4323eSThomas Huth /* DW1 */
3671cf4323eSThomas Huth uint8_t lba_lo[3];
3681cf4323eSThomas Huth uint8_t device;
3691cf4323eSThomas Huth /* DW2 */
3701cf4323eSThomas Huth uint8_t lba_hi[3];
3711cf4323eSThomas Huth uint8_t res0;
3721cf4323eSThomas Huth /* DW3 */
3731cf4323eSThomas Huth uint16_t count;
3741cf4323eSThomas Huth uint16_t res1;
3751cf4323eSThomas Huth /* DW4 */
3761cf4323eSThomas Huth uint32_t res2;
3771cf4323eSThomas Huth } __attribute__((__packed__)) RegD2HFIS;
3781cf4323eSThomas Huth
3791cf4323eSThomas Huth /**
3801cf4323eSThomas Huth * Register device-to-host FIS structure;
3811cf4323eSThomas Huth * PIO Setup variety.
3821cf4323eSThomas Huth */
3831cf4323eSThomas Huth typedef struct PIOSetupFIS {
3841cf4323eSThomas Huth /* DW0 */
3851cf4323eSThomas Huth uint8_t fis_type;
3861cf4323eSThomas Huth uint8_t flags;
3871cf4323eSThomas Huth uint8_t status;
3881cf4323eSThomas Huth uint8_t error;
3891cf4323eSThomas Huth /* DW1 */
3901cf4323eSThomas Huth uint8_t lba_lo[3];
3911cf4323eSThomas Huth uint8_t device;
3921cf4323eSThomas Huth /* DW2 */
3931cf4323eSThomas Huth uint8_t lba_hi[3];
3941cf4323eSThomas Huth uint8_t res0;
3951cf4323eSThomas Huth /* DW3 */
3961cf4323eSThomas Huth uint16_t count;
3971cf4323eSThomas Huth uint8_t res1;
3981cf4323eSThomas Huth uint8_t e_status;
3991cf4323eSThomas Huth /* DW4 */
4001cf4323eSThomas Huth uint16_t tx_count;
4011cf4323eSThomas Huth uint16_t res2;
4021cf4323eSThomas Huth } __attribute__((__packed__)) PIOSetupFIS;
4031cf4323eSThomas Huth
4041cf4323eSThomas Huth /**
4051cf4323eSThomas Huth * Register host-to-device FIS structure.
4061cf4323eSThomas Huth */
4071cf4323eSThomas Huth typedef struct RegH2DFIS {
4081cf4323eSThomas Huth /* DW0 */
4091cf4323eSThomas Huth uint8_t fis_type;
4101cf4323eSThomas Huth uint8_t flags;
4111cf4323eSThomas Huth uint8_t command;
4121cf4323eSThomas Huth uint8_t feature_low;
4131cf4323eSThomas Huth /* DW1 */
4141cf4323eSThomas Huth uint8_t lba_lo[3];
4151cf4323eSThomas Huth uint8_t device;
4161cf4323eSThomas Huth /* DW2 */
4171cf4323eSThomas Huth uint8_t lba_hi[3];
4181cf4323eSThomas Huth uint8_t feature_high;
4191cf4323eSThomas Huth /* DW3 */
4201cf4323eSThomas Huth uint16_t count;
4211cf4323eSThomas Huth uint8_t icc;
4221cf4323eSThomas Huth uint8_t control;
4231cf4323eSThomas Huth /* DW4 */
4241cf4323eSThomas Huth uint8_t aux[4];
4251cf4323eSThomas Huth } __attribute__((__packed__)) RegH2DFIS;
4261cf4323eSThomas Huth
4271cf4323eSThomas Huth /**
4281cf4323eSThomas Huth * Register host-to-device FIS structure, for NCQ commands.
4291cf4323eSThomas Huth * Actually just a RegH2DFIS, but with fields repurposed.
4301cf4323eSThomas Huth * Repurposed fields are annotated below.
4311cf4323eSThomas Huth */
4321cf4323eSThomas Huth typedef struct NCQFIS {
4331cf4323eSThomas Huth /* DW0 */
4341cf4323eSThomas Huth uint8_t fis_type;
4351cf4323eSThomas Huth uint8_t flags;
4361cf4323eSThomas Huth uint8_t command;
4371cf4323eSThomas Huth uint8_t sector_low; /* H2D: Feature 7:0 */
4381cf4323eSThomas Huth /* DW1 */
4391cf4323eSThomas Huth uint8_t lba_lo[3];
4401cf4323eSThomas Huth uint8_t device;
4411cf4323eSThomas Huth /* DW2 */
4421cf4323eSThomas Huth uint8_t lba_hi[3];
4431cf4323eSThomas Huth uint8_t sector_hi; /* H2D: Feature 15:8 */
4441cf4323eSThomas Huth /* DW3 */
4451cf4323eSThomas Huth uint8_t tag; /* H2D: Count 0:7 */
4461cf4323eSThomas Huth uint8_t prio; /* H2D: Count 15:8 */
4471cf4323eSThomas Huth uint8_t icc;
4481cf4323eSThomas Huth uint8_t control;
4491cf4323eSThomas Huth /* DW4 */
4501cf4323eSThomas Huth uint8_t aux[4];
4511cf4323eSThomas Huth } __attribute__((__packed__)) NCQFIS;
4521cf4323eSThomas Huth
4531cf4323eSThomas Huth /**
4541cf4323eSThomas Huth * Command List entry structure.
4551cf4323eSThomas Huth * The command list contains between 1-32 of these structures.
4561cf4323eSThomas Huth */
4571cf4323eSThomas Huth typedef struct AHCICommandHeader {
4581cf4323eSThomas Huth uint16_t flags; /* Cmd-Fis-Len, PMP#, and flags. */
4591cf4323eSThomas Huth uint16_t prdtl; /* Phys Region Desc. Table Length */
4601cf4323eSThomas Huth uint32_t prdbc; /* Phys Region Desc. Byte Count */
4611cf4323eSThomas Huth uint64_t ctba; /* Command Table Descriptor Base Address */
4621cf4323eSThomas Huth uint32_t res[4];
4631cf4323eSThomas Huth } __attribute__((__packed__)) AHCICommandHeader;
4641cf4323eSThomas Huth
4651cf4323eSThomas Huth /**
4661cf4323eSThomas Huth * Physical Region Descriptor; pointed to by the Command List Header,
4671cf4323eSThomas Huth * struct ahci_command.
4681cf4323eSThomas Huth */
4691cf4323eSThomas Huth typedef struct PRD {
4701cf4323eSThomas Huth uint64_t dba; /* Data Base Address */
4711cf4323eSThomas Huth uint32_t res; /* Reserved */
4721cf4323eSThomas Huth uint32_t dbc; /* Data Byte Count (0-indexed) & Interrupt Flag (bit 2^31) */
4731cf4323eSThomas Huth } __attribute__((__packed__)) PRD;
4741cf4323eSThomas Huth
4751cf4323eSThomas Huth /* Opaque, defined within ahci.c */
4761cf4323eSThomas Huth typedef struct AHCICommand AHCICommand;
4771cf4323eSThomas Huth
4781cf4323eSThomas Huth /* Options to ahci_exec */
4791cf4323eSThomas Huth typedef struct AHCIOpts {
4801cf4323eSThomas Huth size_t size; /* Size of transfer */
4811cf4323eSThomas Huth unsigned prd_size; /* Size per-each PRD */
4821cf4323eSThomas Huth bool set_bcl; /* Override the default BCL of ATAPI_SECTOR_SIZE */
4831cf4323eSThomas Huth unsigned bcl; /* Byte Count Limit, for ATAPI PIO */
4841cf4323eSThomas Huth uint64_t lba; /* Starting LBA offset */
4851cf4323eSThomas Huth uint64_t buffer; /* Pointer to source or destination guest buffer */
4861cf4323eSThomas Huth bool atapi; /* ATAPI command? */
4871cf4323eSThomas Huth bool atapi_dma; /* Use DMA for ATAPI? */
4881cf4323eSThomas Huth bool error;
4891cf4323eSThomas Huth int (*pre_cb)(AHCIQState*, AHCICommand*, const struct AHCIOpts *);
4901cf4323eSThomas Huth int (*mid_cb)(AHCIQState*, AHCICommand*, const struct AHCIOpts *);
4911cf4323eSThomas Huth int (*post_cb)(AHCIQState*, AHCICommand*, const struct AHCIOpts *);
4921cf4323eSThomas Huth void *opaque;
4931cf4323eSThomas Huth } AHCIOpts;
4941cf4323eSThomas Huth
4951cf4323eSThomas Huth /*** Macro Utilities ***/
4961cf4323eSThomas Huth #define BITANY(data, mask) (((data) & (mask)) != 0)
4971cf4323eSThomas Huth #define BITSET(data, mask) (((data) & (mask)) == (mask))
4981cf4323eSThomas Huth #define BITCLR(data, mask) (((data) & (mask)) == 0)
4991cf4323eSThomas Huth #define ASSERT_BIT_SET(data, mask) g_assert_cmphex((data) & (mask), ==, (mask))
5001cf4323eSThomas Huth #define ASSERT_BIT_CLEAR(data, mask) g_assert_cmphex((data) & (mask), ==, 0)
5011cf4323eSThomas Huth
5021cf4323eSThomas Huth /* For calculating how big the PRD table needs to be: */
5031cf4323eSThomas Huth #define CMD_TBL_SIZ(n) ((0x80 + ((n) * sizeof(PRD)) + 0x7F) & ~0x7F)
5041cf4323eSThomas Huth
5051cf4323eSThomas Huth /* Helpers for reading/writing AHCI HBA register values */
5061cf4323eSThomas Huth
ahci_mread(AHCIQState * ahci,size_t offset)5071cf4323eSThomas Huth static inline uint32_t ahci_mread(AHCIQState *ahci, size_t offset)
5081cf4323eSThomas Huth {
5091cf4323eSThomas Huth return qpci_io_readl(ahci->dev, ahci->hba_bar, offset);
5101cf4323eSThomas Huth }
5111cf4323eSThomas Huth
ahci_mwrite(AHCIQState * ahci,size_t offset,uint32_t value)5121cf4323eSThomas Huth static inline void ahci_mwrite(AHCIQState *ahci, size_t offset, uint32_t value)
5131cf4323eSThomas Huth {
5141cf4323eSThomas Huth qpci_io_writel(ahci->dev, ahci->hba_bar, offset, value);
5151cf4323eSThomas Huth }
5161cf4323eSThomas Huth
ahci_rreg(AHCIQState * ahci,uint32_t reg_num)5171cf4323eSThomas Huth static inline uint32_t ahci_rreg(AHCIQState *ahci, uint32_t reg_num)
5181cf4323eSThomas Huth {
5191cf4323eSThomas Huth return ahci_mread(ahci, 4 * reg_num);
5201cf4323eSThomas Huth }
5211cf4323eSThomas Huth
ahci_wreg(AHCIQState * ahci,uint32_t reg_num,uint32_t value)5221cf4323eSThomas Huth static inline void ahci_wreg(AHCIQState *ahci, uint32_t reg_num, uint32_t value)
5231cf4323eSThomas Huth {
5241cf4323eSThomas Huth ahci_mwrite(ahci, 4 * reg_num, value);
5251cf4323eSThomas Huth }
5261cf4323eSThomas Huth
ahci_set(AHCIQState * ahci,uint32_t reg_num,uint32_t mask)5271cf4323eSThomas Huth static inline void ahci_set(AHCIQState *ahci, uint32_t reg_num, uint32_t mask)
5281cf4323eSThomas Huth {
5291cf4323eSThomas Huth ahci_wreg(ahci, reg_num, ahci_rreg(ahci, reg_num) | mask);
5301cf4323eSThomas Huth }
5311cf4323eSThomas Huth
ahci_clr(AHCIQState * ahci,uint32_t reg_num,uint32_t mask)5321cf4323eSThomas Huth static inline void ahci_clr(AHCIQState *ahci, uint32_t reg_num, uint32_t mask)
5331cf4323eSThomas Huth {
5341cf4323eSThomas Huth ahci_wreg(ahci, reg_num, ahci_rreg(ahci, reg_num) & ~mask);
5351cf4323eSThomas Huth }
5361cf4323eSThomas Huth
ahci_px_offset(uint8_t port,uint32_t reg_num)5371cf4323eSThomas Huth static inline size_t ahci_px_offset(uint8_t port, uint32_t reg_num)
5381cf4323eSThomas Huth {
5391cf4323eSThomas Huth return AHCI_PORTS + (HBA_PORT_NUM_REG * port) + reg_num;
5401cf4323eSThomas Huth }
5411cf4323eSThomas Huth
ahci_px_rreg(AHCIQState * ahci,uint8_t port,uint32_t reg_num)5421cf4323eSThomas Huth static inline uint32_t ahci_px_rreg(AHCIQState *ahci, uint8_t port,
5431cf4323eSThomas Huth uint32_t reg_num)
5441cf4323eSThomas Huth {
5451cf4323eSThomas Huth return ahci_rreg(ahci, ahci_px_offset(port, reg_num));
5461cf4323eSThomas Huth }
5471cf4323eSThomas Huth
ahci_px_wreg(AHCIQState * ahci,uint8_t port,uint32_t reg_num,uint32_t value)5481cf4323eSThomas Huth static inline void ahci_px_wreg(AHCIQState *ahci, uint8_t port,
5491cf4323eSThomas Huth uint32_t reg_num, uint32_t value)
5501cf4323eSThomas Huth {
5511cf4323eSThomas Huth ahci_wreg(ahci, ahci_px_offset(port, reg_num), value);
5521cf4323eSThomas Huth }
5531cf4323eSThomas Huth
ahci_px_set(AHCIQState * ahci,uint8_t port,uint32_t reg_num,uint32_t mask)5541cf4323eSThomas Huth static inline void ahci_px_set(AHCIQState *ahci, uint8_t port,
5551cf4323eSThomas Huth uint32_t reg_num, uint32_t mask)
5561cf4323eSThomas Huth {
5571cf4323eSThomas Huth ahci_px_wreg(ahci, port, reg_num,
5581cf4323eSThomas Huth ahci_px_rreg(ahci, port, reg_num) | mask);
5591cf4323eSThomas Huth }
5601cf4323eSThomas Huth
ahci_px_clr(AHCIQState * ahci,uint8_t port,uint32_t reg_num,uint32_t mask)5611cf4323eSThomas Huth static inline void ahci_px_clr(AHCIQState *ahci, uint8_t port,
5621cf4323eSThomas Huth uint32_t reg_num, uint32_t mask)
5631cf4323eSThomas Huth {
5641cf4323eSThomas Huth ahci_px_wreg(ahci, port, reg_num,
5651cf4323eSThomas Huth ahci_px_rreg(ahci, port, reg_num) & ~mask);
5661cf4323eSThomas Huth }
5671cf4323eSThomas Huth
5681cf4323eSThomas Huth /*** Prototypes ***/
5691cf4323eSThomas Huth uint64_t ahci_alloc(AHCIQState *ahci, size_t bytes);
5701cf4323eSThomas Huth void ahci_free(AHCIQState *ahci, uint64_t addr);
5711cf4323eSThomas Huth void ahci_clean_mem(AHCIQState *ahci);
5721cf4323eSThomas Huth
5731cf4323eSThomas Huth /* Device management */
5741cf4323eSThomas Huth QPCIDevice *get_ahci_device(QTestState *qts, uint32_t *fingerprint);
5751cf4323eSThomas Huth void free_ahci_device(QPCIDevice *dev);
5761cf4323eSThomas Huth void ahci_pci_enable(AHCIQState *ahci);
5771cf4323eSThomas Huth void start_ahci_device(AHCIQState *ahci);
5781cf4323eSThomas Huth void ahci_hba_enable(AHCIQState *ahci);
5791cf4323eSThomas Huth
5801cf4323eSThomas Huth /* Port Management */
5811cf4323eSThomas Huth unsigned ahci_port_select(AHCIQState *ahci);
5821cf4323eSThomas Huth void ahci_port_clear(AHCIQState *ahci, uint8_t port);
5831cf4323eSThomas Huth
5841cf4323eSThomas Huth /* Command header / table management */
5851cf4323eSThomas Huth unsigned ahci_pick_cmd(AHCIQState *ahci, uint8_t port);
5861cf4323eSThomas Huth void ahci_get_command_header(AHCIQState *ahci, uint8_t port,
5871cf4323eSThomas Huth uint8_t slot, AHCICommandHeader *cmd);
5881cf4323eSThomas Huth void ahci_set_command_header(AHCIQState *ahci, uint8_t port,
5891cf4323eSThomas Huth uint8_t slot, AHCICommandHeader *cmd);
5901cf4323eSThomas Huth void ahci_destroy_command(AHCIQState *ahci, uint8_t port, uint8_t slot);
5911cf4323eSThomas Huth
5921cf4323eSThomas Huth /* AHCI sanity check routines */
593*1a16ce64SNiklas Cassel void ahci_port_check_error(AHCIQState *ahci, AHCICommand *cmd);
594*1a16ce64SNiklas Cassel void ahci_port_check_interrupts(AHCIQState *ahci, AHCICommand *cmd);
595*1a16ce64SNiklas Cassel void ahci_port_check_nonbusy(AHCIQState *ahci, AHCICommand *cmd);
5961cf4323eSThomas Huth void ahci_port_check_d2h_sanity(AHCIQState *ahci, uint8_t port, uint8_t slot);
5971cf4323eSThomas Huth void ahci_port_check_pio_sanity(AHCIQState *ahci, AHCICommand *cmd);
5981cf4323eSThomas Huth void ahci_port_check_cmd_sanity(AHCIQState *ahci, AHCICommand *cmd);
5991cf4323eSThomas Huth
6001cf4323eSThomas Huth /* Misc */
6011cf4323eSThomas Huth bool is_atapi(AHCIQState *ahci, uint8_t port);
6021cf4323eSThomas Huth
6031cf4323eSThomas Huth /* Command: Macro level execution */
6041cf4323eSThomas Huth void ahci_guest_io(AHCIQState *ahci, uint8_t port, uint8_t ide_cmd,
6051cf4323eSThomas Huth uint64_t gbuffer, size_t size, uint64_t sector);
6061cf4323eSThomas Huth AHCICommand *ahci_guest_io_halt(AHCIQState *ahci, uint8_t port, uint8_t ide_cmd,
6071cf4323eSThomas Huth uint64_t gbuffer, size_t size, uint64_t sector);
6081cf4323eSThomas Huth void ahci_guest_io_resume(AHCIQState *ahci, AHCICommand *cmd);
6091cf4323eSThomas Huth void ahci_io(AHCIQState *ahci, uint8_t port, uint8_t ide_cmd,
6101cf4323eSThomas Huth void *buffer, size_t bufsize, uint64_t sector);
6111cf4323eSThomas Huth void ahci_exec(AHCIQState *ahci, uint8_t port,
6121cf4323eSThomas Huth uint8_t op, const AHCIOpts *opts);
6131cf4323eSThomas Huth void ahci_atapi_test_ready(AHCIQState *ahci, uint8_t port, bool ready,
6141cf4323eSThomas Huth uint8_t expected_sense);
6151cf4323eSThomas Huth void ahci_atapi_get_sense(AHCIQState *ahci, uint8_t port,
6161cf4323eSThomas Huth uint8_t *sense, uint8_t *asc);
6171cf4323eSThomas Huth void ahci_atapi_eject(AHCIQState *ahci, uint8_t port);
6181cf4323eSThomas Huth void ahci_atapi_load(AHCIQState *ahci, uint8_t port);
6191cf4323eSThomas Huth
6201cf4323eSThomas Huth /* Command: Fine-grained lifecycle */
6211cf4323eSThomas Huth AHCICommand *ahci_command_create(uint8_t command_name);
6221cf4323eSThomas Huth AHCICommand *ahci_atapi_command_create(uint8_t scsi_cmd, uint16_t bcl, bool dma);
6231cf4323eSThomas Huth void ahci_command_commit(AHCIQState *ahci, AHCICommand *cmd, uint8_t port);
6241cf4323eSThomas Huth void ahci_command_issue(AHCIQState *ahci, AHCICommand *cmd);
6251cf4323eSThomas Huth void ahci_command_issue_async(AHCIQState *ahci, AHCICommand *cmd);
6261cf4323eSThomas Huth void ahci_command_wait(AHCIQState *ahci, AHCICommand *cmd);
6271cf4323eSThomas Huth void ahci_command_verify(AHCIQState *ahci, AHCICommand *cmd);
6281cf4323eSThomas Huth void ahci_command_free(AHCICommand *cmd);
6291cf4323eSThomas Huth
6301cf4323eSThomas Huth /* Command: adjustments */
6311cf4323eSThomas Huth void ahci_command_set_flags(AHCICommand *cmd, uint16_t cmdh_flags);
6321cf4323eSThomas Huth void ahci_command_clr_flags(AHCICommand *cmd, uint16_t cmdh_flags);
6331cf4323eSThomas Huth void ahci_command_set_offset(AHCICommand *cmd, uint64_t lba_sect);
6341cf4323eSThomas Huth void ahci_command_set_buffer(AHCICommand *cmd, uint64_t buffer);
6351cf4323eSThomas Huth void ahci_command_set_size(AHCICommand *cmd, uint64_t xbytes);
6361cf4323eSThomas Huth void ahci_command_set_prd_size(AHCICommand *cmd, unsigned prd_size);
6371cf4323eSThomas Huth void ahci_command_set_sizes(AHCICommand *cmd, uint64_t xbytes,
6381cf4323eSThomas Huth unsigned prd_size);
6391cf4323eSThomas Huth void ahci_command_set_acmd(AHCICommand *cmd, void *acmd);
6401cf4323eSThomas Huth void ahci_command_enable_atapi_dma(AHCICommand *cmd);
6411cf4323eSThomas Huth void ahci_command_adjust(AHCICommand *cmd, uint64_t lba_sect, uint64_t gbuffer,
6421cf4323eSThomas Huth uint64_t xbytes, unsigned prd_size);
6431cf4323eSThomas Huth
6441cf4323eSThomas Huth /* Command: Misc */
6451cf4323eSThomas Huth uint8_t ahci_command_slot(AHCICommand *cmd);
6461cf4323eSThomas Huth void ahci_write_fis(AHCIQState *ahci, AHCICommand *cmd);
6471cf4323eSThomas Huth
6481cf4323eSThomas Huth #endif
649