#define AHCI_MAX_PORTS 32
#define AHCI_MAX_CMDS 32
struct ahci_dma_prd {
uint64_t prd_dba;
uint32_t prd_res;
uint32_t prd_dbc;
#define AHCI_PRD_DBC_MASK 0x003fffff
#define AHCI_PRD_DBC_IPC 0x80000000
} __packed __aligned(8);
#define AHCI_NPRD ((MAXPHYS/PAGE_SIZE) + 1)
struct ahci_cmd_tbl {
uint8_t cmdt_cfis[64];
uint8_t cmdt_acmd[16];
uint8_t cmdt_res[48];
struct ahci_dma_prd cmdt_prd[1];
} __packed __aligned(8);
#define AHCI_CMDTBL_ALIGN 0x7f
#define AHCI_CMDTBL_SIZE ((sizeof(struct ahci_cmd_tbl) + \
(sizeof(struct ahci_dma_prd) * (AHCI_NPRD - 1)) + (AHCI_CMDTBL_ALIGN)) \
& ~AHCI_CMDTBL_ALIGN)
struct ahci_cmd_header {
uint16_t cmdh_flags;
#define AHCI_CMDH_F_PMP_MASK 0xf000
#define AHCI_CMDH_F_PMP_SHIFT 12
#define AHCI_CMDH_F_CBSY 0x0400
#define AHCI_CMDH_F_BIST 0x0200
#define AHCI_CMDH_F_RST 0x0100
#define AHCI_CMDH_F_PRF 0x0080
#define AHCI_CMDH_F_WR 0x0040
#define AHCI_CMDH_F_A 0x0020
#define AHCI_CMDH_F_CFL_MASK 0x001f
#define AHCI_CMDH_F_CFL_SHIFT 0
uint16_t cmdh_prdtl;
uint32_t cmdh_prdbc;
uint64_t cmdh_cmdtba;
uint32_t cmdh_res[4];
} __packed __aligned(8);
#define AHCI_CMDH_SIZE (sizeof(struct ahci_cmd_header) * AHCI_MAX_CMDS)
struct ahci_r_fis {
uint8_t rfis_dsfis[32];
uint8_t rfis_psfis[32];
uint8_t rfis_rfis[24];
uint8_t rfis_sdbfis[8];
uint8_t rfis_ukfis[64];
uint8_t rfis_res[96];
} __packed __aligned(8);
#define AHCI_RFIS_SIZE (sizeof(struct ahci_r_fis))
#define PCI_INTERFACE_SATA_AHCI 0x01
#define AHCI_PCI_ABAR 0x24
#define AHCI_CAP 0x00
#define AHCI_CAP_NPMASK 0x0000001f
#define AHCI_CAP_XS 0x00000020
#define AHCI_CAP_EM 0x00000040
#define AHCI_CAP_CCC 0x00000080
#define AHCI_CAP_NCS 0x00001f00
#define AHCI_CAP_PS 0x00002000
#define AHCI_CAP_SS 0x00004000
#define AHCI_CAP_PMD 0x00008000
#define AHCI_CAP_FBS 0x00010000
#define AHCI_CAP_SPM 0x00020000
#define AHCI_CAP_SAM 0x00040000
#define AHCI_CAP_NZO 0x00080000
#define AHCI_CAP_IS 0x00f00000
#define AHCI_CAP_IS_GEN1 0x00100000
#define AHCI_CAP_IS_GEN2 0x00200000
#define AHCI_CAP_IS_GEN3 0x00300000
#define AHCI_CAP_CLO 0x01000000
#define AHCI_CAP_AL 0x02000000
#define AHCI_CAP_ALP 0x04000000
#define AHCI_CAP_SSU 0x08000000
#define AHCI_CAP_MPS 0x10000000
#define AHCI_CAP_NTF 0x20000000
#define AHCI_CAP_NCQ 0x40000000
#define AHCI_CAP_64BIT 0x80000000
#define AHCI_GHC 0x04
#define AHCI_GHC_HR 0x00000001
#define AHCI_GHC_IE 0x00000002
#define AHCI_GHC_MRSM 0x00000004
#define AHCI_GHC_AE 0x80000000
#define AHCI_IS 0x08
#define AHCI_PI 0x0c
#define AHCI_VS 0x10
#define AHCI_VS_095 0x00000905
#define AHCI_VS_100 0x00010000
#define AHCI_VS_110 0x00010100
#define AHCI_VS_120 0x00010200
#define AHCI_VS_130 0x00010300
#define AHCI_VS_MJR(v) ((unsigned int)__SHIFTOUT(v, __BITS(31, 16)))
#define AHCI_VS_MNR(v) ((unsigned int)__SHIFTOUT(v, __BITS(15, 8)) * 10 + (unsigned int)__SHIFTOUT(v, __BITS(7, 0) * 1))
#define AHCI_CC_CTL 0x14
#define AHCI_CC_TV_MASK 0xffff0000
#define AHCI_CC_TV_SHIFT 16
#define AHCI_CC_CC_MASK 0x0000ff00
#define AHCI_CC_CC_SHIFT 8
#define AHCI_CC_INT_MASK 0x000000f8
#define AHCI_CC_INT_SHIFT 3
#define AHCI_CC_EN 0x000000001
#define AHCI_CC_PORTS 0x18
#define AHCI_EM_LOC 0x1c
#define AHCI_EML_OFF_MASK 0xffff0000
#define AHCI_EML_OFF_SHIFT 16
#define AHCI_EML_SZ_MASK 0x0000ffff
#define AHCI_EML_SZ_SHIFT 0
#define AHCI_EM_CTL 0x20
#define AHCI_EMC_PM 0x08000000
#define AHCI_EMC_ALHD 0x04000000
#define AHCI_EMC_XMIT 0x02000000
#define AHCI_EMC_SMB 0x01000000
#define AHCI_EMC_SGPIO 0x00080000
#define AHCI_EMC_SES2 0x00040000
#define AHCI_EMC_SAF 0x00020000
#define AHCI_EMC_LED 0x00010000
#define AHCI_EMC_RST 0x00000200
#define AHCI_EMC_TM 0x00000100
#define AHCI_EMC_MR 0x00000001
#define AHCI_CAP2 0x24
#define AHCI_CAP2_APST 0x00000004
#define AHCI_CAP2_NVMP 0x00000002
#define AHCI_CAP2_BOH 0x00000001
#define AHCI_BOHC 0x28
#define AHCI_BOHC_BB 0x00000010
#define AHCI_BOHC_OOC 0x00000008
#define AHCI_BOHC_SOOE 0x00000004
#define AHCI_BOHC_OOS 0x00000002
#define AHCI_BOHC_BOS 0x00000001
#define AHCI_P_OFFSET(port) (0x80 * (port))
#define AHCI_P_CLB(p) (0x100 + AHCI_P_OFFSET(p))
#define AHCI_P_CLBU(p) (0x104 + AHCI_P_OFFSET(p))
#define AHCI_P_FB(p) (0x108 + AHCI_P_OFFSET(p))
#define AHCI_P_FBU(p) (0x10c + AHCI_P_OFFSET(p))
#define AHCI_P_IS(p) (0x110 + AHCI_P_OFFSET(p))
#define AHCI_P_IE(p) (0x114 + AHCI_P_OFFSET(p))
#define AHCI_P_IX_CPDS 0x80000000
#define AHCI_P_IX_TFES 0x40000000
#define AHCI_P_IX_HBFS 0x20000000
#define AHCI_P_IX_HBDS 0x10000000
#define AHCI_P_IX_IFS 0x08000000
#define AHCI_P_IX_INFS 0x04000000
#define AHCI_P_IX_OFS 0x01000000
#define AHCI_P_IX_IPMS 0x00800000
#define AHCI_P_IX_PRCS 0x00400000
#define AHCI_P_IX_DMPS 0x00000080
#define AHCI_P_IX_PCS 0x00000040
#define AHCI_P_IX_DPS 0x00000020
#define AHCI_P_IX_UFS 0x00000010
#define AHCI_P_IX_SDBS 0x00000008
#define AHCI_P_IX_DSS 0x00000004
#define AHCI_P_IX_PSS 0x00000002
#define AHCI_P_IX_DHRS 0x00000001
#define AHCI_P_CMD(p) (0x118 + AHCI_P_OFFSET(p))
#define AHCI_P_CMD_ICC_MASK 0xf0000000
#define AHCI_P_CMD_ICC_SL 0x60000000
#define AHCI_P_CMD_ICC_PA 0x20000000
#define AHCI_P_CMD_ICC_AC 0x10000000
#define AHCI_P_CMD_ICC_NO 0x00000000
#define AHCI_P_CMD_ASP 0x08000000
#define AHCI_P_CMD_ALPE 0x04000000
#define AHCI_P_CMD_DLAE 0x02000000
#define AHCI_P_CMD_ATAP 0x01000000
#define AHCI_P_CMD_ESP 0x00200000
#define AHCI_P_CMD_CPD 0x00100000
#define AHCI_P_CMD_MPSP 0x00080000
#define AHCI_P_CMD_HPCP 0x00040000
#define AHCI_P_CMD_PMA 0x00020000
#define AHCI_P_CMD_CPS 0x00010000
#define AHCI_P_CMD_CR 0x00008000
#define AHCI_P_CMD_FR 0x00004000
#define AHCI_P_CMD_MPSS 0x00002000
#define AHCI_P_CMD_CCS_MASK __BITS(12, 8)
#define AHCI_P_CMD_CCS_SHIFT 8
#define AHCI_P_CMD_FRE 0x00000010
#define AHCI_P_CMD_CLO 0x00000008
#define AHCI_P_CMD_POD 0x00000004
#define AHCI_P_CMD_SUD 0x00000002
#define AHCI_P_CMD_ST 0x00000001
#define AHCI_P_TFD(p) (0x120 + AHCI_P_OFFSET(p))
#define AHCI_P_TFD_ERR_MASK 0x0000ff00
#define AHCI_P_TFD_ERR_SHIFT 8
#define AHCI_P_TFD_ST 0x000000ff
#define AHCI_P_TFD_ST_SHIFT 0
#define AHCI_TFD_ERR(tfd) \
(((tfd) & AHCI_P_TFD_ERR_MASK) >> AHCI_P_TFD_ERR_SHIFT)
#define AHCI_TFD_ST(tfd) \
(((tfd) & AHCI_P_TFD_ST) >> AHCI_P_TFD_ST_SHIFT)
#define AHCI_P_SIG(p) (0x124 + AHCI_P_OFFSET(p))
#define AHCI_P_SIG_LBAH_MASK 0xff000000
#define AHCI_P_SIG_LBAH_SHIFT 24
#define AHCI_P_SIG_LBAM_MASK 0x00ff0000
#define AHCI_P_SIG_LBAM_SHIFT 16
#define AHCI_P_SIG_LBAL_MASK 0x0000ff00
#define AHCI_P_SIG_LBAL_SHIFT 8
#define AHCI_P_SIG_SC_MASK 0x000000ff
#define AHCI_P_SIG_SC_SHIFT 0
#define AHCI_P_SSTS(p) (0x128 + AHCI_P_OFFSET(p))
#define AHCI_P_SCTL(p) (0x12c + AHCI_P_OFFSET(p))
#define AHCI_P_SERR(p) (0x130 + AHCI_P_OFFSET(p))
#define AHCI_P_SACT(p) (0x134 + AHCI_P_OFFSET(p))
#define AHCI_P_CI(p) (0x138 + AHCI_P_OFFSET(p))
#define AHCI_P_FNTF(p) (0x13c + AHCI_P_OFFSET(p))
#define AHCI_P_FBS(p) (0x140 + AHCI_P_OFFSET(p))
#define AHCI_P_FBS_EN 0x00000001
#define AHCI_P_FBS_DEC 0x00000002
#define AHCI_P_FBS_SDE 0x00000004
#define AHCI_P_FBS_DEV 0x00000f00
#define AHCI_P_FBS_DEV_SHIFT 8
#define AHCI_P_FBS_ADO 0x0000f000
#define AHCI_P_FBS_ADO_SHIFT 12
#define AHCI_P_FBS_DWE 0x000f0000
#define AHCI_P_FBS_DWE_SHIFT 16