/[qemu]/qemu/hw/ide.c
ViewVC logotype

Diff of /qemu/hw/ide.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.34 by bellard, Sat Apr 30 16:10:35 2005 UTC revision 1.35 by bellard, Sun Jun 5 15:15:26 2005 UTC
# Line 296  typedef struct IDEState { Line 296  typedef struct IDEState {
296      int cylinders, heads, sectors;      int cylinders, heads, sectors;
297      int64_t nb_sectors;      int64_t nb_sectors;
298      int mult_sectors;      int mult_sectors;
299        SetIRQFunc *set_irq;
300        void *irq_opaque;
301      int irq;      int irq;
     openpic_t *openpic;  
302      PCIDevice *pci_dev;      PCIDevice *pci_dev;
303      struct BMDMAState *bmdma;      struct BMDMAState *bmdma;
304      int drive_serial;      int drive_serial;
# Line 342  typedef struct IDEState { Line 343  typedef struct IDEState {
343  #define BM_CMD_START     0x01  #define BM_CMD_START     0x01
344  #define BM_CMD_READ      0x08  #define BM_CMD_READ      0x08
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    
358  typedef int IDEDMAFunc(IDEState *s,  typedef int IDEDMAFunc(IDEState *s,
359                         target_phys_addr_t phys_addr,                         target_phys_addr_t phys_addr,
360                         int transfer_size1);                         int transfer_size1);
# Line 350  typedef struct BMDMAState { Line 363  typedef struct BMDMAState {
363      uint8_t cmd;      uint8_t cmd;
364      uint8_t status;      uint8_t status;
365      uint32_t addr;      uint32_t addr;
366    
367        struct PCIIDEState *pci_dev;
368      /* current transfer state */      /* current transfer state */
369      IDEState *ide_if;      IDEState *ide_if;
370      IDEDMAFunc *dma_cb;      IDEDMAFunc *dma_cb;
# Line 359  typedef struct PCIIDEState { Line 374  typedef struct PCIIDEState {
374      PCIDevice dev;      PCIDevice dev;
375      IDEState ide_if[4];      IDEState ide_if[4];
376      BMDMAState bmdma[2];      BMDMAState bmdma[2];
377        int type; /* see IDE_TYPE_xxx */
378  } PCIIDEState;  } PCIIDEState;
379    
380  static void ide_dma_start(IDEState *s, IDEDMAFunc *dma_cb);  static void ide_dma_start(IDEState *s, IDEDMAFunc *dma_cb);
# Line 502  static inline void ide_set_irq(IDEState Line 518  static inline void ide_set_irq(IDEState
518  {  {
519      BMDMAState *bm = s->bmdma;      BMDMAState *bm = s->bmdma;
520      if (!(s->cmd & IDE_CMD_DISABLE_IRQ)) {      if (!(s->cmd & IDE_CMD_DISABLE_IRQ)) {
521          if (bm)          if (bm) {
522              bm->status |= BM_STATUS_INT;              bm->status |= BM_STATUS_INT;
523  #ifdef TARGET_PPC          }
524          if (s->openpic)          s->set_irq(s->irq_opaque, s->irq, 1);
             openpic_set_irq(s->openpic, s->irq, 1);  
         else  
 #endif  
         if (s->irq == 16)  
             pci_set_irq(s->pci_dev, 0, 1);  
         else  
             pic_set_irq(s->irq, 1);  
525      }      }
526  }  }
527    
# Line 814  static void cd_read_sector(BlockDriverSt Line 823  static void cd_read_sector(BlockDriverSt
823      case 2352:      case 2352:
824          /* sync bytes */          /* sync bytes */
825          buf[0] = 0x00;          buf[0] = 0x00;
826          memset(buf + 1, 0xff, 11);          memset(buf + 1, 0xff, 10);
827            buf[11] = 0x00;
828          buf += 12;          buf += 12;
829          /* MSF */          /* MSF */
830          lba_to_msf(buf, lba);          lba_to_msf(buf, lba);
# Line 942  static int ide_atapi_cmd_read_dma_cb(IDE Line 952  static int ide_atapi_cmd_read_dma_cb(IDE
952            
953      transfer_size = transfer_size1;      transfer_size = transfer_size1;
954      while (transfer_size > 0) {      while (transfer_size > 0) {
955    #ifdef DEBUG_IDE_ATAPI
956            printf("transfer_size: %d phys_addr=%08x\n", transfer_size, phys_addr);
957    #endif
958          if (s->packet_transfer_size <= 0)          if (s->packet_transfer_size <= 0)
959              break;              break;
960          len = s->cd_sector_size - s->io_buffer_index;          len = s->cd_sector_size - s->io_buffer_index;
# Line 1019  static int cdrom_read_toc(IDEState *s, u Line 1032  static int cdrom_read_toc(IDEState *s, u
1032          *q++ = 0; /* reserved */          *q++ = 0; /* reserved */
1033          if (msf) {          if (msf) {
1034              *q++ = 0; /* reserved */              *q++ = 0; /* reserved */
1035              *q++ = 0; /* minute */              lba_to_msf(q, 0);
1036              *q++ = 2; /* second */              q += 3;
             *q++ = 0; /* frame */  
1037          } else {          } else {
1038              /* sector 0 */              /* sector 0 */
1039              cpu_to_ube32(q, 0);              cpu_to_ube32(q, 0);
# Line 1476  static void ide_ioport_write(void *opaqu Line 1488  static void ide_ioport_write(void *opaqu
1488          unit = (val >> 4) & 1;          unit = (val >> 4) & 1;
1489          s = ide_if + unit;          s = ide_if + unit;
1490          ide_if->cur_drive = s;          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
1496          break;          break;
1497      default:      default:
1498      case 7:      case 7:
# Line 1596  static void ide_ioport_write(void *opaqu Line 1613  static void ide_ioport_write(void *opaqu
1613              break;              break;
1614          case WIN_STANDBYNOW1:          case WIN_STANDBYNOW1:
1615          case WIN_IDLEIMMEDIATE:          case WIN_IDLEIMMEDIATE:
1616            case WIN_FLUSH_CACHE:
1617              s->status = READY_STAT;              s->status = READY_STAT;
1618              ide_set_irq(s);              ide_set_irq(s);
1619              break;              break;
# Line 1697  static uint32_t ide_ioport_read(void *op Line 1715  static uint32_t ide_ioport_read(void *op
1715              ret = 0;              ret = 0;
1716          else          else
1717              ret = s->status;              ret = s->status;
1718  #ifdef TARGET_PPC          s->set_irq(s->irq_opaque, s->irq, 0);
         if (s->openpic)  
             openpic_set_irq(s->openpic, s->irq, 0);  
         else  
 #endif  
         if (s->irq == 16)  
             pci_set_irq(s->pci_dev, 0, 0);  
         else  
             pic_set_irq(s->irq, 0);  
1719          break;          break;
1720      }      }
1721  #ifdef DEBUG_IDE  #ifdef DEBUG_IDE
# Line 1898  static int guess_disk_lchs(IDEState *s, Line 1908  static int guess_disk_lchs(IDEState *s,
1908      return -1;      return -1;
1909  }  }
1910    
1911  static void ide_init2(IDEState *ide_state, int irq,  static void ide_init2(IDEState *ide_state,
1912                        BlockDriverState *hd0, BlockDriverState *hd1)                        BlockDriverState *hd0, BlockDriverState *hd1,
1913                          SetIRQFunc *set_irq, void *irq_opaque, int irq)
1914  {  {
1915      IDEState *s;      IDEState *s;
1916      static int drive_serial = 1;      static int drive_serial = 1;
# Line 1960  static void ide_init2(IDEState *ide_stat Line 1971  static void ide_init2(IDEState *ide_stat
1971              }              }
1972          }          }
1973          s->drive_serial = drive_serial++;          s->drive_serial = drive_serial++;
1974            s->set_irq = set_irq;
1975            s->irq_opaque = irq_opaque;
1976          s->irq = irq;          s->irq = irq;
1977          s->sector_write_timer = qemu_new_timer(vm_clock,          s->sector_write_timer = qemu_new_timer(vm_clock,
1978                                                 ide_sector_write_timer_cb, s);                                                 ide_sector_write_timer_cb, s);
# Line 1995  void isa_ide_init(int iobase, int iobase Line 2008  void isa_ide_init(int iobase, int iobase
2008      if (!ide_state)      if (!ide_state)
2009          return;          return;
2010            
2011      ide_init2(ide_state, irq, hd0, hd1);      ide_init2(ide_state, hd0, hd1, pic_set_irq_new, NULL, irq);
2012      ide_init_ioport(ide_state, iobase, iobase2);      ide_init_ioport(ide_state, iobase, iobase2);
2013  }  }
2014    
2015  /***********************************************************/  /***********************************************************/
2016  /* PCI IDE definitions */  /* PCI IDE definitions */
2017    
2018    static void cmd646_update_irq(PCIIDEState *d);
2019    
2020  static void ide_map(PCIDevice *pci_dev, int region_num,  static void ide_map(PCIDevice *pci_dev, int region_num,
2021                      uint32_t addr, uint32_t size, int type)                      uint32_t addr, uint32_t size, int type)
2022  {  {
# Line 2082  static void ide_dma_start(IDEState *s, I Line 2097  static void ide_dma_start(IDEState *s, I
2097      }      }
2098  }  }
2099    
 static uint32_t bmdma_cmd_readb(void *opaque, uint32_t addr)  
 {  
     BMDMAState *bm = opaque;  
     uint32_t val;  
     val = bm->cmd;  
 #ifdef DEBUG_IDE  
     printf("%s: 0x%08x\n", __func__, val);  
 #endif  
     return val;  
 }  
   
