/[dynamips]/trunk/dev_pa_a1.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /trunk/dev_pa_a1.c

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

upstream/dynamips-0.2.6-RC1/dev_pa_a1.c revision 2 by dpavlin, Sat Oct 6 16:03:58 2007 UTC upstream/dynamips-0.2.8-RC1/dev_pa_a1.c revision 11 by dpavlin, Sat Oct 6 16:33:40 2007 UTC
# Line 1  Line 1 
1  /*    /*  
2   * Cisco C7200 (Predator) Simulation Platform.   * Cisco router simulation platform.
3   * Copyright (C) 2005,2006 Christophe Fillot.  All rights reserved.   * Copyright (C) 2005,2006 Christophe Fillot.  All rights reserved.
4   *   *
5   * PA-A1 ATM interface based on TI1570 and PLX 9060-ES.   * PA-A1 ATM interface based on TI1570 and PLX 9060-ES.
# Line 35  Line 35 
35    
36  #include "crc.h"  #include "crc.h"
37  #include "atm.h"  #include "atm.h"
38  #include "mips64.h"  #include "cpu.h"
39    #include "vm.h"
40  #include "dynamips.h"  #include "dynamips.h"
41  #include "memory.h"  #include "memory.h"
42  #include "device.h"  #include "device.h"
# Line 284  struct ti1570_rcr_entry { Line 285  struct ti1570_rcr_entry {
285  struct pa_a1_data {  struct pa_a1_data {
286     char *name;     char *name;
287    
288       /* IRQ clearing counter */
289       u_int irq_clear_count;
290    
291     /* Control Memory pointer */     /* Control Memory pointer */
292     m_uint32_t *ctrl_mem_ptr;     m_uint32_t *ctrl_mem_ptr;
293    
# Line 329  struct pa_a1_data { Line 333  struct pa_a1_data {
333     ptask_id_t tx_tid;     ptask_id_t tx_tid;
334  };  };
335    
 /* EEPROM definition */  
 static const m_uint16_t eeprom_pa_a1_data[64] = {  
    0x0117, 0x010F, 0xffff, 0xffff, 0x4906, 0x2E07, 0x0000, 0x0000,  
    0x5000, 0x0000, 0x0010, 0x2400, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,  
 };  
   
 static const struct c7200_eeprom eeprom_pa_a1 = {  
    "PA-A1-OC3MM", (m_uint16_t *)eeprom_pa_a1_data, sizeof(eeprom_pa_a1_data)/2,  
 };  
   
