⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dev_c7200_bri.c

📁 思科路由器仿真器,用来仿7200系列得,可以在电脑上模拟路由器-Cisco router simulator, used to fake a 7200 series can be simulated
💻 C
📖 第 1 页 / 共 2 页
字号:
   return(TRUE);}/* Scan a channel TX ring */static inline int m32_tx_scan(struct m32_data *d,u_int chan_id){   struct m32_channel *chan = &d->channels[chan_id];   m_uint8_t pkt[M32_MAX_PKT_SIZE];   struct m32_tx_desc txd;   m_uint32_t pkt_len;   if (!chan->tx_current)      return(FALSE);   switch(chan->poll_mode) {      case 0:                 m32_set_cfgw(d,M32_OFFSET_CTDA+(chan_id*4),chan->tx_current);         /* Try to transmit data */         if (!m32_tx_acquire(d,chan->tx_current,&txd))            return(FALSE);         printf("M32: TX scanner for channel %u (tx_current=0x%8.8x)\n",                chan_id,chan->tx_current);         printf("M32: params=0x%8.8x, next=0x%8.8x.\n",txd.params,txd.ntdp);         /* The descriptor has been acquired */         pkt_len = (txd.params & M32_TXDESC_NO_MASK) >> M32_TXDESC_NO_SHIFT;         physmem_copy_from_vm(d->vm,pkt,txd.tdp,pkt_len);         printf("M32: data_ptr=0x%x, len=%u\n",txd.tdp,pkt_len);         mem_dump(stdout,pkt,pkt_len);         /* Poll the next descriptor (wait for HOLD bit to be reset */         chan->poll_mode = 1;           if (txd.params & M32_TXDESC_FE) {            m32_post_interrupt(d,M32_II_FI | chan_id);            vm_set_irq(d->vm,2);         }         break;      case 1:         if (!m32_tx_acquire_next(d,&chan->tx_current))            return(FALSE);         printf("M32: branching on next descriptor 0x%x\n",chan->tx_current);         chan->poll_mode = 0;         break;   }   return(TRUE);}/* Scan the all channel TX rings */static void m32_tx_scan_all_channels(struct m32_data *d){   u_int i;   for(i=0;i<M32_NR_CHANNELS;i++)      m32_tx_scan(d,i);}/*  * Handle an action request. * * IN, ICO and RES bits are mutually exclusive. */static int m32_action_req(struct m32_data *d,m_uint32_t action){   u_int chan_id;   /* Define a new Interrupt Queue */   if (action & M32_AS_IA) {      d->iq_base_addr = d->iq_cur_addr = m32_get_cfgw(d,4);      d->iq_size = ((m32_get_cfgw(d,8) & 0xFF) + 1) * 16 * sizeof(m_uint32_t);   }   /* Initialization Procedure */   if (action & M32_AS_IN) {      /* Fetch all timeslots assignments */      m32_fetch_all_ts(d);      /* Fetch specification of the specified channel */      chan_id = (action & M32_AS_CHAN_MASK) >> M32_AS_CHAN_SHIFT;      m32_fetch_chan_spec(d,chan_id);      /* Generate acknowledge */      if (!(action & M32_AS_IM))         m32_post_interrupt(d,M32_II_ARACK);   }   /* Initialize Channel Only */   if (action & M32_AS_ICO) {      /* Fetch specification of the specified channel */      chan_id = (action & M32_AS_CHAN_MASK) >> M32_AS_CHAN_SHIFT;      m32_fetch_chan_spec(d,chan_id);      /* Generate acknowledge */      if (!(action & M32_AS_IM))         m32_post_interrupt(d,M32_II_ARACK);   }   /* Reset */   if (action & M32_AS_RES) {      /* Fetch all timeslots assignments */      m32_fetch_all_ts(d);      /* Fetch all channel specifications */      m32_fetch_all_chan_spec(d);            /* Generate acknowledge */      if (!(action & M32_AS_IM))         m32_post_interrupt(d,M32_II_ARACK);   }   return(0);}/* Munich32 general access function */static void *m32_gen_access(struct m32_data *d,cpu_mips_t *cpu,                            m_uint32_t offset,u_int op_size,u_int op_type,                            m_uint64_t *data){   u_int p;   switch(offset) {      /* Action Specification */      case 0x0:         if (op_type == MTS_WRITE)            m32_action_req(d,*data);         return NULL;      /* Configuration memory */      default:         switch(op_size) {            case 4:               if (op_type == MTS_READ)                  *data = m32_get_cfgw(d,offset);               else                  m32_set_cfgw(d,offset,*data);               break;            case 1:               if (op_type == MTS_READ) {                  *data = m32_get_cfgw(d,offset & ~0x03);                  *data >>= (24 - ((offset & 0x03) << 3));                  *data &= 0xFF;               } else {                  printf("UNSUPPORTED(1)!!!!\n");               }               break;            case 2:               if (op_type == MTS_READ) {                  *data = m32_get_cfgw(d,offset & ~0x03);                  *data >>= (16 - ((offset & 0x03) << 3));                  *data &= 0xFFFF;               } else {                  printf("UNSUPPORTED(2)!!!!\n");               }               break;            case 8:               if (op_type == MTS_READ) {                  *data = (m_uint64_t)m32_get_cfgw(d,offset) << 32;                  *data |= m32_get_cfgw(d,offset+4);               } else {                  printf("UNSUPPORTED(8)!!!!\n");               }               break;            default:               printf("UNSUPPORTED (size=%u)!!!\n",op_size);         }   }   return NULL;}/* *  pa_4b_access() */void *pa_4b_access(cpu_mips_t *cpu,struct vdevice *dev,m_uint32_t offset,                   u_int op_size,u_int op_type,m_uint64_t *data){   struct pa_4b_data *d = dev->priv_data;   static m_uint32_t test1,test2,test3;   if (op_type == MTS_READ)      *data = 0xFFFFFFFF;#if DEBUG_ACCESS   if (offset >= MUNICH32_MEM_SIZE) {      if (op_type == MTS_READ) {         cpu_log(cpu,d->name,"read  access to offset = 0x%x, pc = 0x%llx "                 "(op_size=%u)\n",offset,cpu->pc,op_size);      } else {         cpu_log(cpu,d->name,"write access to vaddr = 0x%x, pc = 0x%llx, "                 "val = 0x%llx (op_size=%u)\n",offset,cpu->pc,*data,op_size);      }   }#endif   /* Specific cases */   switch(offset) {      case 0x40008:         if (op_type == MTS_READ)            *data = 0xFF;         break;      case 0x40030:         if (op_type == MTS_READ)            *data = 0xFF;         break;      case 0x40000:         if (op_type == MTS_READ)            *data = 0xFFFF;         break;      case 0x40020:         if (op_type == MTS_READ)            *data = 0xFFFFFFFF; //test2;         else            test2 = *data;         break;      case 0x40021:         if (op_type == MTS_READ)            *data = 0xFF; //test3;         else            test3 = *data;         break;      case 0x40023:         if (op_type == MTS_READ)            *data = 0xFF;         break;      case 0x40040:         if (op_type == MTS_READ)            *data = 0x04;         break;         /* Channels enabled ? */      case 0x40044:         if (op_type == MTS_READ)            *data = 0xFF;  /* 0x02 */         break;         /* SID */      case 0x40050:         if (op_type == MTS_WRITE) {            test1 = *data;         } else {            switch(test1) {               case TP3420_SID_PUP:                  *data = TP3420_SR_AI;                  vm_set_irq(d->vm,C7200_PA_MGMT_IRQ);                  break;               case TP3420_SID_ENST:                  *data = 0xB0;                  break;               default:                  *data = 0x03;                  break;            }         }         break;      default:         if (offset < MUNICH32_MEM_SIZE)            return(m32_gen_access(&d->m32_data,cpu,offset - d->m32_offset,                                  op_size,op_type,data));   }   return NULL;}/* * pci_munich32_read() */static m_uint32_t pci_munich32_read(cpu_mips_t *cpu,struct pci_device *dev,                                    int reg){      struct pa_4b_data *d = dev->priv_data;#if DEBUG_ACCESS   BRI_LOG(d,"read PCI register 0x%x\n",reg);#endif   switch(reg) {      case PCI_REG_BAR0:         return(d->dev->phys_addr);      default:         return(0);   }}/* * pci_munich32_write() */static void pci_munich32_write(cpu_mips_t *cpu,struct pci_device *dev,                               int reg,m_uint32_t value){   struct pa_4b_data *d = dev->priv_data;#if DEBUG_ACCESS   BRI_LOG(d,"write 0x%x to PCI register 0x%x\n",value,reg);#endif   switch(reg) {      case PCI_REG_BAR0:         vm_map_device(cpu->vm,d->dev,(m_uint64_t)value);         BRI_LOG(d,"registers are mapped at 0x%x\n",value);         break;   }}/* * dev_c7200_bri_init() * * Add a PA-4B/PA-8B port adapter into specified slot. */int dev_c7200_pa_bri_init(c7200_t *router,char *name,u_int pa_bay){   struct pci_device *pci_dev;   struct pa_4b_data *d;   struct vdevice *dev;   /* Allocate the private data structure for PA-4B chip */   if (!(d = malloc(sizeof(*d)))) {      fprintf(stderr,"%s (PA-4B): out of memory\n",name);      return(-1);   }   memset(d,0,sizeof(*d));   d->m32_offset = 0x08;   d->m32_data.vm = router->vm;   /* Set the EEPROM */   c7200_pa_set_eeprom(router,pa_bay,cisco_eeprom_find_pa("PA-4B"));   /* Add as PCI device PA-4B */   pci_dev = pci_dev_add(router->pa_bay[pa_bay].pci_map,name,                         BRI_PCI_VENDOR_ID,BRI_PCI_PRODUCT_ID,                         0,0,C7200_NETIO_IRQ,d,                         NULL,pci_munich32_read,pci_munich32_write);   if (!pci_dev) {      fprintf(stderr,"%s (PA-4B): unable to create PCI device.\n",name);      return(-1);   }   /* Create the PA-4B structure */   d->name        = name;   d->pci_dev     = pci_dev;   d->vm          = router->vm;   /* Create the device itself */   if (!(dev = dev_create(name))) {      fprintf(stderr,"%s (PA-4B): unable to create device.\n",name);      return(-1);   }   dev->phys_len  = 0x800000;   dev->handler   = pa_4b_access;   /* Store device info */   dev->priv_data = d;   d->dev = dev;   /* Map this device to the VM */   vm_bind_device(router->vm,dev);   /* Store device info into the router structure */   return(c7200_pa_set_drvinfo(router,pa_bay,d));}/* Remove a PA-4B from the specified slot */int dev_c7200_pa_bri_shutdown(c7200_t *router,u_int pa_bay){   struct c7200_pa_bay *bay;   struct pa_4b_data *d;   if (!(bay = c7200_pa_get_info(router,pa_bay)))      return(-1);   d = bay->drv_info;   /* Remove the PA EEPROM */   c7200_pa_unset_eeprom(router,pa_bay);   /* Remove the PCI device */   pci_dev_remove(d->pci_dev);   /* Remove the device from the CPU address space */   vm_unbind_device(router->vm,d->dev);   cpu_group_rebuild_mts(router->vm->cpu_group);   /* Free the device structure itself */   free(d->dev);   free(d);   return(0);}/* Bind a Network IO descriptor to a specific port */int dev_c7200_pa_bri_set_nio(c7200_t *router,u_int pa_bay,u_int port_id,                             netio_desc_t *nio){   struct pa_4b_data *d;   if ((port_id > 0) || !(d = c7200_pa_get_drvinfo(router,pa_bay)))      return(-1);   if (d->nio != NULL)      return(-1);   d->nio = nio;   /* TEST */   d->m32_data.tx_tid = ptask_add((ptask_callback)m32_tx_scan_all_channels,&d->m32_data,NULL);   //netio_rxl_add(nio,(netio_rx_handler_t)dev_pa_4b_handle_rxring,d,NULL);   return(0);}/* Bind a Network IO descriptor to a specific port */int dev_c7200_pa_bri_unset_nio(c7200_t *router,u_int pa_bay,u_int port_id){   struct pa_4b_data *d;   if ((port_id > 0) || !(d = c7200_pa_get_drvinfo(router,pa_bay)))      return(-1);   if (d->nio) {      /* TEST */      ptask_remove(d->m32_data.tx_tid);      //netio_rxl_remove(d->nio);      d->nio = NULL;   }   return(0);}/* PA-4B driver */struct c7200_pa_driver dev_c7200_pa_4b_driver = {   "PA-4B", 0,    dev_c7200_pa_bri_init,   dev_c7200_pa_bri_shutdown,   dev_c7200_pa_bri_set_nio,   dev_c7200_pa_bri_unset_nio,   NULL,};

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -