Revision 69b91039 hw/ide.c
b/hw/ide.c | ||
---|---|---|
1433 | 1433 |
} |
1434 | 1434 |
} |
1435 | 1435 |
|
1436 |
void ide_init(int iobase, int iobase2, int irq,
|
|
1437 |
BlockDriverState *hd0, BlockDriverState *hd1) |
|
1436 |
static void ide_init2(IDEState *ide_state, int irq,
|
|
1437 |
BlockDriverState *hd0, BlockDriverState *hd1)
|
|
1438 | 1438 |
{ |
1439 |
IDEState *s, *ide_state;
|
|
1439 |
IDEState *s; |
|
1440 | 1440 |
static int drive_serial = 1; |
1441 | 1441 |
int i, cylinders, heads, secs; |
1442 | 1442 |
int64_t nb_sectors; |
1443 | 1443 |
|
1444 |
ide_state = qemu_mallocz(sizeof(IDEState) * 2); |
|
1445 |
if (!ide_state) |
|
1446 |
return; |
|
1447 |
|
|
1448 | 1444 |
for(i = 0; i < 2; i++) { |
1449 | 1445 |
s = ide_state + i; |
1450 | 1446 |
if (i == 0) |
... | ... | |
1483 | 1479 |
s->irq = irq; |
1484 | 1480 |
ide_reset(s); |
1485 | 1481 |
} |
1482 |
} |
|
1483 |
|
|
1484 |
/***********************************************************/ |
|
1485 |
/* ISA IDE definitions */ |
|
1486 |
|
|
1487 |
void isa_ide_init(int iobase, int iobase2, int irq, |
|
1488 |
BlockDriverState *hd0, BlockDriverState *hd1) |
|
1489 |
{ |
|
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 |
|
|
1486 | 1498 |
register_ioport_write(iobase, 8, 1, ide_ioport_write, ide_state); |
1487 | 1499 |
register_ioport_read(iobase, 8, 1, ide_ioport_read, ide_state); |
1488 | 1500 |
if (iobase2) { |
... | ... | |
1496 | 1508 |
register_ioport_write(iobase, 4, 4, ide_data_writel, ide_state); |
1497 | 1509 |
register_ioport_read(iobase, 4, 4, ide_data_readl, ide_state); |
1498 | 1510 |
} |
1511 |
|
|
1512 |
/***********************************************************/ |
|
1513 |
/* PCI IDE definitions */ |
|
1514 |
|
|
1515 |
typedef struct PCIIDEState { |
|
1516 |
PCIDevice dev; |
|
1517 |
IDEState ide_if[4]; |
|
1518 |
} PCIIDEState; |
|
1519 |
|
|
1520 |
static uint32_t ide_read_config(PCIDevice *d, |
|
1521 |
uint32_t address, int len) |
|
1522 |
{ |
|
1523 |
uint32_t val; |
|
1524 |
val = 0; |
|
1525 |
memcpy(&val, d->config + address, len); |
|
1526 |
return val; |
|
1527 |
} |
|
1528 |
|
|
1529 |
static void ide_write_config(PCIDevice *d, |
|
1530 |
uint32_t address, uint32_t val, int len) |
|
1531 |
{ |
|
1532 |
memcpy(d->config + address, &val, len); |
|
1533 |
} |
|
1534 |
|
|
1535 |
static void ide_map(PCIDevice *pci_dev, int region_num, |
|
1536 |
uint32_t addr, uint32_t size, int type) |
|
1537 |
{ |
|
1538 |
PCIIDEState *d = (PCIIDEState *)pci_dev; |
|
1539 |
IDEState *ide_state; |
|
1540 |
|
|
1541 |
if (region_num <= 3) { |
|
1542 |
ide_state = &d->ide_if[(region_num >> 1) * 2]; |
|
1543 |
if (region_num & 1) { |
|
1544 |
register_ioport_read(addr + 2, 1, 1, ide_status_read, ide_state); |
|
1545 |
register_ioport_write(addr + 2, 1, 1, ide_cmd_write, ide_state); |
|
1546 |
} else { |
|
1547 |
register_ioport_write(addr, 8, 1, ide_ioport_write, ide_state); |
|
1548 |
register_ioport_read(addr, 8, 1, ide_ioport_read, ide_state); |
|
1549 |
|
|
1550 |
/* data ports */ |
|
1551 |
register_ioport_write(addr, 2, 2, ide_data_writew, ide_state); |
|
1552 |
register_ioport_read(addr, 2, 2, ide_data_readw, ide_state); |
|
1553 |
register_ioport_write(addr, 4, 4, ide_data_writel, ide_state); |
|
1554 |
register_ioport_read(addr, 4, 4, ide_data_readl, ide_state); |
|
1555 |
} |
|
1556 |
} |
|
1557 |
} |
|
1558 |
|
|
1559 |
/* hd_table must contain 4 block drivers */ |
|
1560 |
void pci_ide_init(BlockDriverState **hd_table) |
|
1561 |
{ |
|
1562 |
PCIIDEState *d; |
|
1563 |
uint8_t *pci_conf; |
|
1564 |
|
|
1565 |
d = (PCIIDEState *)pci_register_device("IDE", sizeof(PCIIDEState), |
|
1566 |
0, -1, |
|
1567 |
ide_read_config, |
|
1568 |
ide_write_config); |
|
1569 |
pci_conf = d->dev.config; |
|
1570 |
pci_conf[0x00] = 0x86; // Intel |
|
1571 |
pci_conf[0x01] = 0x80; |
|
1572 |
pci_conf[0x02] = 0x00; // fake |
|
1573 |
pci_conf[0x03] = 0x01; // fake |
|
1574 |
pci_conf[0x0a] = 0x01; // class_sub = PCI_IDE |
|
1575 |
pci_conf[0x0b] = 0x01; // class_base = PCI_mass_storage |
|
1576 |
pci_conf[0x0e] = 0x80; // header_type = PCI_multifunction, generic |
|
1577 |
|
|
1578 |
pci_conf[0x2c] = 0x86; // subsys vendor |
|
1579 |
pci_conf[0x2d] = 0x80; // subsys vendor |
|
1580 |
pci_conf[0x2e] = 0x00; // fake |
|
1581 |
pci_conf[0x2f] = 0x01; // fake |
|
1582 |
|
|
1583 |
pci_register_io_region((PCIDevice *)d, 0, 0x8, |
|
1584 |
PCI_ADDRESS_SPACE_IO, ide_map); |
|
1585 |
pci_register_io_region((PCIDevice *)d, 1, 0x4, |
|
1586 |
PCI_ADDRESS_SPACE_IO, ide_map); |
|
1587 |
pci_register_io_region((PCIDevice *)d, 2, 0x8, |
|
1588 |
PCI_ADDRESS_SPACE_IO, ide_map); |
|
1589 |
pci_register_io_region((PCIDevice *)d, 3, 0x4, |
|
1590 |
PCI_ADDRESS_SPACE_IO, ide_map); |
|
1591 |
|
|
1592 |
ide_init2(&d->ide_if[0], 14, hd_table[0], hd_table[1]); |
|
1593 |
ide_init2(&d->ide_if[2], 15, hd_table[2], hd_table[3]); |
|
1594 |
} |
Also available in: Unified diff