Annotation of cf/dynamips.c, revision 1.1.1.4

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.