2100  static void bmdma_cmd_writeb(void *opaque, uint32_t addr, uint32_t val)  static void bmdma_cmd_writeb(void *opaque, uint32_t addr, uint32_t val)
2101  {  {
2102      BMDMAState *bm = opaque;      BMDMAState *bm = opaque;
# Line 2112  static void bmdma_cmd_writeb(void *opaqu Line 2116  static void bmdma_cmd_writeb(void *opaqu
2116      }      }
2117  }  }
2118    
2119  static uint32_t bmdma_status_readb(void *opaque, uint32_t addr)  static uint32_t bmdma_readb(void *opaque, uint32_t addr)
2120  {  {
2121      BMDMAState *bm = opaque;      BMDMAState *bm = opaque;
2122        PCIIDEState *pci_dev;
2123      uint32_t val;      uint32_t val;
2124      val = bm->status;      
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        }
2155  #ifdef DEBUG_IDE  #ifdef DEBUG_IDE
2156      printf("%s: 0x%08x\n", __func__, val);      printf("bmdma: readb 0x%02x : 0x%02x\n", addr, val);
2157  #endif  #endif
2158      return val;      return val;
2159  }  }
2160    
2161  static void bmdma_status_writeb(void *opaque, uint32_t addr, uint32_t val)  static void bmdma_writeb(void *opaque, uint32_t addr, uint32_t val)
2162  {  {
2163      BMDMAState *bm = opaque;      BMDMAState *bm = opaque;
2164        PCIIDEState *pci_dev;
2165  #ifdef DEBUG_IDE  #ifdef DEBUG_IDE
2166      printf("%s: 0x%08x\n", __func__, val);      printf("bmdma: writeb 0x%02x : 0x%02x\n", addr, val);
2167  #endif  #endif
2168      bm->status = (val & 0x60) | (bm->status & 1) | (bm->status & ~val & 0x06);      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        }
2190  }  }
2191    
2192  static uint32_t bmdma_addr_readl(void *opaque, uint32_t addr)  static uint32_t bmdma_addr_readl(void *opaque, uint32_t addr)
# Line 2162  static void bmdma_map(PCIDevice *pci_dev Line 2219  static void bmdma_map(PCIDevice *pci_dev
2219          BMDMAState *bm = &d->bmdma[i];          BMDMAState *bm = &d->bmdma[i];
2220          d->ide_if[2 * i].bmdma = bm;          d->ide_if[2 * i].bmdma = bm;
2221          d->ide_if[2 * i + 1].bmdma = bm;          d->ide_if[2 * i + 1].bmdma = bm;
2222                    bm->pci_dev = (PCIIDEState *)pci_dev;
2223    
2224          register_ioport_write(addr, 1, 1, bmdma_cmd_writeb, bm);          register_ioport_write(addr, 1, 1, bmdma_cmd_writeb, bm);
         register_ioport_read(addr, 1, 1, bmdma_cmd_readb, bm);  
