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

📄 dev_c7200.c

📁 思科路由器仿真器,用来仿7200系列得,可以在电脑上模拟路由器
💻 C
📖 第 1 页 / 共 5 页
字号:
{   c7200_t *router = VM_C7200(vm);   int i;   /* Stop all CPUs */   if (vm->cpu_group != NULL) {      vm_stop(vm);      if (cpu_group_sync_state(vm->cpu_group) == -1) {         vm_error(vm,"unable to sync with system CPUs.\n");         return(FALSE);      }   }   /* Remove NIO bindings */   for(i=0;i<vm->nr_slots;i++)      vm_slot_remove_all_nio_bindings(vm,i);   /* Free specific HW resources */   c7200_free_hw_ressources(router);   /* Free EEPROMs */   cisco_eeprom_free(&router->cpu_eeprom);   cisco_eeprom_free(&router->mp_eeprom);   cisco_eeprom_free(&router->pem_eeprom);   /* Free all resources used by VM */   vm_free(vm);   /* Free the router structure */   free(router);   return(TRUE);}/* Save configuration of a C7200 instance */static void c7200_save_config(vm_instance_t *vm,FILE *fd){   c7200_t *router = VM_C7200(vm);   fprintf(fd,"c7200 set_npe %s %s\n",vm->name,router->npe_driver->npe_type);   fprintf(fd,"c7200 set_midplane %s %s\n\n",vm->name,router->midplane_type);}/* Set EEPROM for the specified slot */int c7200_set_slot_eeprom(c7200_t *router,u_int slot,                          struct cisco_eeprom *eeprom){   if (slot >= C7200_MAX_PA_BAYS)      return(-1);   switch(slot) {      /* Group 1: bays 0, 1, 3, 4 */      case 0:         router->pa_eeprom_g1.eeprom[0] = eeprom;         break;      case 1:         router->pa_eeprom_g1.eeprom[1] = eeprom;         break;      case 3:         router->pa_eeprom_g1.eeprom[2] = eeprom;         break;      case 4:         router->pa_eeprom_g1.eeprom[3] = eeprom;         break;      /* Group 2: bays 2, 5, 6 */      case 2:         router->pa_eeprom_g2.eeprom[0] = eeprom;         break;              case 5:         router->pa_eeprom_g2.eeprom[1] = eeprom;         break;      case 6:         router->pa_eeprom_g2.eeprom[2] = eeprom;         break;   }   return(0);}/* Get slot/port corresponding to specified network IRQ */static inline void c7200_net_irq_get_slot_port(u_int irq,u_int *slot,u_int *port){   irq -= C7200_NETIO_IRQ_BASE;   *port = irq & C7200_NETIO_IRQ_PORT_MASK;   *slot = irq >> C7200_NETIO_IRQ_PORT_BITS;}/* Get network IRQ for specified slot/port */u_int c7200_net_irq_for_slot_port(u_int slot,u_int port){   u_int irq;   irq = (slot << C7200_NETIO_IRQ_PORT_BITS) + port;   irq += C7200_NETIO_IRQ_BASE;   return(irq);}/* Set NPE eeprom definition */static int c7200_npe_set_eeprom(c7200_t *router){   const struct cisco_eeprom *eeprom;   if (!(eeprom = c7200_get_cpu_eeprom(router->npe_driver->npe_type))) {      vm_error(router->vm,"unknown NPE \"%s\" (internal error)!\n",              router->npe_driver->npe_type);      return(-1);   }   if (cisco_eeprom_copy(&router->cpu_eeprom,eeprom) == -1) {      vm_error(router->vm,"unable to set NPE EEPROM.\n");      return(-1);   }   return(0);}/* Set PEM eeprom definition */static int c7200_pem_set_eeprom(c7200_t *router){   const struct cisco_eeprom *eeprom;   if (!(eeprom = c7200_get_pem_eeprom(router->npe_driver->npe_type))) {      vm_error(router->vm,"no PEM EEPROM found for NPE type \"%s\"!\n",              router->npe_driver->npe_type);      return(-1);   }   if (cisco_eeprom_copy(&router->pem_eeprom,eeprom) == -1) {      vm_error(router->vm,"unable to set PEM EEPROM.\n");      return(-1);   }   return(0);}/* Get an NPE driver */struct c7200_npe_driver *c7200_npe_get_driver(char *npe_type){   int i;   for(i=0;npe_drivers[i].npe_type;i++)      if (!strcmp(npe_drivers[i].npe_type,npe_type))         return(&npe_drivers[i]);   return NULL;}/* Set the NPE type */int c7200_npe_set_type(c7200_t *router,char *npe_type){   struct c7200_npe_driver *driver;   if (router->vm->status == VM_STATUS_RUNNING) {      vm_error(router->vm,"unable to change NPE type when online.\n");      return(-1);   }   if (!(driver = c7200_npe_get_driver(npe_type))) {      vm_error(router->vm,"unknown NPE type '%s'.\n",npe_type);      return(-1);   }   router->npe_driver = driver;   if (c7200_npe_set_eeprom(router) == -1) {      vm_error(router->vm,"unable to find NPE '%s' EEPROM!\n",               router->npe_driver->npe_type);      return(-1);   }#if 1 /* FIXME - for a later release */   /* Use a C7200-IO-FE by default in slot 0 if an I/O card is required */   if (driver->iocard_required) {      vm_slot_add_binding(router->vm,"C7200-IO-FE",0,0);      vm_slot_set_flag(router->vm,0,0,CISCO_CARD_FLAG_OVERRIDE);   }#endif   return(0);}/* Show the list of available NPE drivers */static void c7200_npe_show_drivers(void){   int i;   printf("Available C7200 NPE drivers:\n");   for(i=0;npe_drivers[i].npe_type;i++) {      printf("  * %s %s\n",             npe_drivers[i].npe_type,             !npe_drivers[i].supported ? "(NOT WORKING)" : "");   }      printf("\n");}/* Set Midplane type */int c7200_midplane_set_type(c7200_t *router,char *midplane_type){   const struct cisco_eeprom *eeprom;   m_uint8_t version;   if (router->vm->status == VM_STATUS_RUNNING) {      vm_error(router->vm,"unable to change Midplane type when online.\n");      return(-1);   }   /* Set EEPROM */   if (!(eeprom = c7200_get_midplane_eeprom(midplane_type))) {      vm_error(router->vm,"unknown Midplane \"%s\"!\n",midplane_type);      return(-1);   }   /* Copy the midplane EEPROM */   if (cisco_eeprom_copy(&router->mp_eeprom,eeprom) == -1) {      vm_error(router->vm,"unable to set midplane EEPROM.\n");      return(-1);   }   /* Set the chassis base MAC address */   c7200_burn_mac_addr(router,&router->mac_addr);   /* Get the midplane version */   cisco_eeprom_get_byte(&router->mp_eeprom,2,&version);   router->midplane_version = version;     router->midplane_type = eeprom->name;   return(0);}/* Set chassis MAC address */int c7200_midplane_set_mac_addr(c7200_t *router,char *mac_addr){   if (parse_mac_addr(&router->mac_addr,mac_addr) == -1) {      vm_error(router->vm,"unable to parse MAC address '%s'.\n",mac_addr);      return(-1);   }   /* Set the chassis base MAC address */   c7200_burn_mac_addr(router,&router->mac_addr);   return(0);}/* Create the main PCI bus for a GT64010 based system */static int c7200_init_gt64010(c7200_t *router){      vm_instance_t *vm = router->vm;   if (!(vm->pci_bus[0] = pci_bus_create("MB0/MB1/MB2",0))) {      vm_error(vm,"unable to create PCI data.\n");      return(-1);   }      return(dev_gt64010_init(vm,"gt64010",C7200_GT64K_ADDR,0x1000,                           C7200_GT64K_IRQ));}/* Create the two main PCI busses for a GT64120 based system */static int c7200_init_gt64120(c7200_t *router){   vm_instance_t *vm = router->vm;   vm->pci_bus[0] = pci_bus_create("MB0/MB1",0);   vm->pci_bus[1] = pci_bus_create("MB2",0);   if (!vm->pci_bus[0] || !vm->pci_bus[1]) {      vm_error(vm,"unable to create PCI data.\n");      return(-1);   }      return(dev_gt64120_init(vm,"gt64120",C7200_GT64K_ADDR,0x1000,                           C7200_GT64K_IRQ));}/* Create the two main PCI busses for a dual GT64120 system */static int c7200_init_dual_gt64120(c7200_t *router){   vm_instance_t *vm = router->vm;   vm->pci_bus[0] = pci_bus_create("MB0/MB1",0);   vm->pci_bus[1] = pci_bus_create("MB2",0);   if (!vm->pci_bus[0] || !vm->pci_bus[1]) {      vm_error(vm,"unable to create PCI data.\n",vm->name);      return(-1);   }      /* Initialize the first GT64120 at 0x14000000 */   if (dev_gt64120_init(vm,"gt64120(1)",C7200_GT64K_ADDR,0x1000,                        C7200_GT64K_IRQ) == -1)      return(-1);   /* Initialize the second GT64120 at 0x15000000 */   if (dev_gt64120_init(vm,"gt64120(2)",C7200_GT64K_SEC_ADDR,0x1000,                        C7200_GT64K_IRQ) == -1)      return(-1);   return(0);}/* Create the two main PCI busses for a MV64460 based system */static int c7200_init_mv64460(c7200_t *router){   vm_instance_t *vm = router->vm;   vm->pci_bus[0] = pci_bus_create("MB0/MB1",3);   vm->pci_bus[1] = pci_bus_create("MB2",0);   if (!vm->pci_bus[0] || !vm->pci_bus[1]) {      vm_error(vm,"unable to create PCI data.\n");      return(-1);   }   return(dev_mv64460_init(vm,"mv64460",C7200_G2_MV64460_ADDR,0x10000));}/* Create the PA PCI busses */static int c7200_pa_create_pci_busses(c7200_t *router){      vm_instance_t *vm = router->vm;   char bus_name[128];   int i;   for(i=1;i<C7200_MAX_PA_BAYS;i++) {      snprintf(bus_name,sizeof(bus_name),"PA Slot %d",i);      vm->pci_bus_pool[i] = pci_bus_create(bus_name,-1);      if (!vm->pci_bus_pool[i])         return(-1);   }   return(0);}/* Create a PA bridge, depending on the midplane */static int c7200_pa_init_pci_bridge(c7200_t *router,u_int pa_bay,                                    struct pci_bus *pci_bus,int pci_device){   struct pci_bus *pa_bus;   pa_bus = router->vm->slots_pci_bus[pa_bay];   switch(router->midplane_version) {      case 0:      case 1:         dev_dec21050_init(pci_bus,pci_device,pa_bus);         break;      default:         dev_dec21150_init(pci_bus,pci_device,pa_bus);   }   return(0);}/*  * Hidden "I/O" PCI bridge hack for PCMCIA controller. * * On NPE-175, NPE-225, NPE-300 and NPE-400, PCMCIA controller is * identified on PCI as Bus=2,Device=16. On NPE-G1, this is Bus=17,Device=16. * * However, I don't understand how the bridging between PCI bus 1 and 2 * is done (16 and 17 on NPE-G1).  * * Maybe I'm missing something about PCI-to-PCI bridge mechanism, or there * is a special hidden device that does the job silently (it should be * visible on the PCI bus...) * * BTW, it works. */static int c7200_create_io_pci_bridge(c7200_t *router,struct pci_bus *parent_bus){   vm_instance_t *vm = router->vm;   /* Create the PCI bus where the PCMCIA controller will seat */   if (!(vm->pci_bus_pool[16] = pci_bus_create("I/O secondary bus",-1)))      return(-1);   /* Create the hidden bridge with "special" handling... */   if (!(router->io_pci_bridge = pci_bridge_add(parent_bus)))      return(-1);   router->io_pci_bridge->skip_bus_check = TRUE;   pci_bridge_map_bus(router->io_pci_bridge,vm->pci_bus_pool[16]);   router->pcmcia_bus = vm->pci_bus_pool[16];   return(0);}/* Initialize an NPE-100 board */int c7200_init_npe100(c7200_t *router){      vm_instance_t *vm = router->vm;   int i;   /* Set the processor type: R4600 */   mips64_set_prid(CPU_MIPS64(vm->boot_cpu),MIPS_PRID_R4600);   /* Initialize the Galileo GT-64010 system controller */   if (c7200_init_gt64010(router) == -1)      return(-1);   /* PCMCIA controller is on bus 0 */   router->pcmcia_bus = vm->pci_bus[0];   /* Initialize the PA PCI busses */   if (c7200_pa_create_pci_busses(router) == -1)      return(-1);   /* Create PCI busses for PA Bays 1,3,5 and PA Bays 2,4,6 */   vm->pci_bus_pool[24] = pci_bus_create("PA Slots 1,3,5",-1);   vm->pci_bus_pool[25] = pci_bus_create("PA Slots 2,4,6",-1);   /* PCI bridges (MB0/MB1, MB0/MB2) */   dev_dec21050_init(vm->pci_bus[0],1,NULL);   dev_dec21050_init(vm->pci_bus[0],2,vm->pci_bus_pool[24]);   dev_dec21050_init(vm->pci_bus[0],3,NULL);   dev_dec21050_init(vm->pci_bus[0],4,vm->pci_bus_pool[25]);   /* Map the PA PCI busses */   vm->slots_pci_bus[0] = vm->pci_bus[0];   for(i=1;i<C7200_MAX_PA_BAYS;i++)      vm->slots_pci_bus[i] = vm->pci_bus_pool[i];

⌨️ 快捷键说明

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