Commit 34e538ae5d87d263c024d1b803ccef4983807556

Authored by bellard
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 }
... ...