--- upstream/dynamips-0.2.6-RC2/dynamips.c 2007/10/06 16:05:34 3 +++ upstream/dynamips-0.2.7-RC1/dynamips.c 2007/10/06 16:23:47 7 @@ -1,5 +1,5 @@ /* - * Cisco 7200 (Predator) simulation platform. + * Cisco router simulation platform. * Copyright (c) 2005,2006 Christophe Fillot (cf@utc.fr) * * Many thanks to Nicolas Szalay for his patch @@ -20,13 +20,19 @@ #include #include -#include ARCH_INC_FILE - #include "dynamips.h" -#include "mips64.h" +#include "cpu.h" #include "mips64_exec.h" +#include "mips64_jit.h" +#include "ppc32_exec.h" +#include "ppc32_jit.h" #include "dev_c7200.h" #include "dev_c3600.h" +#include "dev_c2691.h" +#include "dev_c3725.h" +#include "dev_c3745.h" +#include "dev_c2600.h" +#include "ppc32_vmtest.h" #include "dev_vtty.h" #include "ptask.h" #include "timer.h" @@ -171,6 +177,48 @@ def_disk1_size = C3600_DEFAULT_DISK1_SIZE; def_nm_iomem_size = C3600_DEFAULT_IOMEM_SIZE; break; + case VM_TYPE_C2691: + def_ram_size = C2691_DEFAULT_RAM_SIZE; + def_rom_size = C2691_DEFAULT_ROM_SIZE; + def_nvram_size = C2691_DEFAULT_NVRAM_SIZE; + def_conf_reg = C2691_DEFAULT_CONF_REG; + def_clock_div = C2691_DEFAULT_CLOCK_DIV; + def_disk0_size = C2691_DEFAULT_DISK0_SIZE; + def_disk1_size = C2691_DEFAULT_DISK1_SIZE; + def_nm_iomem_size = C2691_DEFAULT_IOMEM_SIZE; + break; + case VM_TYPE_C3725: + def_ram_size = C3725_DEFAULT_RAM_SIZE; + def_rom_size = C3725_DEFAULT_ROM_SIZE; + def_nvram_size = C3725_DEFAULT_NVRAM_SIZE; + def_conf_reg = C3725_DEFAULT_CONF_REG; + def_clock_div = C3725_DEFAULT_CLOCK_DIV; + def_disk0_size = C3725_DEFAULT_DISK0_SIZE; + def_disk1_size = C3725_DEFAULT_DISK1_SIZE; + def_nm_iomem_size = C3725_DEFAULT_IOMEM_SIZE; + break; + case VM_TYPE_C3745: + def_ram_size = C3745_DEFAULT_RAM_SIZE; + def_rom_size = C3745_DEFAULT_ROM_SIZE; + def_nvram_size = C3745_DEFAULT_NVRAM_SIZE; + def_conf_reg = C3745_DEFAULT_CONF_REG; + def_clock_div = C3745_DEFAULT_CLOCK_DIV; + def_disk0_size = C3745_DEFAULT_DISK0_SIZE; + def_disk1_size = C3745_DEFAULT_DISK1_SIZE; + def_nm_iomem_size = C3745_DEFAULT_IOMEM_SIZE; + break; + case VM_TYPE_C2600: + def_ram_size = C2600_DEFAULT_RAM_SIZE; + def_rom_size = C2600_DEFAULT_ROM_SIZE; + def_nvram_size = C2600_DEFAULT_NVRAM_SIZE; + def_conf_reg = C2600_DEFAULT_CONF_REG; + def_clock_div = C2600_DEFAULT_CLOCK_DIV; + def_disk0_size = C2600_DEFAULT_DISK0_SIZE; + def_disk1_size = C2600_DEFAULT_DISK1_SIZE; + def_nm_iomem_size = C3745_DEFAULT_IOMEM_SIZE; + break; + case VM_TYPE_PPC32_TEST: + def_ram_size = PPC32_VMTEST_DEFAULT_RAM_SIZE; default: fprintf(stderr,"show_usage: invalid platform.\n"); return; @@ -180,7 +228,8 @@ printf("Available options:\n" " -H : Run in hypervisor mode\n\n" - " -P : Platform to emulate (7200 or 3600) " + " -P : Platform to emulate (7200, 3600, " + "2691, 3725 or 3745) " "(default: 7200)\n\n" " -l : Set logging file (default is %s)\n" " -j : Disable the JIT compiler, very slow\n" @@ -199,6 +248,9 @@ " -C : Import an IOS configuration file " "into NVRAM\n" " -X : Do not use a file to simulate RAM (faster)\n" + " -G : Use a ghost file to simulate RAM\n" + " -g : Generate a ghost RAM file\n" + " --sparse-mem : Use sparse memory\n" " -R : Load an alternate ROM (default: embedded)\n" " -k : Set the clock divisor (default: %d)\n" "\n" @@ -238,6 +290,38 @@ "Network Module\n", C3600_DEFAULT_CHASSIS,def_nm_iomem_size); break; + + case VM_TYPE_C2691: + printf(" --iomem-size : IO memory (in percents, default: %u)\n" + " -p : Define a Network Module\n" + " -s : Bind a Network IO interface to a " + "Network Module\n", + def_nm_iomem_size); + break; + + case VM_TYPE_C3725: + printf(" --iomem-size : IO memory (in percents, default: %u)\n" + " -p : Define a Network Module\n" + " -s : Bind a Network IO interface to a " + "Network Module\n", + def_nm_iomem_size); + break; + + case VM_TYPE_C3745: + printf(" --iomem-size : IO memory (in percents, default: %u)\n" + " -p : Define a Network Module\n" + " -s : Bind a Network IO interface to a " + "Network Module\n", + def_nm_iomem_size); + break; + + case VM_TYPE_C2600: + printf(" --iomem-size : IO memory (in percents, default: %u)\n" + " -p : Define a Network Module\n" + " -s : Bind a Network IO interface to a " + "Network Module\n", + def_nm_iomem_size); + break; } printf("\n" @@ -286,9 +370,64 @@ /* Show the possible chassis types for C3600 platform */ c3600_chassis_show_drivers(); - /* Show the possible PA drivers */ + /* Show the possible NM drivers */ c3600_nm_show_drivers(); break; + + case VM_TYPE_C2691: + printf(" format:\n" + " \"slot:nm_driver\"\n" + "\n"); + + printf(" format:\n" + " \"slot:port:netio_type{:netio_parameters}\"\n" + "\n"); + + /* Show the possible NM drivers */ + c2691_nm_show_drivers(); + break; + + case VM_TYPE_C3725: + printf(" format:\n" + " \"slot:nm_driver\"\n" + "\n"); + + printf(" format:\n" + " \"slot:port:netio_type{:netio_parameters}\"\n" + "\n"); + + /* Show the possible NM drivers */ + c3725_nm_show_drivers(); + break; + + case VM_TYPE_C3745: + printf(" format:\n" + " \"slot:nm_driver\"\n" + "\n"); + + printf(" format:\n" + " \"slot:port:netio_type{:netio_parameters}\"\n" + "\n"); + + /* Show the possible NM drivers */ + c3745_nm_show_drivers(); + break; + + case VM_TYPE_C2600: + printf(" format:\n" + " \"slot:nm_driver\"\n" + "\n"); + + printf(" format:\n" + " \"slot:port:netio_type{:netio_parameters}\"\n" + "\n"); + + /* Show the possible chassis types for C2600 platform */ + c2600_mainboard_show_drivers(); + + /* Show the possible NM drivers */ + c2600_nm_show_drivers(); + break; } /* Show the possible NETIO types */ @@ -330,6 +469,16 @@ vm_type = VM_TYPE_C3600; else if (!strcmp(str,"7200")) vm_type = VM_TYPE_C7200; + else if (!strcmp(str,"2691")) + vm_type = VM_TYPE_C2691; + else if (!strcmp(str,"3725")) + vm_type = VM_TYPE_C3725; + else if (!strcmp(str,"3745")) + vm_type = VM_TYPE_C3745; + else if (!strcmp(str,"2600")) + vm_type = VM_TYPE_C2600; + else if (!strcmp(str,"PPC32_TEST")) + vm_type = VM_TYPE_PPC32_TEST; else fprintf(stderr,"Invalid platform type '%s'\n",str); } @@ -345,6 +494,7 @@ #define OPT_TIMER_ITV 0x104 #define OPT_VM_DEBUG 0x105 #define OPT_IOMEM_SIZE 0x106 +#define OPT_SPARSE_MEM 0x107 static struct option cmd_line_lopts[] = { { "disk0" , 1, NULL, OPT_DISK0_SIZE }, @@ -354,6 +504,7 @@ { "timer-itv" , 1, NULL, OPT_TIMER_ITV }, { "vm-debug" , 1, NULL, OPT_VM_DEBUG }, { "iomem-size" , 1, NULL, OPT_IOMEM_SIZE }, + { "sparse-mem" , 0, NULL, OPT_SPARSE_MEM }, { NULL , 0, NULL, 0 }, }; @@ -431,12 +582,138 @@ return(0); } +/* Parse specific options for the Cisco 2691 platform */ +static int cli_parse_c2691_options(vm_instance_t *vm,int option) +{ + c2691_t *router; + + router = VM_C2691(vm); + + switch(option) { + /* IO memory reserved for NMs (in percents!) */ + case OPT_IOMEM_SIZE: + router->nm_iomem_size = 0x8000 | atoi(optarg); + break; + + /* NM settings */ + case 'p': + return(c2691_cmd_nm_create(router,optarg)); + + /* NM NIO settings */ + case 's': + return(c2691_cmd_add_nio(router,optarg)); + + /* Unknown option */ + default: + return(-1); + } + + return(0); +} + +/* Parse specific options for the Cisco 3725 platform */ +static int cli_parse_c3725_options(vm_instance_t *vm,int option) +{ + c3725_t *router; + + router = VM_C3725(vm); + + switch(option) { + /* IO memory reserved for NMs (in percents!) */ + case OPT_IOMEM_SIZE: + router->nm_iomem_size = 0x8000 | atoi(optarg); + break; + + /* NM settings */ + case 'p': + return(c3725_cmd_nm_create(router,optarg)); + + /* NM NIO settings */ + case 's': + return(c3725_cmd_add_nio(router,optarg)); + + /* Unknown option */ + default: + return(-1); + } + + return(0); +} + +/* Parse specific options for the Cisco 3745 platform */ +static int cli_parse_c3745_options(vm_instance_t *vm,int option) +{ + c3745_t *router; + + router = VM_C3745(vm); + + switch(option) { + /* IO memory reserved for NMs (in percents!) */ + case OPT_IOMEM_SIZE: + router->nm_iomem_size = 0x8000 | atoi(optarg); + break; + + /* NM settings */ + case 'p': + return(c3745_cmd_nm_create(router,optarg)); + + /* NM NIO settings */ + case 's': + return(c3745_cmd_add_nio(router,optarg)); + + /* Unknown option */ + default: + return(-1); + } + + return(0); +} + +/* Parse specific options for the Cisco 2600 platform */ +static int cli_parse_c2600_options(vm_instance_t *vm,int option) +{ + c2600_t *router; + + router = VM_C2600(vm); + + switch(option) { + /* IO memory reserved for NMs (in percents!) */ + case OPT_IOMEM_SIZE: + router->nm_iomem_size = 0x8000 | atoi(optarg); + break; + + /* Mainboard type */ + case 't': + c2600_mainboard_set_type(router,optarg); + break; + + /* NM settings */ + case 'p': + return(c2600_cmd_nm_create(router,optarg)); + + /* NM NIO settings */ + case 's': + return(c2600_cmd_add_nio(router,optarg)); + + /* Unknown option */ + default: + return(-1); + } + + return(0); +} + /* Create a router instance */ static vm_instance_t *cli_create_instance(char *name,int platform_type, int instance_id) { + vm_instance_t *vm; c7200_t *c7200; c3600_t *c3600; + c2691_t *c2691; + c3725_t *c3725; + c3745_t *c3745; + c2600_t *c2600; switch(platform_type) { case VM_TYPE_C7200: @@ -453,6 +730,41 @@ } return(c3600->vm); + case VM_TYPE_C2691: + if (!(c2691 = c2691_create_instance(name,instance_id))) { + fprintf(stderr,"C2691: unable to create instance!\n"); + return NULL; + } + return(c2691->vm); + + case VM_TYPE_C3725: + if (!(c3725 = c3725_create_instance(name,instance_id))) { + fprintf(stderr,"C3725: unable to create instance!\n"); + return NULL; + } + return(c3725->vm); + + case VM_TYPE_C3745: + if (!(c3745 = c3745_create_instance(name,instance_id))) { + fprintf(stderr,"C3745: unable to create instance!\n"); + return NULL; + } + return(c3745->vm); + + case VM_TYPE_C2600: + if (!(c2600 = c2600_create_instance(name,instance_id))) { + fprintf(stderr,"C2600: unable to create instance!\n"); + return NULL; + } + return(c2600->vm); + + case VM_TYPE_PPC32_TEST: + if (!(vm = ppc32_vmtest_create_instance(name,instance_id))) { + fprintf(stderr,"PPC32_TEST: unable to create instance!\n"); + return NULL; + } + return(vm); + default: fprintf(stderr,"Unknown platform type '%d'!\n",platform_type); return NULL; @@ -463,7 +775,7 @@ static int parse_std_cmd_line(int argc,char *argv[],int *platform) { char *options_list = - "r:o:n:c:m:l:C:i:jt:p:s:k:T:U:A:B:a:f:E:b:S:R:M:eXP:N:"; + "r:o:n:c:m:l:C:i:jt:p:s:k:T:U:A:B:a:f:E:b:S:R:M:eXP:N:G:g:"; vm_instance_t *vm; int instance_id; int res,option; @@ -558,6 +870,23 @@ vm->ram_mmap = 0; break; + /* Use a ghost file to simulate RAM */ + case 'G': + vm->ghost_ram_filename = strdup(optarg); + vm->ghost_status = VM_GHOST_RAM_USE; + break; + + /* Generate a ghost RAM image */ + case 'g': + vm->ghost_ram_filename = strdup(optarg); + vm->ghost_status = VM_GHOST_RAM_GENERATE; + break; + + /* Use sparse memory */ + case OPT_SPARSE_MEM: + vm->sparse_mem = TRUE; + break; + /* Alternate ROM */ case 'R': vm->rom_filename = optarg; @@ -689,6 +1018,18 @@ break; case VM_TYPE_C3600: res = cli_parse_c3600_options(vm,option); + break; + case VM_TYPE_C2691: + res = cli_parse_c2691_options(vm,option); + break; + case VM_TYPE_C3725: + res = cli_parse_c3725_options(vm,option); + break; + case VM_TYPE_C3745: + res = cli_parse_c3745_options(vm,option); + break; + case VM_TYPE_C2600: + res = cli_parse_c2600_options(vm,option); break; } @@ -771,9 +1112,14 @@ { printf("Shutdown in progress...\n"); - /* Delete all C7200 and C3600 instances */ + /* Delete all virtual router instances */ c7200_delete_all_instances(); c3600_delete_all_instances(); + c2691_delete_all_instances(); + c3725_delete_all_instances(); + c3745_delete_all_instances(); + c2600_delete_all_instances(); + ppc32_vmtest_delete_all_instances(); /* Delete ATM and Frame-Relay switches + bridges */ netio_bridge_delete_all(); @@ -799,8 +1145,9 @@ atexit(profiler_savestat); #endif - printf("Cisco 7200 Simulation Platform (version %s)\n",sw_version); - printf("Copyright (c) 2005,2006 Christophe Fillot.\n\n"); + printf("Cisco Router Simulation Platform (version %s)\n",sw_version); + printf("Copyright (c) 2005-2007 Christophe Fillot.\n"); + printf("Build date: %s %s\n\n",__DATE__,__TIME__); /* Initialize timers */ timer_init(); @@ -837,6 +1184,8 @@ /* Create instruction lookup tables */ mips64_jit_create_ilt(); mips64_exec_create_ilt(); + ppc32_jit_create_ilt(); + ppc32_exec_create_ilt(); setup_signals(); @@ -851,6 +1200,21 @@ break; case VM_TYPE_C3600: res = c3600_init_instance(VM_C3600(vm)); + break; + case VM_TYPE_C2691: + res = c2691_init_instance(VM_C2691(vm)); + break; + case VM_TYPE_C3725: + res = c3725_init_instance(VM_C3725(vm)); + break; + case VM_TYPE_C3745: + res = c3745_init_instance(VM_C3745(vm)); + break; + case VM_TYPE_C2600: + res = c2600_init_instance(VM_C2600(vm)); + break; + case VM_TYPE_PPC32_TEST: + res = ppc32_vmtest_init_instance(vm); break; default: res = -1; @@ -861,12 +1225,13 @@ exit(EXIT_FAILURE); } -#if DEBUG_PERF_COUNTER +#if (DEBUG_INSN_PERF_CNT > 0) || (DEBUG_BLOCK_PERF_CNT > 0) { - m_uint64_t prev = 0,delta; + m_uint64_t counter,prev = 0,delta; while(vm->status == VM_STATUS_RUNNING) { - delta = vm->boot_cpu->perf_counter - prev; - prev = vm->boot_cpu->perf_counter; + counter = cpu_get_perf_counter(vm->boot_cpu); + delta = counter - prev; + prev = counter; printf("delta = %llu\n",delta); sleep(1); }