Commit 5457c8ceebafae8d3ff929d22bb32d1edb2250dd

Authored by bellard
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 296 int cylinders, heads, sectors;
297 297 int64_t nb_sectors;
298 298 int mult_sectors;
  299 + SetIRQFunc *set_irq;
  300 + void *irq_opaque;
299 301 int irq;
300   - openpic_t *openpic;
301 302 PCIDevice *pci_dev;
302 303 struct BMDMAState *bmdma;
303 304 int drive_serial;
... ... @@ -342,6 +343,18 @@ typedef struct IDEState {
342 343 #define BM_CMD_START 0x01
343 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 358 typedef int IDEDMAFunc(IDEState *s,
346 359 target_phys_addr_t phys_addr,
347 360 int transfer_size1);
... ... @@ -350,6 +363,8 @@ typedef struct BMDMAState {
350 363 uint8_t cmd;
351 364 uint8_t status;
352 365 uint32_t addr;
  366 +
  367 + struct PCIIDEState *pci_dev;
353 368 /* current transfer state */
354 369 IDEState *ide_if;
355 370 IDEDMAFunc *dma_cb;
... ... @@ -359,6 +374,7 @@ typedef struct PCIIDEState {
359 374 PCIDevice dev;
360 375 IDEState ide_if[4];
361 376 BMDMAState bmdma[2];
  377 + int type; /* see IDE_TYPE_xxx */
362 378 } PCIIDEState;
363 379  
364 380 static void ide_dma_start(IDEState *s, IDEDMAFunc *dma_cb);
... ... @@ -502,17 +518,10 @@ static inline void ide_set_irq(IDEState *s)
502 518 {
503 519 BMDMAState *bm = s->bmdma;
504 520 if (!(s->cmd & IDE_CMD_DISABLE_IRQ)) {
505   - if (bm)
  521 + if (bm) {
506 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 823 case 2352:
815 824 /* sync bytes */
816 825 buf[0] = 0x00;
817   - memset(buf + 1, 0xff, 11);
  826 + memset(buf + 1, 0xff, 10);
  827 + buf[11] = 0x00;
818 828 buf += 12;
819 829 /* MSF */
820 830 lba_to_msf(buf, lba);
... ... @@ -942,6 +952,9 @@ static int ide_atapi_cmd_read_dma_cb(IDEState *s,
942 952  
943 953 transfer_size = transfer_size1;
944 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 958 if (s->packet_transfer_size <= 0)
946 959 break;
947 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 1032 *q++ = 0; /* reserved */
1020 1033 if (msf) {
1021 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 1037 } else {
1026 1038 /* sector 0 */
1027 1039 cpu_to_ube32(q, 0);
... ... @@ -1476,6 +1488,11 @@ static void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val)
1476 1488 unit = (val >> 4) & 1;
1477 1489 s = ide_if + unit;
1478 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 1496 break;
1480 1497 default:
1481 1498 case 7:
... ... @@ -1596,6 +1613,7 @@ static void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val)
1596 1613 break;
1597 1614 case WIN_STANDBYNOW1:
1598 1615 case WIN_IDLEIMMEDIATE:
  1616 + case WIN_FLUSH_CACHE:
1599 1617 s->status = READY_STAT;
1600 1618 ide_set_irq(s);
1601 1619 break;
... ... @@ -1697,15 +1715,7 @@ static uint32_t ide_ioport_read(void *opaque, uint32_t addr1)
1697 1715 ret = 0;
1698 1716 else
1699 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 1719 break;
1710 1720 }
1711 1721 #ifdef DEBUG_IDE
... ... @@ -1898,8 +1908,9 @@ static int guess_disk_lchs(IDEState *s,
1898 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 1915 IDEState *s;
1905 1916 static int drive_serial = 1;
... ... @@ -1960,6 +1971,8 @@ static void ide_init2(IDEState *ide_state, int irq,
1960 1971 }
1961 1972 }
1962 1973 s->drive_serial = drive_serial++;
  1974 + s->set_irq = set_irq;
  1975 + s->irq_opaque = irq_opaque;
1963 1976 s->irq = irq;
1964 1977 s->sector_write_timer = qemu_new_timer(vm_clock,
1965 1978 ide_sector_write_timer_cb, s);
... ... @@ -1995,13 +2008,15 @@ void isa_ide_init(int iobase, int iobase2, int irq,
1995 2008 if (!ide_state)
1996 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 2012 ide_init_ioport(ide_state, iobase, iobase2);
2000 2013 }
2001 2014  
2002 2015 /***********************************************************/
2003 2016 /* PCI IDE definitions */
2004 2017  
  2018 +static void cmd646_update_irq(PCIIDEState *d);
  2019 +
2005 2020 static void ide_map(PCIDevice *pci_dev, int region_num,
2006 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 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 2100 static void bmdma_cmd_writeb(void *opaque, uint32_t addr, uint32_t val)
2097 2101 {
2098 2102 BMDMAState *bm = opaque;
... ... @@ -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 2121 BMDMAState *bm = opaque;
  2122 + PCIIDEState *pci_dev;
2118 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 2155 #ifdef DEBUG_IDE
2121   - printf("%s: 0x%08x\n", __func__, val);
  2156 + printf("bmdma: readb 0x%02x : 0x%02x\n", addr, val);
2122 2157 #endif
2123 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 2163 BMDMAState *bm = opaque;
  2164 + PCIIDEState *pci_dev;
2129 2165 #ifdef DEBUG_IDE
2130   - printf("%s: 0x%08x\n", __func__, val);
  2166 + printf("bmdma: writeb 0x%02x : 0x%02x\n", addr, val);
2131 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 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 2219 BMDMAState *bm = &d->bmdma[i];
2163 2220 d->ide_if[2 * i].bmdma = bm;
2164 2221 d->ide_if[2 * i + 1].bmdma = bm;
2165   -
  2222 + bm->pci_dev = (PCIIDEState *)pci_dev;
  2223 +
2166 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 2229 register_ioport_write(addr + 4, 4, 4, bmdma_addr_writel, bm);
2173 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 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 2265 PCIIDEState *d;
2182 2266 uint8_t *pci_conf;
2183 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 2271 -1,
2187 2272 NULL, NULL);
  2273 + d->type = IDE_TYPE_CMD646;
2188 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 2283 pci_conf[0x0a] = 0x01; // class_sub = PCI_IDE
2194 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 2292 pci_register_io_region((PCIDevice *)d, 0, 0x8,
2203 2293 PCI_ADDRESS_SPACE_IO, ide_map);
... ... @@ -2211,11 +2301,13 @@ void pci_ide_init(PCIBus *bus, BlockDriverState **hd_table)
2211 2301 PCI_ADDRESS_SPACE_IO, bmdma_map);
2212 2302  
2213 2303 pci_conf[0x3d] = 0x01; // interrupt on pin 1
2214   -
  2304 +
2215 2305 for(i = 0; i < 4; i++)
2216 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 2313 /* hd_table must contain 4 block drivers */
... ... @@ -2230,6 +2322,8 @@ void pci_piix3_ide_init(PCIBus *bus, BlockDriverState **hd_table)
2230 2322 sizeof(PCIIDEState),
2231 2323 ((PCIDevice *)piix3_state)->devfn + 1,
2232 2324 NULL, NULL);
  2325 + d->type = IDE_TYPE_PIIX3;
  2326 +
2233 2327 pci_conf = d->dev.config;
2234 2328 pci_conf[0x00] = 0x86; // Intel
2235 2329 pci_conf[0x01] = 0x80;
... ... @@ -2242,8 +2336,10 @@ void pci_piix3_ide_init(PCIBus *bus, BlockDriverState **hd_table)
2242 2336 pci_register_io_region((PCIDevice *)d, 4, 0x10,
2243 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 2343 ide_init_ioport(&d->ide_if[0], 0x1f0, 0x3f6);
2248 2344 ide_init_ioport(&d->ide_if[2], 0x170, 0x376);
2249 2345 }
... ... @@ -2361,15 +2457,14 @@ static CPUReadMemoryFunc *pmac_ide_read[] = {
2361 2457 /* PowerMac uses memory mapped registers, not I/O. Return the memory
2362 2458 I/O index to access the ide. */
2363 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 2462 IDEState *ide_if;
2367 2463 int pmac_ide_memory;
2368 2464  
2369 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 2469 pmac_ide_memory = cpu_register_io_memory(0, pmac_ide_read,
2375 2470 pmac_ide_write, &ide_if[0]);
... ...