2225    
2226          register_ioport_write(addr + 2, 1, 1, bmdma_status_writeb, bm);          register_ioport_write(addr + 1, 3, 1, bmdma_writeb, bm);
2227          register_ioport_read(addr + 2, 1, 1, bmdma_status_readb, bm);          register_ioport_read(addr, 4, 1, bmdma_readb, bm);
2228    
2229          register_ioport_write(addr + 4, 4, 4, bmdma_addr_writel, bm);          register_ioport_write(addr + 4, 4, 4, bmdma_addr_writel, bm);
2230          register_ioport_read(addr + 4, 4, 4, bmdma_addr_readl, bm);          register_ioport_read(addr + 4, 4, 4, bmdma_addr_readl, bm);
# Line 2175  static void bmdma_map(PCIDevice *pci_dev Line 2232  static void bmdma_map(PCIDevice *pci_dev
2232      }      }
2233  }  }
2234    
2235  /* hd_table must contain 4 block drivers */  /* XXX: call it also when the MRDMODE is changed from the PCI config
2236  void pci_ide_init(PCIBus *bus, BlockDriverState **hd_table)     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)
2264  {  {
2265      PCIIDEState *d;      PCIIDEState *d;
2266      uint8_t *pci_conf;      uint8_t *pci_conf;
2267      int i;      int i;
2268    
2269      d = (PCIIDEState *)pci_register_device(bus, "IDE", sizeof(PCIIDEState),      d = (PCIIDEState *)pci_register_device(bus, "CMD646 IDE",
2270                                               sizeof(PCIIDEState),
2271                                             -1,                                             -1,
2272                                             NULL, NULL);                                             NULL, NULL);
2273        d->type = IDE_TYPE_CMD646;
2274      pci_conf = d->dev.config;      pci_conf = d->dev.config;
2275      pci_conf[0x00] = 0x86; // Intel      pci_conf[0x00] = 0x95; // CMD646
2276      pci_conf[0x01] = 0x80;      pci_conf[0x01] = 0x10;
2277      pci_conf[0x02] = 0x00; // fake      pci_conf[0x02] = 0x46;
2278      pci_conf[0x03] = 0x01; // fake      pci_conf[0x03] = 0x06;
2279    
2280        pci_conf[0x08] = 0x07; // IDE controller revision
2281        pci_conf[0x09] = 0x8f;
2282    
2283      pci_conf[0x0a] = 0x01; // class_sub = PCI_IDE      pci_conf[0x0a] = 0x01; // class_sub = PCI_IDE
2284      pci_conf[0x0b] = 0x01; // class_base = PCI_mass_storage      pci_conf[0x0b] = 0x01; // class_base = PCI_mass_storage
2285      pci_conf[0x0e] = 0x80; // header_type = PCI_multifunction, generic      pci_conf[0x0e] = 0x00; // header_type
2286        
2287      pci_conf[0x2c] = 0x86; // subsys vendor      if (secondary_ide_enabled) {
2288      pci_conf[0x2d] = 0x80; // subsys vendor          /* XXX: if not enabled, really disable the seconday IDE controller */
2289      pci_conf[0x2e] = 0x00; // fake          pci_conf[0x51] = 0x80; /* enable IDE1 */
2290      pci_conf[0x2f] = 0x01; // fake      }
2291    
2292      pci_register_io_region((PCIDevice *)d, 0, 0x8,      pci_register_io_region((PCIDevice *)d, 0, 0x8,
2293                             PCI_ADDRESS_SPACE_IO, ide_map);                             PCI_ADDRESS_SPACE_IO, ide_map);
# Line 2211  void pci_ide_init(PCIBus *bus, BlockDriv Line 2301  void pci_ide_init(PCIBus *bus, BlockDriv
2301                             PCI_ADDRESS_SPACE_IO, bmdma_map);                             PCI_ADDRESS_SPACE_IO, bmdma_map);
2302    
2303      pci_conf[0x3d] = 0x01; // interrupt on pin 1      pci_conf[0x3d] = 0x01; // interrupt on pin 1
2304        
2305      for(i = 0; i < 4; i++)      for(i = 0; i < 4; i++)
2306          d->ide_if[i].pci_dev = (PCIDevice *)d;          d->ide_if[i].pci_dev = (PCIDevice *)d;
2307      ide_init2(&d->ide_if[0], 16, hd_table[0], hd_table[1]);      ide_init2(&d->ide_if[0], hd_table[0], hd_table[1],
2308      ide_init2(&d->ide_if[2], 16, hd_table[2], hd_table[3]);                cmd646_set_irq, d, 0);
2309        ide_init2(&d->ide_if[2], hd_table[2], hd_table[3],
2310                  cmd646_set_irq, d, 1);
2311  }  }
2312    
2313  /* hd_table must contain 4 block drivers */  /* hd_table must contain 4 block drivers */
# Line 2230  void pci_piix3_ide_init(PCIBus *bus, Blo Line 2322  void pci_piix3_ide_init(PCIBus *bus, Blo
2322                                             sizeof(PCIIDEState),                                             sizeof(PCIIDEState),
2323                                             ((PCIDevice *)piix3_state)->devfn + 1,                                             ((PCIDevice *)piix3_state)->devfn + 1,
2324                                             NULL, NULL);                                             NULL, NULL);
2325        d->type = IDE_TYPE_PIIX3;
2326    
2327      pci_conf = d->dev.config;      pci_conf = d->dev.config;
2328      pci_conf[0x00] = 0x86; // Intel      pci_conf[0x00] = 0x86; // Intel
2329      pci_conf[0x01] = 0x80;      pci_conf[0x01] = 0x80;
# Line 2242  void pci_piix3_ide_init(PCIBus *bus, Blo Line 2336  void pci_piix3_ide_init(PCIBus *bus, Blo
2336      pci_register_io_region((PCIDevice *)d, 4, 0x10,      pci_register_io_region((PCIDevice *)d, 4, 0x10,
2337                             PCI_ADDRESS_SPACE_IO, bmdma_map);                             PCI_ADDRESS_SPACE_IO, bmdma_map);
2338    
2339      ide_init2(&d->ide_if[0], 14, hd_table[0], hd_table[1]);      ide_init2(&d->ide_if[0], hd_table[0], hd_table[1],
2340      ide_init2(&d->ide_if[2], 15, hd_table[2], hd_table[3]);                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);
2343      ide_init_ioport(&d->ide_if[0], 0x1f0, 0x3f6);      ide_init_ioport(&d->ide_if[0], 0x1f0, 0x3f6);
2344      ide_init_ioport(&d->ide_if[2], 0x170, 0x376);      ide_init_ioport(&d->ide_if[2], 0x170, 0x376);
2345  }  }
# Line 2361  static CPUReadMemoryFunc *pmac_ide_read[ Line 2457  static CPUReadMemoryFunc *pmac_ide_read[
2457  /* PowerMac uses memory mapped registers, not I/O. Return the memory  /* PowerMac uses memory mapped registers, not I/O. Return the memory
2458     I/O index to access the ide. */     I/O index to access the ide. */
2459  int pmac_ide_init (BlockDriverState **hd_table,  int pmac_ide_init (BlockDriverState **hd_table,
2460                     openpic_t *openpic, int irq)                     SetIRQFunc *set_irq, void *irq_opaque, int irq)
2461  {  {
2462      IDEState *ide_if;      IDEState *ide_if;
2463      int pmac_ide_memory;      int pmac_ide_memory;
2464    
2465      ide_if = qemu_mallocz(sizeof(IDEState) * 2);      ide_if = qemu_mallocz(sizeof(IDEState) * 2);
2466      ide_init2(&ide_if[0], irq, hd_table[0], hd_table[1]);      ide_init2(&ide_if[0], hd_table[0], hd_table[1],
2467      ide_if[0].openpic = openpic;                set_irq, irq_opaque, irq);
     ide_if[1].openpic = openpic;  
2468            
2469      pmac_ide_memory = cpu_register_io_memory(0, pmac_ide_read,      pmac_ide_memory = cpu_register_io_memory(0, pmac_ide_read,
2470                                               pmac_ide_write, &ide_if[0]);                                               pmac_ide_write, &ide_if[0]);

Legend:
Removed from v.1.34  
changed lines
  Added in v.1.35

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26