Commit 34e538ae5d87d263c024d1b803ccef4983807556
1 parent
9995c51f
added PIIX3 like IDE controller - PCI irq generation - SETFEATURES IDE command support
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@852 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
76 additions
and
17 deletions
hw/ide.c
... | ... | @@ -297,6 +297,7 @@ typedef struct IDEState { |
297 | 297 | int64_t nb_sectors; |
298 | 298 | int mult_sectors; |
299 | 299 | int irq; |
300 | + PCIDevice *pci_dev; | |
300 | 301 | int drive_serial; |
301 | 302 | /* ide regs */ |
302 | 303 | uint8_t feature; |
... | ... | @@ -463,7 +464,10 @@ static inline void ide_abort_command(IDEState *s) |
463 | 464 | static inline void ide_set_irq(IDEState *s) |
464 | 465 | { |
465 | 466 | if (!(s->cmd & IDE_CMD_DISABLE_IRQ)) { |
466 | - pic_set_irq(s->irq, 1); | |
467 | + if (s->irq == 16) | |
468 | + pci_set_irq(s->pci_dev, 0, 1); | |
469 | + else | |
470 | + pic_set_irq(s->irq, 1); | |
467 | 471 | } |
468 | 472 | } |
469 | 473 | |
... | ... | @@ -1169,7 +1173,22 @@ static void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val) |
1169 | 1173 | s->status = READY_STAT; |
1170 | 1174 | ide_set_irq(s); |
1171 | 1175 | break; |
1172 | - | |
1176 | + case WIN_SETFEATURES: | |
1177 | + if (!s->bs) | |
1178 | + goto abort_cmd; | |
1179 | + /* XXX: valid for CDROM ? */ | |
1180 | + switch(s->feature) { | |
1181 | + case 0x02: /* write cache enable */ | |
1182 | + case 0x82: /* write cache disable */ | |
1183 | + case 0xaa: /* read look-ahead enable */ | |
1184 | + case 0x55: /* read look-ahead disable */ | |
1185 | + s->status = READY_STAT; | |
1186 | + ide_set_irq(s); | |
1187 | + break; | |
1188 | + default: | |
1189 | + goto abort_cmd; | |
1190 | + } | |
1191 | + break; | |
1173 | 1192 | /* ATAPI commands */ |
1174 | 1193 | case WIN_PIDENTIFY: |
1175 | 1194 | if (s->is_cdrom) { |
... | ... | @@ -1262,7 +1281,10 @@ static uint32_t ide_ioport_read(void *opaque, uint32_t addr1) |
1262 | 1281 | ret = 0; |
1263 | 1282 | else |
1264 | 1283 | ret = s->status; |
1265 | - pic_set_irq(s->irq, 0); | |
1284 | + if (s->irq == 16) | |
1285 | + pci_set_irq(s->pci_dev, 0, 0); | |
1286 | + else | |
1287 | + pic_set_irq(s->irq, 0); | |
1266 | 1288 | break; |
1267 | 1289 | } |
1268 | 1290 | #ifdef DEBUG_IDE |
... | ... | @@ -1481,20 +1503,8 @@ static void ide_init2(IDEState *ide_state, int irq, |
1481 | 1503 | } |
1482 | 1504 | } |
1483 | 1505 | |
1484 | -/***********************************************************/ | |
1485 | -/* ISA IDE definitions */ | |
1486 | - | |
1487 | -void isa_ide_init(int iobase, int iobase2, int irq, | |
1488 | - BlockDriverState *hd0, BlockDriverState *hd1) | |
1506 | +static void ide_init_ioport(IDEState *ide_state, int iobase, int iobase2) | |
1489 | 1507 | { |
1490 | - IDEState *ide_state; | |
1491 | - | |
1492 | - ide_state = qemu_mallocz(sizeof(IDEState) * 2); | |
1493 | - if (!ide_state) | |
1494 | - return; | |
1495 | - | |
1496 | - ide_init2(ide_state, irq, hd0, hd1); | |
1497 | - | |
1498 | 1508 | register_ioport_write(iobase, 8, 1, ide_ioport_write, ide_state); |
1499 | 1509 | register_ioport_read(iobase, 8, 1, ide_ioport_read, ide_state); |
1500 | 1510 | if (iobase2) { |
... | ... | @@ -1510,6 +1520,22 @@ void isa_ide_init(int iobase, int iobase2, int irq, |
1510 | 1520 | } |
1511 | 1521 | |
1512 | 1522 | /***********************************************************/ |
1523 | +/* ISA IDE definitions */ | |
1524 | + | |
1525 | +void isa_ide_init(int iobase, int iobase2, int irq, | |
1526 | + BlockDriverState *hd0, BlockDriverState *hd1) | |
1527 | +{ | |
1528 | + IDEState *ide_state; | |
1529 | + | |
1530 | + ide_state = qemu_mallocz(sizeof(IDEState) * 2); | |
1531 | + if (!ide_state) | |
1532 | + return; | |
1533 | + | |
1534 | + ide_init2(ide_state, irq, hd0, hd1); | |
1535 | + ide_init_ioport(ide_state, iobase, iobase2); | |
1536 | +} | |
1537 | + | |
1538 | +/***********************************************************/ | |
1513 | 1539 | /* PCI IDE definitions */ |
1514 | 1540 | |
1515 | 1541 | typedef struct PCIIDEState { |
... | ... | @@ -1546,7 +1572,8 @@ void pci_ide_init(BlockDriverState **hd_table) |
1546 | 1572 | { |
1547 | 1573 | PCIIDEState *d; |
1548 | 1574 | uint8_t *pci_conf; |
1549 | - | |
1575 | + int i; | |
1576 | + | |
1550 | 1577 | d = (PCIIDEState *)pci_register_device("IDE", sizeof(PCIIDEState), |
1551 | 1578 | 0, -1, |
1552 | 1579 | NULL, NULL); |
... | ... | @@ -1573,6 +1600,38 @@ void pci_ide_init(BlockDriverState **hd_table) |
1573 | 1600 | pci_register_io_region((PCIDevice *)d, 3, 0x4, |
1574 | 1601 | PCI_ADDRESS_SPACE_IO, ide_map); |
1575 | 1602 | |
1603 | + pci_conf[0x3d] = 0x01; // interrupt on pin 1 | |
1604 | + | |
1605 | + for(i = 0; i < 4; i++) | |
1606 | + d->ide_if[i].pci_dev = (PCIDevice *)d; | |
1607 | + ide_init2(&d->ide_if[0], 16, hd_table[0], hd_table[1]); | |
1608 | + ide_init2(&d->ide_if[2], 16, hd_table[2], hd_table[3]); | |
1609 | +} | |
1610 | + | |
1611 | +/* hd_table must contain 4 block drivers */ | |
1612 | +/* NOTE: for the PIIX3, the IRQs and IOports are hardcoded */ | |
1613 | +void pci_piix3_ide_init(BlockDriverState **hd_table) | |
1614 | +{ | |
1615 | + PCIIDEState *d; | |
1616 | + uint8_t *pci_conf; | |
1617 | + | |
1618 | + /* register a function 1 of PIIX3 */ | |
1619 | + d = (PCIIDEState *)pci_register_device("PIIX3 IDE", sizeof(PCIIDEState), | |
1620 | + 0, ((PCIDevice *)piix3_state)->devfn + 1, | |
1621 | + NULL, NULL); | |
1622 | + pci_conf = d->dev.config; | |
1623 | + pci_conf[0x00] = 0x86; // Intel | |
1624 | + pci_conf[0x01] = 0x80; | |
1625 | + pci_conf[0x02] = 0x10; | |
1626 | + pci_conf[0x03] = 0x70; | |
1627 | + pci_conf[0x0a] = 0x01; // class_sub = PCI_IDE | |
1628 | + pci_conf[0x0b] = 0x01; // class_base = PCI_mass_storage | |
1629 | + pci_conf[0x0e] = 0x00; // header_type | |
1630 | + | |
1631 | + /* XXX: must add BMDMA support to be fully compliant */ | |
1632 | + | |
1576 | 1633 | ide_init2(&d->ide_if[0], 14, hd_table[0], hd_table[1]); |
1577 | 1634 | ide_init2(&d->ide_if[2], 15, hd_table[2], hd_table[3]); |
1635 | + ide_init_ioport(&d->ide_if[0], 0x1f0, 0x3f6); | |
1636 | + ide_init_ioport(&d->ide_if[2], 0x170, 0x376); | |
1578 | 1637 | } | ... | ... |