ide/pci: convert to qdev.
[qemu] / hw / ide / pci.c
1 /*
2  * QEMU IDE Emulation: PCI Bus support.
3  *
4  * Copyright (c) 2003 Fabrice Bellard
5  * Copyright (c) 2006 Openedhand Ltd.
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a copy
8  * of this software and associated documentation files (the "Software"), to deal
9  * in the Software without restriction, including without limitation the rights
10  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11  * copies of the Software, and to permit persons to whom the Software is
12  * furnished to do so, subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be included in
15  * all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23  * THE SOFTWARE.
24  */
25 #include <hw/hw.h>
26 #include <hw/pc.h>
27 #include <hw/pci.h>
28 #include <hw/isa.h>
29 #include "block.h"
30 #include "block_int.h"
31 #include "sysemu.h"
32 #include "dma.h"
33
34 #include <hw/ide/internal.h>
35
36 /***********************************************************/
37 /* PCI IDE definitions */
38
39 /* CMD646 specific */
40 #define MRDMODE         0x71
41 #define   MRDMODE_INTR_CH0      0x04
42 #define   MRDMODE_INTR_CH1      0x08
43 #define   MRDMODE_BLK_CH0       0x10
44 #define   MRDMODE_BLK_CH1       0x20
45 #define UDIDETCR0       0x73
46 #define UDIDETCR1       0x7B
47
48 #define IDE_TYPE_PIIX3   0
49 #define IDE_TYPE_CMD646  1
50 #define IDE_TYPE_PIIX4   2
51
52 typedef struct PCIIDEState {
53     PCIDevice dev;
54     IDEBus *bus[2];
55     BMDMAState bmdma[2];
56     int type; /* see IDE_TYPE_xxx */
57     uint32_t secondary;
58 } PCIIDEState;
59
60 static void cmd646_update_irq(PCIIDEState *d);
61
62 static void ide_map(PCIDevice *pci_dev, int region_num,
63                     uint32_t addr, uint32_t size, int type)
64 {
65     PCIIDEState *d = (PCIIDEState *)pci_dev;
66     IDEBus *bus;
67
68     if (region_num <= 3) {
69         bus = d->bus[(region_num >> 1)];
70         if (region_num & 1) {
71             register_ioport_read(addr + 2, 1, 1, ide_status_read, bus);
72             register_ioport_write(addr + 2, 1, 1, ide_cmd_write, bus);
73         } else {
74             register_ioport_write(addr, 8, 1, ide_ioport_write, bus);
75             register_ioport_read(addr, 8, 1, ide_ioport_read, bus);
76
77             /* data ports */
78             register_ioport_write(addr, 2, 2, ide_data_writew, bus);
79             register_ioport_read(addr, 2, 2, ide_data_readw, bus);
80             register_ioport_write(addr, 4, 4, ide_data_writel, bus);
81             register_ioport_read(addr, 4, 4, ide_data_readl, bus);
82         }
83     }
84 }
85
86 static void bmdma_cmd_writeb(void *opaque, uint32_t addr, uint32_t val)
87 {
88     BMDMAState *bm = opaque;
89 #ifdef DEBUG_IDE
90     printf("%s: 0x%08x\n", __func__, val);
91 #endif
92     if (!(val & BM_CMD_START)) {
93         /* XXX: do it better */
94         ide_dma_cancel(bm);
95         bm->cmd = val & 0x09;
96     } else {
97         if (!(bm->status & BM_STATUS_DMAING)) {
98             bm->status |= BM_STATUS_DMAING;
99             /* start dma transfer if possible */
100             if (bm->dma_cb)
101                 bm->dma_cb(bm, 0);
102         }
103         bm->cmd = val & 0x09;
104     }
105 }
106
107 static uint32_t bmdma_readb(void *opaque, uint32_t addr)
108 {
109     BMDMAState *bm = opaque;
110     PCIIDEState *pci_dev;
111     uint32_t val;
112
113     switch(addr & 3) {
114     case 0:
115         val = bm->cmd;
116         break;
117     case 1:
118         pci_dev = bm->pci_dev;
119         if (pci_dev->type == IDE_TYPE_CMD646) {
120             val = pci_dev->dev.config[MRDMODE];
121         } else {
122             val = 0xff;
123         }
124         break;
125     case 2:
126         val = bm->status;
127         break;
128     case 3:
129         pci_dev = bm->pci_dev;
130         if (pci_dev->type == IDE_TYPE_CMD646) {
131             if (bm == &pci_dev->bmdma[0])
132                 val = pci_dev->dev.config[UDIDETCR0];
133             else
134                 val = pci_dev->dev.config[UDIDETCR1];
135         } else {
136             val = 0xff;
137         }
138         break;
139     default:
140         val = 0xff;
141         break;
142     }
143 #ifdef DEBUG_IDE
144     printf("bmdma: readb 0x%02x : 0x%02x\n", addr, val);
145 #endif
146     return val;
147 }
148
149 static void bmdma_writeb(void *opaque, uint32_t addr, uint32_t val)
150 {
151     BMDMAState *bm = opaque;
152     PCIIDEState *pci_dev;
153 #ifdef DEBUG_IDE
154     printf("bmdma: writeb 0x%02x : 0x%02x\n", addr, val);
155 #endif
156     switch(addr & 3) {
157     case 1:
158         pci_dev = bm->pci_dev;
159         if (pci_dev->type == IDE_TYPE_CMD646) {
160             pci_dev->dev.config[MRDMODE] =
161                 (pci_dev->dev.config[MRDMODE] & ~0x30) | (val & 0x30);
162             cmd646_update_irq(pci_dev);
163         }
164         break;
165     case 2:
166         bm->status = (val & 0x60) | (bm->status & 1) | (bm->status & ~val & 0x06);
167         break;
168     case 3:
169         pci_dev = bm->pci_dev;
170         if (pci_dev->type == IDE_TYPE_CMD646) {
171             if (bm == &pci_dev->bmdma[0])
172                 pci_dev->dev.config[UDIDETCR0] = val;
173             else
174                 pci_dev->dev.config[UDIDETCR1] = val;
175         }
176         break;
177     }
178 }
179
180 static uint32_t bmdma_addr_readb(void *opaque, uint32_t addr)
181 {
182     BMDMAState *bm = opaque;
183     uint32_t val;
184     val = (bm->addr >> ((addr & 3) * 8)) & 0xff;
185 #ifdef DEBUG_IDE
186     printf("%s: 0x%08x\n", __func__, val);
187 #endif
188     return val;
189 }
190
191 static void bmdma_addr_writeb(void *opaque, uint32_t addr, uint32_t val)
192 {
193     BMDMAState *bm = opaque;
194     int shift = (addr & 3) * 8;
195 #ifdef DEBUG_IDE
196     printf("%s: 0x%08x\n", __func__, val);
197 #endif
198     bm->addr &= ~(0xFF << shift);
199     bm->addr |= ((val & 0xFF) << shift) & ~3;
200     bm->cur_addr = bm->addr;
201 }
202
203 static uint32_t bmdma_addr_readw(void *opaque, uint32_t addr)
204 {
205     BMDMAState *bm = opaque;
206     uint32_t val;
207     val = (bm->addr >> ((addr & 3) * 8)) & 0xffff;
208 #ifdef DEBUG_IDE
209     printf("%s: 0x%08x\n", __func__, val);
210 #endif
211     return val;
212 }
213
214 static void bmdma_addr_writew(void *opaque, uint32_t addr, uint32_t val)
215 {
216     BMDMAState *bm = opaque;
217     int shift = (addr & 3) * 8;
218 #ifdef DEBUG_IDE
219     printf("%s: 0x%08x\n", __func__, val);
220 #endif
221     bm->addr &= ~(0xFFFF << shift);
222     bm->addr |= ((val & 0xFFFF) << shift) & ~3;
223     bm->cur_addr = bm->addr;
224 }
225
226 static uint32_t bmdma_addr_readl(void *opaque, uint32_t addr)
227 {
228     BMDMAState *bm = opaque;
229     uint32_t val;
230     val = bm->addr;
231 #ifdef DEBUG_IDE
232     printf("%s: 0x%08x\n", __func__, val);
233 #endif
234     return val;
235 }
236
237 static void bmdma_addr_writel(void *opaque, uint32_t addr, uint32_t val)
238 {
239     BMDMAState *bm = opaque;
240 #ifdef DEBUG_IDE
241     printf("%s: 0x%08x\n", __func__, val);
242 #endif
243     bm->addr = val & ~3;
244     bm->cur_addr = bm->addr;
245 }
246
247 static void bmdma_map(PCIDevice *pci_dev, int region_num,
248                     uint32_t addr, uint32_t size, int type)
249 {
250     PCIIDEState *d = (PCIIDEState *)pci_dev;
251     int i;
252
253     for(i = 0;i < 2; i++) {
254         BMDMAState *bm = &d->bmdma[i];
255         d->bus[i]->bmdma = bm;
256         bm->pci_dev = DO_UPCAST(PCIIDEState, dev, pci_dev);
257         bm->bus = d->bus[i];
258         qemu_add_vm_change_state_handler(ide_dma_restart_cb, bm);
259
260         register_ioport_write(addr, 1, 1, bmdma_cmd_writeb, bm);
261
262         register_ioport_write(addr + 1, 3, 1, bmdma_writeb, bm);
263         register_ioport_read(addr, 4, 1, bmdma_readb, bm);
264
265         register_ioport_write(addr + 4, 4, 1, bmdma_addr_writeb, bm);
266         register_ioport_read(addr + 4, 4, 1, bmdma_addr_readb, bm);
267         register_ioport_write(addr + 4, 4, 2, bmdma_addr_writew, bm);
268         register_ioport_read(addr + 4, 4, 2, bmdma_addr_readw, bm);
269         register_ioport_write(addr + 4, 4, 4, bmdma_addr_writel, bm);
270         register_ioport_read(addr + 4, 4, 4, bmdma_addr_readl, bm);
271         addr += 8;
272     }
273 }
274
275 static void pci_ide_save(QEMUFile* f, void *opaque)
276 {
277     PCIIDEState *d = opaque;
278     int i;
279
280     pci_device_save(&d->dev, f);
281
282     for(i = 0; i < 2; i++) {
283         BMDMAState *bm = &d->bmdma[i];
284         uint8_t ifidx;
285         qemu_put_8s(f, &bm->cmd);
286         qemu_put_8s(f, &bm->status);
287         qemu_put_be32s(f, &bm->addr);
288         qemu_put_sbe64s(f, &bm->sector_num);
289         qemu_put_be32s(f, &bm->nsector);
290         ifidx = bm->unit + 2*i;
291         qemu_put_8s(f, &ifidx);
292         /* XXX: if a transfer is pending, we do not save it yet */
293     }
294
295     /* per IDE interface data */
296     for(i = 0; i < 2; i++) {
297         idebus_save(f, d->bus[i]);
298     }
299
300     /* per IDE drive data */
301     for(i = 0; i < 2; i++) {
302         ide_save(f, &d->bus[i]->ifs[0]);
303         ide_save(f, &d->bus[i]->ifs[1]);
304     }
305 }
306
307 static int pci_ide_load(QEMUFile* f, void *opaque, int version_id)
308 {
309     PCIIDEState *d = opaque;
310     int ret, i;
311
312     if (version_id != 2 && version_id != 3)
313         return -EINVAL;
314     ret = pci_device_load(&d->dev, f);
315     if (ret < 0)
316         return ret;
317
318     for(i = 0; i < 2; i++) {
319         BMDMAState *bm = &d->bmdma[i];
320         uint8_t ifidx;
321         qemu_get_8s(f, &bm->cmd);
322         qemu_get_8s(f, &bm->status);
323         qemu_get_be32s(f, &bm->addr);
324         qemu_get_sbe64s(f, &bm->sector_num);
325         qemu_get_be32s(f, &bm->nsector);
326         qemu_get_8s(f, &ifidx);
327         bm->unit = ifidx & 1;
328         /* XXX: if a transfer is pending, we do not save it yet */
329     }
330
331     /* per IDE interface data */
332     for(i = 0; i < 2; i++) {
333         idebus_load(f, d->bus[i], version_id);
334     }
335
336     /* per IDE drive data */
337     for(i = 0; i < 2; i++) {
338         ide_load(f, &d->bus[i]->ifs[0], version_id);
339         ide_load(f, &d->bus[i]->ifs[1], version_id);
340     }
341     return 0;
342 }
343
344 static void pci_ide_create_devs(PCIDevice *dev, DriveInfo **hd_table)
345 {
346     PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, dev);
347     static const int bus[4]  = { 0, 0, 1, 1 };
348     static const int unit[4] = { 0, 1, 0, 1 };
349     int i;
350
351     for (i = 0; i < 4; i++) {
352         if (hd_table[i] == NULL)
353             continue;
354         ide_create_drive(d->bus[bus[i]], unit[i], hd_table[i]);
355     }
356 }
357
358 /* XXX: call it also when the MRDMODE is changed from the PCI config
359    registers */
360 static void cmd646_update_irq(PCIIDEState *d)
361 {
362     int pci_level;
363     pci_level = ((d->dev.config[MRDMODE] & MRDMODE_INTR_CH0) &&
364                  !(d->dev.config[MRDMODE] & MRDMODE_BLK_CH0)) ||
365         ((d->dev.config[MRDMODE] & MRDMODE_INTR_CH1) &&
366          !(d->dev.config[MRDMODE] & MRDMODE_BLK_CH1));
367     qemu_set_irq(d->dev.irq[0], pci_level);
368 }
369
370 /* the PCI irq level is the logical OR of the two channels */
371 static void cmd646_set_irq(void *opaque, int channel, int level)
372 {
373     PCIIDEState *d = opaque;
374     int irq_mask;
375
376     irq_mask = MRDMODE_INTR_CH0 << channel;
377     if (level)
378         d->dev.config[MRDMODE] |= irq_mask;
379     else
380         d->dev.config[MRDMODE] &= ~irq_mask;
381     cmd646_update_irq(d);
382 }
383
384 static void cmd646_reset(void *opaque)
385 {
386     PCIIDEState *d = opaque;
387     unsigned int i;
388
389     for (i = 0; i < 2; i++)
390         ide_dma_cancel(&d->bmdma[i]);
391 }
392
393 /* CMD646 PCI IDE controller */
394 static int pci_cmd646_ide_initfn(PCIDevice *dev)
395 {
396     PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, dev);
397     uint8_t *pci_conf = d->dev.config;
398     qemu_irq *irq;
399
400     d->type = IDE_TYPE_CMD646;
401     pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_CMD);
402     pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_CMD_646);
403
404     pci_conf[0x08] = 0x07; // IDE controller revision
405     pci_conf[0x09] = 0x8f;
406
407     pci_config_set_class(pci_conf, PCI_CLASS_STORAGE_IDE);
408     pci_conf[PCI_HEADER_TYPE] = PCI_HEADER_TYPE_NORMAL; // header_type
409
410     pci_conf[0x51] = 0x04; // enable IDE0
411     if (d->secondary) {
412         /* XXX: if not enabled, really disable the seconday IDE controller */
413         pci_conf[0x51] |= 0x08; /* enable IDE1 */
414     }
415
416     pci_register_bar((PCIDevice *)d, 0, 0x8,
417                      PCI_ADDRESS_SPACE_IO, ide_map);
418     pci_register_bar((PCIDevice *)d, 1, 0x4,
419                      PCI_ADDRESS_SPACE_IO, ide_map);
420     pci_register_bar((PCIDevice *)d, 2, 0x8,
421                      PCI_ADDRESS_SPACE_IO, ide_map);
422     pci_register_bar((PCIDevice *)d, 3, 0x4,
423                      PCI_ADDRESS_SPACE_IO, ide_map);
424     pci_register_bar((PCIDevice *)d, 4, 0x10,
425                      PCI_ADDRESS_SPACE_IO, bmdma_map);
426
427     pci_conf[0x3d] = 0x01; // interrupt on pin 1
428
429     irq = qemu_allocate_irqs(cmd646_set_irq, d, 2);
430     d->bus[0] = ide_bus_new(&d->dev.qdev);
431     d->bus[1] = ide_bus_new(&d->dev.qdev);
432     ide_init2(d->bus[0], NULL, NULL, irq[0]);
433     ide_init2(d->bus[1], NULL, NULL, irq[1]);
434
435     register_savevm("ide", 0, 3, pci_ide_save, pci_ide_load, d);
436     qemu_register_reset(cmd646_reset, d);
437     cmd646_reset(d);
438     return 0;
439 }
440
441 void pci_cmd646_ide_init(PCIBus *bus, DriveInfo **hd_table,
442                          int secondary_ide_enabled)
443 {
444     PCIDevice *dev;
445
446     dev = pci_create_noinit(bus, -1, "CMD646 IDE");
447     qdev_prop_set_uint32(&dev->qdev, "secondary", secondary_ide_enabled);
448     qdev_init(&dev->qdev);
449
450     pci_ide_create_devs(dev, hd_table);
451 }
452
453 static void piix3_reset(void *opaque)
454 {
455     PCIIDEState *d = opaque;
456     uint8_t *pci_conf = d->dev.config;
457     int i;
458
459     for (i = 0; i < 2; i++)
460         ide_dma_cancel(&d->bmdma[i]);
461
462     pci_conf[0x04] = 0x00;
463     pci_conf[0x05] = 0x00;
464     pci_conf[0x06] = 0x80; /* FBC */
465     pci_conf[0x07] = 0x02; // PCI_status_devsel_medium
466     pci_conf[0x20] = 0x01; /* BMIBA: 20-23h */
467 }
468
469 static int pci_piix_ide_initfn(PCIIDEState *d)
470 {
471     uint8_t *pci_conf = d->dev.config;
472
473     pci_conf[0x09] = 0x80; // legacy ATA mode
474     pci_config_set_class(pci_conf, PCI_CLASS_STORAGE_IDE);
475     pci_conf[PCI_HEADER_TYPE] = PCI_HEADER_TYPE_NORMAL; // header_type
476
477     qemu_register_reset(piix3_reset, d);
478     piix3_reset(d);
479
480     pci_register_bar((PCIDevice *)d, 4, 0x10,
481                      PCI_ADDRESS_SPACE_IO, bmdma_map);
482
483     register_savevm("ide", 0, 3, pci_ide_save, pci_ide_load, d);
484
485     d->bus[0] = ide_bus_new(&d->dev.qdev);
486     d->bus[1] = ide_bus_new(&d->dev.qdev);
487     ide_init_ioport(d->bus[0], 0x1f0, 0x3f6);
488     ide_init_ioport(d->bus[1], 0x170, 0x376);
489
490     ide_init2(d->bus[0], NULL, NULL, isa_reserve_irq(14));
491     ide_init2(d->bus[1], NULL, NULL, isa_reserve_irq(15));
492     return 0;
493 }
494
495 static int pci_piix3_ide_initfn(PCIDevice *dev)
496 {
497     PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, dev);
498
499     d->type = IDE_TYPE_PIIX3;
500     pci_config_set_vendor_id(d->dev.config, PCI_VENDOR_ID_INTEL);
501     pci_config_set_device_id(d->dev.config, PCI_DEVICE_ID_INTEL_82371SB_1);
502     return pci_piix_ide_initfn(d);
503 }
504
505 static int pci_piix4_ide_initfn(PCIDevice *dev)
506 {
507     PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, dev);
508
509     d->type = IDE_TYPE_PIIX4;
510     pci_config_set_vendor_id(d->dev.config, PCI_VENDOR_ID_INTEL);
511     pci_config_set_device_id(d->dev.config, PCI_DEVICE_ID_INTEL_82371AB);
512     return pci_piix_ide_initfn(d);
513 }
514
515 /* hd_table must contain 4 block drivers */
516 /* NOTE: for the PIIX3, the IRQs and IOports are hardcoded */
517 void pci_piix3_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn)
518 {
519     PCIDevice *dev;
520
521     dev = pci_create_simple(bus, devfn, "PIIX3 IDE");
522     pci_ide_create_devs(dev, hd_table);
523 }
524
525 /* hd_table must contain 4 block drivers */
526 /* NOTE: for the PIIX4, the IRQs and IOports are hardcoded */
527 void pci_piix4_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn)
528 {
529     PCIDevice *dev;
530
531     dev = pci_create_simple(bus, devfn, "PIIX4 IDE");
532     pci_ide_create_devs(dev, hd_table);
533 }
534
535 static PCIDeviceInfo piix_ide_info[] = {
536     {
537         .qdev.name    = "PIIX3 IDE",
538         .qdev.size    = sizeof(PCIIDEState),
539         .init         = pci_piix3_ide_initfn,
540     },{
541         .qdev.name    = "PIIX4 IDE",
542         .qdev.size    = sizeof(PCIIDEState),
543         .init         = pci_piix4_ide_initfn,
544     },{
545         .qdev.name    = "CMD646 IDE",
546         .qdev.size    = sizeof(PCIIDEState),
547         .init         = pci_cmd646_ide_initfn,
548         .qdev.props   = (Property[]) {
549             DEFINE_PROP_UINT32("secondary", PCIIDEState, secondary, 0),
550             DEFINE_PROP_END_OF_LIST(),
551         },
552     },{
553         /* end of list */
554     }
555 };
556
557 static void piix_ide_register(void)
558 {
559     pci_qdev_register_many(piix_ide_info);
560 }
561 device_init(piix_ide_register);