📄 dev_c6sup1.c
字号:
return(0);}/* Show SUP1 hardware info */void c6sup1_show_hardware(c6sup1_t *router){ vm_instance_t *vm = router->vm; printf("C6SUP1 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(" IOMEM size : %u Mb\n",vm->iomem_size); printf(" NVRAM size : %u Kb\n",vm->nvram_size); 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 SUP1 */static void c6sup1_init_defaults(c6sup1_t *router){ vm_instance_t *vm = router->vm; n_eth_addr_t *m; m_uint16_t pid; /* Set platform slots characteristics */ vm->nr_slots = C6SUP1_MAX_PA_BAYS; vm->slots_type = CISCO_CARD_TYPE_PA; vm->slots_drivers = pa_drivers; 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; /* Default slot: 1 */ router->sup_slot = 1; c6sup1_init_eeprom_groups(router); /* Create EOBC and IBC interfaces */ vm_slot_add_binding(vm,"C6SUP1_EOBC",0,0); vm_slot_add_binding(vm,"C6SUP1_IBC",1,0); vm->ram_mmap = C6SUP1_DEFAULT_RAM_MMAP; vm->ram_size = C6SUP1_DEFAULT_RAM_SIZE; vm->rom_size = C6SUP1_DEFAULT_ROM_SIZE; vm->nvram_size = C6SUP1_DEFAULT_NVRAM_SIZE; vm->iomem_size = 0; vm->conf_reg_setup = C6SUP1_DEFAULT_CONF_REG; vm->clock_divisor = C6SUP1_DEFAULT_CLOCK_DIV; vm->nvram_rom_space = C6SUP1_NVRAM_ROM_RES_SIZE;}/* Run the checklist */static int c6sup1_checklist(c6sup1_t *router){ struct vm_instance *vm = router->vm; int res = 0; res += vm_object_check(vm,"ram"); res += vm_object_check(vm,"rom"); res += vm_object_check(vm,"nvram"); res += vm_object_check(vm,"zero"); if (res < 0) vm_error(vm,"incomplete initialization (no memory?)\n"); return(res);}/* Initialize Port Adapters */static int c6sup1_init_platform_pa(c6sup1_t *router){ return(vm_slot_init_all(router->vm));}/* Initialize the SUP1 Platform */static int c6sup1_init_platform(c6sup1_t *router){ struct vm_instance *vm = router->vm; cpu_mips_t *cpu0; cpu_gen_t *gen0; vm_obj_t *obj; /* 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 (!(gen0 = cpu_create(vm,CPU_TYPE_MIPS64,0))) { vm_error(vm,"unable to create CPU0!\n"); return(-1); } cpu0 = CPU_MIPS64(gen0); /* Add this CPU to the system CPU group */ cpu_group_add(vm->cpu_group,gen0); vm->boot_cpu = gen0; /* Initialize the IRQ routing vectors */ vm->set_irq = mips64_vm_set_irq; vm->clear_irq = mips64_vm_clear_irq; /* Mark the Network IO interrupt as high priority */ cpu0->irq_idle_preempt[C6SUP1_NETIO_IRQ] = TRUE; cpu0->irq_idle_preempt[C6SUP1_GT64K_IRQ] = TRUE; /* Copy some parameters from VM to CPU0 (idle PC, ...) */ cpu0->idle_pc = vm->idle_pc; if (vm->timer_irq_check_itv) cpu0->timer_irq_check_itv = vm->timer_irq_check_itv; /* * On the SUP1, bit 33 of physical addresses is used to bypass L2 cache. * We clear it systematically. */ cpu0->addr_bus_mask = C6SUP1_ADDR_BUS_MASK; /* Remote emulator control */ dev_remote_control_init(vm,0x16000000,0x1000); /* Bootflash (8 Mb) */ dev_bootflash_init(vm,"bootflash","c7200-bootflash-8mb", C6SUP1_BOOTFLASH_ADDR); /* NVRAM and calendar */ dev_nvram_init(vm,"nvram",C6SUP1_NVRAM_ADDR, vm->nvram_size*1024,&vm->conf_reg); /* Bit-bucket zone */ dev_zero_init(vm,"zero",C6SUP1_BITBUCKET_ADDR,0xc00000); /* Initialize the NPE board */ if (c6sup1_init_hw(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",C6SUP1_ROM_ADDR,vm->rom_size*1048576, mips64_microcode,mips64_microcode_len); } else { /* use alternate ROM */ dev_ram_init(vm,"rom",TRUE,TRUE,NULL,FALSE, C6SUP1_ROM_ADDR,vm->rom_size*1048576); } /* Byte swapping */ dev_bswap_init(vm,"mem_bswap",C6SUP1_BSWAP_ADDR,1024*1048576,0x00000000ULL); /* PCI IO space */ if (!(vm->pci_io_space = pci_io_data_init(vm,C6SUP1_PCI_IO_ADDR))) return(-1); /* Initialize the Port Adapters */ if (c6sup1_init_platform_pa(router) == -1) return(-1); /* Verify the check list */ if (c6sup1_checklist(router) == -1) return(-1); /* Midplane FPGA */ if (dev_c6sup1_mpfpga_init(router,C6SUP1_MPFPGA_ADDR,0x40000) == -1) return(-1); if (!(obj = vm_object_find(router->vm,"mp_fpga"))) return(-1); router->mpfpga_data = obj->data; /* IO FPGA */ if (dev_c6sup1_iofpga_init(router,C6SUP1_IOFPGA_ADDR,0x1000) == -1) return(-1); /* Show device list */ c6sup1_show_hardware(router); return(0);}/* Boot the IOS image */static int c6sup1_boot_ios(c6sup1_t *router){ vm_instance_t *vm = router->vm; cpu_mips_t *cpu; 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 */ cpu = CPU_MIPS64(vm->boot_cpu); mips64_reset(cpu); /* Load IOS image */ if (mips64_load_elf_image(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("\nC6SUP1 '%s': starting simulation (CPU0 PC=0x%llx), " "JIT %sabled.\n", vm->name,cpu->pc,vm->jit_use ? "en":"dis"); vm_log(vm,"C6SUP1_BOOT", "starting instance (CPU0 PC=0x%llx,idle_pc=0x%llx,JIT %s)\n", cpu->pc,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);}/* Set an IRQ */static void c6sup1_set_irq(vm_instance_t *vm,u_int irq){ c6sup1_t *router = VM_C6SUP1(vm); cpu_mips_t *cpu0 = CPU_MIPS64(vm->boot_cpu); u_int slot,port; switch(irq) { case 0 ... 7: mips64_set_irq(cpu0,irq); if (cpu0->irq_idle_preempt[irq]) cpu_idle_break_wait(cpu0->gen); break; case C6SUP1_NETIO_IRQ_BASE ... C6SUP1_NETIO_IRQ_END: c6sup1_net_irq_get_slot_port(irq,&slot,&port); //dev_c6sup1_mpfpga_net_set_irq(router->mpfpga_data,slot,port); break; }}/* Clear an IRQ */static void c6sup1_clear_irq(vm_instance_t *vm,u_int irq){ c6sup1_t *router = VM_C6SUP1(vm); cpu_mips_t *cpu0 = CPU_MIPS64(vm->boot_cpu); u_int slot,port; switch(irq) { case 0 ... 7: mips64_clear_irq(cpu0,irq); break; case C6SUP1_NETIO_IRQ_BASE ... C6SUP1_NETIO_IRQ_END: c6sup1_net_irq_get_slot_port(irq,&slot,&port); //dev_c6sup1_mpfpga_net_clear_irq(router->mpfpga_data,slot,port); break; }}/* Initialize a SUP1 instance */static int c6sup1_init_instance(vm_instance_t *vm){ c6sup1_t *router = VM_C6SUP1(vm); m_uint32_t rom_entry_point; cpu_mips_t *cpu0; /* Initialize the SUP1 platform */ if (c6sup1_init_platform(router) == -1) { vm_error(vm,"unable to initialize the platform hardware.\n"); return(-1); } /* IRQ routing */ vm->set_irq = c6sup1_set_irq; vm->clear_irq = c6sup1_clear_irq; /* 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 = CPU_MIPS64(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(c6sup1_boot_ios(router));}/* Stop a SUP1 instance */static int c6sup1_stop_instance(vm_instance_t *vm){ printf("\nC6SUP1 '%s': stopping simulation.\n",vm->name); vm_log(vm,"C6SUP1_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 */ c6sup1_free_hw_ressources(VM_C6SUP1(vm)); vm_hardware_shutdown(vm); return(0);}/* Get MAC address MSB */static u_int c6sup1_get_mac_addr_msb(void){ return(0xD0);}/* Show specific CLI options */static void c6sup1_cli_show_options(vm_instance_t *vm){ printf(" -s <pa_nio> : Bind a Network IO interface to a " "Port Adapter\n");}/* Platform definition */static vm_platform_t c6sup1_platform = { "c6sup1", "C6SUP1", "C6SUP1", c6sup1_create_instance, c6sup1_delete_instance, c6sup1_init_instance, c6sup1_stop_instance, c6sup1_nvram_extract_config, c6sup1_nvram_push_config, c6sup1_get_mac_addr_msb, NULL, NULL, c6sup1_cli_show_options, NULL,};/* Register the C6-SUP1 platform */int c6sup1_platform_register(void){ return(vm_platform_register(&c6sup1_platform));}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -