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 | } | ... | ... |