Statistics
| Branch: | Revision:

root / hw / ide / pci.c @ 7ad7e3c3

History | View | Annotate | Download (5.3 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 407a4f30 Juan Quintela
static const VMStateDescription vmstate_bmdma = {
125 407a4f30 Juan Quintela
    .name = "ide bmdma",
126 42ee76fe Marcelo Tosatti
    .version_id = 4,
127 407a4f30 Juan Quintela
    .minimum_version_id = 0,
128 407a4f30 Juan Quintela
    .minimum_version_id_old = 0,
129 407a4f30 Juan Quintela
    .fields      = (VMStateField []) {
130 407a4f30 Juan Quintela
        VMSTATE_UINT8(cmd, BMDMAState),
131 407a4f30 Juan Quintela
        VMSTATE_UINT8(status, BMDMAState),
132 407a4f30 Juan Quintela
        VMSTATE_UINT32(addr, BMDMAState),
133 407a4f30 Juan Quintela
        VMSTATE_INT64(sector_num, BMDMAState),
134 407a4f30 Juan Quintela
        VMSTATE_UINT32(nsector, BMDMAState),
135 407a4f30 Juan Quintela
        VMSTATE_UINT8(unit, BMDMAState),
136 42ee76fe Marcelo Tosatti
        VMSTATE_UINT32_V(cur_addr, BMDMAState, 4),
137 42ee76fe Marcelo Tosatti
        VMSTATE_UINT32_V(cur_prd_last, BMDMAState, 4),
138 42ee76fe Marcelo Tosatti
        VMSTATE_UINT32_V(cur_prd_addr, BMDMAState, 4),
139 42ee76fe Marcelo Tosatti
        VMSTATE_UINT32_V(cur_prd_len, BMDMAState, 4),
140 407a4f30 Juan Quintela
        VMSTATE_END_OF_LIST()
141 977e1244 Gerd Hoffmann
    }
142 407a4f30 Juan Quintela
};
143 977e1244 Gerd Hoffmann
144 407a4f30 Juan Quintela
static int ide_pci_post_load(void *opaque, int version_id)
145 977e1244 Gerd Hoffmann
{
146 977e1244 Gerd Hoffmann
    PCIIDEState *d = opaque;
147 407a4f30 Juan Quintela
    int i;
148 977e1244 Gerd Hoffmann
149 977e1244 Gerd Hoffmann
    for(i = 0; i < 2; i++) {
150 407a4f30 Juan Quintela
        /* current versions always store 0/1, but older version
151 407a4f30 Juan Quintela
           stored bigger values. We only need last bit */
152 407a4f30 Juan Quintela
        d->bmdma[i].unit &= 1;
153 977e1244 Gerd Hoffmann
    }
154 977e1244 Gerd Hoffmann
    return 0;
155 977e1244 Gerd Hoffmann
}
156 977e1244 Gerd Hoffmann
157 407a4f30 Juan Quintela
const VMStateDescription vmstate_ide_pci = {
158 407a4f30 Juan Quintela
    .name = "ide",
159 42ee76fe Marcelo Tosatti
    .version_id = 4,
160 407a4f30 Juan Quintela
    .minimum_version_id = 0,
161 407a4f30 Juan Quintela
    .minimum_version_id_old = 0,
162 407a4f30 Juan Quintela
    .post_load = ide_pci_post_load,
163 407a4f30 Juan Quintela
    .fields      = (VMStateField []) {
164 407a4f30 Juan Quintela
        VMSTATE_PCI_DEVICE(dev, PCIIDEState),
165 407a4f30 Juan Quintela
        VMSTATE_STRUCT_ARRAY(bmdma, PCIIDEState, 2, 0,
166 407a4f30 Juan Quintela
                             vmstate_bmdma, BMDMAState),
167 407a4f30 Juan Quintela
        VMSTATE_IDE_BUS_ARRAY(bus, PCIIDEState, 2),
168 407a4f30 Juan Quintela
        VMSTATE_IDE_DRIVES(bus[0].ifs, PCIIDEState),
169 407a4f30 Juan Quintela
        VMSTATE_IDE_DRIVES(bus[1].ifs, PCIIDEState),
170 407a4f30 Juan Quintela
        VMSTATE_END_OF_LIST()
171 407a4f30 Juan Quintela
    }
172 407a4f30 Juan Quintela
};
173 407a4f30 Juan Quintela
174 3e7e1558 Juan Quintela
void pci_ide_create_devs(PCIDevice *dev, DriveInfo **hd_table)
175 feef3102 Gerd Hoffmann
{
176 feef3102 Gerd Hoffmann
    PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, dev);
177 feef3102 Gerd Hoffmann
    static const int bus[4]  = { 0, 0, 1, 1 };
178 feef3102 Gerd Hoffmann
    static const int unit[4] = { 0, 1, 0, 1 };
179 feef3102 Gerd Hoffmann
    int i;
180 feef3102 Gerd Hoffmann
181 feef3102 Gerd Hoffmann
    for (i = 0; i < 4; i++) {
182 feef3102 Gerd Hoffmann
        if (hd_table[i] == NULL)
183 feef3102 Gerd Hoffmann
            continue;
184 1f850f10 Gerd Hoffmann
        ide_create_drive(d->bus+bus[i], unit[i], hd_table[i]);
185 feef3102 Gerd Hoffmann
    }
186 feef3102 Gerd Hoffmann
}