xref: /qemu/hw/ide/ahci-internal.h (revision 70e2337030fb242b0a7870e781b57055110400a1)
1*70e23370SJohn Snow /*
2*70e23370SJohn Snow  * QEMU AHCI Emulation
3*70e23370SJohn Snow  *
4*70e23370SJohn Snow  * Copyright (c) 2010 qiaochong@loongson.cn
5*70e23370SJohn Snow  * Copyright (c) 2010 Roland Elek <elek.roland@gmail.com>
6*70e23370SJohn Snow  * Copyright (c) 2010 Sebastian Herbszt <herbszt@gmx.de>
7*70e23370SJohn Snow  * Copyright (c) 2010 Alexander Graf <agraf@suse.de>
8*70e23370SJohn Snow  *
9*70e23370SJohn Snow  * This library is free software; you can redistribute it and/or
10*70e23370SJohn Snow  * modify it under the terms of the GNU Lesser General Public
11*70e23370SJohn Snow  * License as published by the Free Software Foundation; either
12*70e23370SJohn Snow  * version 2 of the License, or (at your option) any later version.
13*70e23370SJohn Snow  *
14*70e23370SJohn Snow  * This library is distributed in the hope that it will be useful,
15*70e23370SJohn Snow  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16*70e23370SJohn Snow  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17*70e23370SJohn Snow  * Lesser General Public License for more details.
18*70e23370SJohn Snow  *
19*70e23370SJohn Snow  * You should have received a copy of the GNU Lesser General Public
20*70e23370SJohn Snow  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
21*70e23370SJohn Snow  *
22*70e23370SJohn Snow  */
23*70e23370SJohn Snow 
24*70e23370SJohn Snow #ifndef HW_IDE_AHCI_INTERNAL_H
25*70e23370SJohn Snow #define HW_IDE_AHCI_INTERNAL_H
26*70e23370SJohn Snow 
27*70e23370SJohn Snow #include "hw/ide/ahci.h"
28*70e23370SJohn Snow #include "hw/sysbus.h"
29*70e23370SJohn Snow 
30*70e23370SJohn Snow #define AHCI_MEM_BAR_SIZE         0x1000
31*70e23370SJohn Snow #define AHCI_MAX_PORTS            32
32*70e23370SJohn Snow #define AHCI_MAX_SG               168 /* hardware max is 64K */
33*70e23370SJohn Snow #define AHCI_DMA_BOUNDARY         0xffffffff
34*70e23370SJohn Snow #define AHCI_USE_CLUSTERING       0
35*70e23370SJohn Snow #define AHCI_MAX_CMDS             32
36*70e23370SJohn Snow #define AHCI_CMD_SZ               32
37*70e23370SJohn Snow #define AHCI_CMD_SLOT_SZ          (AHCI_MAX_CMDS * AHCI_CMD_SZ)
38*70e23370SJohn Snow #define AHCI_RX_FIS_SZ            256
39*70e23370SJohn Snow #define AHCI_CMD_TBL_CDB          0x40
40*70e23370SJohn Snow #define AHCI_CMD_TBL_HDR_SZ       0x80
41*70e23370SJohn Snow #define AHCI_CMD_TBL_SZ           (AHCI_CMD_TBL_HDR_SZ + (AHCI_MAX_SG * 16))
42*70e23370SJohn Snow #define AHCI_CMD_TBL_AR_SZ        (AHCI_CMD_TBL_SZ * AHCI_MAX_CMDS)
43*70e23370SJohn Snow #define AHCI_PORT_PRIV_DMA_SZ     (AHCI_CMD_SLOT_SZ + AHCI_CMD_TBL_AR_SZ + \
44*70e23370SJohn Snow                                    AHCI_RX_FIS_SZ)
45*70e23370SJohn Snow 
46*70e23370SJohn Snow #define AHCI_IRQ_ON_SG            (1U << 31)
47*70e23370SJohn Snow #define AHCI_CMD_ATAPI            (1 << 5)
48*70e23370SJohn Snow #define AHCI_CMD_WRITE            (1 << 6)
49*70e23370SJohn Snow #define AHCI_CMD_PREFETCH         (1 << 7)
50*70e23370SJohn Snow #define AHCI_CMD_RESET            (1 << 8)
51*70e23370SJohn Snow #define AHCI_CMD_CLR_BUSY         (1 << 10)
52*70e23370SJohn Snow 
53*70e23370SJohn Snow #define RX_FIS_D2H_REG            0x40 /* offset of D2H Register FIS data */
54*70e23370SJohn Snow #define RX_FIS_SDB                0x58 /* offset of SDB FIS data */
55*70e23370SJohn Snow #define RX_FIS_UNK                0x60 /* offset of Unknown FIS data */
56*70e23370SJohn Snow 
57*70e23370SJohn Snow /* global controller registers */
58*70e23370SJohn Snow #define HOST_CAP                  0x00 /* host capabilities */
59*70e23370SJohn Snow #define HOST_CTL                  0x04 /* global host control */
60*70e23370SJohn Snow #define HOST_IRQ_STAT             0x08 /* interrupt status */
61*70e23370SJohn Snow #define HOST_PORTS_IMPL           0x0c /* bitmap of implemented ports */
62*70e23370SJohn Snow #define HOST_VERSION              0x10 /* AHCI spec. version compliancy */
63*70e23370SJohn Snow 
64*70e23370SJohn Snow /* HOST_CTL bits */
65*70e23370SJohn Snow #define HOST_CTL_RESET            (1 << 0)  /* reset controller; self-clear */
66*70e23370SJohn Snow #define HOST_CTL_IRQ_EN           (1 << 1)  /* global IRQ enable */
67*70e23370SJohn Snow #define HOST_CTL_AHCI_EN          (1U << 31) /* AHCI enabled */
68*70e23370SJohn Snow 
69*70e23370SJohn Snow /* HOST_CAP bits */
70*70e23370SJohn Snow #define HOST_CAP_SSC              (1 << 14) /* Slumber capable */
71*70e23370SJohn Snow #define HOST_CAP_AHCI             (1 << 18) /* AHCI only */
72*70e23370SJohn Snow #define HOST_CAP_CLO              (1 << 24) /* Command List Override support */
73*70e23370SJohn Snow #define HOST_CAP_SSS              (1 << 27) /* Staggered Spin-up */
74*70e23370SJohn Snow #define HOST_CAP_NCQ              (1 << 30) /* Native Command Queueing */
75*70e23370SJohn Snow #define HOST_CAP_64               (1U << 31) /* PCI DAC (64-bit DMA) support */
76*70e23370SJohn Snow 
77*70e23370SJohn Snow /* registers for each SATA port */
78*70e23370SJohn Snow #define PORT_LST_ADDR             0x00 /* command list DMA addr */
79*70e23370SJohn Snow #define PORT_LST_ADDR_HI          0x04 /* command list DMA addr hi */
80*70e23370SJohn Snow #define PORT_FIS_ADDR             0x08 /* FIS rx buf addr */
81*70e23370SJohn Snow #define PORT_FIS_ADDR_HI          0x0c /* FIS rx buf addr hi */
82*70e23370SJohn Snow #define PORT_IRQ_STAT             0x10 /* interrupt status */
83*70e23370SJohn Snow #define PORT_IRQ_MASK             0x14 /* interrupt enable/disable mask */
84*70e23370SJohn Snow #define PORT_CMD                  0x18 /* port command */
85*70e23370SJohn Snow #define PORT_TFDATA               0x20 /* taskfile data */
86*70e23370SJohn Snow #define PORT_SIG                  0x24 /* device TF signature */
87*70e23370SJohn Snow #define PORT_SCR_STAT             0x28 /* SATA phy register: SStatus */
88*70e23370SJohn Snow #define PORT_SCR_CTL              0x2c /* SATA phy register: SControl */
89*70e23370SJohn Snow #define PORT_SCR_ERR              0x30 /* SATA phy register: SError */
90*70e23370SJohn Snow #define PORT_SCR_ACT              0x34 /* SATA phy register: SActive */
91*70e23370SJohn Snow #define PORT_CMD_ISSUE            0x38 /* command issue */
92*70e23370SJohn Snow #define PORT_RESERVED             0x3c /* reserved */
93*70e23370SJohn Snow 
94*70e23370SJohn Snow /* PORT_IRQ_{STAT,MASK} bits */
95*70e23370SJohn Snow #define PORT_IRQ_COLD_PRES        (1U << 31) /* cold presence detect */
96*70e23370SJohn Snow #define PORT_IRQ_TF_ERR           (1 << 30) /* task file error */
97*70e23370SJohn Snow #define PORT_IRQ_HBUS_ERR         (1 << 29) /* host bus fatal error */
98*70e23370SJohn Snow #define PORT_IRQ_HBUS_DATA_ERR    (1 << 28) /* host bus data error */
99*70e23370SJohn Snow #define PORT_IRQ_IF_ERR           (1 << 27) /* interface fatal error */
100*70e23370SJohn Snow #define PORT_IRQ_IF_NONFATAL      (1 << 26) /* interface non-fatal error */
101*70e23370SJohn Snow #define PORT_IRQ_OVERFLOW         (1 << 24) /* xfer exhausted available S/G */
102*70e23370SJohn Snow #define PORT_IRQ_BAD_PMP          (1 << 23) /* incorrect port multiplier */
103*70e23370SJohn Snow 
104*70e23370SJohn Snow #define PORT_IRQ_PHYRDY           (1 << 22) /* PhyRdy changed */
105*70e23370SJohn Snow #define PORT_IRQ_DEV_ILCK         (1 << 7) /* device interlock */
106*70e23370SJohn Snow #define PORT_IRQ_CONNECT          (1 << 6) /* port connect change status */
107*70e23370SJohn Snow #define PORT_IRQ_SG_DONE          (1 << 5) /* descriptor processed */
108*70e23370SJohn Snow #define PORT_IRQ_UNK_FIS          (1 << 4) /* unknown FIS rx'd */
109*70e23370SJohn Snow #define PORT_IRQ_SDB_FIS          (1 << 3) /* Set Device Bits FIS rx'd */
110*70e23370SJohn Snow #define PORT_IRQ_DMAS_FIS         (1 << 2) /* DMA Setup FIS rx'd */
111*70e23370SJohn Snow #define PORT_IRQ_PIOS_FIS         (1 << 1) /* PIO Setup FIS rx'd */
112*70e23370SJohn Snow #define PORT_IRQ_D2H_REG_FIS      (1 << 0) /* D2H Register FIS rx'd */
113*70e23370SJohn Snow 
114*70e23370SJohn Snow #define PORT_IRQ_FREEZE           (PORT_IRQ_HBUS_ERR | PORT_IRQ_IF_ERR |   \
115*70e23370SJohn Snow                                    PORT_IRQ_CONNECT | PORT_IRQ_PHYRDY |    \
116*70e23370SJohn Snow                                    PORT_IRQ_UNK_FIS)
117*70e23370SJohn Snow #define PORT_IRQ_ERROR            (PORT_IRQ_FREEZE | PORT_IRQ_TF_ERR |     \
118*70e23370SJohn Snow                                    PORT_IRQ_HBUS_DATA_ERR)
119*70e23370SJohn Snow #define DEF_PORT_IRQ              (PORT_IRQ_ERROR | PORT_IRQ_SG_DONE |     \
120*70e23370SJohn Snow                                    PORT_IRQ_SDB_FIS | PORT_IRQ_DMAS_FIS |  \
121*70e23370SJohn Snow                                    PORT_IRQ_PIOS_FIS | PORT_IRQ_D2H_REG_FIS)
122*70e23370SJohn Snow 
123*70e23370SJohn Snow /* PORT_CMD bits */
124*70e23370SJohn Snow #define PORT_CMD_ATAPI            (1 << 24) /* Device is ATAPI */
125*70e23370SJohn Snow #define PORT_CMD_LIST_ON          (1 << 15) /* cmd list DMA engine running */
126*70e23370SJohn Snow #define PORT_CMD_FIS_ON           (1 << 14) /* FIS DMA engine running */
127*70e23370SJohn Snow #define PORT_CMD_FIS_RX           (1 << 4) /* Enable FIS receive DMA engine */
128*70e23370SJohn Snow #define PORT_CMD_CLO              (1 << 3) /* Command list override */
129*70e23370SJohn Snow #define PORT_CMD_POWER_ON         (1 << 2) /* Power up device */
130*70e23370SJohn Snow #define PORT_CMD_SPIN_UP          (1 << 1) /* Spin up device */
131*70e23370SJohn Snow #define PORT_CMD_START            (1 << 0) /* Enable port DMA engine */
132*70e23370SJohn Snow 
133*70e23370SJohn Snow #define PORT_CMD_ICC_MASK        (0xfU << 28) /* i/f ICC state mask */
134*70e23370SJohn Snow #define PORT_CMD_ICC_ACTIVE       (0x1 << 28) /* Put i/f in active state */
135*70e23370SJohn Snow #define PORT_CMD_ICC_PARTIAL      (0x2 << 28) /* Put i/f in partial state */
136*70e23370SJohn Snow #define PORT_CMD_ICC_SLUMBER      (0x6 << 28) /* Put i/f in slumber state */
137*70e23370SJohn Snow 
138*70e23370SJohn Snow #define PORT_CMD_RO_MASK          0x007dffe0 /* Which CMD bits are read only? */
139*70e23370SJohn Snow 
140*70e23370SJohn Snow /* ap->flags bits */
141*70e23370SJohn Snow #define AHCI_FLAG_NO_NCQ                  (1 << 24)
142*70e23370SJohn Snow #define AHCI_FLAG_IGN_IRQ_IF_ERR          (1 << 25) /* ignore IRQ_IF_ERR */
143*70e23370SJohn Snow #define AHCI_FLAG_HONOR_PI                (1 << 26) /* honor PORTS_IMPL */
144*70e23370SJohn Snow #define AHCI_FLAG_IGN_SERR_INTERNAL       (1 << 27) /* ignore SERR_INTERNAL */
145*70e23370SJohn Snow #define AHCI_FLAG_32BIT_ONLY              (1 << 28) /* force 32bit */
146*70e23370SJohn Snow 
147*70e23370SJohn Snow #define ATA_SRST                          (1 << 2)  /* software reset */
148*70e23370SJohn Snow 
149*70e23370SJohn Snow #define STATE_RUN                         0
150*70e23370SJohn Snow #define STATE_RESET                       1
151*70e23370SJohn Snow 
152*70e23370SJohn Snow #define SATA_SCR_SSTATUS_DET_NODEV        0x0
153*70e23370SJohn Snow #define SATA_SCR_SSTATUS_DET_DEV_PRESENT_PHY_UP 0x3
154*70e23370SJohn Snow 
155*70e23370SJohn Snow #define SATA_SCR_SSTATUS_SPD_NODEV        0x00
156*70e23370SJohn Snow #define SATA_SCR_SSTATUS_SPD_GEN1         0x10
157*70e23370SJohn Snow 
158*70e23370SJohn Snow #define SATA_SCR_SSTATUS_IPM_NODEV        0x000
159*70e23370SJohn Snow #define SATA_SCR_SSTATUS_IPM_ACTIVE       0X100
160*70e23370SJohn Snow 
161*70e23370SJohn Snow #define AHCI_SCR_SCTL_DET                 0xf
162*70e23370SJohn Snow 
163*70e23370SJohn Snow #define SATA_FIS_TYPE_REGISTER_H2D        0x27
164*70e23370SJohn Snow #define   SATA_FIS_REG_H2D_UPDATE_COMMAND_REGISTER 0x80
165*70e23370SJohn Snow #define SATA_FIS_TYPE_REGISTER_D2H        0x34
166*70e23370SJohn Snow #define SATA_FIS_TYPE_PIO_SETUP           0x5f
167*70e23370SJohn Snow #define SATA_FIS_TYPE_SDB                 0xA1
168*70e23370SJohn Snow 
169*70e23370SJohn Snow #define AHCI_CMD_HDR_CMD_FIS_LEN           0x1f
170*70e23370SJohn Snow #define AHCI_CMD_HDR_PRDT_LEN              16
171*70e23370SJohn Snow 
172*70e23370SJohn Snow #define SATA_SIGNATURE_CDROM               0xeb140101
173*70e23370SJohn Snow #define SATA_SIGNATURE_DISK                0x00000101
174*70e23370SJohn Snow 
175*70e23370SJohn Snow #define AHCI_GENERIC_HOST_CONTROL_REGS_MAX_ADDR 0x20
176*70e23370SJohn Snow                                             /* Shouldn't this be 0x2c? */
177*70e23370SJohn Snow 
178*70e23370SJohn Snow #define AHCI_PORT_REGS_START_ADDR          0x100
179*70e23370SJohn Snow #define AHCI_PORT_ADDR_OFFSET_MASK         0x7f
180*70e23370SJohn Snow #define AHCI_PORT_ADDR_OFFSET_LEN          0x80
181*70e23370SJohn Snow 
182*70e23370SJohn Snow #define AHCI_NUM_COMMAND_SLOTS             31
183*70e23370SJohn Snow #define AHCI_SUPPORTED_SPEED               20
184*70e23370SJohn Snow #define AHCI_SUPPORTED_SPEED_GEN1          1
185*70e23370SJohn Snow #define AHCI_VERSION_1_0                   0x10000
186*70e23370SJohn Snow 
187*70e23370SJohn Snow #define AHCI_PROGMODE_MAJOR_REV_1          1
188*70e23370SJohn Snow 
189*70e23370SJohn Snow #define AHCI_COMMAND_TABLE_ACMD            0x40
190*70e23370SJohn Snow 
191*70e23370SJohn Snow #define AHCI_PRDT_SIZE_MASK                0x3fffff
192*70e23370SJohn Snow 
193*70e23370SJohn Snow #define IDE_FEATURE_DMA                    1
194*70e23370SJohn Snow 
195*70e23370SJohn Snow #define READ_FPDMA_QUEUED                  0x60
196*70e23370SJohn Snow #define WRITE_FPDMA_QUEUED                 0x61
197*70e23370SJohn Snow #define NCQ_NON_DATA                       0x63
198*70e23370SJohn Snow #define RECEIVE_FPDMA_QUEUED               0x65
199*70e23370SJohn Snow #define SEND_FPDMA_QUEUED                  0x64
200*70e23370SJohn Snow 
201*70e23370SJohn Snow #define NCQ_FIS_FUA_MASK                   0x80
202*70e23370SJohn Snow #define NCQ_FIS_RARC_MASK                  0x01
203*70e23370SJohn Snow 
204*70e23370SJohn Snow #define RES_FIS_DSFIS                      0x00
205*70e23370SJohn Snow #define RES_FIS_PSFIS                      0x20
206*70e23370SJohn Snow #define RES_FIS_RFIS                       0x40
207*70e23370SJohn Snow #define RES_FIS_SDBFIS                     0x58
208*70e23370SJohn Snow #define RES_FIS_UFIS                       0x60
209*70e23370SJohn Snow 
210*70e23370SJohn Snow #define SATA_CAP_SIZE           0x8
211*70e23370SJohn Snow #define SATA_CAP_REV            0x2
212*70e23370SJohn Snow #define SATA_CAP_BAR            0x4
213*70e23370SJohn Snow 
214*70e23370SJohn Snow typedef struct AHCIPortRegs {
215*70e23370SJohn Snow     uint32_t    lst_addr;
216*70e23370SJohn Snow     uint32_t    lst_addr_hi;
217*70e23370SJohn Snow     uint32_t    fis_addr;
218*70e23370SJohn Snow     uint32_t    fis_addr_hi;
219*70e23370SJohn Snow     uint32_t    irq_stat;
220*70e23370SJohn Snow     uint32_t    irq_mask;
221*70e23370SJohn Snow     uint32_t    cmd;
222*70e23370SJohn Snow     uint32_t    unused0;
223*70e23370SJohn Snow     uint32_t    tfdata;
224*70e23370SJohn Snow     uint32_t    sig;
225*70e23370SJohn Snow     uint32_t    scr_stat;
226*70e23370SJohn Snow     uint32_t    scr_ctl;
227*70e23370SJohn Snow     uint32_t    scr_err;
228*70e23370SJohn Snow     uint32_t    scr_act;
229*70e23370SJohn Snow     uint32_t    cmd_issue;
230*70e23370SJohn Snow     uint32_t    reserved;
231*70e23370SJohn Snow } AHCIPortRegs;
232*70e23370SJohn Snow 
233*70e23370SJohn Snow typedef struct AHCICmdHdr {
234*70e23370SJohn Snow     uint16_t    opts;
235*70e23370SJohn Snow     uint16_t    prdtl;
236*70e23370SJohn Snow     uint32_t    status;
237*70e23370SJohn Snow     uint64_t    tbl_addr;
238*70e23370SJohn Snow     uint32_t    reserved[4];
239*70e23370SJohn Snow } QEMU_PACKED AHCICmdHdr;
240*70e23370SJohn Snow 
241*70e23370SJohn Snow typedef struct AHCI_SG {
242*70e23370SJohn Snow     uint64_t    addr;
243*70e23370SJohn Snow     uint32_t    reserved;
244*70e23370SJohn Snow     uint32_t    flags_size;
245*70e23370SJohn Snow } QEMU_PACKED AHCI_SG;
246*70e23370SJohn Snow 
247*70e23370SJohn Snow typedef struct NCQTransferState {
248*70e23370SJohn Snow     AHCIDevice *drive;
249*70e23370SJohn Snow     BlockAIOCB *aiocb;
250*70e23370SJohn Snow     AHCICmdHdr *cmdh;
251*70e23370SJohn Snow     QEMUSGList sglist;
252*70e23370SJohn Snow     BlockAcctCookie acct;
253*70e23370SJohn Snow     uint32_t sector_count;
254*70e23370SJohn Snow     uint64_t lba;
255*70e23370SJohn Snow     uint8_t tag;
256*70e23370SJohn Snow     uint8_t cmd;
257*70e23370SJohn Snow     uint8_t slot;
258*70e23370SJohn Snow     bool used;
259*70e23370SJohn Snow     bool halt;
260*70e23370SJohn Snow } NCQTransferState;
261*70e23370SJohn Snow 
262*70e23370SJohn Snow struct AHCIDevice {
263*70e23370SJohn Snow     IDEDMA dma;
264*70e23370SJohn Snow     IDEBus port;
265*70e23370SJohn Snow     int port_no;
266*70e23370SJohn Snow     uint32_t port_state;
267*70e23370SJohn Snow     uint32_t finished;
268*70e23370SJohn Snow     AHCIPortRegs port_regs;
269*70e23370SJohn Snow     struct AHCIState *hba;
270*70e23370SJohn Snow     QEMUBH *check_bh;
271*70e23370SJohn Snow     uint8_t *lst;
272*70e23370SJohn Snow     uint8_t *res_fis;
273*70e23370SJohn Snow     bool done_atapi_packet;
274*70e23370SJohn Snow     int32_t busy_slot;
275*70e23370SJohn Snow     bool init_d2h_sent;
276*70e23370SJohn Snow     AHCICmdHdr *cur_cmd;
277*70e23370SJohn Snow     NCQTransferState ncq_tfs[AHCI_MAX_CMDS];
278*70e23370SJohn Snow };
279*70e23370SJohn Snow 
280*70e23370SJohn Snow struct AHCIPCIState {
281*70e23370SJohn Snow     /*< private >*/
282*70e23370SJohn Snow     PCIDevice parent_obj;
283*70e23370SJohn Snow     /*< public >*/
284*70e23370SJohn Snow 
285*70e23370SJohn Snow     AHCIState ahci;
286*70e23370SJohn Snow };
287*70e23370SJohn Snow 
288*70e23370SJohn Snow #define TYPE_ICH9_AHCI "ich9-ahci"
289*70e23370SJohn Snow 
290*70e23370SJohn Snow #define ICH_AHCI(obj) \
291*70e23370SJohn Snow     OBJECT_CHECK(AHCIPCIState, (obj), TYPE_ICH9_AHCI)
292*70e23370SJohn Snow 
293*70e23370SJohn Snow extern const VMStateDescription vmstate_ahci;
294*70e23370SJohn Snow 
295*70e23370SJohn Snow #define VMSTATE_AHCI(_field, _state) {                               \
296*70e23370SJohn Snow     .name       = (stringify(_field)),                               \
297*70e23370SJohn Snow     .size       = sizeof(AHCIState),                                 \
298*70e23370SJohn Snow     .vmsd       = &vmstate_ahci,                                     \
299*70e23370SJohn Snow     .flags      = VMS_STRUCT,                                        \
300*70e23370SJohn Snow     .offset     = vmstate_offset_value(_state, _field, AHCIState),   \
301*70e23370SJohn Snow }
302*70e23370SJohn Snow 
303*70e23370SJohn Snow /**
304*70e23370SJohn Snow  * NCQFrame is the same as a Register H2D FIS (described in SATA 3.2),
305*70e23370SJohn Snow  * but some fields have been re-mapped and re-purposed, as seen in
306*70e23370SJohn Snow  * SATA 3.2 section 13.6.4.1 ("READ FPDMA QUEUED")
307*70e23370SJohn Snow  *
308*70e23370SJohn Snow  * cmd_fis[3], feature 7:0, becomes sector count 7:0.
309*70e23370SJohn Snow  * cmd_fis[7], device 7:0, uses bit 7 as the Force Unit Access bit.
310*70e23370SJohn Snow  * cmd_fis[11], feature 15:8, becomes sector count 15:8.
311*70e23370SJohn Snow  * cmd_fis[12], count 7:0, becomes the NCQ TAG (7:3) and RARC bit (0)
312*70e23370SJohn Snow  * cmd_fis[13], count 15:8, becomes the priority value (7:6)
313*70e23370SJohn Snow  * bytes 16-19 become an le32 "auxiliary" field.
314*70e23370SJohn Snow  */
315*70e23370SJohn Snow typedef struct NCQFrame {
316*70e23370SJohn Snow     uint8_t fis_type;
317*70e23370SJohn Snow     uint8_t c;
318*70e23370SJohn Snow     uint8_t command;
319*70e23370SJohn Snow     uint8_t sector_count_low;  /* (feature 7:0) */
320*70e23370SJohn Snow     uint8_t lba0;
321*70e23370SJohn Snow     uint8_t lba1;
322*70e23370SJohn Snow     uint8_t lba2;
323*70e23370SJohn Snow     uint8_t fua;               /* (device 7:0) */
324*70e23370SJohn Snow     uint8_t lba3;
325*70e23370SJohn Snow     uint8_t lba4;
326*70e23370SJohn Snow     uint8_t lba5;
327*70e23370SJohn Snow     uint8_t sector_count_high; /* (feature 15:8) */
328*70e23370SJohn Snow     uint8_t tag;               /* (count 0:7) */
329*70e23370SJohn Snow     uint8_t prio;              /* (count 15:8) */
330*70e23370SJohn Snow     uint8_t icc;
331*70e23370SJohn Snow     uint8_t control;
332*70e23370SJohn Snow     uint8_t aux0;
333*70e23370SJohn Snow     uint8_t aux1;
334*70e23370SJohn Snow     uint8_t aux2;
335*70e23370SJohn Snow     uint8_t aux3;
336*70e23370SJohn Snow } QEMU_PACKED NCQFrame;
337*70e23370SJohn Snow 
338*70e23370SJohn Snow typedef struct SDBFIS {
339*70e23370SJohn Snow     uint8_t type;
340*70e23370SJohn Snow     uint8_t flags;
341*70e23370SJohn Snow     uint8_t status;
342*70e23370SJohn Snow     uint8_t error;
343*70e23370SJohn Snow     uint32_t payload;
344*70e23370SJohn Snow } QEMU_PACKED SDBFIS;
345*70e23370SJohn Snow 
346*70e23370SJohn Snow void ahci_realize(AHCIState *s, DeviceState *qdev, AddressSpace *as, int ports);
347*70e23370SJohn Snow void ahci_init(AHCIState *s, DeviceState *qdev);
348*70e23370SJohn Snow void ahci_uninit(AHCIState *s);
349*70e23370SJohn Snow 
350*70e23370SJohn Snow void ahci_reset(AHCIState *s);
351*70e23370SJohn Snow 
352*70e23370SJohn Snow #define TYPE_SYSBUS_AHCI "sysbus-ahci"
353*70e23370SJohn Snow #define SYSBUS_AHCI(obj) OBJECT_CHECK(SysbusAHCIState, (obj), TYPE_SYSBUS_AHCI)
354*70e23370SJohn Snow 
355*70e23370SJohn Snow #define TYPE_ALLWINNER_AHCI "allwinner-ahci"
356*70e23370SJohn Snow #define ALLWINNER_AHCI(obj) OBJECT_CHECK(AllwinnerAHCIState, (obj), \
357*70e23370SJohn Snow                        TYPE_ALLWINNER_AHCI)
358*70e23370SJohn Snow 
359*70e23370SJohn Snow #endif /* HW_IDE_AHCI_H */
360