336  /* Log a TI1570 message */  /* Log a TI1570 message */
337  #define TI1570_LOG(d,msg...) vm_log((d)->vm,(d)->name,msg)  #define TI1570_LOG(d,msg...) vm_log((d)->vm,(d)->name,msg)
338    
339  /* Reset the TI1570 (forward declaration) */  /* Reset the TI1570 (forward declaration) */
340  static void ti1570_reset(struct pa_a1_data *d,int clear_ctrl_mem);  static void ti1570_reset(struct pa_a1_data *d,int clear_ctrl_mem);
341    
342    /* Update the interrupt status */
343    static inline void dev_pa_a1_update_irq_status(struct pa_a1_data *d)
344    {
345       if (d->iregs[TI1570_REG_STATUS] & d->iregs[TI1570_REG_IMASK]) {
346          pci_dev_trigger_irq(d->vm,d->pci_dev_ti);
347       } else {
348          pci_dev_clear_irq(d->vm,d->pci_dev_ti);
349       }
350    }
351    
352  /*  /*
353   * dev_pa_a1_access()   * dev_pa_a1_access()
354   */   */
355  void *dev_pa_a1_access(cpu_mips_t *cpu,struct vdevice *dev,m_uint32_t offset,  void *dev_pa_a1_access(cpu_gen_t *cpu,struct vdevice *dev,m_uint32_t offset,
356                         u_int op_size,u_int op_type,m_uint64_t *data)                         u_int op_size,u_int op_type,m_uint64_t *data)
357  {  {
358     struct pa_a1_data *d = dev->priv_data;     struct pa_a1_data *d = dev->priv_data;
# Line 359  void *dev_pa_a1_access(cpu_mips_t *cpu,s Line 363  void *dev_pa_a1_access(cpu_mips_t *cpu,s
363  #if DEBUG_ACCESS  #if DEBUG_ACCESS
364     if (op_type == MTS_READ) {     if (op_type == MTS_READ) {
365        cpu_log(cpu,"TI1570","read  access to offset = 0x%x, pc = 0x%llx\n",        cpu_log(cpu,"TI1570","read  access to offset = 0x%x, pc = 0x%llx\n",
366                offset,cpu->pc);                offset,cpu_get_pc(cpu));
367     } else {     } else {
368        cpu_log(cpu,"TI1570","write access to vaddr = 0x%x, pc = 0x%llx, "        cpu_log(cpu,"TI1570","write access to vaddr = 0x%x, pc = 0x%llx, "
369                "val = 0x%llx\n",offset,cpu->pc,*data);                "val = 0x%llx\n",offset,cpu_get_pc(cpu),*data);
370     }     }
371  #endif    #endif  
372    
373     /* Specific cases */     /* Specific cases */
374     switch(offset) {     switch(offset) {
375          /* Status register */
376          case 0x3204:
377             if (op_type == MTS_READ) {
378                *data = d->iregs[TI1570_REG_STATUS];
379    
380                if (++d->irq_clear_count == 2) {
381                   d->iregs[TI1570_REG_STATUS] &= ~0x3FF;
382                   d->irq_clear_count = 0;
383                }
384    
385                dev_pa_a1_update_irq_status(d);
386             }
387             break;
388    
389          /* Software Reset register */
390        case 0x3238:        case 0x3238:
391           TI1570_LOG(d,"reset issued.\n");           TI1570_LOG(d,"reset issued.\n");
392           ti1570_reset(d,FALSE);           ti1570_reset(d,FALSE);
# Line 394  void *dev_pa_a1_access(cpu_mips_t *cpu,s Line 413  void *dev_pa_a1_access(cpu_mips_t *cpu,s
413  #if DEBUG_UNKNOWN  #if DEBUG_UNKNOWN
414     if (op_type == MTS_READ) {     if (op_type == MTS_READ) {
415        cpu_log(cpu,d->name,"read from unknown addr 0x%x, pc=0x%llx (size=%u)\n",        cpu_log(cpu,d->name,"read from unknown addr 0x%x, pc=0x%llx (size=%u)\n",
416                offset,cpu->pc,op_size);                offset,cpu_get_pc(cpu),op_size);
417     } else {     } else {
418        cpu_log(cpu,d->name,"write to unknown addr 0x%x, value=0x%llx, "        cpu_log(cpu,d->name,"write to unknown addr 0x%x, value=0x%llx, "
419                "pc=0x%llx (size=%u)\n",offset,*data,cpu->pc,op_size);                "pc=0x%llx (size=%u)\n",offset,*data,cpu_get_pc(cpu),op_size);
420     }     }
421  #endif  #endif
422     return NULL;     return NULL;
# Line 897  static int ti1570_scan_tx_dma_entry_sing Line 916  static int ti1570_scan_tx_dma_entry_sing
916     /* Generate an interrupt if required */     /* Generate an interrupt if required */
917     if (tde->ctrl_buf & TI1570_TX_DMA_TCR_SELECT)     if (tde->ctrl_buf & TI1570_TX_DMA_TCR_SELECT)
918     {     {
919        if (((d->iregs[TI1570_REG_STATUS] & TI1570_CFG_BP_SEL) && buf_end) ||        if (((d->iregs[TI1570_REG_CONFIG] & TI1570_CFG_BP_SEL) && buf_end) ||
920            pkt_end)            pkt_end)
921        {        {
922           d->iregs[TI1570_REG_STATUS] |= TI1570_STAT_CP_TX;           d->iregs[TI1570_REG_STATUS] |= TI1570_STAT_CP_TX;
923           pci_dev_trigger_irq(d->vm,d->pci_dev_ti);           dev_pa_a1_update_irq_status(d);
924        }        }
925     }     }
926    
# Line 1034  static void ti1570_update_rx_cring(struc Line 1053  static void ti1570_update_rx_cring(struc
1053    
1054        /* generate the appropriate IRQ */        /* generate the appropriate IRQ */
1055        d->iregs[TI1570_REG_STATUS] |= TI1570_STAT_CP_RX;        d->iregs[TI1570_REG_STATUS] |= TI1570_STAT_CP_RX;
1056        pci_dev_trigger_irq(d->vm,d->pci_dev_ti);        dev_pa_a1_update_irq_status(d);
1057     } else  {     } else  {
1058        rcr_end = (d->iregs[TI1570_REG_RX_CRING_SIZE] >> 16);        rcr_end = (d->iregs[TI1570_REG_RX_CRING_SIZE] >> 16);
1059        rcr_end &= TI1570_RCR_SIZE_MASK;        rcr_end &= TI1570_RCR_SIZE_MASK;
# Line 1438  static int ti1570_handle_rx_cell(netio_d Line 1457  static int ti1570_handle_rx_cell(netio_d
1457  /*  /*
1458   * pci_ti1570_read()   * pci_ti1570_read()
1459   */   */
1460  static m_uint32_t pci_ti1570_read(cpu_mips_t *cpu,struct pci_device *dev,  static m_uint32_t pci_ti1570_read(cpu_gen_t *cpu,struct pci_device *dev,
1461                                    int reg)                                    int reg)
1462  {  {
1463     struct pa_a1_data *d = dev->priv_data;     struct pa_a1_data *d = dev->priv_data;
# Line 1458  static m_uint32_t pci_ti1570_read(cpu_mi Line 1477  static m_uint32_t pci_ti1570_read(cpu_mi
1477  /*  /*
1478   * pci_ti1570_write()   * pci_ti1570_write()
1479   */   */
1480  static void pci_ti1570_write(cpu_mips_t *cpu,struct pci_device *dev,  static void pci_ti1570_write(cpu_gen_t *cpu,struct pci_device *dev,
1481                               int reg,m_uint32_t value)                               int reg,m_uint32_t value)
1482  {  {
1483     struct pa_a1_data *d = dev->priv_data;     struct pa_a1_data *d = dev->priv_data;
# Line 1478  static void pci_ti1570_write(cpu_mips_t Line 1497  static void pci_ti1570_write(cpu_mips_t
1497  /*  /*
1498   * pci_plx9060es_read()   * pci_plx9060es_read()
1499   */   */
1500  static m_uint32_t pci_plx9060es_read(cpu_mips_t *cpu,struct pci_device *dev,  static m_uint32_t pci_plx9060es_read(cpu_gen_t *cpu,struct pci_device *dev,
1501                                       int reg)                                       int reg)
1502  {  {
1503       struct pa_a1_data *d = dev->priv_data;
1504    
1505  #if DEBUG_ACCESS  #if DEBUG_ACCESS
1506     TI1570_LOG(d,"PLX9060ES","read reg 0x%x\n",reg);     TI1570_LOG(d,"PLX9060ES","read reg 0x%x\n",reg);
1507  #endif  #endif
# Line 1493  static m_uint32_t pci_plx9060es_read(cpu Line 1514  static m_uint32_t pci_plx9060es_read(cpu
1514  /*  /*
1515   * pci_plx9060es_write()   * pci_plx9060es_write()
1516   */   */
1517  static void pci_plx9060es_write(cpu_mips_t *cpu,struct pci_device *dev,  static void pci_plx9060es_write(cpu_gen_t *cpu,struct pci_device *dev,
1518                                  int reg,m_uint32_t value)                                  int reg,m_uint32_t value)
1519  {  {
1520       struct pa_a1_data *d = dev->priv_data;
1521    
1522  #if DEBUG_ACCESS  #if DEBUG_ACCESS
1523     TI1570_LOG(d,"PLX9060ES","write reg 0x%x, value 0x%x\n",reg,value);     TI1570_LOG(d,"PLX9060ES","write reg 0x%x, value 0x%x\n",reg,value);
1524  #endif  #endif
# Line 1521  static void ti1570_reset(struct pa_a1_da Line 1544  static void ti1570_reset(struct pa_a1_da
1544   *   *
1545   * Add a PA-A1 port adapter into specified slot.   * Add a PA-A1 port adapter into specified slot.
1546   */   */
1547  int dev_c7200_pa_a1_init(c7200_t *router,char *name,u_int pa_bay)  int dev_c7200_pa_a1_init(vm_instance_t *vm,struct cisco_card *card)
1548  {    {  
1549       u_int slot = card->slot_id;
1550     struct pci_device *pci_dev_ti,*pci_dev_plx;     struct pci_device *pci_dev_ti,*pci_dev_plx;
1551     struct pa_a1_data *d;     struct pa_a1_data *d;
1552     struct vdevice *dev;     struct vdevice *dev;
# Line 1530  int dev_c7200_pa_a1_init(c7200_t *router Line 1554  int dev_c7200_pa_a1_init(c7200_t *router
1554    
1555     /* Allocate the private data structure for TI1570 chip */     /* Allocate the private data structure for TI1570 chip */
1556     if (!(d = malloc(sizeof(*d)))) {     if (!(d = malloc(sizeof(*d)))) {
1557        fprintf(stderr,"%s (TI1570): out of memory\n",name);        vm_error(vm,"%s: out of memory\n",card->dev_name);
1558        return(-1);        return(-1);
1559     }     }
1560    
1561     memset(d,0,sizeof(*d));     memset(d,0,sizeof(*d));
1562    
1563       /* Set the PCI bus */
1564       card->pci_bus = vm->slots_pci_bus[slot];
1565    
1566     /* Set the EEPROM */     /* Set the EEPROM */
1567     c7200_pa_set_eeprom(router,pa_bay,&eeprom_pa_a1);     cisco_card_set_eeprom(vm,card,cisco_eeprom_find_pa("PA-A1"));
1568       c7200_set_slot_eeprom(VM_C7200(vm),slot,&card->eeprom);
1569    
1570     /* Add PCI device TI1570 */     /* Add PCI device TI1570 */
1571     pci_dev_ti = pci_dev_add(router->pa_bay[pa_bay].pci_map,name,     pci_dev_ti = pci_dev_add(card->pci_bus,card->dev_name,
1572                              TI1570_PCI_VENDOR_ID,TI1570_PCI_PRODUCT_ID,                              TI1570_PCI_VENDOR_ID,TI1570_PCI_PRODUCT_ID,
1573                              0,0,C7200_NETIO_IRQ,d,                              0,0,c7200_net_irq_for_slot_port(slot,0),d,
1574                              NULL,pci_ti1570_read,pci_ti1570_write);                              NULL,pci_ti1570_read,pci_ti1570_write);
1575    
1576     if (!pci_dev_ti) {     if (!pci_dev_ti) {
1577        fprintf(stderr,"%s (TI1570): unable to create PCI device TI1570.\n",        vm_error(vm,"%s: unable to create PCI device TI1570.\n",
1578                name);                 card->dev_name);
1579        return(-1);        return(-1);
1580     }     }
1581    
1582     /* Add PCI device PLX9060ES */     /* Add PCI device PLX9060ES */
1583     pci_dev_plx = pci_dev_add(router->pa_bay[pa_bay].pci_map,name,     pci_dev_plx = pci_dev_add(card->pci_bus,card->dev_name,
1584                               PLX_9060ES_PCI_VENDOR_ID,                               PLX_9060ES_PCI_VENDOR_ID,
1585                               PLX_9060ES_PCI_PRODUCT_ID,                               PLX_9060ES_PCI_PRODUCT_ID,
1586                               1,0,C7200_NETIO_IRQ,d,                               1,0,-1,d,
1587                               NULL,pci_plx9060es_read,pci_plx9060es_write);                               NULL,pci_plx9060es_read,pci_plx9060es_write);
1588    
1589     if (!pci_dev_plx) {     if (!pci_dev_plx) {
1590        fprintf(stderr,"%s (PLX_9060ES): unable to create PCI device "        vm_error(vm,"%s: unable to create PCI device PLX 9060ES.\n",
1591                "PLX 9060ES.\n",name);                 card->dev_name);
1592        return(-1);        return(-1);
1593     }     }
1594    
1595     /* Create the TI1570 structure */     /* Create the TI1570 structure */
1596     d->name        = name;     d->name        = card->dev_name;
1597     d->vm          = router->vm;     d->vm          = vm;
1598     d->pci_dev_ti  = pci_dev_ti;     d->pci_dev_ti  = pci_dev_ti;
1599     d->pci_dev_plx = pci_dev_plx;     d->pci_dev_plx = pci_dev_plx;
1600    
1601     /* Allocate the control memory */     /* Allocate the control memory */
1602     if (!(d->ctrl_mem_ptr = malloc(TI1570_CTRL_MEM_SIZE))) {     if (!(d->ctrl_mem_ptr = malloc(TI1570_CTRL_MEM_SIZE))) {
1603        fprintf(stderr,"%s (PA-A1): unable to create control memory.\n",name);        vm_error(vm,"%s: unable to create control memory.\n",card->dev_name);
1604        return(-1);        return(-1);
1605     }     }
1606    
# Line 1589  int dev_c7200_pa_a1_init(c7200_t *router Line 1617  int dev_c7200_pa_a1_init(c7200_t *router
1617     ti1570_reset(d,TRUE);     ti1570_reset(d,TRUE);
1618    
1619     /* Create the device itself */     /* Create the device itself */
1620     if (!(dev = dev_create(name))) {     if (!(dev = dev_create(card->dev_name))) {
1621        fprintf(stderr,"%s (PA-A1): unable to create device.\n",name);        vm_error(vm,"%s: unable to create device.\n",card->dev_name);
1622        return(-1);        return(-1);
1623     }     }
1624    
# Line 1603  int dev_c7200_pa_a1_init(c7200_t *router Line 1631  int dev_c7200_pa_a1_init(c7200_t *router
1631     d->dev = dev;     d->dev = dev;
1632        
1633     /* Store device info into the router structure */     /* Store device info into the router structure */
1634     return(c7200_pa_set_drvinfo(router,pa_bay,d));     card->drv_info = d;
1635       return(0);
1636  }  }
1637    
1638  /* Remove a PA-A1 from the specified slot */  /* Remove a PA-A1 from the specified slot */
1639  int dev_c7200_pa_a1_shutdown(c7200_t *router,u_int pa_bay)  int dev_c7200_pa_a1_shutdown(vm_instance_t *vm,struct cisco_card *card)
1640  {  {
1641     struct c7200_pa_bay *bay;     struct pa_a1_data *d = card->drv_info;
    struct pa_a1_data *d;  
   
    if (!(bay = c7200_pa_get_info(router,pa_bay)))  
       return(-1);  
   
    d = bay->drv_info;  
1642    
1643     /* Remove the PA EEPROM */     /* Remove the PA EEPROM */
1644     c7200_pa_unset_eeprom(router,pa_bay);     cisco_card_unset_eeprom(card);
1645       c7200_set_slot_eeprom(VM_C7200(vm),card->slot_id,NULL);
1646    
1647     /* Remove the PCI devices */     /* Remove the PCI devices */
1648     pci_dev_remove(d->pci_dev_ti);     pci_dev_remove(d->pci_dev_ti);
1649     pci_dev_remove(d->pci_dev_plx);     pci_dev_remove(d->pci_dev_plx);
1650    
1651     /* Remove the device from the VM address space */     /* Remove the device from the VM address space */
1652     vm_unbind_device(router->vm,d->dev);     vm_unbind_device(vm,d->dev);
1653     cpu_group_rebuild_mts(router->vm->cpu_group);     cpu_group_rebuild_mts(vm->cpu_group);
1654    
1655     /* Free the control memory */     /* Free the control memory */
1656     free(d->ctrl_mem_ptr);     free(d->ctrl_mem_ptr);
# Line 1638  int dev_c7200_pa_a1_shutdown(c7200_t *ro Line 1662  int dev_c7200_pa_a1_shutdown(c7200_t *ro
1662  }  }
1663    
1664  /* Bind a Network IO descriptor to a specific port */  /* Bind a Network IO descriptor to a specific port */
1665  int dev_c7200_pa_a1_set_nio(c7200_t *router,u_int pa_bay,u_int port_id,  int dev_c7200_pa_a1_set_nio(vm_instance_t *vm,struct cisco_card *card,
1666                              netio_desc_t *nio)                              u_int port_id,netio_desc_t *nio)
1667  {  {
1668     struct pa_a1_data *d;     struct pa_a1_data *d = card->drv_info;
1669    
1670     if ((port_id > 0) || !(d = c7200_pa_get_drvinfo(router,pa_bay)))     if (!d || (port_id > 0))
1671        return(-1);        return(-1);
1672    
1673     if (d->nio != NULL)     if (d->nio != NULL)
# Line 1656  int dev_c7200_pa_a1_set_nio(c7200_t *rou Line 1680  int dev_c7200_pa_a1_set_nio(c7200_t *rou
1680  }  }
1681    
1682  /* Unbind a Network IO descriptor to a specific port */  /* Unbind a Network IO descriptor to a specific port */
1683  int dev_c7200_pa_a1_unset_nio(c7200_t *router,u_int pa_bay,u_int port_id)  int dev_c7200_pa_a1_unset_nio(vm_instance_t *vm,struct cisco_card *card,
1684                                  u_int port_id)
1685  {  {
1686     struct pa_a1_data *d;     struct pa_a1_data *d = card->drv_info;
1687    
1688     if ((port_id > 0) || !(d = c7200_pa_get_drvinfo(router,pa_bay)))     if (!d || (port_id > 0))
1689        return(-1);        return(-1);
1690    
1691     if (d->nio) {     if (d->nio) {
# Line 1672  int dev_c7200_pa_a1_unset_nio(c7200_t *r Line 1697  int dev_c7200_pa_a1_unset_nio(c7200_t *r
1697  }  }
1698    
1699  /* PA-A1 driver */  /* PA-A1 driver */
1700  struct c7200_pa_driver dev_c7200_pa_a1_driver = {  struct cisco_card_driver dev_c7200_pa_a1_driver = {
1701     "PA-A1", 1,     "PA-A1", 1, 0,
1702     dev_c7200_pa_a1_init,     dev_c7200_pa_a1_init,
1703     dev_c7200_pa_a1_shutdown,     dev_c7200_pa_a1_shutdown,
1704       NULL,
1705     dev_c7200_pa_a1_set_nio,     dev_c7200_pa_a1_set_nio,
1706     dev_c7200_pa_a1_unset_nio,     dev_c7200_pa_a1_unset_nio,
1707     NULL,     NULL,

Legend:
Removed from v.2  
changed lines
  Added in v.11

  ViewVC Help
Powered by ViewVC 1.1.26