|
|
1.1 root 1: /*
2: * Cisco 7200 (Predator) simulation platform.
3: * Copyright (c) 2005,2006 Christophe Fillot ([email protected])
4: *
5: * Many thanks to Nicolas Szalay for his patch
6: * for the command line parsing and virtual machine
7: * settings (RAM, ROM, NVRAM, ...)
8: */
9:
10: #include <stdio.h>
11: #include <stdlib.h>
12: #include <unistd.h>
13: #include <string.h>
1.1.1.4 ! root 14: #include <errno.h>
1.1 root 15: #include <sys/types.h>
16: #include <sys/stat.h>
17: #include <sys/mman.h>
18: #include <signal.h>
19: #include <fcntl.h>
20: #include <assert.h>
1.1.1.4 ! root 21: #include <getopt.h>
1.1 root 22:
23: #include ARCH_INC_FILE
24:
25: #include "rbtree.h"
1.1.1.4 ! root 26: #include "dynamips.h"
! 27: #include "mips64.h"
1.1 root 28: #include "mips64_exec.h"
29: #include "dev_c7200.h"
1.1.1.4 ! root 30: #include "dev_c3600.h"
1.1 root 31: #include "dev_vtty.h"
32: #include "ptask.h"
1.1.1.4 ! root 33: #include "registry.h"
! 34: #include "hypervisor.h"
1.1.1.2 root 35: #include "net_io.h"
1.1 root 36: #include "net_io_bridge.h"
1.1.1.4 ! root 37: #include "net_io_filter.h"
! 38: #include "crc.h"
! 39: #include "atm.h"
! 40: #include "frame_relay.h"
! 41: #include "eth_switch.h"
1.1.1.2 root 42: #ifdef GEN_ETH
43: #include "gen_eth.h"
44: #endif
1.1 root 45: #ifdef PROFILE
46: #include "profiler.h"
47: #endif
48:
49: /* Default name for logfile */
1.1.1.4 ! root 50: #define LOGFILE_DEFAULT_NAME "dynamips_log.txt"
1.1 root 51:
52: /* Software version */
1.1.1.4 ! root 53: const char *sw_version = DYNAMIPS_VERSION"-"JIT_ARCH;
! 54:
! 55: /* Hypervisor */
! 56: int hypervisor_mode = 0;
! 57: int hypervisor_tcp_port = 0;
1.1 root 58:
59: /* Log file */
1.1.1.4 ! root 60: char *log_file_name = NULL;
1.1 root 61: FILE *log_file = NULL;
62:
63: /* VM flags */
64: volatile int vm_save_state = 0;
65:
66: /* Generic signal handler */
67: void signal_gen_handler(int sig)
68: {
69: switch(sig) {
70: case SIGHUP:
1.1.1.4 ! root 71: /* For future use */
1.1 root 72: break;
73:
74: case SIGQUIT:
75: /* save VM context */
76: vm_save_state = TRUE;
1.1.1.4 ! root 77: break;
! 78:
! 79: case SIGINT:
! 80: /* CTRL+C has been pressed */
! 81: if (hypervisor_mode)
! 82: hypervisor_stopsig();
! 83: else {
! 84: /* In theory, this shouldn't happen thanks to VTTY settings */
! 85: vm_instance_t *vm;
! 86:
! 87: if ((vm = vm_acquire("default")) != NULL) {
! 88: /* Only forward ctrl-c if user has requested local terminal */
! 89: if (vm->vtty_con_type == VTTY_TYPE_TERM) {
! 90: vtty_store_ctrlc(vm->vtty_con);
! 91: } else {
! 92: vm_stop(vm);
! 93: }
! 94: vm_release(vm);
! 95: } else {
! 96: fprintf(stderr,"Error: Cannot acquire instance handle.\n");
! 97: }
! 98: }
1.1 root 99: break;
100:
101: default:
102: fprintf(stderr,"Unhandled signal %d\n",sig);
103: }
104: }
105:
106: /* Setups signals */
107: static void setup_signals(void)
108: {
109: struct sigaction act;
110:
111: memset(&act,0,sizeof(act));
112: act.sa_handler = signal_gen_handler;
113: act.sa_flags = SA_RESTART;
114: sigaction(SIGHUP,&act,NULL);
115: sigaction(SIGQUIT,&act,NULL);
1.1.1.4 ! root 116: sigaction(SIGINT,&act,NULL);
1.1 root 117: }
118:
1.1.1.4 ! root 119: /* Create general log file */
! 120: static void create_log_file(void)
! 121: {
! 122: /* Set the default value of the log file name */
! 123: if (!log_file_name) {
! 124: if (!(log_file_name = strdup(LOGFILE_DEFAULT_NAME))) {
! 125: fprintf(stderr,"Unable to set log file name.\n");
! 126: exit(EXIT_FAILURE);
! 127: }
1.1 root 128: }
129:
1.1.1.4 ! root 130: if (!(log_file = fopen(log_file_name,"w"))) {
! 131: fprintf(stderr,"Unable to create log file (%s).\n",strerror(errno));
! 132: exit(EXIT_FAILURE);
1.1 root 133: }
1.1.1.4 ! root 134: }
1.1 root 135:
1.1.1.4 ! root 136: /* Close general log file */
! 137: static void close_log_file(void)
! 138: {
! 139: if (log_file) fclose(log_file);
! 140: free(log_file_name);
1.1 root 141:
1.1.1.4 ! root 142: log_file = NULL;
! 143: log_file_name = NULL;
! 144: }
1.1 root 145:
1.1.1.4 ! root 146: /* Display the command line use */
! 147: static void show_usage(int argc,char *argv[],int platform)
! 148: {
! 149: u_int def_ram_size,def_rom_size,def_nvram_size;
! 150: u_int def_conf_reg,def_clock_div;
! 151: u_int def_disk0_size,def_disk1_size;
! 152: u_int def_nm_iomem_size = 0;
! 153:
! 154: switch(platform) {
! 155: case VM_TYPE_C7200:
! 156: def_ram_size = C7200_DEFAULT_RAM_SIZE;
! 157: def_rom_size = C7200_DEFAULT_ROM_SIZE;
! 158: def_nvram_size = C7200_DEFAULT_NVRAM_SIZE;
! 159: def_conf_reg = C7200_DEFAULT_CONF_REG;
! 160: def_clock_div = C7200_DEFAULT_CLOCK_DIV;
! 161: def_disk0_size = C7200_DEFAULT_DISK0_SIZE;
! 162: def_disk1_size = C7200_DEFAULT_DISK1_SIZE;
! 163: break;
! 164: case VM_TYPE_C3600:
! 165: def_ram_size = C3600_DEFAULT_RAM_SIZE;
! 166: def_rom_size = C3600_DEFAULT_ROM_SIZE;
! 167: def_nvram_size = C3600_DEFAULT_NVRAM_SIZE;
! 168: def_conf_reg = C3600_DEFAULT_CONF_REG;
! 169: def_clock_div = C3600_DEFAULT_CLOCK_DIV;
! 170: def_disk0_size = C3600_DEFAULT_DISK0_SIZE;
! 171: def_disk1_size = C3600_DEFAULT_DISK1_SIZE;
! 172: def_nm_iomem_size = C3600_DEFAULT_IOMEM_SIZE;
! 173: break;
! 174: default:
! 175: fprintf(stderr,"show_usage: invalid platform.\n");
! 176: return;
! 177: }
! 178:
! 179: printf("Usage: %s [options] <ios_image>\n\n",argv[0]);
1.1 root 180:
1.1.1.4 ! root 181: printf("Available options:\n"
! 182: " -P <platform> : Platform to emulate (7200 or 3600) "
! 183: "(default: 7200)\n\n"
! 184: " -l <log_file> : Set logging file (default is %s)\n"
! 185: " -j : Disable the JIT compiler, very slow\n"
! 186: " --exec-area <size> : Set the exec area size (default: %d Mb)\n"
! 187: " --idle-pc <pc> : Set the idle PC (default: disabled)\n"
! 188: " --timer-itv <val> : Timer IRQ interval check (default: %u)\n"
! 189: "\n"
! 190: " -i <instance> : Set instance ID\n"
! 191: " -r <ram_size> : Set the virtual RAM size (default: %u Mb)\n"
! 192: " -o <rom_size> : Set the virtual ROM size (default: %u Mb)\n"
! 193: " -n <nvram_size> : Set the NVRAM size (default: %d Kb)\n"
! 194: " -c <conf_reg> : Set the configuration register "
! 195: "(default: 0x%04x)\n"
! 196: " -m <mac_addr> : Set the MAC address of the chassis\n"
! 197: " (default: automatically generated)\n"
! 198: " -C <cfg_file> : Import an IOS configuration file "
! 199: "into NVRAM\n"
! 200: " -X : Do not use a file to simulate RAM (faster)\n"
! 201: " -R <rom_file> : Load an alternate ROM (default: embedded)\n"
! 202: " -k <clock_div> : Set the clock divisor (default: %d)\n"
! 203: "\n"
! 204: " -T <port> : Console is on TCP <port>\n"
! 205: " -U <si_desc> : Console in on serial interface <si_desc>\n"
! 206: " (default is on the terminal)\n"
! 207: "\n"
! 208: " -A <port> : AUX is on TCP <port>\n"
! 209: " -B <si_desc> : AUX is on serial interface <si_desc>\n"
! 210: " (default is no AUX port)\n"
! 211: "\n"
! 212: " --disk0 <size> : Set PCMCIA ATA disk0: size "
! 213: "(default: %u Mb)\n"
! 214: " --disk1 <size> : Set PCMCIA ATA disk1: size "
! 215: "(default: %u Mb)\n"
! 216: "\n",
! 217: LOGFILE_DEFAULT_NAME,MIPS_EXEC_AREA_SIZE,VM_TIMER_IRQ_CHECK_ITV,
! 218: def_ram_size,def_rom_size,def_nvram_size,def_conf_reg,
! 219: def_clock_div,def_disk0_size,def_disk1_size);
! 220:
! 221: switch(platform) {
! 222: case VM_TYPE_C7200:
! 223: printf(" -t <npe_type> : Select NPE type (default: \"%s\")\n"
! 224: " -M <midplane> : Select Midplane (\"std\" or \"vxr\")\n"
! 225: " -p <pa_desc> : Define a Port Adapter\n"
! 226: " -s <pa_nio> : Bind a Network IO interface to a "
! 227: "Port Adapter\n",
! 228: C7200_DEFAULT_NPE_TYPE);
! 229: break;
1.1 root 230:
1.1.1.4 ! root 231: case VM_TYPE_C3600:
! 232: printf(" -t <chassis_type> : Select Chassis type "
! 233: "(default: \"%s\")\n"
! 234: " --iomem-size <val> : IO memory (in percents, default: %u)\n"
! 235: " -p <nm_desc> : Define a Network Module\n"
! 236: " -s <nm_nio> : Bind a Network IO interface to a "
! 237: "Network Module\n",
! 238: C3600_DEFAULT_CHASSIS,def_nm_iomem_size);
! 239: break;
! 240: }
1.1 root 241:
1.1.1.4 ! root 242: printf("\n"
! 243: #if DEBUG_SYM_TREE
! 244: " -S <sym_file> : Load a symbol file\n"
! 245: #endif
! 246: " -a <cfg_file> : Virtual ATM switch configuration file\n"
! 247: " -f <cfg_file> : Virtual Frame-Relay switch configuration "
! 248: "file\n"
! 249: " -E <cfg_file> : Virtual Ethernet switch configuration file\n"
! 250: " -b <cfg_file> : Virtual bridge configuration file\n"
! 251: " -e : Show network device list of the "
! 252: "host machine\n"
! 253: "\n");
! 254:
! 255: printf("<si_desc> format:\n"
! 256: " \"device{:baudrate{:databits{:parity{:stopbits{:hwflow}}}}}}\"\n"
! 257: "\n");
1.1 root 258:
1.1.1.4 ! root 259: switch(platform) {
! 260: case VM_TYPE_C7200:
! 261: printf("<pa_desc> format:\n"
! 262: " \"slot:pa_driver\"\n"
! 263: "\n");
! 264:
! 265: printf("<pa_nio> format:\n"
! 266: " \"slot:port:netio_type{:netio_parameters}\"\n"
! 267: "\n");
! 268:
! 269: /* Show the possible NPE drivers */
! 270: c7200_npe_show_drivers();
! 271:
! 272: /* Show the possible PA drivers */
! 273: c7200_pa_show_drivers();
! 274: break;
! 275:
! 276: case VM_TYPE_C3600:
! 277: printf("<nm_desc> format:\n"
! 278: " \"slot:nm_driver\"\n"
! 279: "\n");
! 280:
! 281: printf("<nm_nio> format:\n"
! 282: " \"slot:port:netio_type{:netio_parameters}\"\n"
! 283: "\n");
! 284:
! 285: /* Show the possible chassis types for C3600 platform */
! 286: c3600_chassis_show_drivers();
! 287:
! 288: /* Show the possible PA drivers */
! 289: c3600_nm_show_drivers();
1.1 root 290: break;
291: }
292:
1.1.1.4 ! root 293: /* Show the possible NETIO types */
! 294: netio_show_types();
1.1 root 295: }
296:
1.1.1.4 ! root 297: /* Find an option in the command line */
! 298: static char *cli_find_option(int argc,char *argv[],char *opt)
1.1 root 299: {
1.1.1.4 ! root 300: int i;
1.1 root 301:
1.1.1.4 ! root 302: for(i=1;i<argc;i++) {
! 303: if (!strncmp(argv[i],opt,2)) {
! 304: if (argv[i][2] != 0)
! 305: return(&argv[i][2]);
! 306: else {
! 307: if (argv[i+1] != NULL)
! 308: return(argv[i+1]);
! 309: else {
! 310: fprintf(stderr,"Error: option '%s': no argument specified.\n",
! 311: opt);
! 312: exit(EXIT_FAILURE);
! 313: }
! 314: }
! 315: }
1.1 root 316: }
317:
1.1.1.4 ! root 318: return NULL;
! 319: }
1.1 root 320:
1.1.1.4 ! root 321: /* Determine the platform (Cisco 3600, 7200). Default is Cisco 7200 */
! 322: static int cli_get_platform_type(int argc,char *argv[])
! 323: {
! 324: int vm_type = VM_TYPE_C7200;
! 325: char *str;
1.1 root 326:
1.1.1.4 ! root 327: if ((str = cli_find_option(argc,argv,"-P"))) {
! 328: if (!strcmp(str,"3600"))
! 329: vm_type = VM_TYPE_C3600;
! 330: else if (!strcmp(str,"7200"))
! 331: vm_type = VM_TYPE_C7200;
! 332: else
! 333: fprintf(stderr,"Invalid platform type '%s'\n",str);
1.1 root 334: }
335:
1.1.1.4 ! root 336: return(vm_type);
! 337: }
1.1 root 338:
1.1.1.4 ! root 339: /* Command Line long options */
! 340: #define OPT_DISK0_SIZE 0x100
! 341: #define OPT_DISK1_SIZE 0x101
! 342: #define OPT_EXEC_AREA 0x102
! 343: #define OPT_IDLE_PC 0x103
! 344: #define OPT_TIMER_ITV 0x104
! 345: #define OPT_VM_DEBUG 0x105
! 346: #define OPT_IOMEM_SIZE 0x106
! 347:
! 348: static struct option cmd_line_lopts[] = {
! 349: { "disk0" , 1, NULL, OPT_DISK0_SIZE },
! 350: { "disk1" , 1, NULL, OPT_DISK1_SIZE },
! 351: { "exec-area" , 1, NULL, OPT_EXEC_AREA },
! 352: { "idle-pc" , 1, NULL, OPT_IDLE_PC },
! 353: { "timer-itv" , 1, NULL, OPT_TIMER_ITV },
! 354: { "vm-debug" , 1, NULL, OPT_VM_DEBUG },
! 355: { "iomem-size" , 1, NULL, OPT_IOMEM_SIZE },
! 356: { NULL , 0, NULL, 0 },
! 357: };
1.1 root 358:
1.1.1.4 ! root 359: /* Parse specific options for the Cisco 7200 platform */
! 360: static int cli_parse_c7200_options(vm_instance_t *vm,int option)
! 361: {
! 362: c7200_t *router;
1.1 root 363:
1.1.1.4 ! root 364: router = VM_C7200(vm);
1.1 root 365:
1.1.1.4 ! root 366: switch(option) {
! 367: /* NPE type */
! 368: case 't':
! 369: c7200_npe_set_type(router,optarg);
! 370: break;
1.1 root 371:
1.1.1.4 ! root 372: /* Midplane type */
! 373: case 'M':
! 374: c7200_midplane_set_type(router,optarg);
! 375: break;
1.1 root 376:
1.1.1.4 ! root 377: /* Set the base MAC address */
! 378: case 'm':
! 379: if (!c7200_midplane_set_mac_addr(router,optarg))
! 380: printf("MAC address set to '%s'.\n",optarg);
! 381: break;
1.1 root 382:
1.1.1.4 ! root 383: /* PA settings */
! 384: case 'p':
! 385: return(c7200_cmd_pa_create(router,optarg));
! 386:
! 387: /* PA NIO settings */
! 388: case 's':
! 389: return(c7200_cmd_add_nio(router,optarg));
1.1 root 390:
1.1.1.4 ! root 391: /* Unknown option */
! 392: default:
! 393: return(-1);
! 394: }
1.1 root 395:
396: return(0);
397: }
398:
1.1.1.4 ! root 399: /* Parse specific options for the Cisco 3600 platform */
! 400: static int cli_parse_c3600_options(vm_instance_t *vm,int option)
1.1 root 401: {
1.1.1.4 ! root 402: c3600_t *router;
1.1 root 403:
1.1.1.4 ! root 404: router = VM_C3600(vm);
1.1 root 405:
1.1.1.4 ! root 406: switch(option) {
! 407: /* chassis type */
! 408: case 't':
! 409: c3600_chassis_set_type(router,optarg);
! 410: break;
1.1 root 411:
1.1.1.4 ! root 412: /* IO memory reserved for NMs (in percents!) */
! 413: case OPT_IOMEM_SIZE:
! 414: router->nm_iomem_size = 0x8000 | atoi(optarg);
! 415: break;
1.1 root 416:
1.1.1.4 ! root 417: /* NM settings */
! 418: case 'p':
! 419: return(c3600_cmd_nm_create(router,optarg));
! 420:
! 421: /* NM NIO settings */
! 422: case 's':
! 423: return(c3600_cmd_add_nio(router,optarg));
! 424:
! 425: /* Unknown option */
! 426: default:
! 427: return(-1);
1.1 root 428: }
429:
430: return(0);
431: }
432:
1.1.1.4 ! root 433: /* Create a router instance */
! 434: static vm_instance_t *cli_create_instance(char *name,int platform_type,
! 435: int instance_id)
1.1 root 436: {
1.1.1.4 ! root 437: c7200_t *c7200;
! 438: c3600_t *c3600;
1.1.1.3 root 439:
1.1.1.4 ! root 440: switch(platform_type) {
! 441: case VM_TYPE_C7200:
! 442: if (!(c7200 = c7200_create_instance(name,instance_id))) {
! 443: fprintf(stderr,"C7200: unable to create instance!\n");
! 444: return NULL;
! 445: }
! 446: return(c7200->vm);
1.1 root 447:
1.1.1.4 ! root 448: case VM_TYPE_C3600:
! 449: if (!(c3600 = c3600_create_instance(name,instance_id))) {
! 450: fprintf(stderr,"C3600: unable to create instance!\n");
! 451: return NULL;
! 452: }
! 453: return(c3600->vm);
1.1 root 454:
1.1.1.4 ! root 455: default:
! 456: fprintf(stderr,"Unknown platform type '%d'!\n",platform_type);
! 457: return NULL;
! 458: }
1.1 root 459: }
460:
1.1.1.4 ! root 461: /* Parse the command line */
! 462: static int parse_std_cmd_line(int argc,char *argv[],int *platform)
1.1 root 463: {
1.1.1.4 ! root 464: char *options_list =
! 465: "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:";
! 466: vm_instance_t *vm;
! 467: int instance_id;
! 468: int res,option;
! 469: char *str;
1.1 root 470:
1.1.1.4 ! root 471: /* Get the instance ID */
! 472: instance_id = 0;
1.1 root 473:
1.1.1.4 ! root 474: /* Use the old VM file naming type */
! 475: vm_file_naming_type = 1;
1.1 root 476:
1.1.1.4 ! root 477: if ((str = cli_find_option(argc,argv,"-i"))) {
! 478: instance_id = atoi(str);
! 479: printf("Instance ID set to %d.\n",instance_id);
! 480: }
1.1 root 481:
1.1.1.4 ! root 482: if ((str = cli_find_option(argc,argv,"-N")))
! 483: vm_file_naming_type = atoi(str);
1.1.1.2 root 484:
1.1.1.4 ! root 485: /* Get the platform type */
! 486: *platform = cli_get_platform_type(argc,argv);
! 487:
! 488: /* Create the default instance */
! 489: if (!(vm = cli_create_instance("default",*platform,instance_id)))
! 490: exit(EXIT_FAILURE);
1.1 root 491:
492: opterr = 0;
493:
1.1.1.4 ! root 494: while((option = getopt_long(argc,argv,options_list,
! 495: cmd_line_lopts,NULL)) != -1)
! 496: {
1.1 root 497: switch(option)
498: {
1.1.1.4 ! root 499: /* Instance ID (already managed) */
! 500: case 'i':
! 501: break;
! 502:
! 503: /* Platform (already managed) */
! 504: case 'P':
! 505: break;
! 506:
1.1 root 507: /* RAM size */
508: case 'r':
1.1.1.4 ! root 509: vm->ram_size = strtol(optarg, NULL, 10);
! 510: printf("Virtual RAM size set to %d MB.\n",vm->ram_size);
1.1 root 511: break;
512:
513: /* ROM size */
514: case 'o':
1.1.1.4 ! root 515: vm->rom_size = strtol(optarg, NULL, 10);
! 516: printf("Virtual ROM size set to %d MB.\n",vm->rom_size);
1.1 root 517: break;
518:
519: /* NVRAM size */
520: case 'n':
1.1.1.4 ! root 521: vm->nvram_size = strtol(optarg, NULL, 10);
! 522: printf("NVRAM size set to %d KB.\n",vm->nvram_size);
1.1 root 523: break;
524:
1.1.1.4 ! root 525: /* Execution area size */
! 526: case OPT_EXEC_AREA:
! 527: vm->exec_area_size = atoi(optarg);
1.1 root 528: break;
529:
1.1.1.4 ! root 530: /* PCMCIA disk0 size */
! 531: case OPT_DISK0_SIZE:
! 532: vm->pcmcia_disk_size[0] = atoi(optarg);
! 533: printf("PCMCIA ATA disk0 size set to %u MB.\n",
! 534: vm->pcmcia_disk_size[0]);
1.1 root 535: break;
536:
1.1.1.4 ! root 537: /* PCMCIA disk1 size */
! 538: case OPT_DISK1_SIZE:
! 539: vm->pcmcia_disk_size[1] = atoi(optarg);
! 540: printf("PCMCIA ATA disk1 size set to %u MB.\n",
! 541: vm->pcmcia_disk_size[1]);
! 542: break;
! 543:
! 544: /* Config Register */
! 545: case 'c':
! 546: vm->conf_reg_setup = strtol(optarg, NULL, 0);
! 547: printf("Config. Register set to 0x%x.\n",vm->conf_reg_setup);
1.1 root 548: break;
549:
550: /* IOS configuration file */
551: case 'C':
1.1.1.4 ! root 552: vm_ios_set_config(vm,optarg);
1.1 root 553: break;
554:
1.1.1.3 root 555: /* Use physical memory to emulate RAM (no-mapped file) */
556: case 'X':
1.1.1.4 ! root 557: vm->ram_mmap = 0;
1.1.1.3 root 558: break;
559:
1.1 root 560: /* Alternate ROM */
561: case 'R':
1.1.1.4 ! root 562: vm->rom_filename = optarg;
1.1 root 563: break;
564:
1.1.1.4 ! root 565: /* Idle PC */
! 566: case OPT_IDLE_PC:
! 567: vm->idle_pc = strtoull(optarg,NULL,0);
! 568: printf("Idle PC set to 0x%llx.\n",vm->idle_pc);
1.1 root 569: break;
570:
1.1.1.4 ! root 571: /* Timer IRQ check interval */
! 572: case OPT_TIMER_ITV:
! 573: vm->timer_irq_check_itv = atoi(optarg);
1.1 root 574: break;
575:
1.1.1.4 ! root 576: /* Clock divisor */
! 577: case 'k':
! 578: vm->clock_divisor = atoi(optarg);
! 579:
! 580: if (!vm->clock_divisor) {
! 581: fprintf(stderr,"Invalid Clock Divisor specified!\n");
! 582: exit(EXIT_FAILURE);
! 583: }
! 584:
! 585: printf("Using a clock divisor of %d.\n",vm->clock_divisor);
1.1.1.3 root 586: break;
587:
1.1.1.4 ! root 588: /* Disable JIT */
! 589: case 'j':
! 590: vm->jit_use = FALSE;
1.1 root 591: break;
592:
1.1.1.4 ! root 593: /* VM debug level */
! 594: case OPT_VM_DEBUG:
! 595: vm->debug_level = atoi(optarg);
! 596: break;
1.1 root 597:
1.1.1.4 ! root 598: /* Log file */
! 599: case 'l':
! 600: if (!(log_file_name = strdup(optarg))) {
! 601: fprintf(stderr,"Unable to set log file name.\n");
1.1 root 602: exit(EXIT_FAILURE);
603: }
1.1.1.4 ! root 604: printf("Log file: writing to %s\n",log_file_name);
! 605: break;
1.1 root 606:
1.1.1.4 ! root 607: #if DEBUG_SYM_TREE
! 608: /* Symbol file */
! 609: case 'S':
! 610: vm->sym_filename = strdup(optarg);
1.1 root 611: break;
1.1.1.4 ! root 612: #endif
1.1 root 613:
614: /* TCP server for Console Port */
615: case 'T':
1.1.1.4 ! root 616: vm->vtty_con_type = VTTY_TYPE_TCP;
! 617: vm->vtty_con_tcp_port = atoi(optarg);
! 618: break;
! 619:
! 620: /* Serial interface for Console port */
! 621: case 'U':
! 622: vm->vtty_con_type = VTTY_TYPE_SERIAL;
! 623: if (vtty_parse_serial_option(&vm->vtty_con_serial_option,optarg)) {
! 624: fprintf(stderr,
! 625: "Invalid Console serial interface descriptor!\n");
! 626: exit(EXIT_FAILURE);
! 627: }
1.1 root 628: break;
629:
630: /* TCP server for AUX Port */
631: case 'A':
1.1.1.4 ! root 632: vm->vtty_aux_type = VTTY_TYPE_TCP;
! 633: vm->vtty_aux_tcp_port = atoi(optarg);
! 634: break;
! 635:
! 636: /* Serial interface for AUX port */
! 637: case 'B':
! 638: vm->vtty_aux_type = VTTY_TYPE_SERIAL;
! 639: if (vtty_parse_serial_option(&vm->vtty_aux_serial_option,optarg)) {
! 640: fprintf(stderr,"Invalid AUX serial interface descriptor!\n");
! 641: exit(EXIT_FAILURE);
! 642: }
1.1 root 643: break;
644:
645: /* Virtual ATM switch */
646: case 'a':
647: if (atmsw_start(optarg) == -1)
648: exit(EXIT_FAILURE);
649: break;
650:
1.1.1.3 root 651: /* Virtual Frame-Relay switch */
652: case 'f':
653: if (frsw_start(optarg) == -1)
654: exit(EXIT_FAILURE);
655: break;
656:
1.1.1.4 ! root 657: /* Virtual Ethernet switch */
! 658: case 'E':
! 659: if (ethsw_start(optarg) == -1)
! 660: exit(EXIT_FAILURE);
! 661: break;
! 662:
1.1 root 663: /* Virtual bridge */
664: case 'b':
665: if (netio_bridge_start(optarg) == -1)
666: exit(EXIT_FAILURE);
667: break;
668:
1.1.1.2 root 669: #ifdef GEN_ETH
670: /* Ethernet device list */
671: case 'e':
672: gen_eth_show_dev_list();
673: exit(EXIT_SUCCESS);
674: #endif
675:
1.1 root 676: /* Oops ! */
677: case '?':
1.1.1.4 ! root 678: show_usage(argc,argv,*platform);
1.1 root 679: exit(EXIT_FAILURE);
1.1.1.4 ! root 680:
! 681: /* Parse options specific to the platform */
! 682: default:
! 683: res = 0;
! 684:
! 685: switch(vm->type) {
! 686: case VM_TYPE_C7200:
! 687: res = cli_parse_c7200_options(vm,option);
! 688: break;
! 689: case VM_TYPE_C3600:
! 690: res = cli_parse_c3600_options(vm,option);
! 691: break;
! 692: }
! 693:
! 694: if (res == -1)
! 695: exit(EXIT_FAILURE);
1.1 root 696: }
697: }
698:
699: /* Last argument, this is the IOS filename */
700: if (optind == (argc - 1)) {
701: /* setting IOS image file */
1.1.1.4 ! root 702: vm_ios_set_image(vm,argv[optind]);
! 703: printf("IOS image file: %s\n\n",vm->ios_image);
1.1 root 704: } else {
705: /* IOS missing */
706: fprintf(stderr,"Please specify an IOS image filename\n");
1.1.1.4 ! root 707: show_usage(argc,argv,*platform);
1.1 root 708: exit(EXIT_FAILURE);
709: }
710:
1.1.1.4 ! root 711: vm_release(vm);
! 712: return(0);
! 713: }
! 714:
! 715: /*
! 716: * Run in hypervisor mode with a config file if the "-H" option
! 717: * is present in command line.
! 718: */
! 719: static int run_hypervisor(int argc,char *argv[])
! 720: {
! 721: char *options_list = "H:l:hN:";
! 722: int i,option;
! 723:
! 724: for(i=1;i<argc;i++)
! 725: if (!strcmp(argv[i],"-H")) {
! 726: hypervisor_mode = 1;
! 727: break;
1.1 root 728: }
729:
1.1.1.4 ! root 730: /* standard mode with one instance */
! 731: if (!hypervisor_mode)
! 732: return(FALSE);
! 733:
! 734: opterr = 0;
! 735: while((option = getopt(argc,argv,options_list)) != -1) {
! 736: switch(option)
! 737: {
! 738: /* Hypervisor TCP port */
! 739: case 'H':
! 740: hypervisor_tcp_port = atoi(optarg);
! 741: break;
! 742:
! 743: /* Log file */
! 744: case 'l':
! 745: if (!(log_file_name = malloc(strlen(optarg)+1))) {
! 746: fprintf(stderr,"Unable to set log file name.\n");
! 747: exit(EXIT_FAILURE);
! 748: }
! 749: strcpy(log_file_name, optarg);
! 750: printf("Log file: writing to %s\n",log_file_name);
! 751: break;
! 752:
! 753: /* VM file naming type */
! 754: case 'N':
! 755: vm_file_naming_type = atoi(optarg);
! 756: break;
! 757:
! 758: /* Oops ! */
! 759: case '?':
! 760: show_usage(argc,argv,VM_TYPE_C7200);
! 761: exit(EXIT_FAILURE);
! 762: }
1.1 root 763: }
764:
1.1.1.4 ! root 765: return(TRUE);
! 766: }
1.1 root 767:
1.1.1.4 ! root 768: /* Delete all objects */
! 769: void dynamips_reset(void)
! 770: {
! 771: printf("Shutdown in progress...\n");
1.1 root 772:
1.1.1.4 ! root 773: /* Delete all C7200 and C3600 instances */
! 774: c7200_delete_all_instances();
! 775: c3600_delete_all_instances();
! 776:
! 777: /* Delete ATM and Frame-Relay switches + bridges */
! 778: netio_bridge_delete_all();
! 779: atmsw_delete_all();
! 780: frsw_delete_all();
! 781: ethsw_delete_all();
1.1 root 782:
1.1.1.4 ! root 783: /* Delete all NIO descriptors */
! 784: netio_delete_all();
1.1 root 785:
1.1.1.4 ! root 786: printf("Shutdown completed.\n");
! 787: }
1.1 root 788:
1.1.1.4 ! root 789: int main(int argc,char *argv[])
! 790: {
! 791: vm_instance_t *vm;
! 792: int platform,res;
1.1 root 793:
1.1.1.4 ! root 794: /* Default emulation: Cisco 7200 */
! 795: platform = VM_TYPE_C7200;
1.1 root 796:
1.1.1.4 ! root 797: #ifdef PROFILE
! 798: atexit(profiler_savestat);
! 799: #endif
! 800:
! 801: printf("Cisco 7200 Simulation Platform (version %s)\n",sw_version);
! 802: printf("Copyright (c) 2005,2006 Christophe Fillot.\n\n");
! 803:
! 804: /* Initialize object registry */
! 805: registry_init();
! 806:
! 807: /* Initialize ATM module (for HEC checksums) */
! 808: atm_init();
! 809:
! 810: /* Initialize CRC functions */
! 811: crc_init();
! 812:
! 813: /* Initialize NetIO code */
! 814: netio_rxl_init();
! 815:
! 816: /* Initialize NetIO packet filters */
! 817: netio_filter_load_all();
! 818:
! 819: /* Initialize VTTY code */
! 820: vtty_init();
! 821:
! 822: /* Parse standard command line */
! 823: if (!run_hypervisor(argc,argv))
! 824: parse_std_cmd_line(argc,argv,&platform);
! 825:
! 826: /* Create general log file */
! 827: create_log_file();
! 828:
! 829: /* Periodic tasks initialization */
! 830: if (ptask_init(0) == -1)
1.1 root 831: exit(EXIT_FAILURE);
832:
1.1.1.4 ! root 833: /* Create instruction lookup tables */
! 834: mips64_jit_create_ilt();
! 835: mips64_exec_create_ilt();
1.1 root 836:
837: setup_signals();
838:
1.1.1.4 ! root 839: if (!hypervisor_mode) {
! 840: /* Initialize the default instance */
! 841: vm = vm_acquire("default");
! 842: assert(vm != NULL);
! 843:
! 844: switch(platform) {
! 845: case VM_TYPE_C7200:
! 846: res = c7200_init_instance(VM_C7200(vm));
! 847: break;
! 848: case VM_TYPE_C3600:
! 849: res = c3600_init_instance(VM_C3600(vm));
! 850: break;
! 851: default:
! 852: res = -1;
! 853: }
! 854:
! 855: if (res == -1) {
! 856: fprintf(stderr,"Unable to initialize router instance.\n");
! 857: exit(EXIT_FAILURE);
! 858: }
1.1 root 859:
1.1.1.4 ! root 860: #if DEBUG_PERF_COUNTER
! 861: {
! 862: m_uint64_t prev = 0,delta;
! 863: while(vm->status == VM_STATUS_RUNNING) {
! 864: delta = vm->boot_cpu->perf_counter - prev;
! 865: prev = vm->boot_cpu->perf_counter;
! 866: printf("delta = %llu\n",delta);
! 867: sleep(1);
! 868: }
! 869: }
! 870: #else
! 871: /* Start instance monitoring */
! 872: vm_monitor(vm);
! 873: #endif
1.1 root 874:
1.1.1.4 ! root 875: /* Free resources used by instance */
! 876: vm_release(vm);
! 877: } else {
! 878: hypervisor_tcp_server(hypervisor_tcp_port);
! 879: }
1.1 root 880:
1.1.1.4 ! root 881: dynamips_reset();
! 882: close_log_file();
1.1 root 883: return(0);
884: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.