Statistics
| Branch: | Revision:

root / hw / ide / pci.c @ bc578fe0

History | View | Annotate | Download (5.5 kB)

1 977e1244 Gerd Hoffmann
/*
2 977e1244 Gerd Hoffmann
 * QEMU IDE Emulation: PCI Bus support.
3 977e1244 Gerd Hoffmann
 *
4 977e1244 Gerd Hoffmann
 * Copyright (c) 2003 Fabrice Bellard
5 977e1244 Gerd Hoffmann
 * Copyright (c) 2006 Openedhand Ltd.
6 977e1244 Gerd Hoffmann
 *
7 977e1244 Gerd Hoffmann
 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 977e1244 Gerd Hoffmann
 * of this software and associated documentation files (the "Software"), to deal
9 977e1244 Gerd Hoffmann
 * in the Software without restriction, including without limitation the rights
10 977e1244 Gerd Hoffmann
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 977e1244 Gerd Hoffmann
 * copies of the Software, and to permit persons to whom the Software is
12 977e1244 Gerd Hoffmann
 * furnished to do so, subject to the following conditions:
13 977e1244 Gerd Hoffmann
 *
14 977e1244 Gerd Hoffmann
 * The above copyright notice and this permission notice shall be included in
15 977e1244 Gerd Hoffmann
 * all copies or substantial portions of the Software.
16 977e1244 Gerd Hoffmann
 *
17 977e1244 Gerd Hoffmann
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 977e1244 Gerd Hoffmann
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 977e1244 Gerd Hoffmann
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 977e1244 Gerd Hoffmann
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 977e1244 Gerd Hoffmann
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 977e1244 Gerd Hoffmann
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 977e1244 Gerd Hoffmann
 * THE SOFTWARE.
24 977e1244 Gerd Hoffmann
 */
