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