📄 dev_c3600.c
字号:
case 4: if (!cisco_eeprom_v4_find_field(&router->mb_eeprom,0xC3,&offset)) { cisco_eeprom_set_region(&router->mb_eeprom,offset, addr->eth_addr_byte,6); } break; default: vm_error(router->vm,"c3600_burn_mac_addr: unable to handle " "EEPROM version %u\n",eeprom_ver); return(-1); } return(0);}/* Set chassis MAC address */int c3600_chassis_set_mac_addr(c3600_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 */ c3600_burn_mac_addr(router,&router->mac_addr); return(0);}/* Set the chassis type */int c3600_chassis_set_type(c3600_t *router,char *chassis_type){ struct c3600_chassis_driver *driver; if (router->vm->status == VM_STATUS_RUNNING) { vm_error(router->vm,"unable to change chassis type when online.\n"); return(-1); } if (!(driver = c3600_chassis_get_driver(chassis_type))) { vm_error(router->vm,"unknown chassis type '%s'.\n",chassis_type); return(-1); } router->chassis_driver = driver; /* Copy the mainboard EEPROM */ if (cisco_eeprom_copy(&router->mb_eeprom,driver->eeprom) == -1) { vm_error(router->vm,"unable to set chassis EEPROM '%s'.\n",chassis_type); return(-1); } /* Set the chassis base MAC address */ c3600_burn_mac_addr(router,&router->mac_addr); return(0);}/* Get the chassis ID */int c3600_chassis_get_id(c3600_t *router){ if (router->chassis_driver) return(router->chassis_driver->chassis_id); return(-1);}/* Show the list of available chassis drivers */void c3600_chassis_show_drivers(void){ int i; printf("Available C3600 chassis drivers:\n"); for(i=0;chassis_drivers[i].chassis_type;i++) { printf(" * %s %s\n", chassis_drivers[i].chassis_type, !chassis_drivers[i].supported ? "(NOT WORKING)" : ""); } printf("\n");}/* Create the main PCI bus for a GT64010 based system */static int c3600_init_gt64010(c3600_t *router){ if (!(router->vm->pci_bus[0] = pci_bus_create("PCI bus",0))) { vm_error(router->vm,"unable to create PCI data.\n"); return(-1); } return(dev_gt64010_init(router->vm,"gt64010",C3600_GT64K_ADDR,0x1000, C3600_GT64K_IRQ));}/* Create the two main PCI busses for a GT64120 based system */static int c3600_init_gt64120(c3600_t *router){ vm_instance_t *vm = router->vm; vm->pci_bus[0] = pci_bus_create("PCI bus #0",0); vm->pci_bus[1] = pci_bus_create("PCI bus #1",0); if (!vm->pci_bus[0] || !vm->pci_bus[1]) { vm_error(router->vm,"unable to create PCI data.\n"); return(-1); } return(dev_gt64120_init(vm,"gt64120",C3600_GT64K_ADDR,0x1000, C3600_GT64K_IRQ));}/* Initialize a Cisco 3620 */static int c3620_init(c3600_t *router){ vm_instance_t *vm = router->vm; int i; /* Set the processor type: R4700 */ mips64_set_prid(vm->boot_cpu,MIPS_PRID_R4700); /* Initialize the Galileo GT-64010 PCI controller */ if (c3600_init_gt64010(router) == -1) return(-1); /* Initialize PCI map (no PCI bridge for this chassis) */ for(i=0;i<C3600_MAX_NM_BAYS;i++) router->nm_bay[i].pci_map = vm->pci_bus[0]; vm->elf_machine_id = C3620_ELF_MACHINE_ID; return(0);}/* Initialize a Cisco 3640 */static int c3640_init(c3600_t *router){ vm_instance_t *vm = router->vm; struct nm_bay_info *bay; int i; /* Set the processor type: R4700 */ mips64_set_prid(vm->boot_cpu,MIPS_PRID_R4700); /* Initialize the Galileo GT-64010 PCI controller */ if (c3600_init_gt64010(router) == -1) return(-1); /* Create the NM PCI busses */ vm->pci_bus_pool[0] = pci_bus_create("NM Slots 0,2",-1); vm->pci_bus_pool[1] = pci_bus_create("NM Slots 1,3",-1); /* Initialize PCI map and PCI bridges */ for(i=0;i<=3;i++) { bay = c3600_nm_get_bay_info(3640,i); /* Map the NM PCI bus */ router->nm_bay[i].pci_map = vm->pci_bus_pool[i & 1]; if (bay && (bay->pci_bridge_device != -1)) dev_dec21052_init(vm->pci_bus[0],bay->pci_bridge_device, router->nm_bay[i].pci_map); } vm->elf_machine_id = C3640_ELF_MACHINE_ID; return(0);}/* Initialize a Cisco 3660 */static int c3660_init(c3600_t *router){ vm_instance_t *vm = router->vm; struct nm_bay_info *bay; char bus_name[128]; int i; /* Set the processor type: R5271 */ mips64_set_prid(vm->boot_cpu,MIPS_PRID_R527x); /* Initialize the Galileo GT-64120 PCI controller */ if (c3600_init_gt64120(router) == -1) return(-1); /* Create the NM PCI busses */ for(i=1;i<=6;i++) { snprintf(bus_name,sizeof(bus_name),"NM Slot %d",i); vm->pci_bus_pool[i] = pci_bus_create(bus_name,-1); } /* Slot 0 is mapped to the first bus of GT64120 */ router->nm_bay[0].pci_map = vm->pci_bus[0]; /* Initialize PCI map and PCI bridges */ for(i=1;i<C3600_MAX_NM_BAYS;i++) { bay = c3600_nm_get_bay_info(3660,i); /* Map the NM PCI bus */ router->nm_bay[i].pci_map = vm->pci_bus_pool[i]; /* Slots 1-6 are mapped to the second bus of GT64120 */ if (bay && (bay->pci_bridge_device != -1)) dev_dec21152_init(vm->pci_bus[1],bay->pci_bridge_device, router->nm_bay[i].pci_map); } /* The motherboard has 2 integrated FastEthernet ports */ c3600_nm_add_binding(router,"Leopard-2FE",0); vm->elf_machine_id = C3640_ELF_MACHINE_ID; return(0);}/* Show C3600 hardware info */void c3600_show_hardware(c3600_t *router){ vm_instance_t *vm = router->vm; printf("C3600 instance '%s' (id %d):\n",vm->name,vm->instance_id); printf(" VM Status : %d\n",vm->status); printf(" RAM size : %u Mb\n",vm->ram_size); printf(" NVRAM size : %u Kb\n",vm->nvram_size); printf(" Chassis : %s\n",router->chassis_driver->chassis_type); printf(" IOS image : %s\n\n",vm->ios_image); if (vm->debug_level > 0) { dev_show_list(vm); pci_dev_show_list(vm->pci_bus[0]); pci_dev_show_list(vm->pci_bus[1]); printf("\n"); }}/* Initialize default parameters for a C3600 */void c3600_init_defaults(c3600_t *router){ vm_instance_t *vm = router->vm; n_eth_addr_t *m; m_uint16_t pid; pid = (m_uint16_t)getpid(); /* Generate a chassis MAC address based on the instance ID */ m = &router->mac_addr; m->eth_addr_byte[0] = vm_get_mac_addr_msb(vm); m->eth_addr_byte[1] = vm->instance_id & 0xFF; m->eth_addr_byte[2] = pid >> 8; m->eth_addr_byte[3] = pid & 0xFF; m->eth_addr_byte[4] = 0x00; m->eth_addr_byte[5] = 0x00; c3600_init_eeprom_groups(router); c3600_chassis_set_type(router,C3600_DEFAULT_CHASSIS); vm->ram_mmap = C3600_DEFAULT_RAM_MMAP; vm->ram_size = C3600_DEFAULT_RAM_SIZE; vm->rom_size = C3600_DEFAULT_ROM_SIZE; vm->nvram_size = C3600_DEFAULT_NVRAM_SIZE; vm->conf_reg_setup = C3600_DEFAULT_CONF_REG; vm->clock_divisor = C3600_DEFAULT_CLOCK_DIV; vm->nvram_rom_space = C3600_NVRAM_ROM_RES_SIZE; router->nm_iomem_size = C3600_DEFAULT_IOMEM_SIZE; vm->pcmcia_disk_size[0] = C3600_DEFAULT_DISK0_SIZE; vm->pcmcia_disk_size[1] = C3600_DEFAULT_DISK1_SIZE; /* Enable NVRAM operations to load/store configs */ vm->nvram_extract_config = c3600_nvram_extract_config; vm->nvram_push_config = c3600_nvram_push_config;}/* Initialize the C3600 Platform */int c3600_init_platform(c3600_t *router){ vm_instance_t *vm = router->vm; struct c3600_nm_bay *nm_bay; cpu_mips_t *cpu; int i; /* Copy config register setup into "active" config register */ vm->conf_reg = vm->conf_reg_setup; /* Create Console and AUX ports */ vm_init_vtty(vm); /* Create a CPU group */ vm->cpu_group = cpu_group_create("System CPU"); /* Initialize the virtual MIPS processor */ if (!(cpu = cpu_create(vm,0))) { vm_error(vm,"unable to create CPU!\n"); return(-1); } /* Add this CPU to the system CPU group */ cpu_group_add(vm->cpu_group,cpu); vm->boot_cpu = cpu; /* Mark the Network IO interrupt as high priority */ cpu->irq_idle_preempt[C3600_NETIO_IRQ] = TRUE; cpu->irq_idle_preempt[C3600_GT64K_IRQ] = TRUE; cpu->irq_idle_preempt[C3600_DUART_IRQ] = TRUE; /* Copy some parameters from VM to CPU (idle PC, ...) */ cpu->idle_pc = vm->idle_pc; if (vm->timer_irq_check_itv) cpu->timer_irq_check_itv = vm->timer_irq_check_itv; /* Get chassis specific driver */ if (!router->chassis_driver) { vm_error(vm,"no chassis defined.\n"); return(-1); } /* Remote emulator control */ dev_remote_control_init(vm,0x16000000,0x1000); /* Bootflash */ dev_bootflash_init(vm,"bootflash",C3600_BOOTFLASH_ADDR,(8 * 1048576)); /* NVRAM and calendar */ dev_nvram_init(vm,"nvram", C3600_NVRAM_ADDR,vm->nvram_size*1024,&vm->conf_reg); /* Bit-bucket zone */ dev_zero_init(vm,"zero",C3600_BITBUCKET_ADDR,0xc00000); /* IO FPGA */ if (dev_c3600_iofpga_init(router,C3600_IOFPGA_ADDR,0x40000) == -1) return(-1); /* PCI IO space */ if (!(vm->pci_io_space = pci_io_data_init(vm,C3600_PCI_IO_ADDR))) return(-1); /* Initialize the chassis */ if (router->chassis_driver->chassis_init(router) == -1) return(-1); /* Initialize RAM */ vm_ram_init(vm,0x00000000ULL); /* Initialize ROM */ if (!vm->rom_filename) { /* use embedded ROM */ dev_rom_init(vm,"rom",C3600_ROM_ADDR,vm->rom_size*1048576); } else { /* use alternate ROM */ dev_ram_init(vm,"rom",TRUE,TRUE,NULL, C3600_ROM_ADDR,vm->rom_size*1048576); } /* Initialize the NS16552 DUART */ dev_ns16552_init(vm,C3600_DUART_ADDR,0x1000,3,C3600_DUART_IRQ, vm->vtty_con,vm->vtty_aux); /* Cirrus Logic PD6729 (PCI-to-PCMCIA host adapter) */ dev_clpd6729_init(vm,vm->pci_bus[0],20,vm->pci_io_space,0x4402,0x4403); /* Initialize Network Modules */ for(i=0;i<C3600_MAX_NM_BAYS;i++) { nm_bay = &router->nm_bay[i]; if (!nm_bay->dev_type) continue; if (c3600_nm_init(router,i) == -1) { vm_error(vm,"unable to create Network Module \"%s\"\n", nm_bay->dev_type); return(-1); } } /* Show device list */ c3600_show_hardware(router); return(0);}/* Boot the IOS image */int c3600_boot_ios(c3600_t *router){ vm_instance_t *vm = router->vm; if (!vm->boot_cpu) return(-1); /* Suspend CPU activity since we will restart directly from ROM */ vm_suspend(vm); /* Check that CPU activity is really suspended */ if (cpu_group_sync_state(vm->cpu_group) == -1) { vm_error(vm,"unable to sync with system CPUs.\n"); return(-1); } /* Reset the boot CPU */ mips64_reset(vm->boot_cpu); /* Load IOS image */ if (mips64_load_elf_image(vm->boot_cpu,vm->ios_image, (vm->ghost_status == VM_GHOST_RAM_USE), &vm->ios_entry_point) < 0) { vm_error(vm,"failed to load Cisco IOS image '%s'.\n",vm->ios_image); return(-1); } /* Launch the simulation */ printf("\nC3600 '%s': starting simulation (CPU0 PC=0x%llx), " "JIT %sabled.\n", vm->name,vm->boot_cpu->pc,vm->jit_use ? "en":"dis"); vm_log(vm,"C3600_BOOT", "starting instance (CPU0 PC=0x%llx,idle_pc=0x%llx,JIT %s)\n", vm->boot_cpu->pc,vm->boot_cpu->idle_pc,vm->jit_use ? "on":"off"); /* Start main CPU */ if (vm->ghost_status != VM_GHOST_RAM_GENERATE) { vm->status = VM_STATUS_RUNNING; cpu_start(vm->boot_cpu); } else { vm->status = VM_STATUS_SHUTDOWN; } return(0);}/* Initialize a Cisco 3600 instance */int c3600_init_instance(c3600_t *router){ vm_instance_t *vm = router->vm; m_uint32_t rom_entry_point; cpu_mips_t *cpu0; if (!vm->ios_image) { vm_error(vm,"no Cisco IOS image defined."); return(-1); } /* Initialize the C3600 platform */ if (c3600_init_platform(router) == -1) { vm_error(vm,"unable to initialize the platform hardware.\n"); return(-1); } /* Load IOS configuration file */ if (vm->ios_config != NULL) { vm_nvram_push_config(vm,vm->ios_config); vm->conf_reg &= ~0x40; } /* Load ROM (ELF image or embedded) */ cpu0 = vm->boot_cpu; rom_entry_point = (m_uint32_t)MIPS_ROM_PC; if ((vm->rom_filename != NULL) && (mips64_load_elf_image(cpu0,vm->rom_filename,0,&rom_entry_point) < 0)) { vm_error(vm,"unable to load alternate ROM '%s', " "fallback to embedded ROM.\n\n",vm->rom_filename); vm->rom_filename = NULL; } /* Load symbol file */ if (vm->sym_filename) { mips64_sym_load_file(cpu0,vm->sym_filename); cpu0->sym_trace = 1; } return(c3600_boot_ios(router));}/* Stop a Cisco 3600 instance */int c3600_stop_instance(c3600_t *router){ vm_instance_t *vm = router->vm; printf("\nC3600 '%s': stopping simulation.\n",vm->name); vm_log(vm,"C3600_STOP","stopping simulation.\n"); /* 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(-1); } } /* Free resources that were used during execution to emulate hardware */ c3600_nm_shutdown_all(router); vm_hardware_shutdown(vm); return(0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -