--- upstream/dynamips-0.2.5/dynamips.c 2007/10/06 16:01:44 1 +++ upstream/dynamips-0.2.7-RC2/dynamips.c 2007/10/06 16:24:54 8 @@ -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,16 +20,23 @@ #include #include -#include ARCH_INC_FILE - -#include "rbtree.h" #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 "dev_msfc1.h" +#include "ppc32_vmtest.h" #include "dev_vtty.h" #include "ptask.h" +#include "timer.h" #include "registry.h" #include "hypervisor.h" #include "net_io.h" @@ -52,6 +59,9 @@ /* Software version */ const char *sw_version = DYNAMIPS_VERSION"-"JIT_ARCH; +/* Software version tag */ +const char *sw_version_tag = "2007030219"; + /* Hypervisor */ int hypervisor_mode = 0; int hypervisor_tcp_port = 0; @@ -148,7 +158,7 @@ { u_int def_ram_size,def_rom_size,def_nvram_size; u_int def_conf_reg,def_clock_div; - u_int def_disk0_size,def_disk1_size; + u_int def_disk0_size = 0,def_disk1_size = 0; u_int def_nm_iomem_size = 0; switch(platform) { @@ -171,6 +181,55 @@ 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 = C2600_DEFAULT_IOMEM_SIZE; + break; + case VM_TYPE_MSFC1: + def_ram_size = MSFC1_DEFAULT_RAM_SIZE; + def_rom_size = MSFC1_DEFAULT_ROM_SIZE; + def_nvram_size = MSFC1_DEFAULT_NVRAM_SIZE; + def_conf_reg = MSFC1_DEFAULT_CONF_REG; + def_clock_div = MSFC1_DEFAULT_CLOCK_DIV; + break; + case VM_TYPE_PPC32_TEST: + def_ram_size = PPC32_VMTEST_DEFAULT_RAM_SIZE; default: fprintf(stderr,"show_usage: invalid platform.\n"); return; @@ -179,7 +238,9 @@ printf("Usage: %s [options] \n\n",argv[0]); printf("Available options:\n" - " -P : Platform to emulate (7200 or 3600) " + " -H : Run in hypervisor mode\n\n" + " -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" @@ -198,6 +259,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" @@ -237,6 +301,44 @@ "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; + + case VM_TYPE_MSFC1: + printf(" -s : Bind a Network IO interface to a " + "Port Adapter\n"); + break; + } printf("\n" @@ -285,9 +387,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 */ @@ -329,6 +486,18 @@ 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,"MSFC1")) + vm_type = VM_TYPE_MSFC1; + else if (!strcmp(str,"PPC32_TEST")) + vm_type = VM_TYPE_PPC32_TEST; else fprintf(stderr,"Invalid platform type '%s'\n",str); } @@ -344,6 +513,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 }, @@ -353,6 +523,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 }, }; @@ -430,12 +601,159 @@ 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); +} + +/* Parse specific options for the MSFC1 platform */ +static int cli_parse_msfc1_options(vm_instance_t *vm,int option) +{ + msfc1_t *router; + + router = VM_MSFC1(vm); + + switch(option) { + /* PA NIO settings */ + case 's': + return(msfc1_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; + msfc1_t *msfc1; switch(platform_type) { case VM_TYPE_C7200: @@ -452,6 +770,48 @@ } 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_MSFC1: + if (!(msfc1 = msfc1_create_instance(name,instance_id))) { + fprintf(stderr,"MSFC1: unable to create instance!\n"); + return NULL; + } + return(msfc1->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; @@ -462,7 +822,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; @@ -557,6 +917,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; @@ -688,6 +1065,21 @@ 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; + case VM_TYPE_MSFC1: + res = cli_parse_msfc1_options(vm,option); break; } @@ -770,9 +1162,15 @@ { 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(); + msfc1_delete_all_instances(); + ppc32_vmtest_delete_all_instances(); /* Delete ATM and Frame-Relay switches + bridges */ netio_bridge_delete_all(); @@ -798,8 +1196,12 @@ 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(); /* Initialize object registry */ registry_init(); @@ -833,6 +1235,8 @@ /* Create instruction lookup tables */ mips64_jit_create_ilt(); mips64_exec_create_ilt(); + ppc32_jit_create_ilt(); + ppc32_exec_create_ilt(); setup_signals(); @@ -847,6 +1251,24 @@ 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_MSFC1: + res = msfc1_init_instance(VM_MSFC1(vm)); + break; + case VM_TYPE_PPC32_TEST: + res = ppc32_vmtest_init_instance(vm); break; default: res = -1; @@ -857,12 +1279,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); }