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,6 +297,7 @@ typedef struct IDEState {
297 int64_t nb_sectors; 297 int64_t nb_sectors;
298 int mult_sectors; 298 int mult_sectors;
299 int irq; 299 int irq;
  300 + PCIDevice *pci_dev;
300 int drive_serial; 301 int drive_serial;
301 /* ide regs */ 302 /* ide regs */
302 uint8_t feature; 303 uint8_t feature;
@@ -463,7 +464,10 @@ static inline void ide_abort_command(IDEState *s) @@ -463,7 +464,10 @@ static inline void ide_abort_command(IDEState *s)
463 static inline void ide_set_irq(IDEState *s) 464 static inline void ide_set_irq(IDEState *s)
464 { 465 {
465 if (!(s->cmd & IDE_CMD_DISABLE_IRQ)) { 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,7 +1173,22 @@ static void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val)
1169 s->status = READY_STAT; 1173 s->status = READY_STAT;
1170 ide_set_irq(s); 1174 ide_set_irq(s);
1171 break; 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 /* ATAPI commands */ 1192 /* ATAPI commands */
1174 case WIN_PIDENTIFY: 1193 case WIN_PIDENTIFY:
1175 if (s->is_cdrom) { 1194 if (s->is_cdrom) {
@@ -1262,7 +1281,10 @@ static uint32_t ide_ioport_read(void *opaque, uint32_t addr1) @@ -1262,7 +1281,10 @@ static uint32_t ide_ioport_read(void *opaque, uint32_t addr1)
1262 ret = 0; 1281 ret = 0;
1263 else 1282 else
1264 ret = s->status; 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 break; 1288 break;
1267 } 1289 }
1268 #ifdef DEBUG_IDE 1290 #ifdef DEBUG_IDE
@@ -1481,20 +1503,8 @@ static void ide_init2(IDEState *ide_state, int irq, @@ -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 register_ioport_write(iobase, 8, 1, ide_ioport_write, ide_state); 1508 register_ioport_write(iobase, 8, 1, ide_ioport_write, ide_state);
1499 register_ioport_read(iobase, 8, 1, ide_ioport_read, ide_state); 1509 register_ioport_read(iobase, 8, 1, ide_ioport_read, ide_state);
1500 if (iobase2) { 1510 if (iobase2) {
@@ -1510,6 +1520,22 @@ void isa_ide_init(int iobase, int iobase2, int irq, @@ -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 /* PCI IDE definitions */ 1539 /* PCI IDE definitions */
1514 1540
1515 typedef struct PCIIDEState { 1541 typedef struct PCIIDEState {
@@ -1546,7 +1572,8 @@ void pci_ide_init(BlockDriverState **hd_table) @@ -1546,7 +1572,8 @@ void pci_ide_init(BlockDriverState **hd_table)
1546 { 1572 {
1547 PCIIDEState *d; 1573 PCIIDEState *d;
1548 uint8_t *pci_conf; 1574 uint8_t *pci_conf;
1549 - 1575 + int i;
  1576 +
1550 d = (PCIIDEState *)pci_register_device("IDE", sizeof(PCIIDEState), 1577 d = (PCIIDEState *)pci_register_device("IDE", sizeof(PCIIDEState),
1551 0, -1, 1578 0, -1,
1552 NULL, NULL); 1579 NULL, NULL);
@@ -1573,6 +1600,38 @@ void pci_ide_init(BlockDriverState **hd_table) @@ -1573,6 +1600,38 @@ void pci_ide_init(BlockDriverState **hd_table)
1573 pci_register_io_region((PCIDevice *)d, 3, 0x4, 1600 pci_register_io_region((PCIDevice *)d, 3, 0x4,
1574 PCI_ADDRESS_SPACE_IO, ide_map); 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 ide_init2(&d->ide_if[0], 14, hd_table[0], hd_table[1]); 1633 ide_init2(&d->ide_if[0], 14, hd_table[0], hd_table[1]);
1577 ide_init2(&d->ide_if[2], 15, hd_table[2], hd_table[3]); 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 }