1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24#ifndef HW_IDE_AHCI_INTERNAL_H
25#define HW_IDE_AHCI_INTERNAL_H
26
27#include "hw/ide/ahci.h"
28#include "hw/sysbus.h"
29
30#define AHCI_MEM_BAR_SIZE 0x1000
31#define AHCI_MAX_PORTS 32
32#define AHCI_MAX_SG 168
33#define AHCI_DMA_BOUNDARY 0xffffffff
34#define AHCI_USE_CLUSTERING 0
35#define AHCI_MAX_CMDS 32
36#define AHCI_CMD_SZ 32
37#define AHCI_CMD_SLOT_SZ (AHCI_MAX_CMDS * AHCI_CMD_SZ)
38#define AHCI_RX_FIS_SZ 256
39#define AHCI_CMD_TBL_CDB 0x40
40#define AHCI_CMD_TBL_HDR_SZ 0x80
41#define AHCI_CMD_TBL_SZ (AHCI_CMD_TBL_HDR_SZ + (AHCI_MAX_SG * 16))
42#define AHCI_CMD_TBL_AR_SZ (AHCI_CMD_TBL_SZ * AHCI_MAX_CMDS)
43#define AHCI_PORT_PRIV_DMA_SZ (AHCI_CMD_SLOT_SZ + AHCI_CMD_TBL_AR_SZ + \
44 AHCI_RX_FIS_SZ)
45
46#define AHCI_IRQ_ON_SG (1U << 31)
47#define AHCI_CMD_ATAPI (1 << 5)
48#define AHCI_CMD_WRITE (1 << 6)
49#define AHCI_CMD_PREFETCH (1 << 7)
50#define AHCI_CMD_RESET (1 << 8)
51#define AHCI_CMD_CLR_BUSY (1 << 10)
52
53#define RX_FIS_D2H_REG 0x40
54#define RX_FIS_SDB 0x58
55#define RX_FIS_UNK 0x60
56
57
58#define HOST_CAP 0x00
59#define HOST_CTL 0x04
60#define HOST_IRQ_STAT 0x08
61#define HOST_PORTS_IMPL 0x0c
62#define HOST_VERSION 0x10
63
64
65#define HOST_CTL_RESET (1 << 0)
66#define HOST_CTL_IRQ_EN (1 << 1)
67#define HOST_CTL_AHCI_EN (1U << 31)
68
69
70#define HOST_CAP_SSC (1 << 14)
71#define HOST_CAP_AHCI (1 << 18)
72#define HOST_CAP_CLO (1 << 24)
73#define HOST_CAP_SSS (1 << 27)
74#define HOST_CAP_NCQ (1 << 30)
75#define HOST_CAP_64 (1U << 31)
76
77
78#define PORT_LST_ADDR 0x00
79#define PORT_LST_ADDR_HI 0x04
80#define PORT_FIS_ADDR 0x08
81#define PORT_FIS_ADDR_HI 0x0c
82#define PORT_IRQ_STAT 0x10
83#define PORT_IRQ_MASK 0x14
84#define PORT_CMD 0x18
85#define PORT_TFDATA 0x20
86#define PORT_SIG 0x24
87#define PORT_SCR_STAT 0x28
88#define PORT_SCR_CTL 0x2c
89#define PORT_SCR_ERR 0x30
90#define PORT_SCR_ACT 0x34
91#define PORT_CMD_ISSUE 0x38
92#define PORT_RESERVED 0x3c
93
94
95enum AHCIPortIRQ {
96 AHCI_PORT_IRQ_BIT_DHRS = 0,
97 AHCI_PORT_IRQ_BIT_PSS = 1,
98 AHCI_PORT_IRQ_BIT_DSS = 2,
99 AHCI_PORT_IRQ_BIT_SDBS = 3,
100 AHCI_PORT_IRQ_BIT_UFS = 4,
101 AHCI_PORT_IRQ_BIT_DPS = 5,
102 AHCI_PORT_IRQ_BIT_PCS = 6,
103 AHCI_PORT_IRQ_BIT_DMPS = 7,
104
105 AHCI_PORT_IRQ_BIT_PRCS = 22,
106 AHCI_PORT_IRQ_BIT_IPMS = 23,
107 AHCI_PORT_IRQ_BIT_OFS = 24,
108
109 AHCI_PORT_IRQ_BIT_INFS = 26,
110 AHCI_PORT_IRQ_BIT_IFS = 27,
111 AHCI_PORT_IRQ_BIT_HBDS = 28,
112 AHCI_PORT_IRQ_BIT_HBFS = 29,
113 AHCI_PORT_IRQ_BIT_TFES = 30,
114 AHCI_PORT_IRQ_BIT_CPDS = 31,
115 AHCI_PORT_IRQ__COUNT = 32
116};
117
118
119
120#define PORT_IRQ_COLD_PRES (1U << 31)
121#define PORT_IRQ_TF_ERR (1 << 30)
122#define PORT_IRQ_HBUS_ERR (1 << 29)
123#define PORT_IRQ_HBUS_DATA_ERR (1 << 28)
124#define PORT_IRQ_IF_ERR (1 << 27)
125#define PORT_IRQ_IF_NONFATAL (1 << 26)
126
127#define PORT_IRQ_OVERFLOW (1 << 24)
128#define PORT_IRQ_BAD_PMP (1 << 23)
129#define PORT_IRQ_PHYRDY (1 << 22)
130
131#define PORT_IRQ_DEV_ILCK (1 << 7)
132#define PORT_IRQ_CONNECT (1 << 6)
133#define PORT_IRQ_SG_DONE (1 << 5)
134#define PORT_IRQ_UNK_FIS (1 << 4)
135#define PORT_IRQ_SDB_FIS (1 << 3)
136#define PORT_IRQ_DMAS_FIS (1 << 2)
137#define PORT_IRQ_PIOS_FIS (1 << 1)
138#define PORT_IRQ_D2H_REG_FIS (1 << 0)
139
140#define PORT_IRQ_FREEZE (PORT_IRQ_HBUS_ERR | PORT_IRQ_IF_ERR | \
141 PORT_IRQ_CONNECT | PORT_IRQ_PHYRDY | \
142 PORT_IRQ_UNK_FIS)
143#define PORT_IRQ_ERROR (PORT_IRQ_FREEZE | PORT_IRQ_TF_ERR | \
144 PORT_IRQ_HBUS_DATA_ERR)
145#define DEF_PORT_IRQ (PORT_IRQ_ERROR | PORT_IRQ_SG_DONE | \
146 PORT_IRQ_SDB_FIS | PORT_IRQ_DMAS_FIS | \
147 PORT_IRQ_PIOS_FIS | PORT_IRQ_D2H_REG_FIS)
148
149
150#define PORT_CMD_ATAPI (1 << 24)
151#define PORT_CMD_LIST_ON (1 << 15)
152#define PORT_CMD_FIS_ON (1 << 14)
153#define PORT_CMD_FIS_RX (1 << 4)
154#define PORT_CMD_CLO (1 << 3)
155#define PORT_CMD_POWER_ON (1 << 2)
156#define PORT_CMD_SPIN_UP (1 << 1)
157#define PORT_CMD_START (1 << 0)
158
159#define PORT_CMD_ICC_MASK (0xfU << 28)
160#define PORT_CMD_ICC_ACTIVE (0x1 << 28)
161#define PORT_CMD_ICC_PARTIAL (0x2 << 28)
162#define PORT_CMD_ICC_SLUMBER (0x6 << 28)
163
164#define PORT_CMD_RO_MASK 0x007dffe0
165
166
167#define AHCI_FLAG_NO_NCQ (1 << 24)
168#define AHCI_FLAG_IGN_IRQ_IF_ERR (1 << 25)
169#define AHCI_FLAG_HONOR_PI (1 << 26)
170#define AHCI_FLAG_IGN_SERR_INTERNAL (1 << 27)
171#define AHCI_FLAG_32BIT_ONLY (1 << 28)
172
173#define ATA_SRST (1 << 2)
174
175#define STATE_RUN 0
176#define STATE_RESET 1
177
178#define SATA_SCR_SSTATUS_DET_NODEV 0x0
179#define SATA_SCR_SSTATUS_DET_DEV_PRESENT_PHY_UP 0x3
180
181#define SATA_SCR_SSTATUS_SPD_NODEV 0x00
182#define SATA_SCR_SSTATUS_SPD_GEN1 0x10
183
184#define SATA_SCR_SSTATUS_IPM_NODEV 0x000
185#define SATA_SCR_SSTATUS_IPM_ACTIVE 0X100
186
187#define AHCI_SCR_SCTL_DET 0xf
188
189#define SATA_FIS_TYPE_REGISTER_H2D 0x27
190#define SATA_FIS_REG_H2D_UPDATE_COMMAND_REGISTER 0x80
191#define SATA_FIS_TYPE_REGISTER_D2H 0x34
192#define SATA_FIS_TYPE_PIO_SETUP 0x5f
193#define SATA_FIS_TYPE_SDB 0xA1
194
195#define AHCI_CMD_HDR_CMD_FIS_LEN 0x1f
196#define AHCI_CMD_HDR_PRDT_LEN 16
197
198#define SATA_SIGNATURE_CDROM 0xeb140101
199#define SATA_SIGNATURE_DISK 0x00000101
200
201#define AHCI_GENERIC_HOST_CONTROL_REGS_MAX_ADDR 0x20
202
203
204#define AHCI_PORT_REGS_START_ADDR 0x100
205#define AHCI_PORT_ADDR_OFFSET_MASK 0x7f
206#define AHCI_PORT_ADDR_OFFSET_LEN 0x80
207
208#define AHCI_NUM_COMMAND_SLOTS 31
209#define AHCI_SUPPORTED_SPEED 20
210#define AHCI_SUPPORTED_SPEED_GEN1 1
211#define AHCI_VERSION_1_0 0x10000
212
213#define AHCI_PROGMODE_MAJOR_REV_1 1
214
215#define AHCI_COMMAND_TABLE_ACMD 0x40
216
217#define AHCI_PRDT_SIZE_MASK 0x3fffff
218
219#define IDE_FEATURE_DMA 1
220
221#define READ_FPDMA_QUEUED 0x60
222#define WRITE_FPDMA_QUEUED 0x61
223#define NCQ_NON_DATA 0x63
224#define RECEIVE_FPDMA_QUEUED 0x65
225#define SEND_FPDMA_QUEUED 0x64
226
227#define NCQ_FIS_FUA_MASK 0x80
228#define NCQ_FIS_RARC_MASK 0x01
229
230#define RES_FIS_DSFIS 0x00
231#define RES_FIS_PSFIS 0x20
232#define RES_FIS_RFIS 0x40
233#define RES_FIS_SDBFIS 0x58
234#define RES_FIS_UFIS 0x60
235
236#define SATA_CAP_SIZE 0x8
237#define SATA_CAP_REV 0x2
238#define SATA_CAP_BAR 0x4
239
240typedef struct AHCIPortRegs {
241 uint32_t lst_addr;
242 uint32_t lst_addr_hi;
243 uint32_t fis_addr;
244 uint32_t fis_addr_hi;
245 uint32_t irq_stat;
246 uint32_t irq_mask;
247 uint32_t cmd;
248 uint32_t unused0;
249 uint32_t tfdata;
250 uint32_t sig;
251 uint32_t scr_stat;
252 uint32_t scr_ctl;
253 uint32_t scr_err;
254 uint32_t scr_act;
255 uint32_t cmd_issue;
256 uint32_t reserved;
257} AHCIPortRegs;
258
259typedef struct AHCICmdHdr {
260 uint16_t opts;
261 uint16_t prdtl;
262 uint32_t status;
263 uint64_t tbl_addr;
264 uint32_t reserved[4];
265} QEMU_PACKED AHCICmdHdr;
266
267typedef struct AHCI_SG {
268 uint64_t addr;
269 uint32_t reserved;
270 uint32_t flags_size;
271} QEMU_PACKED AHCI_SG;
272
273typedef struct NCQTransferState {
274 AHCIDevice *drive;
275 BlockAIOCB *aiocb;
276 AHCICmdHdr *cmdh;
277 QEMUSGList sglist;
278 BlockAcctCookie acct;
279 uint32_t sector_count;
280 uint64_t lba;
281 uint8_t tag;
282 uint8_t cmd;
283 uint8_t slot;
284 bool used;
285 bool halt;
286} NCQTransferState;
287
288struct AHCIDevice {
289 IDEDMA dma;
290 IDEBus port;
291 int port_no;
292 uint32_t port_state;
293 uint32_t finished;
294 AHCIPortRegs port_regs;
295 struct AHCIState *hba;
296 QEMUBH *check_bh;
297 uint8_t *lst;
298 uint8_t *res_fis;
299 bool done_atapi_packet;
300 int32_t busy_slot;
301 bool init_d2h_sent;
302 AHCICmdHdr *cur_cmd;
303 NCQTransferState ncq_tfs[AHCI_MAX_CMDS];
304};
305
306struct AHCIPCIState {
307
308 PCIDevice parent_obj;
309
310
311 AHCIState ahci;
312};
313
314#define ICH_AHCI(obj) \
315 OBJECT_CHECK(AHCIPCIState, (obj), TYPE_ICH9_AHCI)
316
317extern const VMStateDescription vmstate_ahci;
318
319#define VMSTATE_AHCI(_field, _state) { \
320 .name = (stringify(_field)), \
321 .size = sizeof(AHCIState), \
322 .vmsd = &vmstate_ahci, \
323 .flags = VMS_STRUCT, \
324 .offset = vmstate_offset_value(_state, _field, AHCIState), \
325}
326
327
328
329
330
331
332
333
334
335
336
337
338
339typedef struct NCQFrame {
340 uint8_t fis_type;
341 uint8_t c;
342 uint8_t command;
343 uint8_t sector_count_low;
344 uint8_t lba0;
345 uint8_t lba1;
346 uint8_t lba2;
347 uint8_t fua;
348 uint8_t lba3;
349 uint8_t lba4;
350 uint8_t lba5;
351 uint8_t sector_count_high;
352 uint8_t tag;
353 uint8_t prio;
354 uint8_t icc;
355 uint8_t control;
356 uint8_t aux0;
357 uint8_t aux1;
358 uint8_t aux2;
359 uint8_t aux3;
360} QEMU_PACKED NCQFrame;
361
362typedef struct SDBFIS {
363 uint8_t type;
364 uint8_t flags;
365 uint8_t status;
366 uint8_t error;
367 uint32_t payload;
368} QEMU_PACKED SDBFIS;
369
370void ahci_realize(AHCIState *s, DeviceState *qdev, AddressSpace *as, int ports);
371void ahci_init(AHCIState *s, DeviceState *qdev);
372void ahci_uninit(AHCIState *s);
373
374void ahci_reset(AHCIState *s);
375
376#define SYSBUS_AHCI(obj) OBJECT_CHECK(SysbusAHCIState, (obj), TYPE_SYSBUS_AHCI)
377
378#define ALLWINNER_AHCI(obj) OBJECT_CHECK(AllwinnerAHCIState, (obj), \
379 TYPE_ALLWINNER_AHCI)
380
381#endif
382