25 59f2a787 Gerd Hoffmann
#include <hw/hw.h>
26 59f2a787 Gerd Hoffmann
#include <hw/pc.h>
27 59f2a787 Gerd Hoffmann
#include <hw/pci.h>
28 feef3102 Gerd Hoffmann
#include <hw/isa.h>
29 977e1244 Gerd Hoffmann
#include "block.h"
30 977e1244 Gerd Hoffmann
#include "block_int.h"
31 977e1244 Gerd Hoffmann
#include "sysemu.h"
32 977e1244 Gerd Hoffmann
#include "dma.h"
33 59f2a787 Gerd Hoffmann
34 65c0f135 Juan Quintela
#include <hw/ide/pci.h>
35 977e1244 Gerd Hoffmann
36 3e7e1558 Juan Quintela
void bmdma_cmd_writeb(void *opaque, uint32_t addr, uint32_t val)
37 977e1244 Gerd Hoffmann
{
38 977e1244 Gerd Hoffmann
    BMDMAState *bm = opaque;
39 977e1244 Gerd Hoffmann
#ifdef DEBUG_IDE
40 977e1244 Gerd Hoffmann
    printf("%s: 0x%08x\n", __func__, val);
41 977e1244 Gerd Hoffmann
#endif
42 977e1244 Gerd Hoffmann
    if (!(val & BM_CMD_START)) {
43 977e1244 Gerd Hoffmann
        /* XXX: do it better */
44 977e1244 Gerd Hoffmann
        ide_dma_cancel(bm);
45 977e1244 Gerd Hoffmann
        bm->cmd = val & 0x09;
46 977e1244 Gerd Hoffmann
    } else {
47 977e1244 Gerd Hoffmann
        if (!(bm->status & BM_STATUS_DMAING)) {
48 977e1244 Gerd Hoffmann
            bm->status |= BM_STATUS_DMAING;
49 977e1244 Gerd Hoffmann
            /* start dma transfer if possible */
50 977e1244 Gerd Hoffmann
            if (bm->dma_cb)
51 977e1244 Gerd Hoffmann
                bm->dma_cb(bm, 0);
52 977e1244 Gerd Hoffmann
        }
53 977e1244 Gerd Hoffmann
        bm->cmd = val & 0x09;
54 977e1244 Gerd Hoffmann
    }
55 977e1244 Gerd Hoffmann
}
56 977e1244 Gerd Hoffmann
57 3e7e1558 Juan Quintela
uint32_t bmdma_addr_readb(void *opaque, uint32_t addr)
58 977e1244 Gerd Hoffmann
{
59 977e1244 Gerd Hoffmann
    BMDMAState *bm = opaque;
60 977e1244 Gerd Hoffmann
    uint32_t val;
61 977e1244 Gerd Hoffmann
    val = (bm->addr >> ((addr & 3) * 8)) & 0xff;
62 977e1244 Gerd Hoffmann
#ifdef DEBUG_IDE
63 977e1244 Gerd Hoffmann
    printf("%s: 0x%08x\n", __func__, val);
64 977e1244 Gerd Hoffmann
#endif
65 977e1244 Gerd Hoffmann
    return val;
66 977e1244 Gerd Hoffmann
}
67 977e1244 Gerd Hoffmann
68 3e7e1558 Juan Quintela
void bmdma_addr_writeb(void *opaque, uint32_t addr, uint32_t val)
69 977e1244 Gerd Hoffmann
{
70 977e1244 Gerd Hoffmann
    BMDMAState *bm = opaque;
71 977e1244 Gerd Hoffmann
    int shift = (addr & 3) * 8;
72 977e1244 Gerd Hoffmann
#ifdef DEBUG_IDE
73 977e1244 Gerd Hoffmann
    printf("%s: 0x%08x\n", __func__, val);
74 977e1244 Gerd Hoffmann
#endif
75 977e1244 Gerd Hoffmann
    bm->addr &= ~(0xFF << shift);
76 977e1244 Gerd Hoffmann
    bm->addr |= ((val & 0xFF) << shift) & ~3;
77 977e1244 Gerd Hoffmann
    bm->cur_addr = bm->addr;
78 977e1244 Gerd Hoffmann
}
79 977e1244 Gerd Hoffmann
80 3e7e1558 Juan Quintela
uint32_t bmdma_addr_readw(void *opaque, uint32_t addr)
81 977e1244 Gerd Hoffmann
{
82 977e1244 Gerd Hoffmann
    BMDMAState *bm = opaque;
83 977e1244 Gerd Hoffmann
    uint32_t val;
84 977e1244 Gerd Hoffmann
    val = (bm->addr >> ((addr & 3) * 8)) & 0xffff;
85 977e1244 Gerd Hoffmann
#ifdef DEBUG_IDE
86 977e1244 Gerd Hoffmann
    printf("%s: 0x%08x\n", __func__, val);
87 977e1244 Gerd Hoffmann
#endif
88 977e1244 Gerd Hoffmann
    return val;
89 977e1244 Gerd Hoffmann
}
90 977e1244 Gerd Hoffmann
91 3e7e1558 Juan Quintela
void bmdma_addr_writew(void *opaque, uint32_t addr, uint32_t val)
92 977e1244 Gerd Hoffmann
{
93 977e1244 Gerd Hoffmann
    BMDMAState *bm = opaque;
94 977e1244 Gerd Hoffmann
    int shift = (addr & 3) * 8;
95 977e1244 Gerd Hoffmann
#ifdef DEBUG_IDE
96 977e1244 Gerd Hoffmann
    printf("%s: 0x%08x\n", __func__, val);
97 977e1244 Gerd Hoffmann
#endif
98 977e1244 Gerd Hoffmann
    bm->addr &= ~(0xFFFF << shift);
99 977e1244 Gerd Hoffmann
    bm->addr |= ((val & 0xFFFF) << shift) & ~3;
100 977e1244 Gerd Hoffmann
    bm->cur_addr = bm->addr;
101 977e1244 Gerd Hoffmann
}
102 977e1244 Gerd Hoffmann
103 3e7e1558 Juan Quintela
uint32_t bmdma_addr_readl(void *opaque, uint32_t addr)
104 977e1244 Gerd Hoffmann
{
105 977e1244 Gerd Hoffmann
    BMDMAState *bm = opaque;
106 977e1244 Gerd Hoffmann
    uint32_t val;
107 977e1244 Gerd Hoffmann
    val = bm->addr;
108 977e1244 Gerd Hoffmann
#ifdef DEBUG_IDE
109 977e1244 Gerd Hoffmann
    printf("%s: 0x%08x\n", __func__, val);
110 977e1244 Gerd Hoffmann
#endif
111 977e1244 Gerd Hoffmann
    return val;
112 977e1244 Gerd Hoffmann
}
113 977e1244 Gerd Hoffmann
114 3e7e1558 Juan Quintela
void bmdma_addr_writel(void *opaque, uint32_t addr, uint32_t val)
115 977e1244 Gerd Hoffmann
{
116 977e1244 Gerd Hoffmann
    BMDMAState *bm = opaque;
117 977e1244 Gerd Hoffmann
#ifdef DEBUG_IDE
118 977e1244 Gerd Hoffmann
    printf("%s: 0x%08x\n", __func__, val);
119 977e1244 Gerd Hoffmann
#endif
120 977e1244 Gerd Hoffmann
    bm->addr = val & ~3;
121 977e1244 Gerd Hoffmann
    bm->cur_addr = bm->addr;
122 977e1244 Gerd Hoffmann
}
123 977e1244 Gerd Hoffmann
124 3e7e1558 Juan Quintela
void pci_ide_save(QEMUFile* f, void *opaque)
125 977e1244 Gerd Hoffmann
{
126 977e1244 Gerd Hoffmann
    PCIIDEState *d = opaque;
127 977e1244 Gerd Hoffmann
    int i;
128 977e1244 Gerd Hoffmann
129 977e1244 Gerd Hoffmann
    pci_device_save(&d->dev, f);
130 977e1244 Gerd Hoffmann
131 977e1244 Gerd Hoffmann
    for(i = 0; i < 2; i++) {
132 977e1244 Gerd Hoffmann
        BMDMAState *bm = &d->bmdma[i];
133 977e1244 Gerd Hoffmann
        uint8_t ifidx;
134 977e1244 Gerd Hoffmann
        qemu_put_8s(f, &bm->cmd);
135 977e1244 Gerd Hoffmann
        qemu_put_8s(f, &bm->status);
136 977e1244 Gerd Hoffmann
        qemu_put_be32s(f, &bm->addr);
137 977e1244 Gerd Hoffmann
        qemu_put_sbe64s(f, &bm->sector_num);
138 977e1244 Gerd Hoffmann
        qemu_put_be32s(f, &bm->nsector);
139 977e1244 Gerd Hoffmann
        ifidx = bm->unit + 2*i;
140 977e1244 Gerd Hoffmann
        qemu_put_8s(f, &ifidx);
141 977e1244 Gerd Hoffmann
        /* XXX: if a transfer is pending, we do not save it yet */
142 977e1244 Gerd Hoffmann
    }
143 977e1244 Gerd Hoffmann
144 977e1244 Gerd Hoffmann
    /* per IDE interface data */
145 977e1244 Gerd Hoffmann
    for(i = 0; i < 2; i++) {
146 1f850f10 Gerd Hoffmann
        idebus_save(f, d->bus+i);
147 977e1244 Gerd Hoffmann
    }
148 977e1244 Gerd Hoffmann
149 977e1244 Gerd Hoffmann
    /* per IDE drive data */
150 977e1244 Gerd Hoffmann
    for(i = 0; i < 2; i++) {
151 1f850f10 Gerd Hoffmann
        ide_save(f, &d->bus[i].ifs[0]);
152 1f850f10 Gerd Hoffmann
        ide_save(f, &d->bus[i].ifs[1]);
153 977e1244 Gerd Hoffmann
    }
154 977e1244 Gerd Hoffmann
}
155 977e1244 Gerd Hoffmann
156 3e7e1558 Juan Quintela
int pci_ide_load(QEMUFile* f, void *opaque, int version_id)
157 977e1244 Gerd Hoffmann
{
158 977e1244 Gerd Hoffmann
    PCIIDEState *d = opaque;
159 977e1244 Gerd Hoffmann
    int ret, i;
160 977e1244 Gerd Hoffmann
161 977e1244 Gerd Hoffmann
    if (version_id != 2 && version_id != 3)
162 977e1244 Gerd Hoffmann
        return -EINVAL;
163 977e1244 Gerd Hoffmann
    ret = pci_device_load(&d->dev, f);
164 977e1244 Gerd Hoffmann
    if (ret < 0)
165 977e1244 Gerd Hoffmann
        return ret;
166 977e1244 Gerd Hoffmann
167 977e1244 Gerd Hoffmann
    for(i = 0; i < 2; i++) {
168 977e1244 Gerd Hoffmann
        BMDMAState *bm = &d->bmdma[i];
169 977e1244 Gerd Hoffmann
        uint8_t ifidx;
170 977e1244 Gerd Hoffmann
        qemu_get_8s(f, &bm->cmd);
171 977e1244 Gerd Hoffmann
        qemu_get_8s(f, &bm->status);
172 977e1244 Gerd Hoffmann
        qemu_get_be32s(f, &bm->addr);
173 977e1244 Gerd Hoffmann
        qemu_get_sbe64s(f, &bm->sector_num);
174 977e1244 Gerd Hoffmann
        qemu_get_be32s(f, &bm->nsector);
175 977e1244 Gerd Hoffmann
        qemu_get_8s(f, &ifidx);
176 977e1244 Gerd Hoffmann
        bm->unit = ifidx & 1;
177 977e1244 Gerd Hoffmann
        /* XXX: if a transfer is pending, we do not save it yet */
178 977e1244 Gerd Hoffmann
    }
179 977e1244 Gerd Hoffmann
180 977e1244 Gerd Hoffmann
    /* per IDE interface data */
181 977e1244 Gerd Hoffmann
    for(i = 0; i < 2; i++) {
182 1f850f10 Gerd Hoffmann
        idebus_load(f, d->bus+i, version_id);
183 977e1244 Gerd Hoffmann
    }
184 977e1244 Gerd Hoffmann
185 977e1244 Gerd Hoffmann
    /* per IDE drive data */
186 977e1244 Gerd Hoffmann
    for(i = 0; i < 2; i++) {
187 1f850f10 Gerd Hoffmann
        ide_load(f, &d->bus[i].ifs[0], version_id);
188 1f850f10 Gerd Hoffmann
        ide_load(f, &d->bus[i].ifs[1], version_id);
189 977e1244 Gerd Hoffmann
    }
190 977e1244 Gerd Hoffmann
    return 0;
191 977e1244 Gerd Hoffmann
}
192 977e1244 Gerd Hoffmann
193 3e7e1558 Juan Quintela
void pci_ide_create_devs(PCIDevice *dev, DriveInfo **hd_table)
194 feef3102 Gerd Hoffmann
{
195 feef3102 Gerd Hoffmann
    PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, dev);
196 feef3102 Gerd Hoffmann
    static const int bus[4]  = { 0, 0, 1, 1 };
197 feef3102 Gerd Hoffmann
    static const int unit[4] = { 0, 1, 0, 1 };
198 feef3102 Gerd Hoffmann
    int i;
199 feef3102 Gerd Hoffmann
200 feef3102 Gerd Hoffmann
    for (i = 0; i < 4; i++) {
201 feef3102 Gerd Hoffmann
        if (hd_table[i] == NULL)
202 feef3102 Gerd Hoffmann
            continue;
203 1f850f10 Gerd Hoffmann
        ide_create_drive(d->bus+bus[i], unit[i], hd_table[i]);
204 feef3102 Gerd Hoffmann
    }
205 feef3102 Gerd Hoffmann
}