1 /*
2  * Copyright (c) 2006-2023, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2023-02-25     GuEe-GUI     the first version
9  */
10 
11 #ifndef __AHCI_H__
12 #define __AHCI_H__
13 
14 #include <rthw.h>
15 #include <rtthread.h>
16 #include <drivers/scsi.h>
17 #include <drivers/misc.h>
18 
19 struct rt_ahci_ops;
20 
21 /* Generic Host Control */
22 #define RT_AHCI_HBA_CAP                     0x00    /* Host capability*/
23 #define   RT_AHCI_CAP_NP                    RT_GENMASK(4, 0)    /* Number of Ports */
24 #define   RT_AHCI_CAP_NCS                   RT_GENMASK(8, 12)   /* Number of Command Slots */
25 #define   RT_AHCI_CAP_PSC                   RT_BIT(13)          /* Partial State Capable */
26 #define   RT_AHCI_CAP_SSC                   RT_BIT(14)          /* Slumber capable */
27 #define   RT_AHCI_CAP_PMD                   RT_BIT(15)          /* PIO Multiple DRQ Block */
28 #define   RT_AHCI_CAP_SPM                   RT_BIT(17)          /* Port Multiplier */
29 #define   RT_AHCI_CAP_AHCI                  RT_BIT(18)          /* AHCI only */
30 #define   RT_AHCI_CAP_SNZO                  RT_BIT(19)          /* Non-Zero DMA Offsets */
31 #define   RT_AHCI_CAP_ISS                   RT_GENMASK(23, 20)  /* Interface Speed Support */
32 #define   RT_AHCI_CAP_CLO                   RT_BIT(24)          /* Command List Override support */
33 #define   RT_AHCI_CAP_SAL                   RT_BIT(25)          /* Activity LED */
34 #define   RT_AHCI_CAP_SALP                  RT_BIT(26)          /* Aggressive Link Power Management */
35 #define   RT_AHCI_CAP_SSS                   RT_BIT(27)          /* Staggered Spin-up */
36 #define   RT_AHCI_CAP_SIS                   RT_BIT(28)          /* Interlock Switch */
37 #define   RT_AHCI_CAP_NCQ                   RT_BIT(30)          /* Native Command Queueing */
38 #define   RT_AHCI_CAP_64                    RT_BIT(31)          /* PCI DAC (64-bit DMA) support */
39 #define RT_AHCI_HBA_GHC                     0x04    /* Global host control */
40 #define   RT_AHCI_GHC_RESET                 RT_BIT(0)           /* Reset controller; self-clear */
41 #define   RT_AHCI_GHC_IRQ_EN                RT_BIT(1)           /* Global IRQ enable */
42 #define   RT_AHCI_GHC_AHCI_EN               RT_BIT(31)          /* AHCI enabled */
43 #define RT_AHCI_HBA_INTS                    0x08    /* Interrupt status */
44 #define RT_AHCI_HBA_PI                      0x0c    /* Port implemented */
45 #define RT_AHCI_HBA_VS                      0x10    /* Version */
46 #define RT_AHCI_HBA_CCC_CTL                 0x14    /* Command completion coalescing control */
47 #define RT_AHCI_HBA_CCC_PTS                 0x18    /* Command completion coalescing ports */
48 #define RT_AHCI_HBA_EM_LOC                  0x1c    /* Enclosure management location */
49 #define RT_AHCI_HBA_EM_CTL                  0x20    /* Enclosure management control */
50 #define RT_AHCI_HBA_CAP2                    0x24    /* Host capabilities extended */
51 #define RT_AHCI_HBA_BOHC                    0x28    /* BIOS/OS handoff control and status */
52 #define RT_AHCI_HBA_VENDOR                  0xa0    /* Vendor specific registers (0xa0 - 0xff) */
53 
54 #define RT_AHCI_PORT_CLB                    0x00    /* Command list base address, 1K-byte aligned */
55 #define RT_AHCI_PORT_CLBU                   0x04    /* Command list base address upper 32 bits */
56 #define RT_AHCI_PORT_FB                     0x08    /* FIS base address, 256-byte aligned */
57 #define RT_AHCI_PORT_FBU                    0x0C    /* FIS base address upper 32 bits */
58 #define RT_AHCI_PORT_INTS                   0x10    /* Interrupt status */
59 #define RT_AHCI_PORT_INTE                   0x14    /* Interrupt enable */
60 #define   RT_AHCI_PORT_INTE_D2H_REG_FIS     RT_BIT(0)           /* D2H Register FIS rx'd */
61 #define   RT_AHCI_PORT_INTE_PIOS_FIS        RT_BIT(1)           /* PIO Setup FIS rx'd */
62 #define   RT_AHCI_PORT_INTE_DMAS_FIS        RT_BIT(2)           /* DMA Setup FIS rx'd */
63 #define   RT_AHCI_PORT_INTE_SDB_FIS         RT_BIT(3)           /* Set Device Bits FIS rx'd */
64 #define   RT_AHCI_PORT_INTE_UNK_FIS         RT_BIT(4)           /* Unknown FIS rx'd */
65 #define   RT_AHCI_PORT_INTE_SG_DONE         RT_BIT(5)           /* Descriptor processed */
66 #define   RT_AHCI_PORT_INTE_CONNECT         RT_BIT(6)           /* Port connect change status */
67 #define   RT_AHCI_PORT_INTE_DMPS            RT_BIT(7)           /* Mechanical presence status */
68 #define   RT_AHCI_PORT_INTE_PHYRDY          RT_BIT(22)          /* PhyRdy changed */
69 #define   RT_AHCI_PORT_INTE_BAD_PMP         RT_BIT(23)          /* Incorrect port multiplier */
70 #define   RT_AHCI_PORT_INTE_OVERFLOW        RT_BIT(24)          /* Xfer exhausted available S/G */
71 #define   RT_AHCI_PORT_INTE_IF_NONFATAL     RT_BIT(26)          /* Interface non-fatal error */
72 #define   RT_AHCI_PORT_INTE_IF_ERR          RT_BIT(27)          /* Interface fatal error */
73 #define   RT_AHCI_PORT_INTE_HBUS_DATA_ERR   RT_BIT(28)          /* Host bus data error */
74 #define   RT_AHCI_PORT_INTE_HBUS_ERR        RT_BIT(29)          /* Host bus fatal error */
75 #define   RT_AHCI_PORT_INTE_TF_ERR          RT_BIT(30)          /* Task file error */
76 #define   RT_AHCI_PORT_INTE_COLD_PRES       RT_BIT(31)          /* Cold presence detect */
77 #define RT_AHCI_PORT_CMD                    0x18    /* Command and status */
78 #define   RT_AHCI_PORT_CMD_START            RT_BIT(0)           /* Enable port DMA engine */
79 #define   RT_AHCI_PORT_CMD_SPIN_UP          RT_BIT(1)           /* Spin up device */
80 #define   RT_AHCI_PORT_CMD_POWER_ON         RT_BIT(2)           /* Power up device */
81 #define   RT_AHCI_PORT_CMD_CLO              RT_BIT(3)           /* Command list override */
82 #define   RT_AHCI_PORT_CMD_FIS_RX           RT_BIT(4)           /* Enable FIS receive DMA engine */
83 #define   RT_AHCI_PORT_CMD_FIS_ON           RT_BIT(14)          /* FIS DMA engine running */
84 #define   RT_AHCI_PORT_CMD_LIST_ON          RT_BIT(15)          /* cmd list DMA engine running */
85 #define   RT_AHCI_PORT_CMD_ATAPI            RT_BIT(24)          /* Device is ATAPI */
86 #define   RT_AHCI_PORT_CMD_ACTIVE           RT_BIT(28)          /* Active state */
87 #define RT_AHCI_PORT_TFD                    0x20    /* Task file data */
88 #define   RT_AHCI_PORT_TFDATA_ERR           RT_BIT(0)           /* Indicates an error during the transfer */
89 #define   RT_AHCI_PORT_TFDATA_DRQ           RT_BIT(3)           /* Indicates a data transfer is requested */
90 #define   RT_AHCI_PORT_TFDATA_BSY           RT_BIT(7)           /* Indicates the interface is busy */
91 #define RT_AHCI_PORT_SIG                    0x24    /* Signature */
92 #define   RT_AHCI_PORT_SIG_REG_MASK         0xff
93 #define   RT_AHCI_PORT_SIG_SECTOR_NR_SHIFT  0       /* Sector Count Register */
94 #define   RT_AHCI_PORT_SIG_LBA_LOW_SHIFT    8       /* LBA Low Register */
95 #define   RT_AHCI_PORT_SIG_LBA_MID_SHIFT    16      /* LBA Mid Register */
96 #define   RT_AHCI_PORT_SIG_LBA_HIGH_SHIFT   24      /* LBA High Register */
97 #define RT_AHCI_PORT_SIG_SATA_CDROM         0xeb140101
98 #define RT_AHCI_PORT_SIG_SATA_DISK          0x00000101
99 #define RT_AHCI_PORT_SSTS                   0x28    /* SATA status (SCR0:SStatus) */
100 #define   RT_AHCI_PORT_SSTS_DET_MASK        0x3
101 #define   RT_AHCI_PORT_SSTS_DET_COMINIT     0x1
102 #define   RT_AHCI_PORT_SSTS_DET_PHYRDY      0x3
103 #define RT_AHCI_PORT_SCTL                   0x2c    /* SATA control (SCR2:SControl) */
104 #define RT_AHCI_PORT_SERR                   0x30    /* SATA error (SCR1:SError) */
105 #define   RT_AHCI_PORT_SERR_ERR_I           RT_BIT(0)           /* Recovered Data Integrity Error */
106 #define   RT_AHCI_PORT_SERR_ERR_M           RT_BIT(1)           /* Recovered Communications Error */
107 #define   RT_AHCI_PORT_SERR_ERR_T           RT_BIT(8)           /* Transient Data Integrity Error */
108 #define   RT_AHCI_PORT_SERR_ERR_C           RT_BIT(9)           /* Persistent Communication or Data Integrity Error */
109 #define   RT_AHCI_PORT_SERR_ERR_P           RT_BIT(10)          /* Protocol Error */
110 #define   RT_AHCI_PORT_SERR_ERR_E           RT_BIT(11)          /* Internal Error */
111 #define   RT_AHCI_PORT_SERR_DIAG_N          RT_BIT(16)          /* PhyRdy Change */
112 #define   RT_AHCI_PORT_SERR_DIAG_I          RT_BIT(17)          /* Phy Internal Error */
113 #define   RT_AHCI_PORT_SERR_DIAG_W          RT_BIT(18)          /* Comm Wake */
114 #define   RT_AHCI_PORT_SERR_DIAG_B          RT_BIT(19)          /* 10B to 8B Decode Error */
115 #define   RT_AHCI_PORT_SERR_DIAG_D          RT_BIT(20)          /* Disparity Error */
116 #define   RT_AHCI_PORT_SERR_DIAG_C          RT_BIT(21)          /* CRC Error */
117 #define   RT_AHCI_PORT_SERR_DIAG_H          RT_BIT(22)          /* Handshake Error */
118 #define   RT_AHCI_PORT_SERR_DIAG_S          RT_BIT(23)          /* Link Sequence Error */
119 #define   RT_AHCI_PORT_SERR_DIAG_T          RT_BIT(24)          /* Transport state transition error */
120 #define   RT_AHCI_PORT_SERR_DIAG_F          RT_BIT(25)          /* Unknown FIS Type */
121 #define   RT_AHCI_PORT_SERR_DIAG_X          RT_BIT(26)          /* Exchanged */
122 #define RT_AHCI_PORT_SACT                   0x34    /* SATA active (SCR3:SActive) */
123 #define RT_AHCI_PORT_CI                     0x38    /* Command issue */
124 #define RT_AHCI_PORT_SNTF                   0x3c    /* SATA notification (SCR4:SNotification) */
125 #define RT_AHCI_PORT_FBS                    0x40    /* FIS-based switch control */
126 #define RT_AHCI_PORT_VENDOR                 0x70    /* Vendor specific (0x70 - 0x7f) */
127 
128 #define RT_AHCI_MAX_SG                      56
129 #define RT_AHCI_CMD_SLOT_SIZE               32
130 #define RT_AHCI_MAX_CMD_SLOT                32
131 #define RT_AHCI_RX_FIS_SIZE                 256
132 #define RT_AHCI_CMD_TBL_HDR                 0x80
133 #define RT_AHCI_CMD_TBL_CDB                 0x40
134 #define RT_AHCI_CMD_TBL_SIZE                RT_AHCI_CMD_TBL_HDR + (RT_AHCI_MAX_SG * 16)
135 #define RT_AHCI_DMA_SIZE                    (RT_AHCI_CMD_SLOT_SIZE * RT_AHCI_MAX_CMD_SLOT + RT_AHCI_CMD_TBL_SIZE + RT_AHCI_RX_FIS_SIZE)
136 #define RT_ACHI_PRDT_BYTES_MAX              (4 * 1024 * 1024)
137 
138 #define RT_AHCI_FIS_TYPE_REG_H2D            0x27    /* Register FIS - host to device */
139 #define RT_AHCI_FIS_TYPE_REG_D2H            0x34    /* Register FIS - device to host */
140 #define RT_AHCI_FIS_TYPE_DMA_ACT            0x39    /* DMA activate FIS - device to host */
141 #define RT_AHCI_FIS_TYPE_DMA_SETUP          0x41    /* DMA setup FIS - bidirectional */
142 #define RT_AHCI_FIS_TYPE_DATA               0x46    /* Data FIS - bidirectional */
143 #define RT_AHCI_FIS_TYPE_BIST               0x58    /* BIST activate FIS - bidirectional */
144 #define RT_AHCI_FIS_TYPE_PIO_SETUP          0x5f    /* PIO setup FIS - device to host */
145 #define RT_AHCI_FIS_TYPE_DEV_BITS           0xa1    /* Set device bits FIS - device to host */
146 
147 #define RT_AHCI_ATA_ID_WORDS                256
148 #define RT_AHCI_ATA_ID_CONFIG               0
149 #define RT_AHCI_ATA_ID_CYLS                 1
150 #define RT_AHCI_ATA_ID_HEADS                3
151 #define RT_AHCI_ATA_ID_SECTORS              6
152 #define RT_AHCI_ATA_ID_SERNO                10
153 #define RT_AHCI_ATA_ID_BUF_SIZE             21
154 #define RT_AHCI_ATA_ID_FW_REV               23
155 #define RT_AHCI_ATA_ID_PROD                 27
156 #define RT_AHCI_ATA_ID_MAX_MULTSECT         47
157 #define RT_AHCI_ATA_ID_DWORD_IO             48
158 #define RT_AHCI_ATA_ID_TRUSTED              48
159 #define RT_AHCI_ATA_ID_CAPABILITY           49
160 #define RT_AHCI_ATA_ID_OLD_PIO_MODES        51
161 #define RT_AHCI_ATA_ID_OLD_DMA_MODES        52
162 #define RT_AHCI_ATA_ID_FIELD_VALID          53
163 #define RT_AHCI_ATA_ID_CUR_CYLS             54
164 #define RT_AHCI_ATA_ID_CUR_HEADS            55
165 #define RT_AHCI_ATA_ID_CUR_SECTORS          56
166 #define RT_AHCI_ATA_ID_MULTSECT             59
167 #define RT_AHCI_ATA_ID_LBA_CAPACITY         60
168 #define RT_AHCI_ATA_ID_SWDMA_MODES          62
169 #define RT_AHCI_ATA_ID_MWDMA_MODES          63
170 #define RT_AHCI_ATA_ID_PIO_MODES            64
171 #define RT_AHCI_ATA_ID_EIDE_DMA_MIN         65
172 #define RT_AHCI_ATA_ID_EIDE_DMA_TIME        66
173 #define RT_AHCI_ATA_ID_EIDE_PIO             67
174 #define RT_AHCI_ATA_ID_EIDE_PIO_IORDY       68
175 #define RT_AHCI_ATA_ID_ADDITIONAL_SUPP      69
176 #define RT_AHCI_ATA_ID_QUEUE_DEPTH          75
177 #define RT_AHCI_ATA_ID_SATA_CAPABILITY      76
178 #define RT_AHCI_ATA_ID_SATA_CAPABILITY_2    77
179 #define RT_AHCI_ATA_ID_FEATURE_SUPP         78
180 #define RT_AHCI_ATA_ID_MAJOR_VER            80
181 #define RT_AHCI_ATA_ID_COMMAND_SET_1        82
182 #define RT_AHCI_ATA_ID_COMMAND_SET_2        83
183 #define RT_AHCI_ATA_ID_CFSSE                84
184 #define RT_AHCI_ATA_ID_CFS_ENABLE_1         85
185 #define RT_AHCI_ATA_ID_CFS_ENABLE_2         86
186 #define RT_AHCI_ATA_ID_CSF_DEFAULT          87
187 #define RT_AHCI_ATA_ID_UDMA_MODES           88
188 #define RT_AHCI_ATA_ID_HW_CONFIG            93
189 #define RT_AHCI_ATA_ID_SPG                  98
190 #define RT_AHCI_ATA_ID_LBA_CAPACITY_2       100
191 #define RT_AHCI_ATA_ID_SECTOR_SIZE          106
192 #define RT_AHCI_ATA_ID_WWN                  108
193 #define RT_AHCI_ATA_ID_LOGICAL_SECTOR_SIZE  117
194 #define RT_AHCI_ATA_ID_COMMAND_SET_3        119
195 #define RT_AHCI_ATA_ID_COMMAND_SET_4        120
196 #define RT_AHCI_ATA_ID_LAST_LUN             126
197 #define RT_AHCI_ATA_ID_DLF                  128
198 #define RT_AHCI_ATA_ID_CSFO                 129
199 #define RT_AHCI_ATA_ID_CFA_POWER            160
200 #define RT_AHCI_ATA_ID_CFA_KEY_MGMT         162
201 #define RT_AHCI_ATA_ID_CFA_MODES            163
202 #define RT_AHCI_ATA_ID_DATA_SET_MGMT        169
203 #define RT_AHCI_ATA_ID_SCT_CMD_XPORT        206
204 #define RT_AHCI_ATA_ID_ROT_SPEED            217
205 #define RT_AHCI_ATA_ID_PIO4                 (1 << 1)
206 #define RT_AHCI_ATA_ID_SERNO_LEN            20
207 #define RT_AHCI_ATA_ID_FW_REV_LEN           8
208 #define RT_AHCI_ATA_ID_PROD_LEN             40
209 #define RT_AHCI_ATA_ID_WWN_LEN              8
210 
211 #define RT_AHCI_ATA_CMD_DSM                 0x06
212 #define RT_AHCI_ATA_CMD_DEV_RESET           0x08    /* ATAPI device reset */
213 #define RT_AHCI_ATA_CMD_PIO_READ            0x20    /* Read sectors with retry */
214 #define RT_AHCI_ATA_CMD_PIO_READ_EXT        0x24
215 #define RT_AHCI_ATA_CMD_READ_EXT            0x25
216 #define RT_AHCI_ATA_CMD_READ_NATIVE_MAX_EXT 0x27
217 #define RT_AHCI_ATA_CMD_READ_MULTI_EXT      0x29
218 #define RT_AHCI_ATA_CMD_READ_LOG_EXT        0x2f
219 #define RT_AHCI_ATA_CMD_PIO_WRITE           0x30    /* Write sectors with retry */
220 #define RT_AHCI_ATA_CMD_PIO_WRITE_EXT       0x34
221 #define RT_AHCI_ATA_CMD_WRITE_EXT           0x35
222 #define RT_AHCI_ATA_CMD_SET_MAX_EXT         0x37
223 #define RT_AHCI_ATA_CMD_WRITE_MULTI_EXT     0x39
224 #define RT_AHCI_ATA_CMD_WRITE_FUA_EXT       0x3d
225 #define RT_AHCI_ATA_CMD_VERIFY              0x40    /* Read verify sectors with retry */
226 #define RT_AHCI_ATA_CMD_VERIFY_EXT          0x42
227 #define RT_AHCI_ATA_CMD_FPDMA_READ          0x60
228 #define RT_AHCI_ATA_CMD_FPDMA_WRITE         0x61
229 #define RT_AHCI_ATA_CMD_EDD                 0x90    /* Execute device diagnostic */
230 #define RT_AHCI_ATA_CMD_INIT_DEV_PARAMS     0x91    /* Initialize device parameters */
231 #define RT_AHCI_ATA_CMD_PACKET              0xa0    /* ATAPI packet */
232 #define RT_AHCI_ATA_CMD_ID_ATAPI            0xa1    /* ATAPI identify device */
233 #define RT_AHCI_ATA_CMD_CONF_OVERLAY        0xb1
234 #define RT_AHCI_ATA_CMD_READ_MULTI          0xc4    /* Read multiple */
235 #define RT_AHCI_ATA_CMD_WRITE_MULTI         0xc5    /* Write multiple */
236 #define RT_AHCI_ATA_CMD_SET_MULTI           0xc6    /* Set multiple mode */
237 #define RT_AHCI_ATA_CMD_READ                0xc8    /* Read DMA with retry */
238 #define RT_AHCI_ATA_CMD_WRITE               0xca    /* Write DMA with retry */
239 #define RT_AHCI_ATA_CMD_WRITE_MULTI_FUA_EXT 0xce
240 #define RT_AHCI_ATA_CMD_STANDBYNOW1         0xe0    /* Standby immediate */
241 #define RT_AHCI_ATA_CMD_IDLEIMMEDIATE       0xe1    /* Idle immediate */
242 #define RT_AHCI_ATA_CMD_STANDBY             0xe2    /* Place in standby power mode */
243 #define RT_AHCI_ATA_CMD_IDLE                0xe3    /* Place in idle power mode */
244 #define RT_AHCI_ATA_CMD_PMP_READ            0xe4    /* Read buffer */
245 #define RT_AHCI_ATA_CMD_CHK_POWER           0xe5    /* Check power mode */
246 #define RT_AHCI_ATA_CMD_SLEEP               0xe6    /* Sleep */
247 #define RT_AHCI_ATA_CMD_FLUSH               0xe7
248 #define RT_AHCI_ATA_CMD_PMP_WRITE           0xe8    /* Write buffer */
249 #define RT_AHCI_ATA_CMD_FLUSH_EXT           0xea
250 #define RT_AHCI_ATA_CMD_ID_ATA              0xec    /* Identify device */
251 #define RT_AHCI_ATA_CMD_SET_FEATURES        0xef    /* Set features */
252 #define RT_AHCI_ATA_CMD_SEC_FREEZE_LOCK     0xf5    /* Security freeze */
253 #define RT_AHCI_ATA_CMD_READ_NATIVE_MAX     0xf8
254 #define RT_AHCI_ATA_CMD_SET_MAX             0xf9
255 
256 #define RT_AHCI_ATA_DSM_TRIM                0x01
257 
258 #define RT_AHCI_ATA_PROT_FLAG_PIO           RT_BIT(0)
259 #define RT_AHCI_ATA_PROT_FLAG_DMA           RT_BIT(1)
260 #define RT_AHCI_ATA_PROT_FLAG_NCQ           RT_BIT(2)
261 #define RT_AHCI_ATA_PROT_FLAG_ATAPI         RT_BIT(3)
262 
263 #define rt_ahci_ata_id_is_ata(id)           (((id)[0] & (1 << 15)) == 0)
264 #define rt_ahci_ata_id_has_lba(id)          ((id)[49] & (1 << 9))
265 #define rt_ahci_ata_id_has_dma(id)          ((id)[49] & (1 << 8))
266 #define rt_ahci_ata_id_has_ncq(id)          ((id)[76] & (1 << 8))
267 #define rt_ahci_ata_id_queue_depth(id)      (((id)[75] & 0x1f) + 1)
268 #define rt_ahci_ata_id_removeable(id)       ((id)[0] & (1 << 7))
269 #define rt_ahci_ata_id_iordy_disable(id)    ((id)[49] & (1 << 10))
270 #define rt_ahci_ata_id_has_iordy(id)        ((id)[49] & (1 << 11))
271 
272 #define rt_ahci_ata_id_u32(id, n)           (((rt_uint32_t)(id)[(n) + 1] << 16) | ((rt_uint32_t) (id)[(n)]))
273 #define rt_ahci_ata_id_u64(id, n)           (((rt_uint64_t)(id)[(n) + 3] << 48) | ((rt_uint64_t)(id)[(n) + 2] << 32) | \
274                                             ((rt_uint64_t)(id)[(n) + 1] << 16) | ((rt_uint64_t)(id)[(n) + 0]) )
275 
rt_ahci_ata_id_has_lba48(const rt_uint16_t * id)276 rt_inline rt_bool_t rt_ahci_ata_id_has_lba48(const rt_uint16_t *id)
277 {
278     if ((id[RT_AHCI_ATA_ID_COMMAND_SET_2] & 0xc000) != 0x4000 ||
279         !rt_ahci_ata_id_u64(id, RT_AHCI_ATA_ID_LBA_CAPACITY_2))
280     {
281         return 0;
282     }
283 
284     return !!(id[RT_AHCI_ATA_ID_COMMAND_SET_2] & (1 << 10));
285 }
286 
rt_ahci_ata_id_n_sectors(rt_uint16_t * id)287 rt_inline rt_uint64_t rt_ahci_ata_id_n_sectors(rt_uint16_t *id)
288 {
289     if (rt_ahci_ata_id_has_lba(id))
290     {
291         if (rt_ahci_ata_id_has_lba48(id))
292         {
293             return rt_ahci_ata_id_u64(id, RT_AHCI_ATA_ID_LBA_CAPACITY_2);
294         }
295 
296         return rt_ahci_ata_id_u32(id, RT_AHCI_ATA_ID_LBA_CAPACITY);
297     }
298 
299     return 0;
300 }
301 
rt_ahci_ata_id_wcache_enabled(const rt_uint16_t * id)302 rt_inline rt_bool_t rt_ahci_ata_id_wcache_enabled(const rt_uint16_t *id)
303 {
304     if ((id[RT_AHCI_ATA_ID_CSF_DEFAULT] & 0xc000) != 0x4000)
305     {
306         return RT_FALSE;
307     }
308     return id[RT_AHCI_ATA_ID_CFS_ENABLE_1] & (1 << 5);
309 }
310 
rt_ahci_ata_id_has_flush(const rt_uint16_t * id)311 rt_inline rt_bool_t rt_ahci_ata_id_has_flush(const rt_uint16_t *id)
312 {
313     if ((id[RT_AHCI_ATA_ID_COMMAND_SET_2] & 0xc000) != 0x4000)
314     {
315         return RT_FALSE;
316     }
317     return id[RT_AHCI_ATA_ID_COMMAND_SET_2] & (1 << 12);
318 }
319 
rt_ahci_ata_id_has_flush_ext(const rt_uint16_t * id)320 rt_inline rt_bool_t rt_ahci_ata_id_has_flush_ext(const rt_uint16_t *id)
321 {
322     if ((id[RT_AHCI_ATA_ID_COMMAND_SET_2] & 0xc000) != 0x4000)
323     {
324         return RT_FALSE;
325     }
326     return id[RT_AHCI_ATA_ID_COMMAND_SET_2] & (1 << 13);
327 }
328 
329 struct rt_ahci_cmd_hdr
330 {
331     rt_uint32_t opts;
332     rt_uint32_t status;
333     rt_uint32_t tbl_addr_lo;
334     rt_uint32_t tbl_addr_hi;
335     rt_uint32_t reserved[4];
336 };
337 
338 struct rt_ahci_sg
339 {
340     rt_uint32_t addr_lo;
341     rt_uint32_t addr_hi;
342     rt_uint32_t reserved;
343     rt_uint32_t flags_size;
344 };
345 
346 struct rt_ahci_port
347 {
348     void *regs;
349 
350     void *dma;
351     rt_ubase_t dma_handle;
352 
353     struct rt_ahci_cmd_hdr *cmd_slot;
354     struct rt_ahci_sg *cmd_tbl_sg;
355     void *cmd_tbl;
356     rt_ubase_t cmd_tbl_dma;
357     void *rx_fis;
358 
359     rt_uint32_t int_enabled;
360     rt_size_t block_size;
361 
362     rt_uint16_t *ataid;
363 
364     rt_bool_t link;
365     struct rt_completion done;
366 };
367 
368 struct rt_ahci_host
369 {
370     struct rt_scsi_host parent;
371 
372     int irq;
373     void *regs;
374 
375     rt_size_t ports_nr;
376     rt_uint32_t ports_map;
377     struct rt_ahci_port ports[32];
378 
379     rt_uint32_t cap;
380     rt_uint32_t max_blocks;
381 
382     const struct rt_ahci_ops *ops;
383 };
384 
385 struct rt_ahci_ops
386 {
387     rt_err_t (*host_init)(struct rt_ahci_host *host);
388     rt_err_t (*port_init)(struct rt_ahci_host *host, struct rt_ahci_port *port);
389     rt_err_t (*port_link_up)(struct rt_ahci_host *host, struct rt_ahci_port *port);
390     rt_err_t (*port_dma_init)(struct rt_ahci_host *host, struct rt_ahci_port *port);
391     rt_err_t (*port_isr)(struct rt_ahci_host *host, struct rt_ahci_port *port, rt_uint32_t isr);
392 };
393 
394 rt_err_t rt_ahci_host_register(struct rt_ahci_host *host);
395 rt_err_t rt_ahci_host_unregister(struct rt_ahci_host *host);
396 
397 #endif /* __AHCI_H__ */
398