root / hw / ide / cmd646.c @ c9159fe9
History | View | Annotate | Download (10.2 kB)
1 | 4c3df0ec | Juan Quintela | /*
|
---|---|---|---|
2 | 4c3df0ec | Juan Quintela | * QEMU IDE Emulation: PCI cmd646 support.
|
3 | 4c3df0ec | Juan Quintela | *
|
4 | 4c3df0ec | Juan Quintela | * Copyright (c) 2003 Fabrice Bellard
|
5 | 4c3df0ec | Juan Quintela | * Copyright (c) 2006 Openedhand Ltd.
|
6 | 4c3df0ec | Juan Quintela | *
|
7 | 4c3df0ec | Juan Quintela | * Permission is hereby granted, free of charge, to any person obtaining a copy
|
8 | 4c3df0ec | Juan Quintela | * of this software and associated documentation files (the "Software"), to deal
|
9 | 4c3df0ec | Juan Quintela | * in the Software without restriction, including without limitation the rights
|
10 | 4c3df0ec | Juan Quintela | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 | 4c3df0ec | Juan Quintela | * copies of the Software, and to permit persons to whom the Software is
|
12 | 4c3df0ec | Juan Quintela | * furnished to do so, subject to the following conditions:
|
13 | 4c3df0ec | Juan Quintela | *
|
14 | 4c3df0ec | Juan Quintela | * The above copyright notice and this permission notice shall be included in
|
15 | 4c3df0ec | Juan Quintela | * all copies or substantial portions of the Software.
|
16 | 4c3df0ec | Juan Quintela | *
|
17 | 4c3df0ec | Juan Quintela | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18 | 4c3df0ec | Juan Quintela | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19 | 4c3df0ec | Juan Quintela | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
20 | 4c3df0ec | Juan Quintela | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21 | 4c3df0ec | Juan Quintela | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22 | 4c3df0ec | Juan Quintela | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23 | 4c3df0ec | Juan Quintela | * THE SOFTWARE.
|
24 | 4c3df0ec | Juan Quintela | */
|
25 | 4c3df0ec | Juan Quintela | #include <hw/hw.h> |
26 | 4c3df0ec | Juan Quintela | #include <hw/pc.h> |
27 | 4c3df0ec | Juan Quintela | #include <hw/pci.h> |
28 | 4c3df0ec | Juan Quintela | #include <hw/isa.h> |
29 | 4c3df0ec | Juan Quintela | #include "block.h" |
30 | 4c3df0ec | Juan Quintela | #include "sysemu.h" |
31 | 4c3df0ec | Juan Quintela | #include "dma.h" |
32 | 4c3df0ec | Juan Quintela | |
33 | 4c3df0ec | Juan Quintela | #include <hw/ide/pci.h> |
34 | 4c3df0ec | Juan Quintela | |
35 | 4c3df0ec | Juan Quintela | /* CMD646 specific */
|
36 | 4c3df0ec | Juan Quintela | #define MRDMODE 0x71 |
37 | 4c3df0ec | Juan Quintela | #define MRDMODE_INTR_CH0 0x04 |
38 | 4c3df0ec | Juan Quintela | #define MRDMODE_INTR_CH1 0x08 |
39 | 4c3df0ec | Juan Quintela | #define MRDMODE_BLK_CH0 0x10 |
40 | 4c3df0ec | Juan Quintela | #define MRDMODE_BLK_CH1 0x20 |
41 | 4c3df0ec | Juan Quintela | #define UDIDETCR0 0x73 |
42 | 4c3df0ec | Juan Quintela | #define UDIDETCR1 0x7B |
43 | 4c3df0ec | Juan Quintela | |
44 | 4c3df0ec | Juan Quintela | static void cmd646_update_irq(PCIIDEState *d); |
45 | 4c3df0ec | Juan Quintela | |
46 | a9deb8c6 | Avi Kivity | static uint64_t cmd646_cmd_read(void *opaque, target_phys_addr_t addr, |
47 | a9deb8c6 | Avi Kivity | unsigned size)
|
48 | 4c3df0ec | Juan Quintela | { |
49 | a9deb8c6 | Avi Kivity | CMD646BAR *cmd646bar = opaque; |
50 | a9deb8c6 | Avi Kivity | |
51 | a9deb8c6 | Avi Kivity | if (addr != 2 || size != 1) { |
52 | a9deb8c6 | Avi Kivity | return ((uint64_t)1 << (size * 8)) - 1; |
53 | a9deb8c6 | Avi Kivity | } |
54 | a9deb8c6 | Avi Kivity | return ide_status_read(cmd646bar->bus, addr + 2); |
55 | a9deb8c6 | Avi Kivity | } |
56 | a9deb8c6 | Avi Kivity | |
57 | a9deb8c6 | Avi Kivity | static void cmd646_cmd_write(void *opaque, target_phys_addr_t addr, |
58 | a9deb8c6 | Avi Kivity | uint64_t data, unsigned size)
|
59 | a9deb8c6 | Avi Kivity | { |
60 | a9deb8c6 | Avi Kivity | CMD646BAR *cmd646bar = opaque; |
61 | a9deb8c6 | Avi Kivity | |
62 | a9deb8c6 | Avi Kivity | if (addr != 2 || size != 1) { |
63 | a9deb8c6 | Avi Kivity | return;
|
64 | a9deb8c6 | Avi Kivity | } |
65 | a9deb8c6 | Avi Kivity | ide_cmd_write(cmd646bar->bus, addr + 2, data);
|
66 | a9deb8c6 | Avi Kivity | } |
67 | a9deb8c6 | Avi Kivity | |
68 | a348f108 | Stefan Weil | static const MemoryRegionOps cmd646_cmd_ops = { |
69 | a9deb8c6 | Avi Kivity | .read = cmd646_cmd_read, |
70 | a9deb8c6 | Avi Kivity | .write = cmd646_cmd_write, |
71 | a9deb8c6 | Avi Kivity | .endianness = DEVICE_LITTLE_ENDIAN, |
72 | a9deb8c6 | Avi Kivity | }; |
73 | a9deb8c6 | Avi Kivity | |
74 | a9deb8c6 | Avi Kivity | static uint64_t cmd646_data_read(void *opaque, target_phys_addr_t addr, |
75 | a9deb8c6 | Avi Kivity | unsigned size)
|
76 | a9deb8c6 | Avi Kivity | { |
77 | a9deb8c6 | Avi Kivity | CMD646BAR *cmd646bar = opaque; |
78 | a9deb8c6 | Avi Kivity | |
79 | a9deb8c6 | Avi Kivity | if (size == 1) { |
80 | a9deb8c6 | Avi Kivity | return ide_ioport_read(cmd646bar->bus, addr);
|
81 | a9deb8c6 | Avi Kivity | } else if (addr == 0) { |
82 | a9deb8c6 | Avi Kivity | if (size == 2) { |
83 | a9deb8c6 | Avi Kivity | return ide_data_readw(cmd646bar->bus, addr);
|
84 | 4c3df0ec | Juan Quintela | } else {
|
85 | a9deb8c6 | Avi Kivity | return ide_data_readl(cmd646bar->bus, addr);
|
86 | 4c3df0ec | Juan Quintela | } |
87 | 4c3df0ec | Juan Quintela | } |
88 | a9deb8c6 | Avi Kivity | return ((uint64_t)1 << (size * 8)) - 1; |
89 | 4c3df0ec | Juan Quintela | } |
90 | 4c3df0ec | Juan Quintela | |
91 | a9deb8c6 | Avi Kivity | static void cmd646_data_write(void *opaque, target_phys_addr_t addr, |
92 | a9deb8c6 | Avi Kivity | uint64_t data, unsigned size)
|
93 | 61f58e59 | Juan Quintela | { |
94 | a9deb8c6 | Avi Kivity | CMD646BAR *cmd646bar = opaque; |
95 | a9deb8c6 | Avi Kivity | |
96 | a9deb8c6 | Avi Kivity | if (size == 1) { |
97 | 0ed8b6f6 | Blue Swirl | ide_ioport_write(cmd646bar->bus, addr, data); |
98 | a9deb8c6 | Avi Kivity | } else if (addr == 0) { |
99 | a9deb8c6 | Avi Kivity | if (size == 2) { |
100 | 0ed8b6f6 | Blue Swirl | ide_data_writew(cmd646bar->bus, addr, data); |
101 | a9deb8c6 | Avi Kivity | } else {
|
102 | 0ed8b6f6 | Blue Swirl | ide_data_writel(cmd646bar->bus, addr, data); |
103 | a9deb8c6 | Avi Kivity | } |
104 | a9deb8c6 | Avi Kivity | } |
105 | a9deb8c6 | Avi Kivity | } |
106 | a9deb8c6 | Avi Kivity | |
107 | a348f108 | Stefan Weil | static const MemoryRegionOps cmd646_data_ops = { |
108 | a9deb8c6 | Avi Kivity | .read = cmd646_data_read, |
109 | a9deb8c6 | Avi Kivity | .write = cmd646_data_write, |
110 | a9deb8c6 | Avi Kivity | .endianness = DEVICE_LITTLE_ENDIAN, |
111 | a9deb8c6 | Avi Kivity | }; |
112 | a9deb8c6 | Avi Kivity | |
113 | a9deb8c6 | Avi Kivity | static void setup_cmd646_bar(PCIIDEState *d, int bus_num) |
114 | a9deb8c6 | Avi Kivity | { |
115 | a9deb8c6 | Avi Kivity | IDEBus *bus = &d->bus[bus_num]; |
116 | a9deb8c6 | Avi Kivity | CMD646BAR *bar = &d->cmd646_bar[bus_num]; |
117 | a9deb8c6 | Avi Kivity | |
118 | a9deb8c6 | Avi Kivity | bar->bus = bus; |
119 | a9deb8c6 | Avi Kivity | bar->pci_dev = d; |
120 | a9deb8c6 | Avi Kivity | memory_region_init_io(&bar->cmd, &cmd646_cmd_ops, bar, "cmd646-cmd", 4); |
121 | a9deb8c6 | Avi Kivity | memory_region_init_io(&bar->data, &cmd646_data_ops, bar, "cmd646-data", 8); |
122 | a9deb8c6 | Avi Kivity | } |
123 | a9deb8c6 | Avi Kivity | |
124 | a9deb8c6 | Avi Kivity | static uint64_t bmdma_read(void *opaque, target_phys_addr_t addr, |
125 | a9deb8c6 | Avi Kivity | unsigned size)
|
126 | a9deb8c6 | Avi Kivity | { |
127 | a9deb8c6 | Avi Kivity | BMDMAState *bm = opaque; |
128 | a9deb8c6 | Avi Kivity | PCIIDEState *pci_dev = bm->pci_dev; |
129 | 4c3df0ec | Juan Quintela | uint32_t val; |
130 | 4c3df0ec | Juan Quintela | |
131 | a9deb8c6 | Avi Kivity | if (size != 1) { |
132 | a9deb8c6 | Avi Kivity | return ((uint64_t)1 << (size * 8)) - 1; |
133 | a9deb8c6 | Avi Kivity | } |
134 | a9deb8c6 | Avi Kivity | |
135 | 4c3df0ec | Juan Quintela | switch(addr & 3) { |
136 | 4c3df0ec | Juan Quintela | case 0: |
137 | 4c3df0ec | Juan Quintela | val = bm->cmd; |
138 | 4c3df0ec | Juan Quintela | break;
|
139 | 4c3df0ec | Juan Quintela | case 1: |
140 | 58c0e732 | Juan Quintela | val = pci_dev->dev.config[MRDMODE]; |
141 | 4c3df0ec | Juan Quintela | break;
|
142 | 4c3df0ec | Juan Quintela | case 2: |
143 | 4c3df0ec | Juan Quintela | val = bm->status; |
144 | 4c3df0ec | Juan Quintela | break;
|
145 | 4c3df0ec | Juan Quintela | case 3: |
146 | 70ae65f5 | Igor V. Kovalenko | if (bm == &pci_dev->bmdma[0]) { |
147 | 58c0e732 | Juan Quintela | val = pci_dev->dev.config[UDIDETCR0]; |
148 | 4c3df0ec | Juan Quintela | } else {
|
149 | 58c0e732 | Juan Quintela | val = pci_dev->dev.config[UDIDETCR1]; |
150 | 4c3df0ec | Juan Quintela | } |
151 | 4c3df0ec | Juan Quintela | break;
|
152 | 4c3df0ec | Juan Quintela | default:
|
153 | 4c3df0ec | Juan Quintela | val = 0xff;
|
154 | 4c3df0ec | Juan Quintela | break;
|
155 | 4c3df0ec | Juan Quintela | } |
156 | 4c3df0ec | Juan Quintela | #ifdef DEBUG_IDE
|
157 | 08406b03 | malc | printf("bmdma: readb 0x%02x : 0x%02x\n", addr, val);
|
158 | 4c3df0ec | Juan Quintela | #endif
|
159 | 4c3df0ec | Juan Quintela | return val;
|
160 | 4c3df0ec | Juan Quintela | } |
161 | 4c3df0ec | Juan Quintela | |
162 | a9deb8c6 | Avi Kivity | static void bmdma_write(void *opaque, target_phys_addr_t addr, |
163 | a9deb8c6 | Avi Kivity | uint64_t val, unsigned size)
|
164 | 70ae65f5 | Igor V. Kovalenko | { |
165 | a9deb8c6 | Avi Kivity | BMDMAState *bm = opaque; |
166 | a9deb8c6 | Avi Kivity | PCIIDEState *pci_dev = bm->pci_dev; |
167 | 70ae65f5 | Igor V. Kovalenko | |
168 | a9deb8c6 | Avi Kivity | if (size != 1) { |
169 | a9deb8c6 | Avi Kivity | return;
|
170 | a9deb8c6 | Avi Kivity | } |
171 | 70ae65f5 | Igor V. Kovalenko | |
172 | 4c3df0ec | Juan Quintela | #ifdef DEBUG_IDE
|
173 | 08406b03 | malc | printf("bmdma: writeb 0x%02x : 0x%02x\n", addr, val);
|
174 | 4c3df0ec | Juan Quintela | #endif
|
175 | 4c3df0ec | Juan Quintela | switch(addr & 3) { |
176 | 50a48094 | Igor V. Kovalenko | case 0: |
177 | a9deb8c6 | Avi Kivity | bmdma_cmd_writeb(bm, val); |
178 | 50a48094 | Igor V. Kovalenko | break;
|
179 | 4c3df0ec | Juan Quintela | case 1: |
180 | 58c0e732 | Juan Quintela | pci_dev->dev.config[MRDMODE] = |
181 | 58c0e732 | Juan Quintela | (pci_dev->dev.config[MRDMODE] & ~0x30) | (val & 0x30); |
182 | 58c0e732 | Juan Quintela | cmd646_update_irq(pci_dev); |
183 | 4c3df0ec | Juan Quintela | break;
|
184 | 4c3df0ec | Juan Quintela | case 2: |
185 | 4c3df0ec | Juan Quintela | bm->status = (val & 0x60) | (bm->status & 1) | (bm->status & ~val & 0x06); |
186 | 4c3df0ec | Juan Quintela | break;
|
187 | 4c3df0ec | Juan Quintela | case 3: |
188 | 70ae65f5 | Igor V. Kovalenko | if (bm == &pci_dev->bmdma[0]) |
189 | 58c0e732 | Juan Quintela | pci_dev->dev.config[UDIDETCR0] = val; |
190 | 58c0e732 | Juan Quintela | else
|
191 | 58c0e732 | Juan Quintela | pci_dev->dev.config[UDIDETCR1] = val; |
192 | 4c3df0ec | Juan Quintela | break;
|
193 | 4c3df0ec | Juan Quintela | } |
194 | 4c3df0ec | Juan Quintela | } |
195 | 4c3df0ec | Juan Quintela | |
196 | a348f108 | Stefan Weil | static const MemoryRegionOps cmd646_bmdma_ops = { |
197 | a9deb8c6 | Avi Kivity | .read = bmdma_read, |
198 | a9deb8c6 | Avi Kivity | .write = bmdma_write, |
199 | a9deb8c6 | Avi Kivity | }; |
200 | 70ae65f5 | Igor V. Kovalenko | |
201 | a9deb8c6 | Avi Kivity | static void bmdma_setup_bar(PCIIDEState *d) |
202 | 4c3df0ec | Juan Quintela | { |
203 | a9deb8c6 | Avi Kivity | BMDMAState *bm; |
204 | 4c3df0ec | Juan Quintela | int i;
|
205 | 4c3df0ec | Juan Quintela | |
206 | a9deb8c6 | Avi Kivity | memory_region_init(&d->bmdma_bar, "cmd646-bmdma", 16); |
207 | 4c3df0ec | Juan Quintela | for(i = 0;i < 2; i++) { |
208 | a9deb8c6 | Avi Kivity | bm = &d->bmdma[i]; |
209 | a9deb8c6 | Avi Kivity | memory_region_init_io(&bm->extra_io, &cmd646_bmdma_ops, bm, |
210 | a9deb8c6 | Avi Kivity | "cmd646-bmdma-bus", 4); |
211 | a9deb8c6 | Avi Kivity | memory_region_add_subregion(&d->bmdma_bar, i * 8, &bm->extra_io);
|
212 | a9deb8c6 | Avi Kivity | memory_region_init_io(&bm->addr_ioport, &bmdma_addr_ioport_ops, bm, |
213 | a9deb8c6 | Avi Kivity | "cmd646-bmdma-ioport", 4); |
214 | a9deb8c6 | Avi Kivity | memory_region_add_subregion(&d->bmdma_bar, i * 8 + 4, &bm->addr_ioport); |
215 | 4c3df0ec | Juan Quintela | } |
216 | 4c3df0ec | Juan Quintela | } |
217 | 4c3df0ec | Juan Quintela | |
218 | 4c3df0ec | Juan Quintela | /* XXX: call it also when the MRDMODE is changed from the PCI config
|
219 | 4c3df0ec | Juan Quintela | registers */
|
220 | 4c3df0ec | Juan Quintela | static void cmd646_update_irq(PCIIDEState *d) |
221 | 4c3df0ec | Juan Quintela | { |
222 | 4c3df0ec | Juan Quintela | int pci_level;
|
223 | 4c3df0ec | Juan Quintela | pci_level = ((d->dev.config[MRDMODE] & MRDMODE_INTR_CH0) && |
224 | 4c3df0ec | Juan Quintela | !(d->dev.config[MRDMODE] & MRDMODE_BLK_CH0)) || |
225 | 4c3df0ec | Juan Quintela | ((d->dev.config[MRDMODE] & MRDMODE_INTR_CH1) && |
226 | 4c3df0ec | Juan Quintela | !(d->dev.config[MRDMODE] & MRDMODE_BLK_CH1)); |
227 | 4c3df0ec | Juan Quintela | qemu_set_irq(d->dev.irq[0], pci_level);
|
228 | 4c3df0ec | Juan Quintela | } |
229 | 4c3df0ec | Juan Quintela | |
230 | 4c3df0ec | Juan Quintela | /* the PCI irq level is the logical OR of the two channels */
|
231 | 4c3df0ec | Juan Quintela | static void cmd646_set_irq(void *opaque, int channel, int level) |
232 | 4c3df0ec | Juan Quintela | { |
233 | 4c3df0ec | Juan Quintela | PCIIDEState *d = opaque; |
234 | 4c3df0ec | Juan Quintela | int irq_mask;
|
235 | 4c3df0ec | Juan Quintela | |
236 | 4c3df0ec | Juan Quintela | irq_mask = MRDMODE_INTR_CH0 << channel; |
237 | 4c3df0ec | Juan Quintela | if (level)
|
238 | 4c3df0ec | Juan Quintela | d->dev.config[MRDMODE] |= irq_mask; |
239 | 4c3df0ec | Juan Quintela | else
|
240 | 4c3df0ec | Juan Quintela | d->dev.config[MRDMODE] &= ~irq_mask; |
241 | 4c3df0ec | Juan Quintela | cmd646_update_irq(d); |
242 | 4c3df0ec | Juan Quintela | } |
243 | 4c3df0ec | Juan Quintela | |
244 | 4c3df0ec | Juan Quintela | static void cmd646_reset(void *opaque) |
245 | 4c3df0ec | Juan Quintela | { |
246 | 4c3df0ec | Juan Quintela | PCIIDEState *d = opaque; |
247 | 4c3df0ec | Juan Quintela | unsigned int i; |
248 | 4c3df0ec | Juan Quintela | |
249 | 4a643563 | Blue Swirl | for (i = 0; i < 2; i++) { |
250 | 4a643563 | Blue Swirl | ide_bus_reset(&d->bus[i]); |
251 | 4a643563 | Blue Swirl | } |
252 | 4c3df0ec | Juan Quintela | } |
253 | 4c3df0ec | Juan Quintela | |
254 | 4c3df0ec | Juan Quintela | /* CMD646 PCI IDE controller */
|
255 | 4c3df0ec | Juan Quintela | static int pci_cmd646_ide_initfn(PCIDevice *dev) |
256 | 4c3df0ec | Juan Quintela | { |
257 | 4c3df0ec | Juan Quintela | PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, dev); |
258 | 4c3df0ec | Juan Quintela | uint8_t *pci_conf = d->dev.config; |
259 | 4c3df0ec | Juan Quintela | qemu_irq *irq; |
260 | 61d9d6b0 | Stefan Hajnoczi | int i;
|
261 | 4c3df0ec | Juan Quintela | |
262 | 409570a7 | Michael S. Tsirkin | pci_conf[PCI_CLASS_PROG] = 0x8f;
|
263 | 4c3df0ec | Juan Quintela | |
264 | 4c3df0ec | Juan Quintela | pci_conf[0x51] = 0x04; // enable IDE0 |
265 | 4c3df0ec | Juan Quintela | if (d->secondary) {
|
266 | 4c3df0ec | Juan Quintela | /* XXX: if not enabled, really disable the seconday IDE controller */
|
267 | 4c3df0ec | Juan Quintela | pci_conf[0x51] |= 0x08; /* enable IDE1 */ |
268 | 4c3df0ec | Juan Quintela | } |
269 | 4c3df0ec | Juan Quintela | |
270 | a9deb8c6 | Avi Kivity | setup_cmd646_bar(d, 0);
|
271 | a9deb8c6 | Avi Kivity | setup_cmd646_bar(d, 1);
|
272 | e824b2cc | Avi Kivity | pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd646_bar[0].data); |
273 | e824b2cc | Avi Kivity | pci_register_bar(dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd646_bar[0].cmd); |
274 | e824b2cc | Avi Kivity | pci_register_bar(dev, 2, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd646_bar[1].data); |
275 | e824b2cc | Avi Kivity | pci_register_bar(dev, 3, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd646_bar[1].cmd); |
276 | a9deb8c6 | Avi Kivity | bmdma_setup_bar(d); |
277 | e824b2cc | Avi Kivity | pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_bar);
|
278 | 4c3df0ec | Juan Quintela | |
279 | 409570a7 | Michael S. Tsirkin | /* TODO: RST# value should be 0 */
|
280 | 409570a7 | Michael S. Tsirkin | pci_conf[PCI_INTERRUPT_PIN] = 0x01; // interrupt on pin 1 |
281 | 4c3df0ec | Juan Quintela | |
282 | 4c3df0ec | Juan Quintela | irq = qemu_allocate_irqs(cmd646_set_irq, d, 2);
|
283 | 61d9d6b0 | Stefan Hajnoczi | for (i = 0; i < 2; i++) { |
284 | 61d9d6b0 | Stefan Hajnoczi | ide_bus_new(&d->bus[i], &d->dev.qdev, i); |
285 | 61d9d6b0 | Stefan Hajnoczi | ide_init2(&d->bus[i], irq[i]); |
286 | 61d9d6b0 | Stefan Hajnoczi | |
287 | a9deb8c6 | Avi Kivity | bmdma_init(&d->bus[i], &d->bmdma[i], d); |
288 | f56b18c0 | Kevin Wolf | d->bmdma[i].bus = &d->bus[i]; |
289 | 61d9d6b0 | Stefan Hajnoczi | qemu_add_vm_change_state_handler(d->bus[i].dma->ops->restart_cb, |
290 | f56b18c0 | Kevin Wolf | &d->bmdma[i].dma); |
291 | 61d9d6b0 | Stefan Hajnoczi | } |
292 | 4c3df0ec | Juan Quintela | |
293 | 0be71e32 | Alex Williamson | vmstate_register(&dev->qdev, 0, &vmstate_ide_pci, d);
|
294 | 4c3df0ec | Juan Quintela | qemu_register_reset(cmd646_reset, d); |
295 | 4c3df0ec | Juan Quintela | return 0; |
296 | 4c3df0ec | Juan Quintela | } |
297 | 4c3df0ec | Juan Quintela | |
298 | f90c2bcd | Alex Williamson | static void pci_cmd646_ide_exitfn(PCIDevice *dev) |
299 | a9deb8c6 | Avi Kivity | { |
300 | a9deb8c6 | Avi Kivity | PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, dev); |
301 | a9deb8c6 | Avi Kivity | unsigned i;
|
302 | a9deb8c6 | Avi Kivity | |
303 | a9deb8c6 | Avi Kivity | for (i = 0; i < 2; ++i) { |
304 | a9deb8c6 | Avi Kivity | memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].extra_io); |
305 | a9deb8c6 | Avi Kivity | memory_region_destroy(&d->bmdma[i].extra_io); |
306 | a9deb8c6 | Avi Kivity | memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].addr_ioport); |
307 | a9deb8c6 | Avi Kivity | memory_region_destroy(&d->bmdma[i].addr_ioport); |
308 | a9deb8c6 | Avi Kivity | memory_region_destroy(&d->cmd646_bar[i].cmd); |
309 | a9deb8c6 | Avi Kivity | memory_region_destroy(&d->cmd646_bar[i].data); |
310 | a9deb8c6 | Avi Kivity | } |
311 | a9deb8c6 | Avi Kivity | memory_region_destroy(&d->bmdma_bar); |
312 | a9deb8c6 | Avi Kivity | } |
313 | a9deb8c6 | Avi Kivity | |
314 | 4c3df0ec | Juan Quintela | void pci_cmd646_ide_init(PCIBus *bus, DriveInfo **hd_table,
|
315 | 4c3df0ec | Juan Quintela | int secondary_ide_enabled)
|
316 | 4c3df0ec | Juan Quintela | { |
317 | 4c3df0ec | Juan Quintela | PCIDevice *dev; |
318 | 4c3df0ec | Juan Quintela | |
319 | 556cd098 | Markus Armbruster | dev = pci_create(bus, -1, "cmd646-ide"); |
320 | 4c3df0ec | Juan Quintela | qdev_prop_set_uint32(&dev->qdev, "secondary", secondary_ide_enabled);
|
321 | 4c3df0ec | Juan Quintela | qdev_init_nofail(&dev->qdev); |
322 | 4c3df0ec | Juan Quintela | |
323 | 4c3df0ec | Juan Quintela | pci_ide_create_devs(dev, hd_table); |
324 | 4c3df0ec | Juan Quintela | } |
325 | 4c3df0ec | Juan Quintela | |
326 | 40021f08 | Anthony Liguori | static Property cmd646_ide_properties[] = {
|
327 | 40021f08 | Anthony Liguori | DEFINE_PROP_UINT32("secondary", PCIIDEState, secondary, 0), |
328 | 40021f08 | Anthony Liguori | DEFINE_PROP_END_OF_LIST(), |
329 | 40021f08 | Anthony Liguori | }; |
330 | 40021f08 | Anthony Liguori | |
331 | 40021f08 | Anthony Liguori | static void cmd646_ide_class_init(ObjectClass *klass, void *data) |
332 | 40021f08 | Anthony Liguori | { |
333 | 39bffca2 | Anthony Liguori | DeviceClass *dc = DEVICE_CLASS(klass); |
334 | 40021f08 | Anthony Liguori | PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); |
335 | 40021f08 | Anthony Liguori | |
336 | 40021f08 | Anthony Liguori | k->init = pci_cmd646_ide_initfn; |
337 | 40021f08 | Anthony Liguori | k->exit = pci_cmd646_ide_exitfn; |
338 | 40021f08 | Anthony Liguori | k->vendor_id = PCI_VENDOR_ID_CMD; |
339 | 40021f08 | Anthony Liguori | k->device_id = PCI_DEVICE_ID_CMD_646; |
340 | 40021f08 | Anthony Liguori | k->revision = 0x07;
|
341 | 40021f08 | Anthony Liguori | k->class_id = PCI_CLASS_STORAGE_IDE; |
342 | 39bffca2 | Anthony Liguori | dc->props = cmd646_ide_properties; |
343 | 40021f08 | Anthony Liguori | } |
344 | 40021f08 | Anthony Liguori | |
345 | 39bffca2 | Anthony Liguori | static TypeInfo cmd646_ide_info = {
|
346 | 39bffca2 | Anthony Liguori | .name = "cmd646-ide",
|
347 | 39bffca2 | Anthony Liguori | .parent = TYPE_PCI_DEVICE, |
348 | 39bffca2 | Anthony Liguori | .instance_size = sizeof(PCIIDEState),
|
349 | 39bffca2 | Anthony Liguori | .class_init = cmd646_ide_class_init, |
350 | 4c3df0ec | Juan Quintela | }; |
351 | 4c3df0ec | Juan Quintela | |
352 | 83f7d43a | Andreas Färber | static void cmd646_ide_register_types(void) |
353 | 4c3df0ec | Juan Quintela | { |
354 | 39bffca2 | Anthony Liguori | type_register_static(&cmd646_ide_info); |
355 | 4c3df0ec | Juan Quintela | } |
356 | 83f7d43a | Andreas Färber | |
357 | 83f7d43a | Andreas Färber | type_init(cmd646_ide_register_types) |