Statistics
| Branch: | Revision:

root / hw / ide / ahci.c @ b8676728

History | View | Annotate | Download (35.9 kB)

1 f6ad2e32 Alexander Graf
/*
2 f6ad2e32 Alexander Graf
 * QEMU AHCI Emulation
3 f6ad2e32 Alexander Graf
 *
4 f6ad2e32 Alexander Graf
 * Copyright (c) 2010 qiaochong@loongson.cn
5 f6ad2e32 Alexander Graf
 * Copyright (c) 2010 Roland Elek <elek.roland@gmail.com>
6 f6ad2e32 Alexander Graf
 * Copyright (c) 2010 Sebastian Herbszt <herbszt@gmx.de>
7 f6ad2e32 Alexander Graf
 * Copyright (c) 2010 Alexander Graf <agraf@suse.de>
8 f6ad2e32 Alexander Graf
 *
9 f6ad2e32 Alexander Graf
 * This library is free software; you can redistribute it and/or
10 f6ad2e32 Alexander Graf
 * modify it under the terms of the GNU Lesser General Public
11 f6ad2e32 Alexander Graf
 * License as published by the Free Software Foundation; either
12 f6ad2e32 Alexander Graf
 * version 2 of the License, or (at your option) any later version.
13 f6ad2e32 Alexander Graf
 *
14 f6ad2e32 Alexander Graf
 * This library is distributed in the hope that it will be useful,
15 f6ad2e32 Alexander Graf
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 f6ad2e32 Alexander Graf
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17 f6ad2e32 Alexander Graf
 * Lesser General Public License for more details.
18 f6ad2e32 Alexander Graf
 *
19 f6ad2e32 Alexander Graf
 * You should have received a copy of the GNU Lesser General Public
20 f6ad2e32 Alexander Graf
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
21 f6ad2e32 Alexander Graf
 *
22 f6ad2e32 Alexander Graf
 */
23 f6ad2e32 Alexander Graf
24 f6ad2e32 Alexander Graf
#include <hw/hw.h>
25 f6ad2e32 Alexander Graf
#include <hw/msi.h>
26 f6ad2e32 Alexander Graf
#include <hw/pc.h>
27 f6ad2e32 Alexander Graf
#include <hw/pci.h>
28 d9fa31a3 Rob Herring
#include <hw/sysbus.h>
29 f6ad2e32 Alexander Graf
30 f6ad2e32 Alexander Graf
#include "monitor.h"
31 f6ad2e32 Alexander Graf
#include "dma.h"
32 f6ad2e32 Alexander Graf
#include "cpu-common.h"
33 f6ad2e32 Alexander Graf
#include "internal.h"
34 f6ad2e32 Alexander Graf
#include <hw/ide/pci.h>
35 03c7a6a8 Sebastian Herbszt
#include <hw/ide/ahci.h>
36 f6ad2e32 Alexander Graf
37 f6ad2e32 Alexander Graf
/* #define DEBUG_AHCI */
38 f6ad2e32 Alexander Graf
39 f6ad2e32 Alexander Graf
#ifdef DEBUG_AHCI
40 f6ad2e32 Alexander Graf
#define DPRINTF(port, fmt, ...) \
41 f6ad2e32 Alexander Graf
do { fprintf(stderr, "ahci: %s: [%d] ", __FUNCTION__, port); \
42 f6ad2e32 Alexander Graf
     fprintf(stderr, fmt, ## __VA_ARGS__); } while (0)
43 f6ad2e32 Alexander Graf
#else
44 f6ad2e32 Alexander Graf
#define DPRINTF(port, fmt, ...) do {} while(0)
45 f6ad2e32 Alexander Graf
#endif
46 f6ad2e32 Alexander Graf
47 f6ad2e32 Alexander Graf
static void check_cmd(AHCIState *s, int port);
48 f6ad2e32 Alexander Graf
static int handle_cmd(AHCIState *s,int port,int slot);
49 f6ad2e32 Alexander Graf
static void ahci_reset_port(AHCIState *s, int port);
50 f6ad2e32 Alexander Graf
static void ahci_write_fis_d2h(AHCIDevice *ad, uint8_t *cmd_fis);
51 87e62065 Alexander Graf
static void ahci_init_d2h(AHCIDevice *ad);
52 f6ad2e32 Alexander Graf
53 f6ad2e32 Alexander Graf
static uint32_t  ahci_port_read(AHCIState *s, int port, int offset)
54 f6ad2e32 Alexander Graf
{
55 f6ad2e32 Alexander Graf
    uint32_t val;
56 f6ad2e32 Alexander Graf
    AHCIPortRegs *pr;
57 f6ad2e32 Alexander Graf
    pr = &s->dev[port].port_regs;
58 f6ad2e32 Alexander Graf
59 f6ad2e32 Alexander Graf
    switch (offset) {
60 f6ad2e32 Alexander Graf
    case PORT_LST_ADDR:
61 f6ad2e32 Alexander Graf
        val = pr->lst_addr;
62 f6ad2e32 Alexander Graf
        break;
63 f6ad2e32 Alexander Graf
    case PORT_LST_ADDR_HI:
64 f6ad2e32 Alexander Graf
        val = pr->lst_addr_hi;
65 f6ad2e32 Alexander Graf
        break;
66 f6ad2e32 Alexander Graf
    case PORT_FIS_ADDR:
67 f6ad2e32 Alexander Graf
        val = pr->fis_addr;
68 f6ad2e32 Alexander Graf
        break;
69 f6ad2e32 Alexander Graf
    case PORT_FIS_ADDR_HI:
70 f6ad2e32 Alexander Graf
        val = pr->fis_addr_hi;
71 f6ad2e32 Alexander Graf
        break;
72 f6ad2e32 Alexander Graf
    case PORT_IRQ_STAT:
73 f6ad2e32 Alexander Graf
        val = pr->irq_stat;
74 f6ad2e32 Alexander Graf
        break;
75 f6ad2e32 Alexander Graf
    case PORT_IRQ_MASK:
76 f6ad2e32 Alexander Graf
        val = pr->irq_mask;
77 f6ad2e32 Alexander Graf
        break;
78 f6ad2e32 Alexander Graf
    case PORT_CMD:
79 f6ad2e32 Alexander Graf
        val = pr->cmd;
80 f6ad2e32 Alexander Graf
        break;
81 f6ad2e32 Alexander Graf
    case PORT_TFDATA:
82 f6ad2e32 Alexander Graf
        val = ((uint16_t)s->dev[port].port.ifs[0].error << 8) |
83 f6ad2e32 Alexander Graf
              s->dev[port].port.ifs[0].status;
84 f6ad2e32 Alexander Graf
        break;
85 f6ad2e32 Alexander Graf
    case PORT_SIG:
86 f6ad2e32 Alexander Graf
        val = pr->sig;
87 f6ad2e32 Alexander Graf
        break;
88 f6ad2e32 Alexander Graf
    case PORT_SCR_STAT:
89 f6ad2e32 Alexander Graf
        if (s->dev[port].port.ifs[0].bs) {
90 f6ad2e32 Alexander Graf
            val = SATA_SCR_SSTATUS_DET_DEV_PRESENT_PHY_UP |
91 f6ad2e32 Alexander Graf
                  SATA_SCR_SSTATUS_SPD_GEN1 | SATA_SCR_SSTATUS_IPM_ACTIVE;
92 f6ad2e32 Alexander Graf
        } else {
93 f6ad2e32 Alexander Graf
            val = SATA_SCR_SSTATUS_DET_NODEV;
94 f6ad2e32 Alexander Graf
        }
95 f6ad2e32 Alexander Graf
        break;
96 f6ad2e32 Alexander Graf
    case PORT_SCR_CTL:
97 f6ad2e32 Alexander Graf
        val = pr->scr_ctl;
98 f6ad2e32 Alexander Graf
        break;
99 f6ad2e32 Alexander Graf
    case PORT_SCR_ERR:
100 f6ad2e32 Alexander Graf
        val = pr->scr_err;
101 f6ad2e32 Alexander Graf
        break;
102 f6ad2e32 Alexander Graf
    case PORT_SCR_ACT:
103 f6ad2e32 Alexander Graf
        pr->scr_act &= ~s->dev[port].finished;
104 f6ad2e32 Alexander Graf
        s->dev[port].finished = 0;
105 f6ad2e32 Alexander Graf
        val = pr->scr_act;
106 f6ad2e32 Alexander Graf
        break;
107 f6ad2e32 Alexander Graf
    case PORT_CMD_ISSUE:
108 f6ad2e32 Alexander Graf
        val = pr->cmd_issue;
109 f6ad2e32 Alexander Graf
        break;
110 f6ad2e32 Alexander Graf
    case PORT_RESERVED:
111 f6ad2e32 Alexander Graf
    default:
112 f6ad2e32 Alexander Graf
        val = 0;
113 f6ad2e32 Alexander Graf
    }
114 f6ad2e32 Alexander Graf
    DPRINTF(port, "offset: 0x%x val: 0x%x\n", offset, val);
115 f6ad2e32 Alexander Graf
    return val;
116 f6ad2e32 Alexander Graf
117 f6ad2e32 Alexander Graf
}
118 f6ad2e32 Alexander Graf
119 f6ad2e32 Alexander Graf
static void ahci_irq_raise(AHCIState *s, AHCIDevice *dev)
120 f6ad2e32 Alexander Graf
{
121 f6ad2e32 Alexander Graf
    struct AHCIPCIState *d = container_of(s, AHCIPCIState, ahci);
122 f6ad2e32 Alexander Graf
123 f6ad2e32 Alexander Graf
    DPRINTF(0, "raise irq\n");
124 f6ad2e32 Alexander Graf
125 f6ad2e32 Alexander Graf
    if (msi_enabled(&d->card)) {
126 f6ad2e32 Alexander Graf
        msi_notify(&d->card, 0);
127 f6ad2e32 Alexander Graf
    } else {
128 f6ad2e32 Alexander Graf
        qemu_irq_raise(s->irq);
129 f6ad2e32 Alexander Graf
    }
130 f6ad2e32 Alexander Graf
}
131 f6ad2e32 Alexander Graf
132 f6ad2e32 Alexander Graf
static void ahci_irq_lower(AHCIState *s, AHCIDevice *dev)
133 f6ad2e32 Alexander Graf
{
134 f6ad2e32 Alexander Graf
    struct AHCIPCIState *d = container_of(s, AHCIPCIState, ahci);
135 f6ad2e32 Alexander Graf
136 f6ad2e32 Alexander Graf
    DPRINTF(0, "lower irq\n");
137 f6ad2e32 Alexander Graf
138 f6ad2e32 Alexander Graf
    if (!msi_enabled(&d->card)) {
139 f6ad2e32 Alexander Graf
        qemu_irq_lower(s->irq);
140 f6ad2e32 Alexander Graf
    }
141 f6ad2e32 Alexander Graf
}
142 f6ad2e32 Alexander Graf
143 f6ad2e32 Alexander Graf
static void ahci_check_irq(AHCIState *s)
144 f6ad2e32 Alexander Graf
{
145 f6ad2e32 Alexander Graf
    int i;
146 f6ad2e32 Alexander Graf
147 f6ad2e32 Alexander Graf
    DPRINTF(-1, "check irq %#x\n", s->control_regs.irqstatus);
148 f6ad2e32 Alexander Graf
149 b8676728 Alexander Graf
    s->control_regs.irqstatus = 0;
150 2c4b9d0e Alexander Graf
    for (i = 0; i < s->ports; i++) {
151 f6ad2e32 Alexander Graf
        AHCIPortRegs *pr = &s->dev[i].port_regs;
152 f6ad2e32 Alexander Graf
        if (pr->irq_stat & pr->irq_mask) {
153 f6ad2e32 Alexander Graf
            s->control_regs.irqstatus |= (1 << i);
154 f6ad2e32 Alexander Graf
        }
155 f6ad2e32 Alexander Graf
    }
156 f6ad2e32 Alexander Graf
157 f6ad2e32 Alexander Graf
    if (s->control_regs.irqstatus &&
158 f6ad2e32 Alexander Graf
        (s->control_regs.ghc & HOST_CTL_IRQ_EN)) {
159 f6ad2e32 Alexander Graf
            ahci_irq_raise(s, NULL);
160 f6ad2e32 Alexander Graf
    } else {
161 f6ad2e32 Alexander Graf
        ahci_irq_lower(s, NULL);
162 f6ad2e32 Alexander Graf
    }
163 f6ad2e32 Alexander Graf
}
164 f6ad2e32 Alexander Graf
165 f6ad2e32 Alexander Graf
static void ahci_trigger_irq(AHCIState *s, AHCIDevice *d,
166 f6ad2e32 Alexander Graf
                             int irq_type)
167 f6ad2e32 Alexander Graf
{
168 f6ad2e32 Alexander Graf
    DPRINTF(d->port_no, "trigger irq %#x -> %x\n",
169 f6ad2e32 Alexander Graf
            irq_type, d->port_regs.irq_mask & irq_type);
170 f6ad2e32 Alexander Graf
171 f6ad2e32 Alexander Graf
    d->port_regs.irq_stat |= irq_type;
172 f6ad2e32 Alexander Graf
    ahci_check_irq(s);
173 f6ad2e32 Alexander Graf
}
174 f6ad2e32 Alexander Graf
175 f6ad2e32 Alexander Graf
static void map_page(uint8_t **ptr, uint64_t addr, uint32_t wanted)
176 f6ad2e32 Alexander Graf
{
177 f6ad2e32 Alexander Graf
    target_phys_addr_t len = wanted;
178 f6ad2e32 Alexander Graf
179 f6ad2e32 Alexander Graf
    if (*ptr) {
180 fe6ceac8 Stefan Hajnoczi
        cpu_physical_memory_unmap(*ptr, len, 1, len);
181 f6ad2e32 Alexander Graf
    }
182 f6ad2e32 Alexander Graf
183 f6ad2e32 Alexander Graf
    *ptr = cpu_physical_memory_map(addr, &len, 1);
184 f6ad2e32 Alexander Graf
    if (len < wanted) {
185 fe6ceac8 Stefan Hajnoczi
        cpu_physical_memory_unmap(*ptr, len, 1, len);
186 f6ad2e32 Alexander Graf
        *ptr = NULL;
187 f6ad2e32 Alexander Graf
    }
188 f6ad2e32 Alexander Graf
}
189 f6ad2e32 Alexander Graf
190 f6ad2e32 Alexander Graf
static void  ahci_port_write(AHCIState *s, int port, int offset, uint32_t val)
191 f6ad2e32 Alexander Graf
{
192 f6ad2e32 Alexander Graf
    AHCIPortRegs *pr = &s->dev[port].port_regs;
193 f6ad2e32 Alexander Graf
194 f6ad2e32 Alexander Graf
    DPRINTF(port, "offset: 0x%x val: 0x%x\n", offset, val);
195 f6ad2e32 Alexander Graf
    switch (offset) {
196 f6ad2e32 Alexander Graf
        case PORT_LST_ADDR:
197 f6ad2e32 Alexander Graf
            pr->lst_addr = val;
198 f6ad2e32 Alexander Graf
            map_page(&s->dev[port].lst,
199 f6ad2e32 Alexander Graf
                     ((uint64_t)pr->lst_addr_hi << 32) | pr->lst_addr, 1024);
200 f6ad2e32 Alexander Graf
            s->dev[port].cur_cmd = NULL;
201 f6ad2e32 Alexander Graf
            break;
202 f6ad2e32 Alexander Graf
        case PORT_LST_ADDR_HI:
203 f6ad2e32 Alexander Graf
            pr->lst_addr_hi = val;
204 f6ad2e32 Alexander Graf
            map_page(&s->dev[port].lst,
205 f6ad2e32 Alexander Graf
                     ((uint64_t)pr->lst_addr_hi << 32) | pr->lst_addr, 1024);
206 f6ad2e32 Alexander Graf
            s->dev[port].cur_cmd = NULL;
207 f6ad2e32 Alexander Graf
            break;
208 f6ad2e32 Alexander Graf
        case PORT_FIS_ADDR:
209 f6ad2e32 Alexander Graf
            pr->fis_addr = val;
210 f6ad2e32 Alexander Graf
            map_page(&s->dev[port].res_fis,
211 f6ad2e32 Alexander Graf
                     ((uint64_t)pr->fis_addr_hi << 32) | pr->fis_addr, 256);
212 f6ad2e32 Alexander Graf
            break;
213 f6ad2e32 Alexander Graf
        case PORT_FIS_ADDR_HI:
214 f6ad2e32 Alexander Graf
            pr->fis_addr_hi = val;
215 f6ad2e32 Alexander Graf
            map_page(&s->dev[port].res_fis,
216 f6ad2e32 Alexander Graf
                     ((uint64_t)pr->fis_addr_hi << 32) | pr->fis_addr, 256);
217 f6ad2e32 Alexander Graf
            break;
218 f6ad2e32 Alexander Graf
        case PORT_IRQ_STAT:
219 f6ad2e32 Alexander Graf
            pr->irq_stat &= ~val;
220 b8676728 Alexander Graf
            ahci_check_irq(s);
221 f6ad2e32 Alexander Graf
            break;
222 f6ad2e32 Alexander Graf
        case PORT_IRQ_MASK:
223 f6ad2e32 Alexander Graf
            pr->irq_mask = val & 0xfdc000ff;
224 f6ad2e32 Alexander Graf
            ahci_check_irq(s);
225 f6ad2e32 Alexander Graf
            break;
226 f6ad2e32 Alexander Graf
        case PORT_CMD:
227 f6ad2e32 Alexander Graf
            pr->cmd = val & ~(PORT_CMD_LIST_ON | PORT_CMD_FIS_ON);
228 f6ad2e32 Alexander Graf
229 f6ad2e32 Alexander Graf
            if (pr->cmd & PORT_CMD_START) {
230 f6ad2e32 Alexander Graf
                pr->cmd |= PORT_CMD_LIST_ON;
231 f6ad2e32 Alexander Graf
            }
232 f6ad2e32 Alexander Graf
233 f6ad2e32 Alexander Graf
            if (pr->cmd & PORT_CMD_FIS_RX) {
234 f6ad2e32 Alexander Graf
                pr->cmd |= PORT_CMD_FIS_ON;
235 f6ad2e32 Alexander Graf
            }
236 f6ad2e32 Alexander Graf
237 87e62065 Alexander Graf
            /* XXX usually the FIS would be pending on the bus here and
238 87e62065 Alexander Graf
                   issuing deferred until the OS enables FIS receival.
239 87e62065 Alexander Graf
                   Instead, we only submit it once - which works in most
240 87e62065 Alexander Graf
                   cases, but is a hack. */
241 87e62065 Alexander Graf
            if ((pr->cmd & PORT_CMD_FIS_ON) &&
242 87e62065 Alexander Graf
                !s->dev[port].init_d2h_sent) {
243 87e62065 Alexander Graf
                ahci_init_d2h(&s->dev[port]);
244 87e62065 Alexander Graf
                s->dev[port].init_d2h_sent = 1;
245 87e62065 Alexander Graf
            }
246 87e62065 Alexander Graf
247 f6ad2e32 Alexander Graf
            check_cmd(s, port);
248 f6ad2e32 Alexander Graf
            break;
249 f6ad2e32 Alexander Graf
        case PORT_TFDATA:
250 f6ad2e32 Alexander Graf
            s->dev[port].port.ifs[0].error = (val >> 8) & 0xff;
251 f6ad2e32 Alexander Graf
            s->dev[port].port.ifs[0].status = val & 0xff;
252 f6ad2e32 Alexander Graf
            break;
253 f6ad2e32 Alexander Graf
        case PORT_SIG:
254 f6ad2e32 Alexander Graf
            pr->sig = val;
255 f6ad2e32 Alexander Graf
            break;
256 f6ad2e32 Alexander Graf
        case PORT_SCR_STAT:
257 f6ad2e32 Alexander Graf
            pr->scr_stat = val;
258 f6ad2e32 Alexander Graf
            break;
259 f6ad2e32 Alexander Graf
        case PORT_SCR_CTL:
260 f6ad2e32 Alexander Graf
            if (((pr->scr_ctl & AHCI_SCR_SCTL_DET) == 1) &&
261 f6ad2e32 Alexander Graf
                ((val & AHCI_SCR_SCTL_DET) == 0)) {
262 f6ad2e32 Alexander Graf
                ahci_reset_port(s, port);
263 f6ad2e32 Alexander Graf
            }
264 f6ad2e32 Alexander Graf
            pr->scr_ctl = val;
265 f6ad2e32 Alexander Graf
            break;
266 f6ad2e32 Alexander Graf
        case PORT_SCR_ERR:
267 f6ad2e32 Alexander Graf
            pr->scr_err &= ~val;
268 f6ad2e32 Alexander Graf
            break;
269 f6ad2e32 Alexander Graf
        case PORT_SCR_ACT:
270 f6ad2e32 Alexander Graf
            /* RW1 */
271 f6ad2e32 Alexander Graf
            pr->scr_act |= val;
272 f6ad2e32 Alexander Graf
            break;
273 f6ad2e32 Alexander Graf
        case PORT_CMD_ISSUE:
274 f6ad2e32 Alexander Graf
            pr->cmd_issue |= val;
275 f6ad2e32 Alexander Graf
            check_cmd(s, port);
276 f6ad2e32 Alexander Graf
            break;
277 f6ad2e32 Alexander Graf
        default:
278 f6ad2e32 Alexander Graf
            break;
279 f6ad2e32 Alexander Graf
    }
280 f6ad2e32 Alexander Graf
}
281 f6ad2e32 Alexander Graf
282 67e576c2 Avi Kivity
static uint64_t ahci_mem_read(void *opaque, target_phys_addr_t addr,
283 67e576c2 Avi Kivity
                              unsigned size)
284 f6ad2e32 Alexander Graf
{
285 67e576c2 Avi Kivity
    AHCIState *s = opaque;
286 f6ad2e32 Alexander Graf
    uint32_t val = 0;
287 f6ad2e32 Alexander Graf
288 f6ad2e32 Alexander Graf
    if (addr < AHCI_GENERIC_HOST_CONTROL_REGS_MAX_ADDR) {
289 f6ad2e32 Alexander Graf
        switch (addr) {
290 f6ad2e32 Alexander Graf
        case HOST_CAP:
291 f6ad2e32 Alexander Graf
            val = s->control_regs.cap;
292 f6ad2e32 Alexander Graf
            break;
293 f6ad2e32 Alexander Graf
        case HOST_CTL:
294 f6ad2e32 Alexander Graf
            val = s->control_regs.ghc;
295 f6ad2e32 Alexander Graf
            break;
296 f6ad2e32 Alexander Graf
        case HOST_IRQ_STAT:
297 f6ad2e32 Alexander Graf
            val = s->control_regs.irqstatus;
298 f6ad2e32 Alexander Graf
            break;
299 f6ad2e32 Alexander Graf
        case HOST_PORTS_IMPL:
300 f6ad2e32 Alexander Graf
            val = s->control_regs.impl;
301 f6ad2e32 Alexander Graf
            break;
302 f6ad2e32 Alexander Graf
        case HOST_VERSION:
303 f6ad2e32 Alexander Graf
            val = s->control_regs.version;
304 f6ad2e32 Alexander Graf
            break;
305 f6ad2e32 Alexander Graf
        }
306 f6ad2e32 Alexander Graf
307 f6ad2e32 Alexander Graf
        DPRINTF(-1, "(addr 0x%08X), val 0x%08X\n", (unsigned) addr, val);
308 f6ad2e32 Alexander Graf
    } else if ((addr >= AHCI_PORT_REGS_START_ADDR) &&
309 2c4b9d0e Alexander Graf
               (addr < (AHCI_PORT_REGS_START_ADDR +
310 2c4b9d0e Alexander Graf
                (s->ports * AHCI_PORT_ADDR_OFFSET_LEN)))) {
311 f6ad2e32 Alexander Graf
        val = ahci_port_read(s, (addr - AHCI_PORT_REGS_START_ADDR) >> 7,
312 f6ad2e32 Alexander Graf
                             addr & AHCI_PORT_ADDR_OFFSET_MASK);
313 f6ad2e32 Alexander Graf
    }
314 f6ad2e32 Alexander Graf
315 f6ad2e32 Alexander Graf
    return val;
316 f6ad2e32 Alexander Graf
}
317 f6ad2e32 Alexander Graf
318 f6ad2e32 Alexander Graf
319 f6ad2e32 Alexander Graf
320 67e576c2 Avi Kivity
static void ahci_mem_write(void *opaque, target_phys_addr_t addr,
321 67e576c2 Avi Kivity
                           uint64_t val, unsigned size)
322 f6ad2e32 Alexander Graf
{
323 67e576c2 Avi Kivity
    AHCIState *s = opaque;
324 f6ad2e32 Alexander Graf
325 f6ad2e32 Alexander Graf
    /* Only aligned reads are allowed on AHCI */
326 f6ad2e32 Alexander Graf
    if (addr & 3) {
327 f6ad2e32 Alexander Graf
        fprintf(stderr, "ahci: Mis-aligned write to addr 0x"
328 f6ad2e32 Alexander Graf
                TARGET_FMT_plx "\n", addr);
329 f6ad2e32 Alexander Graf
        return;
330 f6ad2e32 Alexander Graf
    }
331 f6ad2e32 Alexander Graf
332 f6ad2e32 Alexander Graf
    if (addr < AHCI_GENERIC_HOST_CONTROL_REGS_MAX_ADDR) {
333 3899edf7 Max Filippov
        DPRINTF(-1, "(addr 0x%08X), val 0x%08"PRIX64"\n", (unsigned) addr, val);
334 f6ad2e32 Alexander Graf
335 f6ad2e32 Alexander Graf
        switch (addr) {
336 f6ad2e32 Alexander Graf
            case HOST_CAP: /* R/WO, RO */
337 f6ad2e32 Alexander Graf
                /* FIXME handle R/WO */
338 f6ad2e32 Alexander Graf
                break;
339 f6ad2e32 Alexander Graf
            case HOST_CTL: /* R/W */
340 f6ad2e32 Alexander Graf
                if (val & HOST_CTL_RESET) {
341 f6ad2e32 Alexander Graf
                    DPRINTF(-1, "HBA Reset\n");
342 760c3e44 Alexander Graf
                    ahci_reset(container_of(s, AHCIPCIState, ahci));
343 f6ad2e32 Alexander Graf
                } else {
344 f6ad2e32 Alexander Graf
                    s->control_regs.ghc = (val & 0x3) | HOST_CTL_AHCI_EN;
345 f6ad2e32 Alexander Graf
                    ahci_check_irq(s);
346 f6ad2e32 Alexander Graf
                }
347 f6ad2e32 Alexander Graf
                break;
348 f6ad2e32 Alexander Graf
            case HOST_IRQ_STAT: /* R/WC, RO */
349 f6ad2e32 Alexander Graf
                s->control_regs.irqstatus &= ~val;
350 f6ad2e32 Alexander Graf
                ahci_check_irq(s);
351 f6ad2e32 Alexander Graf
                break;
352 f6ad2e32 Alexander Graf
            case HOST_PORTS_IMPL: /* R/WO, RO */
353 f6ad2e32 Alexander Graf
                /* FIXME handle R/WO */
354 f6ad2e32 Alexander Graf
                break;
355 f6ad2e32 Alexander Graf
            case HOST_VERSION: /* RO */
356 f6ad2e32 Alexander Graf
                /* FIXME report write? */
357 f6ad2e32 Alexander Graf
                break;
358 f6ad2e32 Alexander Graf
            default:
359 f6ad2e32 Alexander Graf
                DPRINTF(-1, "write to unknown register 0x%x\n", (unsigned)addr);
360 f6ad2e32 Alexander Graf
        }
361 f6ad2e32 Alexander Graf
    } else if ((addr >= AHCI_PORT_REGS_START_ADDR) &&
362 2c4b9d0e Alexander Graf
               (addr < (AHCI_PORT_REGS_START_ADDR +
363 2c4b9d0e Alexander Graf
                (s->ports * AHCI_PORT_ADDR_OFFSET_LEN)))) {
364 f6ad2e32 Alexander Graf
        ahci_port_write(s, (addr - AHCI_PORT_REGS_START_ADDR) >> 7,
365 f6ad2e32 Alexander Graf
                        addr & AHCI_PORT_ADDR_OFFSET_MASK, val);
366 f6ad2e32 Alexander Graf
    }
367 f6ad2e32 Alexander Graf
368 f6ad2e32 Alexander Graf
}
369 f6ad2e32 Alexander Graf
370 67e576c2 Avi Kivity
static MemoryRegionOps ahci_mem_ops = {
371 67e576c2 Avi Kivity
    .read = ahci_mem_read,
372 67e576c2 Avi Kivity
    .write = ahci_mem_write,
373 67e576c2 Avi Kivity
    .endianness = DEVICE_LITTLE_ENDIAN,
374 f6ad2e32 Alexander Graf
};
375 f6ad2e32 Alexander Graf
376 465f1ab1 Daniel Verkamp
static uint64_t ahci_idp_read(void *opaque, target_phys_addr_t addr,
377 465f1ab1 Daniel Verkamp
                              unsigned size)
378 465f1ab1 Daniel Verkamp
{
379 465f1ab1 Daniel Verkamp
    AHCIState *s = opaque;
380 465f1ab1 Daniel Verkamp
381 465f1ab1 Daniel Verkamp
    if (addr == s->idp_offset) {
382 465f1ab1 Daniel Verkamp
        /* index register */
383 465f1ab1 Daniel Verkamp
        return s->idp_index;
384 465f1ab1 Daniel Verkamp
    } else if (addr == s->idp_offset + 4) {
385 465f1ab1 Daniel Verkamp
        /* data register - do memory read at location selected by index */
386 465f1ab1 Daniel Verkamp
        return ahci_mem_read(opaque, s->idp_index, size);
387 465f1ab1 Daniel Verkamp
    } else {
388 465f1ab1 Daniel Verkamp
        return 0;
389 465f1ab1 Daniel Verkamp
    }
390 465f1ab1 Daniel Verkamp
}
391 465f1ab1 Daniel Verkamp
392 465f1ab1 Daniel Verkamp
static void ahci_idp_write(void *opaque, target_phys_addr_t addr,
393 465f1ab1 Daniel Verkamp
                           uint64_t val, unsigned size)
394 465f1ab1 Daniel Verkamp
{
395 465f1ab1 Daniel Verkamp
    AHCIState *s = opaque;
396 465f1ab1 Daniel Verkamp
397 465f1ab1 Daniel Verkamp
    if (addr == s->idp_offset) {
398 465f1ab1 Daniel Verkamp
        /* index register - mask off reserved bits */
399 465f1ab1 Daniel Verkamp
        s->idp_index = (uint32_t)val & ((AHCI_MEM_BAR_SIZE - 1) & ~3);
400 465f1ab1 Daniel Verkamp
    } else if (addr == s->idp_offset + 4) {
401 465f1ab1 Daniel Verkamp
        /* data register - do memory write at location selected by index */
402 465f1ab1 Daniel Verkamp
        ahci_mem_write(opaque, s->idp_index, val, size);
403 465f1ab1 Daniel Verkamp
    }
404 465f1ab1 Daniel Verkamp
}
405 465f1ab1 Daniel Verkamp
406 465f1ab1 Daniel Verkamp
static MemoryRegionOps ahci_idp_ops = {
407 465f1ab1 Daniel Verkamp
    .read = ahci_idp_read,
408 465f1ab1 Daniel Verkamp
    .write = ahci_idp_write,
409 465f1ab1 Daniel Verkamp
    .endianness = DEVICE_LITTLE_ENDIAN,
410 465f1ab1 Daniel Verkamp
};
411 465f1ab1 Daniel Verkamp
412 465f1ab1 Daniel Verkamp
413 f6ad2e32 Alexander Graf
static void ahci_reg_init(AHCIState *s)
414 f6ad2e32 Alexander Graf
{
415 f6ad2e32 Alexander Graf
    int i;
416 f6ad2e32 Alexander Graf
417 2c4b9d0e Alexander Graf
    s->control_regs.cap = (s->ports - 1) |
418 f6ad2e32 Alexander Graf
                          (AHCI_NUM_COMMAND_SLOTS << 8) |
419 f6ad2e32 Alexander Graf
                          (AHCI_SUPPORTED_SPEED_GEN1 << AHCI_SUPPORTED_SPEED) |
420 f6ad2e32 Alexander Graf
                          HOST_CAP_NCQ | HOST_CAP_AHCI;
421 f6ad2e32 Alexander Graf
422 2c4b9d0e Alexander Graf
    s->control_regs.impl = (1 << s->ports) - 1;
423 f6ad2e32 Alexander Graf
424 f6ad2e32 Alexander Graf
    s->control_regs.version = AHCI_VERSION_1_0;
425 f6ad2e32 Alexander Graf
426 2c4b9d0e Alexander Graf
    for (i = 0; i < s->ports; i++) {
427 f6ad2e32 Alexander Graf
        s->dev[i].port_state = STATE_RUN;
428 f6ad2e32 Alexander Graf
    }
429 f6ad2e32 Alexander Graf
}
430 f6ad2e32 Alexander Graf
431 f6ad2e32 Alexander Graf
static uint32_t read_from_sglist(uint8_t *buffer, uint32_t len,
432 f6ad2e32 Alexander Graf
                                 QEMUSGList *sglist)
433 f6ad2e32 Alexander Graf
{
434 f6ad2e32 Alexander Graf
    uint32_t i = 0;
435 f6ad2e32 Alexander Graf
    uint32_t total = 0, once;
436 f6ad2e32 Alexander Graf
    ScatterGatherEntry *cur_prd;
437 f6ad2e32 Alexander Graf
    uint32_t sgcount;
438 f6ad2e32 Alexander Graf
439 f6ad2e32 Alexander Graf
    cur_prd = sglist->sg;
440 f6ad2e32 Alexander Graf
    sgcount = sglist->nsg;
441 f6ad2e32 Alexander Graf
    for (i = 0; len && sgcount; i++) {
442 f6ad2e32 Alexander Graf
        once = MIN(cur_prd->len, len);
443 f6ad2e32 Alexander Graf
        cpu_physical_memory_read(cur_prd->base, buffer, once);
444 f6ad2e32 Alexander Graf
        cur_prd++;
445 f6ad2e32 Alexander Graf
        sgcount--;
446 f6ad2e32 Alexander Graf
        len -= once;
447 f6ad2e32 Alexander Graf
        buffer += once;
448 f6ad2e32 Alexander Graf
        total += once;
449 f6ad2e32 Alexander Graf
    }
450 f6ad2e32 Alexander Graf
451 f6ad2e32 Alexander Graf
    return total;
452 f6ad2e32 Alexander Graf
}
453 f6ad2e32 Alexander Graf
454 f6ad2e32 Alexander Graf
static uint32_t write_to_sglist(uint8_t *buffer, uint32_t len,
455 f6ad2e32 Alexander Graf
                                QEMUSGList *sglist)
456 f6ad2e32 Alexander Graf
{
457 f6ad2e32 Alexander Graf
    uint32_t i = 0;
458 f6ad2e32 Alexander Graf
    uint32_t total = 0, once;
459 f6ad2e32 Alexander Graf
    ScatterGatherEntry *cur_prd;
460 f6ad2e32 Alexander Graf
    uint32_t sgcount;
461 f6ad2e32 Alexander Graf
462 f6ad2e32 Alexander Graf
    DPRINTF(-1, "total: 0x%x bytes\n", len);
463 f6ad2e32 Alexander Graf
464 f6ad2e32 Alexander Graf
    cur_prd = sglist->sg;
465 f6ad2e32 Alexander Graf
    sgcount = sglist->nsg;
466 f6ad2e32 Alexander Graf
    for (i = 0; len && sgcount; i++) {
467 f6ad2e32 Alexander Graf
        once = MIN(cur_prd->len, len);
468 f6ad2e32 Alexander Graf
        DPRINTF(-1, "write 0x%x bytes to 0x%lx\n", once, (long)cur_prd->base);
469 f6ad2e32 Alexander Graf
        cpu_physical_memory_write(cur_prd->base, buffer, once);
470 f6ad2e32 Alexander Graf
        cur_prd++;
471 f6ad2e32 Alexander Graf
        sgcount--;
472 f6ad2e32 Alexander Graf
        len -= once;
473 f6ad2e32 Alexander Graf
        buffer += once;
474 f6ad2e32 Alexander Graf
        total += once;
475 f6ad2e32 Alexander Graf
    }
476 f6ad2e32 Alexander Graf
477 f6ad2e32 Alexander Graf
    return total;
478 f6ad2e32 Alexander Graf
}
479 f6ad2e32 Alexander Graf
480 f6ad2e32 Alexander Graf
static void check_cmd(AHCIState *s, int port)
481 f6ad2e32 Alexander Graf
{
482 f6ad2e32 Alexander Graf
    AHCIPortRegs *pr = &s->dev[port].port_regs;
483 f6ad2e32 Alexander Graf
    int slot;
484 f6ad2e32 Alexander Graf
485 f6ad2e32 Alexander Graf
    if ((pr->cmd & PORT_CMD_START) && pr->cmd_issue) {
486 f6ad2e32 Alexander Graf
        for (slot = 0; (slot < 32) && pr->cmd_issue; slot++) {
487 f6ad2e32 Alexander Graf
            if ((pr->cmd_issue & (1 << slot)) &&
488 f6ad2e32 Alexander Graf
                !handle_cmd(s, port, slot)) {
489 f6ad2e32 Alexander Graf
                pr->cmd_issue &= ~(1 << slot);
490 f6ad2e32 Alexander Graf
            }
491 f6ad2e32 Alexander Graf
        }
492 f6ad2e32 Alexander Graf
    }
493 f6ad2e32 Alexander Graf
}
494 f6ad2e32 Alexander Graf
495 f6ad2e32 Alexander Graf
static void ahci_check_cmd_bh(void *opaque)
496 f6ad2e32 Alexander Graf
{
497 f6ad2e32 Alexander Graf
    AHCIDevice *ad = opaque;
498 f6ad2e32 Alexander Graf
499 f6ad2e32 Alexander Graf
    qemu_bh_delete(ad->check_bh);
500 f6ad2e32 Alexander Graf
    ad->check_bh = NULL;
501 f6ad2e32 Alexander Graf
502 f6ad2e32 Alexander Graf
    if ((ad->busy_slot != -1) &&
503 f6ad2e32 Alexander Graf
        !(ad->port.ifs[0].status & (BUSY_STAT|DRQ_STAT))) {
504 f6ad2e32 Alexander Graf
        /* no longer busy */
505 f6ad2e32 Alexander Graf
        ad->port_regs.cmd_issue &= ~(1 << ad->busy_slot);
506 f6ad2e32 Alexander Graf
        ad->busy_slot = -1;
507 f6ad2e32 Alexander Graf
    }
508 f6ad2e32 Alexander Graf
509 f6ad2e32 Alexander Graf
    check_cmd(ad->hba, ad->port_no);
510 f6ad2e32 Alexander Graf
}
511 f6ad2e32 Alexander Graf
512 87e62065 Alexander Graf
static void ahci_init_d2h(AHCIDevice *ad)
513 87e62065 Alexander Graf
{
514 87e62065 Alexander Graf
    uint8_t init_fis[0x20];
515 87e62065 Alexander Graf
    IDEState *ide_state = &ad->port.ifs[0];
516 87e62065 Alexander Graf
517 87e62065 Alexander Graf
    memset(init_fis, 0, sizeof(init_fis));
518 87e62065 Alexander Graf
519 87e62065 Alexander Graf
    init_fis[4] = 1;
520 87e62065 Alexander Graf
    init_fis[12] = 1;
521 87e62065 Alexander Graf
522 87e62065 Alexander Graf
    if (ide_state->drive_kind == IDE_CD) {
523 87e62065 Alexander Graf
        init_fis[5] = ide_state->lcyl;
524 87e62065 Alexander Graf
        init_fis[6] = ide_state->hcyl;
525 87e62065 Alexander Graf
    }
526 87e62065 Alexander Graf
527 87e62065 Alexander Graf
    ahci_write_fis_d2h(ad, init_fis);
528 87e62065 Alexander Graf
}
529 87e62065 Alexander Graf
530 f6ad2e32 Alexander Graf
static void ahci_reset_port(AHCIState *s, int port)
531 f6ad2e32 Alexander Graf
{
532 f6ad2e32 Alexander Graf
    AHCIDevice *d = &s->dev[port];
533 f6ad2e32 Alexander Graf
    AHCIPortRegs *pr = &d->port_regs;
534 f6ad2e32 Alexander Graf
    IDEState *ide_state = &d->port.ifs[0];
535 f6ad2e32 Alexander Graf
    int i;
536 f6ad2e32 Alexander Graf
537 f6ad2e32 Alexander Graf
    DPRINTF(port, "reset port\n");
538 f6ad2e32 Alexander Graf
539 f6ad2e32 Alexander Graf
    ide_bus_reset(&d->port);
540 f6ad2e32 Alexander Graf
    ide_state->ncq_queues = AHCI_MAX_CMDS;
541 f6ad2e32 Alexander Graf
542 f6ad2e32 Alexander Graf
    pr->scr_stat = 0;
543 f6ad2e32 Alexander Graf
    pr->scr_err = 0;
544 f6ad2e32 Alexander Graf
    pr->scr_act = 0;
545 f6ad2e32 Alexander Graf
    d->busy_slot = -1;
546 87e62065 Alexander Graf
    d->init_d2h_sent = 0;
547 f6ad2e32 Alexander Graf
548 f6ad2e32 Alexander Graf
    ide_state = &s->dev[port].port.ifs[0];
549 f6ad2e32 Alexander Graf
    if (!ide_state->bs) {
550 f6ad2e32 Alexander Graf
        return;
551 f6ad2e32 Alexander Graf
    }
552 f6ad2e32 Alexander Graf
553 f6ad2e32 Alexander Graf
    /* reset ncq queue */
554 f6ad2e32 Alexander Graf
    for (i = 0; i < AHCI_MAX_CMDS; i++) {
555 f6ad2e32 Alexander Graf
        NCQTransferState *ncq_tfs = &s->dev[port].ncq_tfs[i];
556 f6ad2e32 Alexander Graf
        if (!ncq_tfs->used) {
557 f6ad2e32 Alexander Graf
            continue;
558 f6ad2e32 Alexander Graf
        }
559 f6ad2e32 Alexander Graf
560 f6ad2e32 Alexander Graf
        if (ncq_tfs->aiocb) {
561 f6ad2e32 Alexander Graf
            bdrv_aio_cancel(ncq_tfs->aiocb);
562 f6ad2e32 Alexander Graf
            ncq_tfs->aiocb = NULL;
563 f6ad2e32 Alexander Graf
        }
564 f6ad2e32 Alexander Graf
565 c9b308d2 Alexander Graf
        /* Maybe we just finished the request thanks to bdrv_aio_cancel() */
566 c9b308d2 Alexander Graf
        if (!ncq_tfs->used) {
567 c9b308d2 Alexander Graf
            continue;
568 c9b308d2 Alexander Graf
        }
569 c9b308d2 Alexander Graf
570 f6ad2e32 Alexander Graf
        qemu_sglist_destroy(&ncq_tfs->sglist);
571 f6ad2e32 Alexander Graf
        ncq_tfs->used = 0;
572 f6ad2e32 Alexander Graf
    }
573 f6ad2e32 Alexander Graf
574 f6ad2e32 Alexander Graf
    s->dev[port].port_state = STATE_RUN;
575 f6ad2e32 Alexander Graf
    if (!ide_state->bs) {
576 f6ad2e32 Alexander Graf
        s->dev[port].port_regs.sig = 0;
577 cdfe17df Blue Swirl
        ide_state->status = SEEK_STAT | WRERR_STAT;
578 f6ad2e32 Alexander Graf
    } else if (ide_state->drive_kind == IDE_CD) {
579 f6ad2e32 Alexander Graf
        s->dev[port].port_regs.sig = SATA_SIGNATURE_CDROM;
580 f6ad2e32 Alexander Graf
        ide_state->lcyl = 0x14;
581 f6ad2e32 Alexander Graf
        ide_state->hcyl = 0xeb;
582 f6ad2e32 Alexander Graf
        DPRINTF(port, "set lcyl = %d\n", ide_state->lcyl);
583 f6ad2e32 Alexander Graf
        ide_state->status = SEEK_STAT | WRERR_STAT | READY_STAT;
584 f6ad2e32 Alexander Graf
    } else {
585 f6ad2e32 Alexander Graf
        s->dev[port].port_regs.sig = SATA_SIGNATURE_DISK;
586 f6ad2e32 Alexander Graf
        ide_state->status = SEEK_STAT | WRERR_STAT;
587 f6ad2e32 Alexander Graf
    }
588 f6ad2e32 Alexander Graf
589 f6ad2e32 Alexander Graf
    ide_state->error = 1;
590 87e62065 Alexander Graf
    ahci_init_d2h(d);
591 f6ad2e32 Alexander Graf
}
592 f6ad2e32 Alexander Graf
593 f6ad2e32 Alexander Graf
static void debug_print_fis(uint8_t *fis, int cmd_len)
594 f6ad2e32 Alexander Graf
{
595 f6ad2e32 Alexander Graf
#ifdef DEBUG_AHCI
596 f6ad2e32 Alexander Graf
    int i;
597 f6ad2e32 Alexander Graf
598 f6ad2e32 Alexander Graf
    fprintf(stderr, "fis:");
599 f6ad2e32 Alexander Graf
    for (i = 0; i < cmd_len; i++) {
600 f6ad2e32 Alexander Graf
        if ((i & 0xf) == 0) {
601 f6ad2e32 Alexander Graf
            fprintf(stderr, "\n%02x:",i);
602 f6ad2e32 Alexander Graf
        }
603 f6ad2e32 Alexander Graf
        fprintf(stderr, "%02x ",fis[i]);
604 f6ad2e32 Alexander Graf
    }
605 f6ad2e32 Alexander Graf
    fprintf(stderr, "\n");
606 f6ad2e32 Alexander Graf
#endif
607 f6ad2e32 Alexander Graf
}
608 f6ad2e32 Alexander Graf
609 f6ad2e32 Alexander Graf
static void ahci_write_fis_sdb(AHCIState *s, int port, uint32_t finished)
610 f6ad2e32 Alexander Graf
{
611 f6ad2e32 Alexander Graf
    AHCIPortRegs *pr = &s->dev[port].port_regs;
612 f6ad2e32 Alexander Graf
    IDEState *ide_state;
613 f6ad2e32 Alexander Graf
    uint8_t *sdb_fis;
614 f6ad2e32 Alexander Graf
615 f6ad2e32 Alexander Graf
    if (!s->dev[port].res_fis ||
616 f6ad2e32 Alexander Graf
        !(pr->cmd & PORT_CMD_FIS_RX)) {
617 f6ad2e32 Alexander Graf
        return;
618 f6ad2e32 Alexander Graf
    }
619 f6ad2e32 Alexander Graf
620 f6ad2e32 Alexander Graf
    sdb_fis = &s->dev[port].res_fis[RES_FIS_SDBFIS];
621 f6ad2e32 Alexander Graf
    ide_state = &s->dev[port].port.ifs[0];
622 f6ad2e32 Alexander Graf
623 f6ad2e32 Alexander Graf
    /* clear memory */
624 f6ad2e32 Alexander Graf
    *(uint32_t*)sdb_fis = 0;
625 f6ad2e32 Alexander Graf
626 f6ad2e32 Alexander Graf
    /* write values */
627 f6ad2e32 Alexander Graf
    sdb_fis[0] = ide_state->error;
628 f6ad2e32 Alexander Graf
    sdb_fis[2] = ide_state->status & 0x77;
629 f6ad2e32 Alexander Graf
    s->dev[port].finished |= finished;
630 f6ad2e32 Alexander Graf
    *(uint32_t*)(sdb_fis + 4) = cpu_to_le32(s->dev[port].finished);
631 f6ad2e32 Alexander Graf
632 f6ad2e32 Alexander Graf
    ahci_trigger_irq(s, &s->dev[port], PORT_IRQ_STAT_SDBS);
633 f6ad2e32 Alexander Graf
}
634 f6ad2e32 Alexander Graf
635 f6ad2e32 Alexander Graf
static void ahci_write_fis_d2h(AHCIDevice *ad, uint8_t *cmd_fis)
636 f6ad2e32 Alexander Graf
{
637 f6ad2e32 Alexander Graf
    AHCIPortRegs *pr = &ad->port_regs;
638 f6ad2e32 Alexander Graf
    uint8_t *d2h_fis;
639 f6ad2e32 Alexander Graf
    int i;
640 f6ad2e32 Alexander Graf
    target_phys_addr_t cmd_len = 0x80;
641 f6ad2e32 Alexander Graf
    int cmd_mapped = 0;
642 f6ad2e32 Alexander Graf
643 f6ad2e32 Alexander Graf
    if (!ad->res_fis || !(pr->cmd & PORT_CMD_FIS_RX)) {
644 f6ad2e32 Alexander Graf
        return;
645 f6ad2e32 Alexander Graf
    }
646 f6ad2e32 Alexander Graf
647 f6ad2e32 Alexander Graf
    if (!cmd_fis) {
648 f6ad2e32 Alexander Graf
        /* map cmd_fis */
649 f6ad2e32 Alexander Graf
        uint64_t tbl_addr = le64_to_cpu(ad->cur_cmd->tbl_addr);
650 f6ad2e32 Alexander Graf
        cmd_fis = cpu_physical_memory_map(tbl_addr, &cmd_len, 0);
651 f6ad2e32 Alexander Graf
        cmd_mapped = 1;
652 f6ad2e32 Alexander Graf
    }
653 f6ad2e32 Alexander Graf
654 f6ad2e32 Alexander Graf
    d2h_fis = &ad->res_fis[RES_FIS_RFIS];
655 f6ad2e32 Alexander Graf
656 f6ad2e32 Alexander Graf
    d2h_fis[0] = 0x34;
657 f6ad2e32 Alexander Graf
    d2h_fis[1] = (ad->hba->control_regs.irqstatus ? (1 << 6) : 0);
658 f6ad2e32 Alexander Graf
    d2h_fis[2] = ad->port.ifs[0].status;
659 f6ad2e32 Alexander Graf
    d2h_fis[3] = ad->port.ifs[0].error;
660 f6ad2e32 Alexander Graf
661 f6ad2e32 Alexander Graf
    d2h_fis[4] = cmd_fis[4];
662 f6ad2e32 Alexander Graf
    d2h_fis[5] = cmd_fis[5];
663 f6ad2e32 Alexander Graf
    d2h_fis[6] = cmd_fis[6];
664 f6ad2e32 Alexander Graf
    d2h_fis[7] = cmd_fis[7];
665 f6ad2e32 Alexander Graf
    d2h_fis[8] = cmd_fis[8];
666 f6ad2e32 Alexander Graf
    d2h_fis[9] = cmd_fis[9];
667 f6ad2e32 Alexander Graf
    d2h_fis[10] = cmd_fis[10];
668 f6ad2e32 Alexander Graf
    d2h_fis[11] = cmd_fis[11];
669 f6ad2e32 Alexander Graf
    d2h_fis[12] = cmd_fis[12];
670 f6ad2e32 Alexander Graf
    d2h_fis[13] = cmd_fis[13];
671 f6ad2e32 Alexander Graf
    for (i = 14; i < 0x20; i++) {
672 f6ad2e32 Alexander Graf
        d2h_fis[i] = 0;
673 f6ad2e32 Alexander Graf
    }
674 f6ad2e32 Alexander Graf
675 f6ad2e32 Alexander Graf
    if (d2h_fis[2] & ERR_STAT) {
676 f6ad2e32 Alexander Graf
        ahci_trigger_irq(ad->hba, ad, PORT_IRQ_STAT_TFES);
677 f6ad2e32 Alexander Graf
    }
678 f6ad2e32 Alexander Graf
679 f6ad2e32 Alexander Graf
    ahci_trigger_irq(ad->hba, ad, PORT_IRQ_D2H_REG_FIS);
680 f6ad2e32 Alexander Graf
681 f6ad2e32 Alexander Graf
    if (cmd_mapped) {
682 fe6ceac8 Stefan Hajnoczi
        cpu_physical_memory_unmap(cmd_fis, cmd_len, 0, cmd_len);
683 f6ad2e32 Alexander Graf
    }
684 f6ad2e32 Alexander Graf
}
685 f6ad2e32 Alexander Graf
686 f6ad2e32 Alexander Graf
static int ahci_populate_sglist(AHCIDevice *ad, QEMUSGList *sglist)
687 f6ad2e32 Alexander Graf
{
688 f6ad2e32 Alexander Graf
    AHCICmdHdr *cmd = ad->cur_cmd;
689 f6ad2e32 Alexander Graf
    uint32_t opts = le32_to_cpu(cmd->opts);
690 f6ad2e32 Alexander Graf
    uint64_t prdt_addr = le64_to_cpu(cmd->tbl_addr) + 0x80;
691 f6ad2e32 Alexander Graf
    int sglist_alloc_hint = opts >> AHCI_CMD_HDR_PRDT_LEN;
692 f6ad2e32 Alexander Graf
    target_phys_addr_t prdt_len = (sglist_alloc_hint * sizeof(AHCI_SG));
693 f6ad2e32 Alexander Graf
    target_phys_addr_t real_prdt_len = prdt_len;
694 f6ad2e32 Alexander Graf
    uint8_t *prdt;
695 f6ad2e32 Alexander Graf
    int i;
696 f6ad2e32 Alexander Graf
    int r = 0;
697 f6ad2e32 Alexander Graf
698 f6ad2e32 Alexander Graf
    if (!sglist_alloc_hint) {
699 f6ad2e32 Alexander Graf
        DPRINTF(ad->port_no, "no sg list given by guest: 0x%08x\n", opts);
700 f6ad2e32 Alexander Graf
        return -1;
701 f6ad2e32 Alexander Graf
    }
702 f6ad2e32 Alexander Graf
703 f6ad2e32 Alexander Graf
    /* map PRDT */
704 f6ad2e32 Alexander Graf
    if (!(prdt = cpu_physical_memory_map(prdt_addr, &prdt_len, 0))){
705 f6ad2e32 Alexander Graf
        DPRINTF(ad->port_no, "map failed\n");
706 f6ad2e32 Alexander Graf
        return -1;
707 f6ad2e32 Alexander Graf
    }
708 f6ad2e32 Alexander Graf
709 f6ad2e32 Alexander Graf
    if (prdt_len < real_prdt_len) {
710 f6ad2e32 Alexander Graf
        DPRINTF(ad->port_no, "mapped less than expected\n");
711 f6ad2e32 Alexander Graf
        r = -1;
712 f6ad2e32 Alexander Graf
        goto out;
713 f6ad2e32 Alexander Graf
    }
714 f6ad2e32 Alexander Graf
715 f6ad2e32 Alexander Graf
    /* Get entries in the PRDT, init a qemu sglist accordingly */
716 f6ad2e32 Alexander Graf
    if (sglist_alloc_hint > 0) {
717 f6ad2e32 Alexander Graf
        AHCI_SG *tbl = (AHCI_SG *)prdt;
718 f6ad2e32 Alexander Graf
719 f6ad2e32 Alexander Graf
        qemu_sglist_init(sglist, sglist_alloc_hint);
720 f6ad2e32 Alexander Graf
        for (i = 0; i < sglist_alloc_hint; i++) {
721 f6ad2e32 Alexander Graf
            /* flags_size is zero-based */
722 f6ad2e32 Alexander Graf
            qemu_sglist_add(sglist, le64_to_cpu(tbl[i].addr),
723 f6ad2e32 Alexander Graf
                            le32_to_cpu(tbl[i].flags_size) + 1);
724 f6ad2e32 Alexander Graf
        }
725 f6ad2e32 Alexander Graf
    }
726 f6ad2e32 Alexander Graf
727 f6ad2e32 Alexander Graf
out:
728 fe6ceac8 Stefan Hajnoczi
    cpu_physical_memory_unmap(prdt, prdt_len, 0, prdt_len);
729 f6ad2e32 Alexander Graf
    return r;
730 f6ad2e32 Alexander Graf
}
731 f6ad2e32 Alexander Graf
732 f6ad2e32 Alexander Graf
static void ncq_cb(void *opaque, int ret)
733 f6ad2e32 Alexander Graf
{
734 f6ad2e32 Alexander Graf
    NCQTransferState *ncq_tfs = (NCQTransferState *)opaque;
735 f6ad2e32 Alexander Graf
    IDEState *ide_state = &ncq_tfs->drive->port.ifs[0];
736 f6ad2e32 Alexander Graf
737 f6ad2e32 Alexander Graf
    /* Clear bit for this tag in SActive */
738 f6ad2e32 Alexander Graf
    ncq_tfs->drive->port_regs.scr_act &= ~(1 << ncq_tfs->tag);
739 f6ad2e32 Alexander Graf
740 f6ad2e32 Alexander Graf
    if (ret < 0) {
741 f6ad2e32 Alexander Graf
        /* error */
742 f6ad2e32 Alexander Graf
        ide_state->error = ABRT_ERR;
743 f6ad2e32 Alexander Graf
        ide_state->status = READY_STAT | ERR_STAT;
744 f6ad2e32 Alexander Graf
        ncq_tfs->drive->port_regs.scr_err |= (1 << ncq_tfs->tag);
745 f6ad2e32 Alexander Graf
    } else {
746 f6ad2e32 Alexander Graf
        ide_state->status = READY_STAT | SEEK_STAT;
747 f6ad2e32 Alexander Graf
    }
748 f6ad2e32 Alexander Graf
749 f6ad2e32 Alexander Graf
    ahci_write_fis_sdb(ncq_tfs->drive->hba, ncq_tfs->drive->port_no,
750 f6ad2e32 Alexander Graf
                       (1 << ncq_tfs->tag));
751 f6ad2e32 Alexander Graf
752 f6ad2e32 Alexander Graf
    DPRINTF(ncq_tfs->drive->port_no, "NCQ transfer tag %d finished\n",
753 f6ad2e32 Alexander Graf
            ncq_tfs->tag);
754 f6ad2e32 Alexander Graf
755 a597e79c Christoph Hellwig
    bdrv_acct_done(ncq_tfs->drive->port.ifs[0].bs, &ncq_tfs->acct);
756 f6ad2e32 Alexander Graf
    qemu_sglist_destroy(&ncq_tfs->sglist);
757 f6ad2e32 Alexander Graf
    ncq_tfs->used = 0;
758 f6ad2e32 Alexander Graf
}
759 f6ad2e32 Alexander Graf
760 f6ad2e32 Alexander Graf
static void process_ncq_command(AHCIState *s, int port, uint8_t *cmd_fis,
761 f6ad2e32 Alexander Graf
                                int slot)
762 f6ad2e32 Alexander Graf
{
763 f6ad2e32 Alexander Graf
    NCQFrame *ncq_fis = (NCQFrame*)cmd_fis;
764 f6ad2e32 Alexander Graf
    uint8_t tag = ncq_fis->tag >> 3;
765 f6ad2e32 Alexander Graf
    NCQTransferState *ncq_tfs = &s->dev[port].ncq_tfs[tag];
766 f6ad2e32 Alexander Graf
767 f6ad2e32 Alexander Graf
    if (ncq_tfs->used) {
768 f6ad2e32 Alexander Graf
        /* error - already in use */
769 f6ad2e32 Alexander Graf
        fprintf(stderr, "%s: tag %d already used\n", __FUNCTION__, tag);
770 f6ad2e32 Alexander Graf
        return;
771 f6ad2e32 Alexander Graf
    }
772 f6ad2e32 Alexander Graf
773 f6ad2e32 Alexander Graf
    ncq_tfs->used = 1;
774 f6ad2e32 Alexander Graf
    ncq_tfs->drive = &s->dev[port];
775 f6ad2e32 Alexander Graf
    ncq_tfs->slot = slot;
776 f6ad2e32 Alexander Graf
    ncq_tfs->lba = ((uint64_t)ncq_fis->lba5 << 40) |
777 f6ad2e32 Alexander Graf
                   ((uint64_t)ncq_fis->lba4 << 32) |
778 f6ad2e32 Alexander Graf
                   ((uint64_t)ncq_fis->lba3 << 24) |
779 f6ad2e32 Alexander Graf
                   ((uint64_t)ncq_fis->lba2 << 16) |
780 f6ad2e32 Alexander Graf
                   ((uint64_t)ncq_fis->lba1 << 8) |
781 f6ad2e32 Alexander Graf
                   (uint64_t)ncq_fis->lba0;
782 f6ad2e32 Alexander Graf
783 f6ad2e32 Alexander Graf
    /* Note: We calculate the sector count, but don't currently rely on it.
784 f6ad2e32 Alexander Graf
     * The total size of the DMA buffer tells us the transfer size instead. */
785 f6ad2e32 Alexander Graf
    ncq_tfs->sector_count = ((uint16_t)ncq_fis->sector_count_high << 8) |
786 f6ad2e32 Alexander Graf
                                ncq_fis->sector_count_low;
787 f6ad2e32 Alexander Graf
788 3899edf7 Max Filippov
    DPRINTF(port, "NCQ transfer LBA from %"PRId64" to %"PRId64", "
789 3899edf7 Max Filippov
            "drive max %"PRId64"\n",
790 f6ad2e32 Alexander Graf
            ncq_tfs->lba, ncq_tfs->lba + ncq_tfs->sector_count - 2,
791 f6ad2e32 Alexander Graf
            s->dev[port].port.ifs[0].nb_sectors - 1);
792 f6ad2e32 Alexander Graf
793 f6ad2e32 Alexander Graf
    ahci_populate_sglist(&s->dev[port], &ncq_tfs->sglist);
794 f6ad2e32 Alexander Graf
    ncq_tfs->tag = tag;
795 f6ad2e32 Alexander Graf
796 f6ad2e32 Alexander Graf
    switch(ncq_fis->command) {
797 f6ad2e32 Alexander Graf
        case READ_FPDMA_QUEUED:
798 3899edf7 Max Filippov
            DPRINTF(port, "NCQ reading %d sectors from LBA %"PRId64", "
799 3899edf7 Max Filippov
                    "tag %d\n",
800 f6ad2e32 Alexander Graf
                    ncq_tfs->sector_count-1, ncq_tfs->lba, ncq_tfs->tag);
801 f6ad2e32 Alexander Graf
802 3899edf7 Max Filippov
            DPRINTF(port, "tag %d aio read %"PRId64"\n",
803 3899edf7 Max Filippov
                    ncq_tfs->tag, ncq_tfs->lba);
804 a597e79c Christoph Hellwig
805 a597e79c Christoph Hellwig
            bdrv_acct_start(ncq_tfs->drive->port.ifs[0].bs, &ncq_tfs->acct,
806 a597e79c Christoph Hellwig
                            (ncq_tfs->sector_count-1) * BDRV_SECTOR_SIZE,
807 a597e79c Christoph Hellwig
                            BDRV_ACCT_READ);
808 f6ad2e32 Alexander Graf
            ncq_tfs->aiocb = dma_bdrv_read(ncq_tfs->drive->port.ifs[0].bs,
809 f6ad2e32 Alexander Graf
                                           &ncq_tfs->sglist, ncq_tfs->lba,
810 f6ad2e32 Alexander Graf
                                           ncq_cb, ncq_tfs);
811 f6ad2e32 Alexander Graf
            break;
812 f6ad2e32 Alexander Graf
        case WRITE_FPDMA_QUEUED:
813 3899edf7 Max Filippov
            DPRINTF(port, "NCQ writing %d sectors to LBA %"PRId64", tag %d\n",
814 f6ad2e32 Alexander Graf
                    ncq_tfs->sector_count-1, ncq_tfs->lba, ncq_tfs->tag);
815 f6ad2e32 Alexander Graf
816 3899edf7 Max Filippov
            DPRINTF(port, "tag %d aio write %"PRId64"\n",
817 3899edf7 Max Filippov
                    ncq_tfs->tag, ncq_tfs->lba);
818 a597e79c Christoph Hellwig
819 a597e79c Christoph Hellwig
            bdrv_acct_start(ncq_tfs->drive->port.ifs[0].bs, &ncq_tfs->acct,
820 a597e79c Christoph Hellwig
                            (ncq_tfs->sector_count-1) * BDRV_SECTOR_SIZE,
821 a597e79c Christoph Hellwig
                            BDRV_ACCT_WRITE);
822 f6ad2e32 Alexander Graf
            ncq_tfs->aiocb = dma_bdrv_write(ncq_tfs->drive->port.ifs[0].bs,
823 f6ad2e32 Alexander Graf
                                            &ncq_tfs->sglist, ncq_tfs->lba,
824 f6ad2e32 Alexander Graf
                                            ncq_cb, ncq_tfs);
825 f6ad2e32 Alexander Graf
            break;
826 f6ad2e32 Alexander Graf
        default:
827 f6ad2e32 Alexander Graf
            DPRINTF(port, "error: tried to process non-NCQ command as NCQ\n");
828 f6ad2e32 Alexander Graf
            qemu_sglist_destroy(&ncq_tfs->sglist);
829 f6ad2e32 Alexander Graf
            break;
830 f6ad2e32 Alexander Graf
    }
831 f6ad2e32 Alexander Graf
}
832 f6ad2e32 Alexander Graf
833 f6ad2e32 Alexander Graf
static int handle_cmd(AHCIState *s, int port, int slot)
834 f6ad2e32 Alexander Graf
{
835 f6ad2e32 Alexander Graf
    IDEState *ide_state;
836 f6ad2e32 Alexander Graf
    uint32_t opts;
837 f6ad2e32 Alexander Graf
    uint64_t tbl_addr;
838 f6ad2e32 Alexander Graf
    AHCICmdHdr *cmd;
839 f6ad2e32 Alexander Graf
    uint8_t *cmd_fis;
840 f6ad2e32 Alexander Graf
    target_phys_addr_t cmd_len;
841 f6ad2e32 Alexander Graf
842 f6ad2e32 Alexander Graf
    if (s->dev[port].port.ifs[0].status & (BUSY_STAT|DRQ_STAT)) {
843 f6ad2e32 Alexander Graf
        /* Engine currently busy, try again later */
844 f6ad2e32 Alexander Graf
        DPRINTF(port, "engine busy\n");
845 f6ad2e32 Alexander Graf
        return -1;
846 f6ad2e32 Alexander Graf
    }
847 f6ad2e32 Alexander Graf
848 f6ad2e32 Alexander Graf
    cmd = &((AHCICmdHdr *)s->dev[port].lst)[slot];
849 f6ad2e32 Alexander Graf
850 f6ad2e32 Alexander Graf
    if (!s->dev[port].lst) {
851 f6ad2e32 Alexander Graf
        DPRINTF(port, "error: lst not given but cmd handled");
852 f6ad2e32 Alexander Graf
        return -1;
853 f6ad2e32 Alexander Graf
    }
854 f6ad2e32 Alexander Graf
855 f6ad2e32 Alexander Graf
    /* remember current slot handle for later */
856 f6ad2e32 Alexander Graf
    s->dev[port].cur_cmd = cmd;
857 f6ad2e32 Alexander Graf
858 f6ad2e32 Alexander Graf
    opts = le32_to_cpu(cmd->opts);
859 f6ad2e32 Alexander Graf
    tbl_addr = le64_to_cpu(cmd->tbl_addr);
860 f6ad2e32 Alexander Graf
861 f6ad2e32 Alexander Graf
    cmd_len = 0x80;
862 f6ad2e32 Alexander Graf
    cmd_fis = cpu_physical_memory_map(tbl_addr, &cmd_len, 1);
863 f6ad2e32 Alexander Graf
864 f6ad2e32 Alexander Graf
    if (!cmd_fis) {
865 f6ad2e32 Alexander Graf
        DPRINTF(port, "error: guest passed us an invalid cmd fis\n");
866 f6ad2e32 Alexander Graf
        return -1;
867 f6ad2e32 Alexander Graf
    }
868 f6ad2e32 Alexander Graf
869 f6ad2e32 Alexander Graf
    /* The device we are working for */
870 f6ad2e32 Alexander Graf
    ide_state = &s->dev[port].port.ifs[0];
871 f6ad2e32 Alexander Graf
872 f6ad2e32 Alexander Graf
    if (!ide_state->bs) {
873 f6ad2e32 Alexander Graf
        DPRINTF(port, "error: guest accessed unused port");
874 f6ad2e32 Alexander Graf
        goto out;
875 f6ad2e32 Alexander Graf
    }
876 f6ad2e32 Alexander Graf
877 f6ad2e32 Alexander Graf
    debug_print_fis(cmd_fis, 0x90);
878 f6ad2e32 Alexander Graf
    //debug_print_fis(cmd_fis, (opts & AHCI_CMD_HDR_CMD_FIS_LEN) * 4);
879 f6ad2e32 Alexander Graf
880 f6ad2e32 Alexander Graf
    switch (cmd_fis[0]) {
881 f6ad2e32 Alexander Graf
        case SATA_FIS_TYPE_REGISTER_H2D:
882 f6ad2e32 Alexander Graf
            break;
883 f6ad2e32 Alexander Graf
        default:
884 f6ad2e32 Alexander Graf
            DPRINTF(port, "unknown command cmd_fis[0]=%02x cmd_fis[1]=%02x "
885 f6ad2e32 Alexander Graf
                          "cmd_fis[2]=%02x\n", cmd_fis[0], cmd_fis[1],
886 f6ad2e32 Alexander Graf
                          cmd_fis[2]);
887 f6ad2e32 Alexander Graf
            goto out;
888 f6ad2e32 Alexander Graf
            break;
889 f6ad2e32 Alexander Graf
    }
890 f6ad2e32 Alexander Graf
891 f6ad2e32 Alexander Graf
    switch (cmd_fis[1]) {
892 f6ad2e32 Alexander Graf
        case SATA_FIS_REG_H2D_UPDATE_COMMAND_REGISTER:
893 f6ad2e32 Alexander Graf
            break;
894 f6ad2e32 Alexander Graf
        case 0:
895 f6ad2e32 Alexander Graf
            break;
896 f6ad2e32 Alexander Graf
        default:
897 f6ad2e32 Alexander Graf
            DPRINTF(port, "unknown command cmd_fis[0]=%02x cmd_fis[1]=%02x "
898 f6ad2e32 Alexander Graf
                          "cmd_fis[2]=%02x\n", cmd_fis[0], cmd_fis[1],
899 f6ad2e32 Alexander Graf
                          cmd_fis[2]);
900 f6ad2e32 Alexander Graf
            goto out;
901 f6ad2e32 Alexander Graf
            break;
902 f6ad2e32 Alexander Graf
    }
903 f6ad2e32 Alexander Graf
904 f6ad2e32 Alexander Graf
    switch (s->dev[port].port_state) {
905 f6ad2e32 Alexander Graf
        case STATE_RUN:
906 f6ad2e32 Alexander Graf
            if (cmd_fis[15] & ATA_SRST) {
907 f6ad2e32 Alexander Graf
                s->dev[port].port_state = STATE_RESET;
908 f6ad2e32 Alexander Graf
            }
909 f6ad2e32 Alexander Graf
            break;
910 f6ad2e32 Alexander Graf
        case STATE_RESET:
911 f6ad2e32 Alexander Graf
            if (!(cmd_fis[15] & ATA_SRST)) {
912 f6ad2e32 Alexander Graf
                ahci_reset_port(s, port);
913 f6ad2e32 Alexander Graf
            }
914 f6ad2e32 Alexander Graf
            break;
915 f6ad2e32 Alexander Graf
    }
916 f6ad2e32 Alexander Graf
917 f6ad2e32 Alexander Graf
    if (cmd_fis[1] == SATA_FIS_REG_H2D_UPDATE_COMMAND_REGISTER) {
918 f6ad2e32 Alexander Graf
919 f6ad2e32 Alexander Graf
        /* Check for NCQ command */
920 f6ad2e32 Alexander Graf
        if ((cmd_fis[2] == READ_FPDMA_QUEUED) ||
921 f6ad2e32 Alexander Graf
            (cmd_fis[2] == WRITE_FPDMA_QUEUED)) {
922 f6ad2e32 Alexander Graf
            process_ncq_command(s, port, cmd_fis, slot);
923 f6ad2e32 Alexander Graf
            goto out;
924 f6ad2e32 Alexander Graf
        }
925 f6ad2e32 Alexander Graf
926 f6ad2e32 Alexander Graf
        /* Decompose the FIS  */
927 f6ad2e32 Alexander Graf
        ide_state->nsector = (int64_t)((cmd_fis[13] << 8) | cmd_fis[12]);
928 f6ad2e32 Alexander Graf
        ide_state->feature = cmd_fis[3];
929 f6ad2e32 Alexander Graf
        if (!ide_state->nsector) {
930 f6ad2e32 Alexander Graf
            ide_state->nsector = 256;
931 f6ad2e32 Alexander Graf
        }
932 f6ad2e32 Alexander Graf
933 f6ad2e32 Alexander Graf
        if (ide_state->drive_kind != IDE_CD) {
934 1fddfba1 Alexander Graf
            /*
935 1fddfba1 Alexander Graf
             * We set the sector depending on the sector defined in the FIS.
936 1fddfba1 Alexander Graf
             * Unfortunately, the spec isn't exactly obvious on this one.
937 1fddfba1 Alexander Graf
             *
938 1fddfba1 Alexander Graf
             * Apparently LBA48 commands set fis bytes 10,9,8,6,5,4 to the
939 1fddfba1 Alexander Graf
             * 48 bit sector number. ATA_CMD_READ_DMA_EXT is an example for
940 1fddfba1 Alexander Graf
             * such a command.
941 1fddfba1 Alexander Graf
             *
942 1fddfba1 Alexander Graf
             * Non-LBA48 commands however use 7[lower 4 bits],6,5,4 to define a
943 1fddfba1 Alexander Graf
             * 28-bit sector number. ATA_CMD_READ_DMA is an example for such
944 1fddfba1 Alexander Graf
             * a command.
945 1fddfba1 Alexander Graf
             *
946 1fddfba1 Alexander Graf
             * Since the spec doesn't explicitly state what each field should
947 1fddfba1 Alexander Graf
             * do, I simply assume non-used fields as reserved and OR everything
948 1fddfba1 Alexander Graf
             * together, independent of the command.
949 1fddfba1 Alexander Graf
             */
950 1fddfba1 Alexander Graf
            ide_set_sector(ide_state, ((uint64_t)cmd_fis[10] << 40)
951 1fddfba1 Alexander Graf
                                    | ((uint64_t)cmd_fis[9] << 32)
952 1fddfba1 Alexander Graf
                                    /* This is used for LBA48 commands */
953 1fddfba1 Alexander Graf
                                    | ((uint64_t)cmd_fis[8] << 24)
954 1fddfba1 Alexander Graf
                                    /* This is used for non-LBA48 commands */
955 1fddfba1 Alexander Graf
                                    | ((uint64_t)(cmd_fis[7] & 0xf) << 24)
956 1fddfba1 Alexander Graf
                                    | ((uint64_t)cmd_fis[6] << 16)
957 1fddfba1 Alexander Graf
                                    | ((uint64_t)cmd_fis[5] << 8)
958 1fddfba1 Alexander Graf
                                    | cmd_fis[4]);
959 f6ad2e32 Alexander Graf
        }
960 f6ad2e32 Alexander Graf
961 f6ad2e32 Alexander Graf
        /* Copy the ACMD field (ATAPI packet, if any) from the AHCI command
962 f6ad2e32 Alexander Graf
         * table to ide_state->io_buffer
963 f6ad2e32 Alexander Graf
         */
964 f6ad2e32 Alexander Graf
        if (opts & AHCI_CMD_ATAPI) {
965 f6ad2e32 Alexander Graf
            memcpy(ide_state->io_buffer, &cmd_fis[AHCI_COMMAND_TABLE_ACMD], 0x10);
966 f6ad2e32 Alexander Graf
            ide_state->lcyl = 0x14;
967 f6ad2e32 Alexander Graf
            ide_state->hcyl = 0xeb;
968 f6ad2e32 Alexander Graf
            debug_print_fis(ide_state->io_buffer, 0x10);
969 f6ad2e32 Alexander Graf
            ide_state->feature = IDE_FEATURE_DMA;
970 f6ad2e32 Alexander Graf
            s->dev[port].done_atapi_packet = 0;
971 f6ad2e32 Alexander Graf
            /* XXX send PIO setup FIS */
972 f6ad2e32 Alexander Graf
        }
973 f6ad2e32 Alexander Graf
974 f6ad2e32 Alexander Graf
        ide_state->error = 0;
975 f6ad2e32 Alexander Graf
976 f6ad2e32 Alexander Graf
        /* Reset transferred byte counter */
977 f6ad2e32 Alexander Graf
        cmd->status = 0;
978 f6ad2e32 Alexander Graf
979 f6ad2e32 Alexander Graf
        /* We're ready to process the command in FIS byte 2. */
980 f6ad2e32 Alexander Graf
        ide_exec_cmd(&s->dev[port].port, cmd_fis[2]);
981 f6ad2e32 Alexander Graf
982 f6ad2e32 Alexander Graf
        if (s->dev[port].port.ifs[0].status & READY_STAT) {
983 f6ad2e32 Alexander Graf
            ahci_write_fis_d2h(&s->dev[port], cmd_fis);
984 f6ad2e32 Alexander Graf
        }
985 f6ad2e32 Alexander Graf
    }
986 f6ad2e32 Alexander Graf
987 f6ad2e32 Alexander Graf
out:
988 fe6ceac8 Stefan Hajnoczi
    cpu_physical_memory_unmap(cmd_fis, cmd_len, 1, cmd_len);
989 f6ad2e32 Alexander Graf
990 f6ad2e32 Alexander Graf
    if (s->dev[port].port.ifs[0].status & (BUSY_STAT|DRQ_STAT)) {
991 f6ad2e32 Alexander Graf
        /* async command, complete later */
992 f6ad2e32 Alexander Graf
        s->dev[port].busy_slot = slot;
993 f6ad2e32 Alexander Graf
        return -1;
994 f6ad2e32 Alexander Graf
    }
995 f6ad2e32 Alexander Graf
996 f6ad2e32 Alexander Graf
    /* done handling the command */
997 f6ad2e32 Alexander Graf
    return 0;
998 f6ad2e32 Alexander Graf
}
999 f6ad2e32 Alexander Graf
1000 f6ad2e32 Alexander Graf
/* DMA dev <-> ram */
1001 f6ad2e32 Alexander Graf
static int ahci_start_transfer(IDEDMA *dma)
1002 f6ad2e32 Alexander Graf
{
1003 f6ad2e32 Alexander Graf
    AHCIDevice *ad = DO_UPCAST(AHCIDevice, dma, dma);
1004 f6ad2e32 Alexander Graf
    IDEState *s = &ad->port.ifs[0];
1005 f6ad2e32 Alexander Graf
    uint32_t size = (uint32_t)(s->data_end - s->data_ptr);
1006 f6ad2e32 Alexander Graf
    /* write == ram -> device */
1007 f6ad2e32 Alexander Graf
    uint32_t opts = le32_to_cpu(ad->cur_cmd->opts);
1008 f6ad2e32 Alexander Graf
    int is_write = opts & AHCI_CMD_WRITE;
1009 f6ad2e32 Alexander Graf
    int is_atapi = opts & AHCI_CMD_ATAPI;
1010 f6ad2e32 Alexander Graf
    int has_sglist = 0;
1011 f6ad2e32 Alexander Graf
1012 f6ad2e32 Alexander Graf
    if (is_atapi && !ad->done_atapi_packet) {
1013 f6ad2e32 Alexander Graf
        /* already prepopulated iobuffer */
1014 f6ad2e32 Alexander Graf
        ad->done_atapi_packet = 1;
1015 f6ad2e32 Alexander Graf
        goto out;
1016 f6ad2e32 Alexander Graf
    }
1017 f6ad2e32 Alexander Graf
1018 f6ad2e32 Alexander Graf
    if (!ahci_populate_sglist(ad, &s->sg)) {
1019 f6ad2e32 Alexander Graf
        has_sglist = 1;
1020 f6ad2e32 Alexander Graf
    }
1021 f6ad2e32 Alexander Graf
1022 f6ad2e32 Alexander Graf
    DPRINTF(ad->port_no, "%sing %d bytes on %s w/%s sglist\n",
1023 f6ad2e32 Alexander Graf
            is_write ? "writ" : "read", size, is_atapi ? "atapi" : "ata",
1024 f6ad2e32 Alexander Graf
            has_sglist ? "" : "o");
1025 f6ad2e32 Alexander Graf
1026 f6ad2e32 Alexander Graf
    if (is_write && has_sglist && (s->data_ptr < s->data_end)) {
1027 f6ad2e32 Alexander Graf
        read_from_sglist(s->data_ptr, size, &s->sg);
1028 f6ad2e32 Alexander Graf
    }
1029 f6ad2e32 Alexander Graf
1030 f6ad2e32 Alexander Graf
    if (!is_write && has_sglist && (s->data_ptr < s->data_end)) {
1031 f6ad2e32 Alexander Graf
        write_to_sglist(s->data_ptr, size, &s->sg);
1032 f6ad2e32 Alexander Graf
    }
1033 f6ad2e32 Alexander Graf
1034 f6ad2e32 Alexander Graf
    /* update number of transferred bytes */
1035 f6ad2e32 Alexander Graf
    ad->cur_cmd->status = cpu_to_le32(le32_to_cpu(ad->cur_cmd->status) + size);
1036 f6ad2e32 Alexander Graf
1037 f6ad2e32 Alexander Graf
out:
1038 f6ad2e32 Alexander Graf
    /* declare that we processed everything */
1039 f6ad2e32 Alexander Graf
    s->data_ptr = s->data_end;
1040 f6ad2e32 Alexander Graf
1041 f6ad2e32 Alexander Graf
    if (has_sglist) {
1042 f6ad2e32 Alexander Graf
        qemu_sglist_destroy(&s->sg);
1043 f6ad2e32 Alexander Graf
    }
1044 f6ad2e32 Alexander Graf
1045 f6ad2e32 Alexander Graf
    s->end_transfer_func(s);
1046 f6ad2e32 Alexander Graf
1047 f6ad2e32 Alexander Graf
    if (!(s->status & DRQ_STAT)) {
1048 f6ad2e32 Alexander Graf
        /* done with DMA */
1049 f6ad2e32 Alexander Graf
        ahci_trigger_irq(ad->hba, ad, PORT_IRQ_STAT_DSS);
1050 f6ad2e32 Alexander Graf
    }
1051 f6ad2e32 Alexander Graf
1052 f6ad2e32 Alexander Graf
    return 0;
1053 f6ad2e32 Alexander Graf
}
1054 f6ad2e32 Alexander Graf
1055 f6ad2e32 Alexander Graf
static void ahci_start_dma(IDEDMA *dma, IDEState *s,
1056 f6ad2e32 Alexander Graf
                           BlockDriverCompletionFunc *dma_cb)
1057 f6ad2e32 Alexander Graf
{
1058 f6ad2e32 Alexander Graf
    AHCIDevice *ad = DO_UPCAST(AHCIDevice, dma, dma);
1059 f6ad2e32 Alexander Graf
1060 f6ad2e32 Alexander Graf
    DPRINTF(ad->port_no, "\n");
1061 f6ad2e32 Alexander Graf
    ad->dma_cb = dma_cb;
1062 f6ad2e32 Alexander Graf
    ad->dma_status |= BM_STATUS_DMAING;
1063 f6ad2e32 Alexander Graf
    dma_cb(s, 0);
1064 f6ad2e32 Alexander Graf
}
1065 f6ad2e32 Alexander Graf
1066 f6ad2e32 Alexander Graf
static int ahci_dma_prepare_buf(IDEDMA *dma, int is_write)
1067 f6ad2e32 Alexander Graf
{
1068 f6ad2e32 Alexander Graf
    AHCIDevice *ad = DO_UPCAST(AHCIDevice, dma, dma);
1069 f6ad2e32 Alexander Graf
    IDEState *s = &ad->port.ifs[0];
1070 f6ad2e32 Alexander Graf
    int i;
1071 f6ad2e32 Alexander Graf
1072 f6ad2e32 Alexander Graf
    ahci_populate_sglist(ad, &s->sg);
1073 f6ad2e32 Alexander Graf
1074 f6ad2e32 Alexander Graf
    s->io_buffer_size = 0;
1075 f6ad2e32 Alexander Graf
    for (i = 0; i < s->sg.nsg; i++) {
1076 f6ad2e32 Alexander Graf
        s->io_buffer_size += s->sg.sg[i].len;
1077 f6ad2e32 Alexander Graf
    }
1078 f6ad2e32 Alexander Graf
1079 f6ad2e32 Alexander Graf
    DPRINTF(ad->port_no, "len=%#x\n", s->io_buffer_size);
1080 f6ad2e32 Alexander Graf
    return s->io_buffer_size != 0;
1081 f6ad2e32 Alexander Graf
}
1082 f6ad2e32 Alexander Graf
1083 f6ad2e32 Alexander Graf
static int ahci_dma_rw_buf(IDEDMA *dma, int is_write)
1084 f6ad2e32 Alexander Graf
{
1085 f6ad2e32 Alexander Graf
    AHCIDevice *ad = DO_UPCAST(AHCIDevice, dma, dma);
1086 f6ad2e32 Alexander Graf
    IDEState *s = &ad->port.ifs[0];
1087 f6ad2e32 Alexander Graf
    uint8_t *p = s->io_buffer + s->io_buffer_index;
1088 f6ad2e32 Alexander Graf
    int l = s->io_buffer_size - s->io_buffer_index;
1089 f6ad2e32 Alexander Graf
1090 f6ad2e32 Alexander Graf
    if (ahci_populate_sglist(ad, &s->sg)) {
1091 f6ad2e32 Alexander Graf
        return 0;
1092 f6ad2e32 Alexander Graf
    }
1093 f6ad2e32 Alexander Graf
1094 f6ad2e32 Alexander Graf
    if (is_write) {
1095 f6ad2e32 Alexander Graf
        write_to_sglist(p, l, &s->sg);
1096 f6ad2e32 Alexander Graf
    } else {
1097 f6ad2e32 Alexander Graf
        read_from_sglist(p, l, &s->sg);
1098 f6ad2e32 Alexander Graf
    }
1099 f6ad2e32 Alexander Graf
1100 f6ad2e32 Alexander Graf
    /* update number of transferred bytes */
1101 f6ad2e32 Alexander Graf
    ad->cur_cmd->status = cpu_to_le32(le32_to_cpu(ad->cur_cmd->status) + l);
1102 f6ad2e32 Alexander Graf
    s->io_buffer_index += l;
1103 f6ad2e32 Alexander Graf
1104 f6ad2e32 Alexander Graf
    DPRINTF(ad->port_no, "len=%#x\n", l);
1105 f6ad2e32 Alexander Graf
1106 f6ad2e32 Alexander Graf
    return 1;
1107 f6ad2e32 Alexander Graf
}
1108 f6ad2e32 Alexander Graf
1109 f6ad2e32 Alexander Graf
static int ahci_dma_set_unit(IDEDMA *dma, int unit)
1110 f6ad2e32 Alexander Graf
{
1111 f6ad2e32 Alexander Graf
    /* only a single unit per link */
1112 f6ad2e32 Alexander Graf
    return 0;
1113 f6ad2e32 Alexander Graf
}
1114 f6ad2e32 Alexander Graf
1115 f6ad2e32 Alexander Graf
static int ahci_dma_add_status(IDEDMA *dma, int status)
1116 f6ad2e32 Alexander Graf
{
1117 f6ad2e32 Alexander Graf
    AHCIDevice *ad = DO_UPCAST(AHCIDevice, dma, dma);
1118 f6ad2e32 Alexander Graf
    ad->dma_status |= status;
1119 f6ad2e32 Alexander Graf
    DPRINTF(ad->port_no, "set status: %x\n", status);
1120 f6ad2e32 Alexander Graf
1121 f6ad2e32 Alexander Graf
    if (status & BM_STATUS_INT) {
1122 f6ad2e32 Alexander Graf
        ahci_trigger_irq(ad->hba, ad, PORT_IRQ_STAT_DSS);
1123 f6ad2e32 Alexander Graf
    }
1124 f6ad2e32 Alexander Graf
1125 f6ad2e32 Alexander Graf
    return 0;
1126 f6ad2e32 Alexander Graf
}
1127 f6ad2e32 Alexander Graf
1128 f6ad2e32 Alexander Graf
static int ahci_dma_set_inactive(IDEDMA *dma)
1129 f6ad2e32 Alexander Graf
{
1130 f6ad2e32 Alexander Graf
    AHCIDevice *ad = DO_UPCAST(AHCIDevice, dma, dma);
1131 f6ad2e32 Alexander Graf
1132 f6ad2e32 Alexander Graf
    DPRINTF(ad->port_no, "dma done\n");
1133 f6ad2e32 Alexander Graf
1134 f6ad2e32 Alexander Graf
    /* update d2h status */
1135 f6ad2e32 Alexander Graf
    ahci_write_fis_d2h(ad, NULL);
1136 f6ad2e32 Alexander Graf
1137 f6ad2e32 Alexander Graf
    ad->dma_cb = NULL;
1138 f6ad2e32 Alexander Graf
1139 4d29b50a Jan Kiszka
    if (!ad->check_bh) {
1140 4d29b50a Jan Kiszka
        /* maybe we still have something to process, check later */
1141 4d29b50a Jan Kiszka
        ad->check_bh = qemu_bh_new(ahci_check_cmd_bh, ad);
1142 4d29b50a Jan Kiszka
        qemu_bh_schedule(ad->check_bh);
1143 4d29b50a Jan Kiszka
    }
1144 f6ad2e32 Alexander Graf
1145 f6ad2e32 Alexander Graf
    return 0;
1146 f6ad2e32 Alexander Graf
}
1147 f6ad2e32 Alexander Graf
1148 f6ad2e32 Alexander Graf
static void ahci_irq_set(void *opaque, int n, int level)
1149 f6ad2e32 Alexander Graf
{
1150 f6ad2e32 Alexander Graf
}
1151 f6ad2e32 Alexander Graf
1152 1dfb4dd9 Luiz Capitulino
static void ahci_dma_restart_cb(void *opaque, int running, RunState state)
1153 f6ad2e32 Alexander Graf
{
1154 f6ad2e32 Alexander Graf
}
1155 f6ad2e32 Alexander Graf
1156 f6ad2e32 Alexander Graf
static int ahci_dma_reset(IDEDMA *dma)
1157 f6ad2e32 Alexander Graf
{
1158 f6ad2e32 Alexander Graf
    return 0;
1159 f6ad2e32 Alexander Graf
}
1160 f6ad2e32 Alexander Graf
1161 f6ad2e32 Alexander Graf
static const IDEDMAOps ahci_dma_ops = {
1162 f6ad2e32 Alexander Graf
    .start_dma = ahci_start_dma,
1163 f6ad2e32 Alexander Graf
    .start_transfer = ahci_start_transfer,
1164 f6ad2e32 Alexander Graf
    .prepare_buf = ahci_dma_prepare_buf,
1165 f6ad2e32 Alexander Graf
    .rw_buf = ahci_dma_rw_buf,
1166 f6ad2e32 Alexander Graf
    .set_unit = ahci_dma_set_unit,
1167 f6ad2e32 Alexander Graf
    .add_status = ahci_dma_add_status,
1168 f6ad2e32 Alexander Graf
    .set_inactive = ahci_dma_set_inactive,
1169 f6ad2e32 Alexander Graf
    .restart_cb = ahci_dma_restart_cb,
1170 f6ad2e32 Alexander Graf
    .reset = ahci_dma_reset,
1171 f6ad2e32 Alexander Graf
};
1172 f6ad2e32 Alexander Graf
1173 2c4b9d0e Alexander Graf
void ahci_init(AHCIState *s, DeviceState *qdev, int ports)
1174 f6ad2e32 Alexander Graf
{
1175 f6ad2e32 Alexander Graf
    qemu_irq *irqs;
1176 f6ad2e32 Alexander Graf
    int i;
1177 f6ad2e32 Alexander Graf
1178 2c4b9d0e Alexander Graf
    s->ports = ports;
1179 7267c094 Anthony Liguori
    s->dev = g_malloc0(sizeof(AHCIDevice) * ports);
1180 f6ad2e32 Alexander Graf
    ahci_reg_init(s);
1181 67e576c2 Avi Kivity
    /* XXX BAR size should be 1k, but that breaks, so bump it to 4k for now */
1182 465f1ab1 Daniel Verkamp
    memory_region_init_io(&s->mem, &ahci_mem_ops, s, "ahci", AHCI_MEM_BAR_SIZE);
1183 465f1ab1 Daniel Verkamp
    memory_region_init_io(&s->idp, &ahci_idp_ops, s, "ahci-idp", 32);
1184 465f1ab1 Daniel Verkamp
1185 2c4b9d0e Alexander Graf
    irqs = qemu_allocate_irqs(ahci_irq_set, s, s->ports);
1186 f6ad2e32 Alexander Graf
1187 2c4b9d0e Alexander Graf
    for (i = 0; i < s->ports; i++) {
1188 f6ad2e32 Alexander Graf
        AHCIDevice *ad = &s->dev[i];
1189 f6ad2e32 Alexander Graf
1190 f6ad2e32 Alexander Graf
        ide_bus_new(&ad->port, qdev, i);
1191 f6ad2e32 Alexander Graf
        ide_init2(&ad->port, irqs[i]);
1192 f6ad2e32 Alexander Graf
1193 f6ad2e32 Alexander Graf
        ad->hba = s;
1194 f6ad2e32 Alexander Graf
        ad->port_no = i;
1195 f6ad2e32 Alexander Graf
        ad->port.dma = &ad->dma;
1196 f6ad2e32 Alexander Graf
        ad->port.dma->ops = &ahci_dma_ops;
1197 f6ad2e32 Alexander Graf
        ad->port_regs.cmd = PORT_CMD_SPIN_UP | PORT_CMD_POWER_ON;
1198 f6ad2e32 Alexander Graf
    }
1199 f6ad2e32 Alexander Graf
}
1200 f6ad2e32 Alexander Graf
1201 2c4b9d0e Alexander Graf
void ahci_uninit(AHCIState *s)
1202 2c4b9d0e Alexander Graf
{
1203 67e576c2 Avi Kivity
    memory_region_destroy(&s->mem);
1204 465f1ab1 Daniel Verkamp
    memory_region_destroy(&s->idp);
1205 7267c094 Anthony Liguori
    g_free(s->dev);
1206 2c4b9d0e Alexander Graf
}
1207 2c4b9d0e Alexander Graf
1208 03c7a6a8 Sebastian Herbszt
void ahci_reset(void *opaque)
1209 f6ad2e32 Alexander Graf
{
1210 f6ad2e32 Alexander Graf
    struct AHCIPCIState *d = opaque;
1211 a26a13da Alexander Motin
    AHCIPortRegs *pr;
1212 f6ad2e32 Alexander Graf
    int i;
1213 f6ad2e32 Alexander Graf
1214 760c3e44 Alexander Graf
    d->ahci.control_regs.irqstatus = 0;
1215 760c3e44 Alexander Graf
    d->ahci.control_regs.ghc = 0;
1216 760c3e44 Alexander Graf
1217 2c4b9d0e Alexander Graf
    for (i = 0; i < d->ahci.ports; i++) {
1218 a26a13da Alexander Motin
        pr = &d->ahci.dev[i].port_regs;
1219 a26a13da Alexander Motin
        pr->irq_stat = 0;
1220 a26a13da Alexander Motin
        pr->irq_mask = 0;
1221 a26a13da Alexander Motin
        pr->scr_ctl = 0;
1222 f6ad2e32 Alexander Graf
        ahci_reset_port(&d->ahci, i);
1223 f6ad2e32 Alexander Graf
    }
1224 f6ad2e32 Alexander Graf
}
1225 d9fa31a3 Rob Herring
1226 d9fa31a3 Rob Herring
typedef struct SysbusAHCIState {
1227 d9fa31a3 Rob Herring
    SysBusDevice busdev;
1228 d9fa31a3 Rob Herring
    AHCIState ahci;
1229 d9fa31a3 Rob Herring
    uint32_t num_ports;
1230 d9fa31a3 Rob Herring
} SysbusAHCIState;
1231 d9fa31a3 Rob Herring
1232 d9fa31a3 Rob Herring
static const VMStateDescription vmstate_sysbus_ahci = {
1233 d9fa31a3 Rob Herring
    .name = "sysbus-ahci",
1234 d9fa31a3 Rob Herring
    .unmigratable = 1,
1235 d9fa31a3 Rob Herring
};
1236 d9fa31a3 Rob Herring
1237 d9fa31a3 Rob Herring
static int sysbus_ahci_init(SysBusDevice *dev)
1238 d9fa31a3 Rob Herring
{
1239 d9fa31a3 Rob Herring
    SysbusAHCIState *s = FROM_SYSBUS(SysbusAHCIState, dev);
1240 d9fa31a3 Rob Herring
    ahci_init(&s->ahci, &dev->qdev, s->num_ports);
1241 d9fa31a3 Rob Herring
1242 d9fa31a3 Rob Herring
    sysbus_init_mmio(dev, &s->ahci.mem);
1243 d9fa31a3 Rob Herring
    sysbus_init_irq(dev, &s->ahci.irq);
1244 d9fa31a3 Rob Herring
1245 d9fa31a3 Rob Herring
    qemu_register_reset(ahci_reset, &s->ahci);
1246 d9fa31a3 Rob Herring
    return 0;
1247 d9fa31a3 Rob Herring
}
1248 d9fa31a3 Rob Herring
1249 39bffca2 Anthony Liguori
static Property sysbus_ahci_properties[] = {
1250 39bffca2 Anthony Liguori
    DEFINE_PROP_UINT32("num-ports", SysbusAHCIState, num_ports, 1),
1251 39bffca2 Anthony Liguori
    DEFINE_PROP_END_OF_LIST(),
1252 39bffca2 Anthony Liguori
};
1253 39bffca2 Anthony Liguori
1254 999e12bb Anthony Liguori
static void sysbus_ahci_class_init(ObjectClass *klass, void *data)
1255 999e12bb Anthony Liguori
{
1256 999e12bb Anthony Liguori
    SysBusDeviceClass *sbc = SYS_BUS_DEVICE_CLASS(klass);
1257 39bffca2 Anthony Liguori
    DeviceClass *dc = DEVICE_CLASS(klass);
1258 999e12bb Anthony Liguori
1259 999e12bb Anthony Liguori
    sbc->init = sysbus_ahci_init;
1260 39bffca2 Anthony Liguori
    dc->vmsd = &vmstate_sysbus_ahci;
1261 39bffca2 Anthony Liguori
    dc->props = sysbus_ahci_properties;
1262 999e12bb Anthony Liguori
}
1263 999e12bb Anthony Liguori
1264 39bffca2 Anthony Liguori
static TypeInfo sysbus_ahci_info = {
1265 39bffca2 Anthony Liguori
    .name          = "sysbus-ahci",
1266 39bffca2 Anthony Liguori
    .parent        = TYPE_SYS_BUS_DEVICE,
1267 39bffca2 Anthony Liguori
    .instance_size = sizeof(SysbusAHCIState),
1268 39bffca2 Anthony Liguori
    .class_init    = sysbus_ahci_class_init,
1269 d9fa31a3 Rob Herring
};
1270 d9fa31a3 Rob Herring
1271 d9fa31a3 Rob Herring
static void sysbus_ahci_register(void)
1272 d9fa31a3 Rob Herring
{
1273 39bffca2 Anthony Liguori
    type_register_static(&sysbus_ahci_info);
1274 d9fa31a3 Rob Herring
}
1275 d9fa31a3 Rob Herring
1276 d9fa31a3 Rob Herring
device_init(sysbus_ahci_register);