Commit 5457c8ceebafae8d3ff929d22bb32d1edb2250dd
1 parent
0aa6a4a2
added CMD646 PCI IDE controller support - better IRQ handling - added IDE flush …
…cache command - added work around for Darwin/PPC to select IDE drive git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1449 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
165 additions
and
70 deletions
hw/ide.c
| @@ -296,8 +296,9 @@ typedef struct IDEState { | @@ -296,8 +296,9 @@ typedef struct IDEState { | ||
| 296 | int cylinders, heads, sectors; | 296 | int cylinders, heads, sectors; |
| 297 | int64_t nb_sectors; | 297 | int64_t nb_sectors; |
| 298 | int mult_sectors; | 298 | int mult_sectors; |
| 299 | + SetIRQFunc *set_irq; | ||
| 300 | + void *irq_opaque; | ||
| 299 | int irq; | 301 | int irq; |
| 300 | - openpic_t *openpic; | ||
| 301 | PCIDevice *pci_dev; | 302 | PCIDevice *pci_dev; |
| 302 | struct BMDMAState *bmdma; | 303 | struct BMDMAState *bmdma; |
| 303 | int drive_serial; | 304 | int drive_serial; |
| @@ -342,6 +343,18 @@ typedef struct IDEState { | @@ -342,6 +343,18 @@ typedef struct IDEState { | ||
| 342 | #define BM_CMD_START 0x01 | 343 | #define BM_CMD_START 0x01 |
| 343 | #define BM_CMD_READ 0x08 | 344 | #define BM_CMD_READ 0x08 |
| 344 | 345 | ||
| 346 | +#define IDE_TYPE_PIIX3 0 | ||
| 347 | +#define IDE_TYPE_CMD646 1 | ||
| 348 | + | ||
| 349 | +/* CMD646 specific */ | ||
| 350 | +#define MRDMODE 0x71 | ||
| 351 | +#define MRDMODE_INTR_CH0 0x04 | ||
| 352 | +#define MRDMODE_INTR_CH1 0x08 | ||
| 353 | +#define MRDMODE_BLK_CH0 0x10 | ||
| 354 | +#define MRDMODE_BLK_CH1 0x20 | ||
| 355 | +#define UDIDETCR0 0x73 | ||
| 356 | +#define UDIDETCR1 0x7B | ||
| 357 | + | ||
| 345 | typedef int IDEDMAFunc(IDEState *s, | 358 | typedef int IDEDMAFunc(IDEState *s, |
| 346 | target_phys_addr_t phys_addr, | 359 | target_phys_addr_t phys_addr, |
| 347 | int transfer_size1); | 360 | int transfer_size1); |
| @@ -350,6 +363,8 @@ typedef struct BMDMAState { | @@ -350,6 +363,8 @@ typedef struct BMDMAState { | ||
| 350 | uint8_t cmd; | 363 | uint8_t cmd; |
| 351 | uint8_t status; | 364 | uint8_t status; |
| 352 | uint32_t addr; | 365 | uint32_t addr; |
| 366 | + | ||
| 367 | + struct PCIIDEState *pci_dev; | ||
| 353 | /* current transfer state */ | 368 | /* current transfer state */ |
| 354 | IDEState *ide_if; | 369 | IDEState *ide_if; |
| 355 | IDEDMAFunc *dma_cb; | 370 | IDEDMAFunc *dma_cb; |
| @@ -359,6 +374,7 @@ typedef struct PCIIDEState { | @@ -359,6 +374,7 @@ typedef struct PCIIDEState { | ||
| 359 | PCIDevice dev; | 374 | PCIDevice dev; |
| 360 | IDEState ide_if[4]; | 375 | IDEState ide_if[4]; |
| 361 | BMDMAState bmdma[2]; | 376 | BMDMAState bmdma[2]; |
| 377 | + int type; /* see IDE_TYPE_xxx */ | ||
| 362 | } PCIIDEState; | 378 | } PCIIDEState; |
| 363 | 379 | ||
| 364 | static void ide_dma_start(IDEState *s, IDEDMAFunc *dma_cb); | 380 | static void ide_dma_start(IDEState *s, IDEDMAFunc *dma_cb); |
| @@ -502,17 +518,10 @@ static inline void ide_set_irq(IDEState *s) | @@ -502,17 +518,10 @@ static inline void ide_set_irq(IDEState *s) | ||
| 502 | { | 518 | { |
| 503 | BMDMAState *bm = s->bmdma; | 519 | BMDMAState *bm = s->bmdma; |
| 504 | if (!(s->cmd & IDE_CMD_DISABLE_IRQ)) { | 520 | if (!(s->cmd & IDE_CMD_DISABLE_IRQ)) { |
| 505 | - if (bm) | 521 | + if (bm) { |
| 506 | bm->status |= BM_STATUS_INT; | 522 | bm->status |= BM_STATUS_INT; |
| 507 | -#ifdef TARGET_PPC | ||
| 508 | - if (s->openpic) | ||
| 509 | - openpic_set_irq(s->openpic, s->irq, 1); | ||
| 510 | - else | ||
| 511 | -#endif | ||
| 512 | - if (s->irq == 16) | ||
| 513 | - pci_set_irq(s->pci_dev, 0, 1); | ||
| 514 | - else | ||
| 515 | - pic_set_irq(s->irq, 1); | 523 | + } |
| 524 | + s->set_irq(s->irq_opaque, s->irq, 1); | ||
| 516 | } | 525 | } |
| 517 | } | 526 | } |
| 518 | 527 | ||
| @@ -814,7 +823,8 @@ static void cd_read_sector(BlockDriverState *bs, int lba, uint8_t *buf, | @@ -814,7 +823,8 @@ static void cd_read_sector(BlockDriverState *bs, int lba, uint8_t *buf, | ||
| 814 | case 2352: | 823 | case 2352: |
| 815 | /* sync bytes */ | 824 | /* sync bytes */ |
| 816 | buf[0] = 0x00; | 825 | buf[0] = 0x00; |
| 817 | - memset(buf + 1, 0xff, 11); | 826 | + memset(buf + 1, 0xff, 10); |
| 827 | + buf[11] = 0x00; | ||
| 818 | buf += 12; | 828 | buf += 12; |
| 819 | /* MSF */ | 829 | /* MSF */ |
| 820 | lba_to_msf(buf, lba); | 830 | lba_to_msf(buf, lba); |
| @@ -942,6 +952,9 @@ static int ide_atapi_cmd_read_dma_cb(IDEState *s, | @@ -942,6 +952,9 @@ static int ide_atapi_cmd_read_dma_cb(IDEState *s, | ||
| 942 | 952 | ||
| 943 | transfer_size = transfer_size1; | 953 | transfer_size = transfer_size1; |
| 944 | while (transfer_size > 0) { | 954 | while (transfer_size > 0) { |
| 955 | +#ifdef DEBUG_IDE_ATAPI | ||
| 956 | + printf("transfer_size: %d phys_addr=%08x\n", transfer_size, phys_addr); | ||
| 957 | +#endif | ||
| 945 | if (s->packet_transfer_size <= 0) | 958 | if (s->packet_transfer_size <= 0) |
| 946 | break; | 959 | break; |
| 947 | len = s->cd_sector_size - s->io_buffer_index; | 960 | len = s->cd_sector_size - s->io_buffer_index; |
| @@ -1019,9 +1032,8 @@ static int cdrom_read_toc(IDEState *s, uint8_t *buf, int msf, int start_track) | @@ -1019,9 +1032,8 @@ static int cdrom_read_toc(IDEState *s, uint8_t *buf, int msf, int start_track) | ||
| 1019 | *q++ = 0; /* reserved */ | 1032 | *q++ = 0; /* reserved */ |
| 1020 | if (msf) { | 1033 | if (msf) { |
| 1021 | *q++ = 0; /* reserved */ | 1034 | *q++ = 0; /* reserved */ |
| 1022 | - *q++ = 0; /* minute */ | ||
| 1023 | - *q++ = 2; /* second */ | ||
| 1024 | - *q++ = 0; /* frame */ | 1035 | + lba_to_msf(q, 0); |
| 1036 | + q += 3; | ||
| 1025 | } else { | 1037 | } else { |
| 1026 | /* sector 0 */ | 1038 | /* sector 0 */ |
| 1027 | cpu_to_ube32(q, 0); | 1039 | cpu_to_ube32(q, 0); |
| @@ -1476,6 +1488,11 @@ static void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val) | @@ -1476,6 +1488,11 @@ static void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val) | ||
| 1476 | unit = (val >> 4) & 1; | 1488 | unit = (val >> 4) & 1; |
| 1477 | s = ide_if + unit; | 1489 | s = ide_if + unit; |
| 1478 | ide_if->cur_drive = s; | 1490 | ide_if->cur_drive = s; |
| 1491 | +#ifdef TARGET_PPC | ||
| 1492 | + /* XXX: currently a workaround for Darwin/PPC. Need to check | ||
| 1493 | + the IDE spec to see if it is correct */ | ||
| 1494 | + ide_set_signature(s); | ||
| 1495 | +#endif | ||
| 1479 | break; | 1496 | break; |
| 1480 | default: | 1497 | default: |
| 1481 | case 7: | 1498 | case 7: |
| @@ -1596,6 +1613,7 @@ static void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val) | @@ -1596,6 +1613,7 @@ static void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val) | ||
| 1596 | break; | 1613 | break; |
| 1597 | case WIN_STANDBYNOW1: | 1614 | case WIN_STANDBYNOW1: |
| 1598 | case WIN_IDLEIMMEDIATE: | 1615 | case WIN_IDLEIMMEDIATE: |
| 1616 | + case WIN_FLUSH_CACHE: | ||
| 1599 | s->status = READY_STAT; | 1617 | s->status = READY_STAT; |
| 1600 | ide_set_irq(s); | 1618 | ide_set_irq(s); |
| 1601 | break; | 1619 | break; |
| @@ -1697,15 +1715,7 @@ static uint32_t ide_ioport_read(void *opaque, uint32_t addr1) | @@ -1697,15 +1715,7 @@ static uint32_t ide_ioport_read(void *opaque, uint32_t addr1) | ||
| 1697 | ret = 0; | 1715 | ret = 0; |
| 1698 | else | 1716 | else |
| 1699 | ret = s->status; | 1717 | ret = s->status; |
| 1700 | -#ifdef TARGET_PPC | ||
| 1701 | - if (s->openpic) | ||
| 1702 | - openpic_set_irq(s->openpic, s->irq, 0); | ||
| 1703 | - else | ||
| 1704 | -#endif | ||
| 1705 | - if (s->irq == 16) | ||
| 1706 | - pci_set_irq(s->pci_dev, 0, 0); | ||
| 1707 | - else | ||
| 1708 | - pic_set_irq(s->irq, 0); | 1718 | + s->set_irq(s->irq_opaque, s->irq, 0); |
| 1709 | break; | 1719 | break; |
| 1710 | } | 1720 | } |
| 1711 | #ifdef DEBUG_IDE | 1721 | #ifdef DEBUG_IDE |
| @@ -1898,8 +1908,9 @@ static int guess_disk_lchs(IDEState *s, | @@ -1898,8 +1908,9 @@ static int guess_disk_lchs(IDEState *s, | ||
| 1898 | return -1; | 1908 | return -1; |
| 1899 | } | 1909 | } |
| 1900 | 1910 | ||
| 1901 | -static void ide_init2(IDEState *ide_state, int irq, | ||
| 1902 | - BlockDriverState *hd0, BlockDriverState *hd1) | 1911 | +static void ide_init2(IDEState *ide_state, |
| 1912 | + BlockDriverState *hd0, BlockDriverState *hd1, | ||
| 1913 | + SetIRQFunc *set_irq, void *irq_opaque, int irq) | ||
| 1903 | { | 1914 | { |
| 1904 | IDEState *s; | 1915 | IDEState *s; |
| 1905 | static int drive_serial = 1; | 1916 | static int drive_serial = 1; |
| @@ -1960,6 +1971,8 @@ static void ide_init2(IDEState *ide_state, int irq, | @@ -1960,6 +1971,8 @@ static void ide_init2(IDEState *ide_state, int irq, | ||
| 1960 | } | 1971 | } |
| 1961 | } | 1972 | } |
| 1962 | s->drive_serial = drive_serial++; | 1973 | s->drive_serial = drive_serial++; |
| 1974 | + s->set_irq = set_irq; | ||
| 1975 | + s->irq_opaque = irq_opaque; | ||
| 1963 | s->irq = irq; | 1976 | s->irq = irq; |
| 1964 | s->sector_write_timer = qemu_new_timer(vm_clock, | 1977 | s->sector_write_timer = qemu_new_timer(vm_clock, |
| 1965 | ide_sector_write_timer_cb, s); | 1978 | ide_sector_write_timer_cb, s); |
| @@ -1995,13 +2008,15 @@ void isa_ide_init(int iobase, int iobase2, int irq, | @@ -1995,13 +2008,15 @@ void isa_ide_init(int iobase, int iobase2, int irq, | ||
| 1995 | if (!ide_state) | 2008 | if (!ide_state) |
| 1996 | return; | 2009 | return; |
| 1997 | 2010 | ||
| 1998 | - ide_init2(ide_state, irq, hd0, hd1); | 2011 | + ide_init2(ide_state, hd0, hd1, pic_set_irq_new, NULL, irq); |
| 1999 | ide_init_ioport(ide_state, iobase, iobase2); | 2012 | ide_init_ioport(ide_state, iobase, iobase2); |
| 2000 | } | 2013 | } |
| 2001 | 2014 | ||
| 2002 | /***********************************************************/ | 2015 | /***********************************************************/ |
| 2003 | /* PCI IDE definitions */ | 2016 | /* PCI IDE definitions */ |
| 2004 | 2017 | ||
| 2018 | +static void cmd646_update_irq(PCIIDEState *d); | ||
| 2019 | + | ||
| 2005 | static void ide_map(PCIDevice *pci_dev, int region_num, | 2020 | static void ide_map(PCIDevice *pci_dev, int region_num, |
| 2006 | uint32_t addr, uint32_t size, int type) | 2021 | uint32_t addr, uint32_t size, int type) |
| 2007 | { | 2022 | { |
| @@ -2082,17 +2097,6 @@ static void ide_dma_start(IDEState *s, IDEDMAFunc *dma_cb) | @@ -2082,17 +2097,6 @@ static void ide_dma_start(IDEState *s, IDEDMAFunc *dma_cb) | ||
| 2082 | } | 2097 | } |
| 2083 | } | 2098 | } |
| 2084 | 2099 | ||
| 2085 | -static uint32_t bmdma_cmd_readb(void *opaque, uint32_t addr) | ||
| 2086 | -{ | ||
| 2087 | - BMDMAState *bm = opaque; | ||
| 2088 | - uint32_t val; | ||
| 2089 | - val = bm->cmd; | ||
| 2090 | -#ifdef DEBUG_IDE | ||
| 2091 | - printf("%s: 0x%08x\n", __func__, val); | ||
| 2092 | -#endif | ||
| 2093 | - return val; | ||
| 2094 | -} | ||
| 2095 | - | ||
| 2096 | static void bmdma_cmd_writeb(void *opaque, uint32_t addr, uint32_t val) | 2100 | static void bmdma_cmd_writeb(void *opaque, uint32_t addr, uint32_t val) |
| 2097 | { | 2101 | { |
| 2098 | BMDMAState *bm = opaque; | 2102 | BMDMAState *bm = opaque; |
| @@ -2112,24 +2116,77 @@ static void bmdma_cmd_writeb(void *opaque, uint32_t addr, uint32_t val) | @@ -2112,24 +2116,77 @@ static void bmdma_cmd_writeb(void *opaque, uint32_t addr, uint32_t val) | ||
| 2112 | } | 2116 | } |
| 2113 | } | 2117 | } |
| 2114 | 2118 | ||
| 2115 | -static uint32_t bmdma_status_readb(void *opaque, uint32_t addr) | 2119 | +static uint32_t bmdma_readb(void *opaque, uint32_t addr) |
| 2116 | { | 2120 | { |
| 2117 | BMDMAState *bm = opaque; | 2121 | BMDMAState *bm = opaque; |
| 2122 | + PCIIDEState *pci_dev; | ||
| 2118 | uint32_t val; | 2123 | uint32_t val; |
| 2119 | - val = bm->status; | 2124 | + |
| 2125 | + switch(addr & 3) { | ||
| 2126 | + case 0: | ||
| 2127 | + val = bm->cmd; | ||
| 2128 | + break; | ||
| 2129 | + case 1: | ||
| 2130 | + pci_dev = bm->pci_dev; | ||
| 2131 | + if (pci_dev->type == IDE_TYPE_CMD646) { | ||
| 2132 | + val = pci_dev->dev.config[MRDMODE]; | ||
| 2133 | + } else { | ||
| 2134 | + val = 0xff; | ||
| 2135 | + } | ||
| 2136 | + break; | ||
| 2137 | + case 2: | ||
| 2138 | + val = bm->status; | ||
| 2139 | + break; | ||
| 2140 | + case 3: | ||
| 2141 | + pci_dev = bm->pci_dev; | ||
| 2142 | + if (pci_dev->type == IDE_TYPE_CMD646) { | ||
| 2143 | + if (bm == &pci_dev->bmdma[0]) | ||
| 2144 | + val = pci_dev->dev.config[UDIDETCR0]; | ||
| 2145 | + else | ||
| 2146 | + val = pci_dev->dev.config[UDIDETCR1]; | ||
| 2147 | + } else { | ||
| 2148 | + val = 0xff; | ||
| 2149 | + } | ||
| 2150 | + break; | ||
| 2151 | + default: | ||
| 2152 | + val = 0xff; | ||
| 2153 | + break; | ||
| 2154 | + } | ||
| 2120 | #ifdef DEBUG_IDE | 2155 | #ifdef DEBUG_IDE |
| 2121 | - printf("%s: 0x%08x\n", __func__, val); | 2156 | + printf("bmdma: readb 0x%02x : 0x%02x\n", addr, val); |
| 2122 | #endif | 2157 | #endif |
| 2123 | return val; | 2158 | return val; |
| 2124 | } | 2159 | } |
| 2125 | 2160 | ||
| 2126 | -static void bmdma_status_writeb(void *opaque, uint32_t addr, uint32_t val) | 2161 | +static void bmdma_writeb(void *opaque, uint32_t addr, uint32_t val) |
| 2127 | { | 2162 | { |
| 2128 | BMDMAState *bm = opaque; | 2163 | BMDMAState *bm = opaque; |
| 2164 | + PCIIDEState *pci_dev; | ||
| 2129 | #ifdef DEBUG_IDE | 2165 | #ifdef DEBUG_IDE |
| 2130 | - printf("%s: 0x%08x\n", __func__, val); | 2166 | + printf("bmdma: writeb 0x%02x : 0x%02x\n", addr, val); |
| 2131 | #endif | 2167 | #endif |
| 2132 | - bm->status = (val & 0x60) | (bm->status & 1) | (bm->status & ~val & 0x06); | 2168 | + switch(addr & 3) { |
| 2169 | + case 1: | ||
| 2170 | + pci_dev = bm->pci_dev; | ||
| 2171 | + if (pci_dev->type == IDE_TYPE_CMD646) { | ||
| 2172 | + pci_dev->dev.config[MRDMODE] = | ||
| 2173 | + (pci_dev->dev.config[MRDMODE] & ~0x30) | (val & 0x30); | ||
| 2174 | + cmd646_update_irq(pci_dev); | ||
| 2175 | + } | ||
| 2176 | + break; | ||
| 2177 | + case 2: | ||
| 2178 | + bm->status = (val & 0x60) | (bm->status & 1) | (bm->status & ~val & 0x06); | ||
| 2179 | + break; | ||
| 2180 | + case 3: | ||
| 2181 | + pci_dev = bm->pci_dev; | ||
| 2182 | + if (pci_dev->type == IDE_TYPE_CMD646) { | ||
| 2183 | + if (bm == &pci_dev->bmdma[0]) | ||
| 2184 | + pci_dev->dev.config[UDIDETCR0] = val; | ||
| 2185 | + else | ||
| 2186 | + pci_dev->dev.config[UDIDETCR1] = val; | ||
| 2187 | + } | ||
| 2188 | + break; | ||
| 2189 | + } | ||
| 2133 | } | 2190 | } |
| 2134 | 2191 | ||
| 2135 | static uint32_t bmdma_addr_readl(void *opaque, uint32_t addr) | 2192 | static uint32_t bmdma_addr_readl(void *opaque, uint32_t addr) |
| @@ -2162,12 +2219,12 @@ static void bmdma_map(PCIDevice *pci_dev, int region_num, | @@ -2162,12 +2219,12 @@ static void bmdma_map(PCIDevice *pci_dev, int region_num, | ||
| 2162 | BMDMAState *bm = &d->bmdma[i]; | 2219 | BMDMAState *bm = &d->bmdma[i]; |
| 2163 | d->ide_if[2 * i].bmdma = bm; | 2220 | d->ide_if[2 * i].bmdma = bm; |
| 2164 | d->ide_if[2 * i + 1].bmdma = bm; | 2221 | d->ide_if[2 * i + 1].bmdma = bm; |
| 2165 | - | 2222 | + bm->pci_dev = (PCIIDEState *)pci_dev; |
| 2223 | + | ||
| 2166 | register_ioport_write(addr, 1, 1, bmdma_cmd_writeb, bm); | 2224 | register_ioport_write(addr, 1, 1, bmdma_cmd_writeb, bm); |
| 2167 | - register_ioport_read(addr, 1, 1, bmdma_cmd_readb, bm); | ||
| 2168 | 2225 | ||
| 2169 | - register_ioport_write(addr + 2, 1, 1, bmdma_status_writeb, bm); | ||
| 2170 | - register_ioport_read(addr + 2, 1, 1, bmdma_status_readb, bm); | 2226 | + register_ioport_write(addr + 1, 3, 1, bmdma_writeb, bm); |
| 2227 | + register_ioport_read(addr, 4, 1, bmdma_readb, bm); | ||
| 2171 | 2228 | ||
| 2172 | register_ioport_write(addr + 4, 4, 4, bmdma_addr_writel, bm); | 2229 | register_ioport_write(addr + 4, 4, 4, bmdma_addr_writel, bm); |
| 2173 | register_ioport_read(addr + 4, 4, 4, bmdma_addr_readl, bm); | 2230 | register_ioport_read(addr + 4, 4, 4, bmdma_addr_readl, bm); |
| @@ -2175,29 +2232,62 @@ static void bmdma_map(PCIDevice *pci_dev, int region_num, | @@ -2175,29 +2232,62 @@ static void bmdma_map(PCIDevice *pci_dev, int region_num, | ||
| 2175 | } | 2232 | } |
| 2176 | } | 2233 | } |
| 2177 | 2234 | ||
| 2178 | -/* hd_table must contain 4 block drivers */ | ||
| 2179 | -void pci_ide_init(PCIBus *bus, BlockDriverState **hd_table) | 2235 | +/* XXX: call it also when the MRDMODE is changed from the PCI config |
| 2236 | + registers */ | ||
| 2237 | +static void cmd646_update_irq(PCIIDEState *d) | ||
| 2238 | +{ | ||
| 2239 | + int pci_level; | ||
| 2240 | + pci_level = ((d->dev.config[MRDMODE] & MRDMODE_INTR_CH0) && | ||
| 2241 | + !(d->dev.config[MRDMODE] & MRDMODE_BLK_CH0)) || | ||
| 2242 | + ((d->dev.config[MRDMODE] & MRDMODE_INTR_CH1) && | ||
| 2243 | + !(d->dev.config[MRDMODE] & MRDMODE_BLK_CH1)); | ||
| 2244 | + pci_set_irq((PCIDevice *)d, 0, pci_level); | ||
| 2245 | +} | ||
| 2246 | + | ||
| 2247 | +/* the PCI irq level is the logical OR of the two channels */ | ||
| 2248 | +static void cmd646_set_irq(void *opaque, int channel, int level) | ||
| 2249 | +{ | ||
| 2250 | + PCIIDEState *d = opaque; | ||
| 2251 | + int irq_mask; | ||
| 2252 | + | ||
| 2253 | + irq_mask = MRDMODE_INTR_CH0 << channel; | ||
| 2254 | + if (level) | ||
| 2255 | + d->dev.config[MRDMODE] |= irq_mask; | ||
| 2256 | + else | ||
| 2257 | + d->dev.config[MRDMODE] &= ~irq_mask; | ||
| 2258 | + cmd646_update_irq(d); | ||
| 2259 | +} | ||
| 2260 | + | ||
| 2261 | +/* CMD646 PCI IDE controller */ | ||
| 2262 | +void pci_cmd646_ide_init(PCIBus *bus, BlockDriverState **hd_table, | ||
| 2263 | + int secondary_ide_enabled) | ||
| 2180 | { | 2264 | { |
| 2181 | PCIIDEState *d; | 2265 | PCIIDEState *d; |
| 2182 | uint8_t *pci_conf; | 2266 | uint8_t *pci_conf; |
| 2183 | int i; | 2267 | int i; |
| 2184 | 2268 | ||
| 2185 | - d = (PCIIDEState *)pci_register_device(bus, "IDE", sizeof(PCIIDEState), | 2269 | + d = (PCIIDEState *)pci_register_device(bus, "CMD646 IDE", |
| 2270 | + sizeof(PCIIDEState), | ||
| 2186 | -1, | 2271 | -1, |
| 2187 | NULL, NULL); | 2272 | NULL, NULL); |
| 2273 | + d->type = IDE_TYPE_CMD646; | ||
| 2188 | pci_conf = d->dev.config; | 2274 | pci_conf = d->dev.config; |
| 2189 | - pci_conf[0x00] = 0x86; // Intel | ||
| 2190 | - pci_conf[0x01] = 0x80; | ||
| 2191 | - pci_conf[0x02] = 0x00; // fake | ||
| 2192 | - pci_conf[0x03] = 0x01; // fake | 2275 | + pci_conf[0x00] = 0x95; // CMD646 |
| 2276 | + pci_conf[0x01] = 0x10; | ||
| 2277 | + pci_conf[0x02] = 0x46; | ||
| 2278 | + pci_conf[0x03] = 0x06; | ||
| 2279 | + | ||
| 2280 | + pci_conf[0x08] = 0x07; // IDE controller revision | ||
| 2281 | + pci_conf[0x09] = 0x8f; | ||
| 2282 | + | ||
| 2193 | pci_conf[0x0a] = 0x01; // class_sub = PCI_IDE | 2283 | pci_conf[0x0a] = 0x01; // class_sub = PCI_IDE |
| 2194 | pci_conf[0x0b] = 0x01; // class_base = PCI_mass_storage | 2284 | pci_conf[0x0b] = 0x01; // class_base = PCI_mass_storage |
| 2195 | - pci_conf[0x0e] = 0x80; // header_type = PCI_multifunction, generic | ||
| 2196 | - | ||
| 2197 | - pci_conf[0x2c] = 0x86; // subsys vendor | ||
| 2198 | - pci_conf[0x2d] = 0x80; // subsys vendor | ||
| 2199 | - pci_conf[0x2e] = 0x00; // fake | ||
| 2200 | - pci_conf[0x2f] = 0x01; // fake | 2285 | + pci_conf[0x0e] = 0x00; // header_type |
| 2286 | + | ||
| 2287 | + if (secondary_ide_enabled) { | ||
| 2288 | + /* XXX: if not enabled, really disable the seconday IDE controller */ | ||
| 2289 | + pci_conf[0x51] = 0x80; /* enable IDE1 */ | ||
| 2290 | + } | ||
| 2201 | 2291 | ||
| 2202 | pci_register_io_region((PCIDevice *)d, 0, 0x8, | 2292 | pci_register_io_region((PCIDevice *)d, 0, 0x8, |
| 2203 | PCI_ADDRESS_SPACE_IO, ide_map); | 2293 | PCI_ADDRESS_SPACE_IO, ide_map); |
| @@ -2211,11 +2301,13 @@ void pci_ide_init(PCIBus *bus, BlockDriverState **hd_table) | @@ -2211,11 +2301,13 @@ void pci_ide_init(PCIBus *bus, BlockDriverState **hd_table) | ||
| 2211 | PCI_ADDRESS_SPACE_IO, bmdma_map); | 2301 | PCI_ADDRESS_SPACE_IO, bmdma_map); |
| 2212 | 2302 | ||
| 2213 | pci_conf[0x3d] = 0x01; // interrupt on pin 1 | 2303 | pci_conf[0x3d] = 0x01; // interrupt on pin 1 |
| 2214 | - | 2304 | + |
| 2215 | for(i = 0; i < 4; i++) | 2305 | for(i = 0; i < 4; i++) |
| 2216 | d->ide_if[i].pci_dev = (PCIDevice *)d; | 2306 | d->ide_if[i].pci_dev = (PCIDevice *)d; |
| 2217 | - ide_init2(&d->ide_if[0], 16, hd_table[0], hd_table[1]); | ||
| 2218 | - ide_init2(&d->ide_if[2], 16, hd_table[2], hd_table[3]); | 2307 | + ide_init2(&d->ide_if[0], hd_table[0], hd_table[1], |
| 2308 | + cmd646_set_irq, d, 0); | ||
| 2309 | + ide_init2(&d->ide_if[2], hd_table[2], hd_table[3], | ||
| 2310 | + cmd646_set_irq, d, 1); | ||
| 2219 | } | 2311 | } |
| 2220 | 2312 | ||
| 2221 | /* hd_table must contain 4 block drivers */ | 2313 | /* hd_table must contain 4 block drivers */ |
| @@ -2230,6 +2322,8 @@ void pci_piix3_ide_init(PCIBus *bus, BlockDriverState **hd_table) | @@ -2230,6 +2322,8 @@ void pci_piix3_ide_init(PCIBus *bus, BlockDriverState **hd_table) | ||
| 2230 | sizeof(PCIIDEState), | 2322 | sizeof(PCIIDEState), |
| 2231 | ((PCIDevice *)piix3_state)->devfn + 1, | 2323 | ((PCIDevice *)piix3_state)->devfn + 1, |
| 2232 | NULL, NULL); | 2324 | NULL, NULL); |
| 2325 | + d->type = IDE_TYPE_PIIX3; | ||
| 2326 | + | ||
| 2233 | pci_conf = d->dev.config; | 2327 | pci_conf = d->dev.config; |
| 2234 | pci_conf[0x00] = 0x86; // Intel | 2328 | pci_conf[0x00] = 0x86; // Intel |
| 2235 | pci_conf[0x01] = 0x80; | 2329 | pci_conf[0x01] = 0x80; |
| @@ -2242,8 +2336,10 @@ void pci_piix3_ide_init(PCIBus *bus, BlockDriverState **hd_table) | @@ -2242,8 +2336,10 @@ void pci_piix3_ide_init(PCIBus *bus, BlockDriverState **hd_table) | ||
| 2242 | pci_register_io_region((PCIDevice *)d, 4, 0x10, | 2336 | pci_register_io_region((PCIDevice *)d, 4, 0x10, |
| 2243 | PCI_ADDRESS_SPACE_IO, bmdma_map); | 2337 | PCI_ADDRESS_SPACE_IO, bmdma_map); |
| 2244 | 2338 | ||
| 2245 | - ide_init2(&d->ide_if[0], 14, hd_table[0], hd_table[1]); | ||
| 2246 | - ide_init2(&d->ide_if[2], 15, hd_table[2], hd_table[3]); | 2339 | + ide_init2(&d->ide_if[0], hd_table[0], hd_table[1], |
| 2340 | + pic_set_irq_new, NULL, 14); | ||
| 2341 | + ide_init2(&d->ide_if[2], hd_table[2], hd_table[3], | ||
| 2342 | + pic_set_irq_new, NULL, 15); | ||
| 2247 | ide_init_ioport(&d->ide_if[0], 0x1f0, 0x3f6); | 2343 | ide_init_ioport(&d->ide_if[0], 0x1f0, 0x3f6); |
| 2248 | ide_init_ioport(&d->ide_if[2], 0x170, 0x376); | 2344 | ide_init_ioport(&d->ide_if[2], 0x170, 0x376); |
| 2249 | } | 2345 | } |
| @@ -2361,15 +2457,14 @@ static CPUReadMemoryFunc *pmac_ide_read[] = { | @@ -2361,15 +2457,14 @@ static CPUReadMemoryFunc *pmac_ide_read[] = { | ||
| 2361 | /* PowerMac uses memory mapped registers, not I/O. Return the memory | 2457 | /* PowerMac uses memory mapped registers, not I/O. Return the memory |
| 2362 | I/O index to access the ide. */ | 2458 | I/O index to access the ide. */ |
| 2363 | int pmac_ide_init (BlockDriverState **hd_table, | 2459 | int pmac_ide_init (BlockDriverState **hd_table, |
| 2364 | - openpic_t *openpic, int irq) | 2460 | + SetIRQFunc *set_irq, void *irq_opaque, int irq) |
| 2365 | { | 2461 | { |
| 2366 | IDEState *ide_if; | 2462 | IDEState *ide_if; |
| 2367 | int pmac_ide_memory; | 2463 | int pmac_ide_memory; |
| 2368 | 2464 | ||
| 2369 | ide_if = qemu_mallocz(sizeof(IDEState) * 2); | 2465 | ide_if = qemu_mallocz(sizeof(IDEState) * 2); |
| 2370 | - ide_init2(&ide_if[0], irq, hd_table[0], hd_table[1]); | ||
| 2371 | - ide_if[0].openpic = openpic; | ||
| 2372 | - ide_if[1].openpic = openpic; | 2466 | + ide_init2(&ide_if[0], hd_table[0], hd_table[1], |
| 2467 | + set_irq, irq_opaque, irq); | ||
| 2373 | 2468 | ||
| 2374 | pmac_ide_memory = cpu_register_io_memory(0, pmac_ide_read, | 2469 | pmac_ide_memory = cpu_register_io_memory(0, pmac_ide_read, |
| 2375 | pmac_ide_write, &ide_if[0]); | 2470 | pmac_ide_write, &ide_if[0]); |